@ashishpandeyone/cdk-lambda-web-function 0.1.2 → 0.1.3

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.
@@ -37,10 +37,13 @@ exports.WebFunctionEndpoint = void 0;
37
37
  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
38
38
  const node_crypto_1 = require("node:crypto");
39
39
  const aws_cdk_lib_1 = require("aws-cdk-lib");
40
+ const cloudwatch = __importStar(require("aws-cdk-lib/aws-cloudwatch"));
40
41
  const lambda = __importStar(require("aws-cdk-lib/aws-lambda"));
41
42
  const constructs_1 = require("constructs");
42
43
  const enums_1 = require("./enums");
43
44
  const endpoint_lookup_1 = require("./private/endpoint-lookup");
45
+ const metrics_1 = require("./private/metrics");
46
+ const regional_alarm_1 = require("./private/regional-alarm");
44
47
  const traffic_shift_1 = require("./private/traffic-shift");
45
48
  const validation_1 = require("./private/validation");
46
49
  const web_function_grants_1 = require("./web-function-grants");
@@ -50,7 +53,7 @@ const web_function_grants_1 = require("./web-function-grants");
50
53
  * Endpoints are created only through `WebFunction`, which owns their log groups in every region, so the constructor is private.
51
54
  */
52
55
  class WebFunctionEndpoint extends constructs_1.Construct {
53
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@ashishpandeyone/cdk-lambda-web-function.WebFunctionEndpoint", version: "0.1.2" };
56
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@ashishpandeyone/cdk-lambda-web-function.WebFunctionEndpoint", version: "0.1.3" };
54
57
  /**
55
58
  * Creates an endpoint of a Web Function. Used by `WebFunction`.
56
59
  *
@@ -79,6 +82,11 @@ class WebFunctionEndpoint extends constructs_1.Construct {
79
82
  url;
80
83
  /** Grants on this endpoint (e.g. `grants.invoke(principal)`). */
81
84
  grants;
85
+ /**
86
+ * The alarms this endpoint created for its deployment's `rollbackOn`, one per threshold in every region it serves from
87
+ * (the home region's first). Empty without `rollbackOn`.
88
+ */
89
+ rollbackAlarms = [];
82
90
  homeRegion;
83
91
  webFunction;
84
92
  resource;
@@ -125,6 +133,12 @@ class WebFunctionEndpoint extends constructs_1.Construct {
125
133
  if (props.revision !== undefined || props.additionalRevisions !== undefined) {
126
134
  throw new Error(`${this.node.path}: an endpoint with a ${props.deployment._kind} deployment always moves to the current revision; it can't also set revision or additionalRevisions`);
127
135
  }
136
+ const rollbackAlarmArns = props.deployment._rollbackOn ? this.createRollbackAlarms(props.deployment._rollbackOn) : [];
137
+ const waitSeconds = props.deployment._waitSeconds;
138
+ const rollback = props.deployment._rollbackOn;
139
+ if (rollback && waitSeconds < rollback.period.toSeconds() * rollback.evaluationPeriods + 120) {
140
+ aws_cdk_lib_1.Annotations.of(this).addWarningV2('@cdk-lambda-web:rollbackSlowerThanStep', `rollbackOn needs ${rollback.evaluationPeriods} period(s) of ${rollback.period.toHumanString()} plus about 2 minutes of CloudWatch delay to fire, longer than each ${props.deployment._kind} step (${aws_cdk_lib_1.Duration.seconds(waitSeconds).toHumanString()}): a bad revision can reach the next step before its alarm fires.`);
141
+ }
128
142
  // Moves the traffic in steps before CloudFormation writes the endpoint, which then finds it already done.
129
143
  const shift = new traffic_shift_1.TrafficShift(this, 'Deployment', {
130
144
  functionName: props.webFunction.webFunctionName,
@@ -132,6 +146,7 @@ class WebFunctionEndpoint extends constructs_1.Construct {
132
146
  endpointName: this.endpointName,
133
147
  revisionId: props.currentRevision.revisionId,
134
148
  deployment: props.deployment,
149
+ alarmArns: rollbackAlarmArns,
135
150
  endpointConfig: {
136
151
  endpointType,
137
152
  authType: props.authType,
@@ -142,6 +157,9 @@ class WebFunctionEndpoint extends constructs_1.Construct {
142
157
  },
143
158
  });
144
159
  resource.node.addDependency(shift);
160
+ // Alarms in other regions are only referenced by ARN.
161
+ for (const alarm of this.node.findAll().filter((c) => c instanceof regional_alarm_1.RegionalAlarm))
162
+ shift.node.addDependency(alarm);
145
163
  }
146
164
  if (props.revision !== undefined || props.additionalRevisions !== undefined) {
147
165
  this.routeTraffic(props.revision ?? props.currentRevision, props.additionalRevisions);
@@ -202,6 +220,66 @@ class WebFunctionEndpoint extends constructs_1.Construct {
202
220
  _revisionIds() {
203
221
  return this.weights.map((w) => w.revisionId);
204
222
  }
223
+ /**
224
+ * A metric of this endpoint in `AWS/Lambda/Web` (dimensions `FunctionName` and `EndpointName`).
225
+ *
226
+ * Metrics are published in the region that served the request: pass `region` for one of the endpoint's
227
+ * other regions. An alarm can only use metrics from its own stack's region.
228
+ *
229
+ * @default - sum over 1 minute, in the home region
230
+ */
231
+ metric(metricName, props) {
232
+ return new cloudwatch.Metric({
233
+ namespace: metrics_1.WEB_NAMESPACE,
234
+ metricName,
235
+ dimensionsMap: (0, metrics_1.endpointDimensions)(this.metricIds()),
236
+ statistic: cloudwatch.Stats.SUM,
237
+ period: metrics_1.DEFAULT_PERIOD,
238
+ ...props,
239
+ });
240
+ }
241
+ /** Requests the endpoint served (`ExecutedRequests`). There's no separate count of successful (2XX) responses. */
242
+ metricRequests(props) {
243
+ return this.metric(metrics_1.REQUESTS, props);
244
+ }
245
+ /**
246
+ * Requests answered with a 4XX status (`HTTPResponseStatusClass4XX`), including 429s from `rateLimit` and `maxEnvironments`.
247
+ * The metric only exists once it's non-zero, so alarms should treat missing data as not breaching.
248
+ */
249
+ metricClientErrors(props) {
250
+ return this.metric(metrics_1.CLIENT_ERRORS, props);
251
+ }
252
+ /**
253
+ * Requests answered with a 5XX status (`HTTPResponseStatusClass5XX`). Includes the platform's 503s while the endpoint
254
+ * scales up for a sudden burst, not only your application's errors. The metric only exists once it's non-zero.
255
+ */
256
+ metricServerErrors(props) {
257
+ return this.metric(metrics_1.SERVER_ERRORS, props);
258
+ }
259
+ /** The percentage of requests answered with a 4XX status (math expression; periods with no 4XX count as 0). */
260
+ metricClientErrorRate(props) {
261
+ return this.rate(metrics_1.CLIENT_ERRORS, 'Client error rate (%)', props);
262
+ }
263
+ /** The percentage of requests answered with a 5XX status (math expression; periods with no 5XX count as 0). */
264
+ metricServerErrorRate(props) {
265
+ return this.rate(metrics_1.SERVER_ERRORS, 'Server error rate (%)', props);
266
+ }
267
+ /**
268
+ * Execution environments serving the endpoint (`EndpointActiveEnvironments`), to compare with `maxEnvironments`.
269
+ *
270
+ * @default - maximum over 1 minute, in the home region
271
+ */
272
+ metricActiveEnvironments(props) {
273
+ return this.usageMetric('EndpointActiveEnvironments', cloudwatch.Stats.MAXIMUM, props);
274
+ }
275
+ /** Requests rejected with 429 because the endpoint reached its `rateLimit` (`EndpointRequestThrottles`). */
276
+ metricRequestThrottles(props) {
277
+ return this.usageMetric('EndpointRequestThrottles', cloudwatch.Stats.SUM, props);
278
+ }
279
+ /** Requests rejected with 429 because the endpoint reached `maxEnvironments` (`EndpointActiveEnvironmentThrottles`). */
280
+ metricEnvironmentThrottles(props) {
281
+ return this.usageMetric('EndpointActiveEnvironmentThrottles', cloudwatch.Stats.SUM, props);
282
+ }
205
283
  /**
206
284
  * Allows `grantee` to call this endpoint. Shortcut for `grants.invoke(grantee)`.
207
285
  * [disable-awslint:no-grants]
@@ -209,6 +287,81 @@ class WebFunctionEndpoint extends constructs_1.Construct {
209
287
  grantInvoke(grantee) {
210
288
  return this.grants.invoke(grantee);
211
289
  }
290
+ metricIds() {
291
+ return { functionName: this.webFunction.webFunctionName, endpointName: this.endpointName };
292
+ }
293
+ rate(errorMetric, label, props) {
294
+ const period = props?.period ?? metrics_1.DEFAULT_PERIOD;
295
+ const options = { period, region: props?.region, account: props?.account };
296
+ return new cloudwatch.MathExpression({
297
+ expression: (0, metrics_1.rateExpression)(1),
298
+ usingMetrics: { requests: this.metric(metrics_1.REQUESTS, options), errors: this.metric(errorMetric, options) },
299
+ period,
300
+ label: props?.label ?? label,
301
+ });
302
+ }
303
+ usageMetric(metricName, statistic, props) {
304
+ return new cloudwatch.Metric({
305
+ namespace: metrics_1.USAGE_NAMESPACE,
306
+ metricName,
307
+ dimensionsMap: { ...(0, metrics_1.endpointDimensions)(this.metricIds()), ExecutionRegion: props?.region ?? this.homeRegion },
308
+ statistic,
309
+ period: metrics_1.DEFAULT_PERIOD,
310
+ ...props,
311
+ });
312
+ }
313
+ /** One alarm per threshold in every serving region: a CloudFormation alarm at home, a custom resource elsewhere. Returns their ARNs. */
314
+ createRollbackAlarms(rollback) {
315
+ const thresholds = [
316
+ { key: 'ServerErrors', short: '5xx', metric: metrics_1.SERVER_ERRORS, status: '5XX', threshold: rollback.serverErrorRate },
317
+ { key: 'ClientErrors', short: '4xx', metric: metrics_1.CLIENT_ERRORS, status: '4XX', threshold: rollback.clientErrorRate },
318
+ ];
319
+ const arns = [];
320
+ for (const t of thresholds) {
321
+ if (t.threshold === undefined)
322
+ continue;
323
+ for (const region of this.regions) {
324
+ const description = `Rolls back deployments of endpoint ${this.endpointName} of ${this.webFunction.webFunctionName} when more than `
325
+ + `${t.threshold}% of its requests in ${region} get a ${t.status} response (${rollback.evaluationPeriods} x ${rollback.period.toHumanString()}, `
326
+ + `periods with fewer than ${rollback.minimumRequests} requests ignored).`;
327
+ if (region === this.homeRegion) {
328
+ const alarm = new cloudwatch.Alarm(this, `Rollback${t.key}`, {
329
+ metric: new cloudwatch.MathExpression({
330
+ expression: (0, metrics_1.rateExpression)(rollback.minimumRequests),
331
+ usingMetrics: {
332
+ requests: this.metric(metrics_1.REQUESTS, { period: rollback.period }),
333
+ errors: this.metric(t.metric, { period: rollback.period }),
334
+ },
335
+ period: rollback.period,
336
+ label: `${t.status} rate (%)`,
337
+ }),
338
+ threshold: t.threshold,
339
+ evaluationPeriods: rollback.evaluationPeriods,
340
+ comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
341
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
342
+ alarmDescription: description,
343
+ });
344
+ this.rollbackAlarms.push(alarm);
345
+ arns.push(alarm.alarmArn);
346
+ }
347
+ else {
348
+ const alarm = new regional_alarm_1.RegionalAlarm(this, `Rollback${t.key}-${region}`, {
349
+ region,
350
+ alarmName: `${regional_alarm_1.ALARM_NAME_PREFIX}${this.webFunction.webFunctionName}-${this.endpointName}-${t.short}-rate`,
351
+ alarmDescription: description,
352
+ metrics: (0, metrics_1.rateAlarmQueries)(this.metricIds(), t.metric, rollback.period, rollback.minimumRequests),
353
+ threshold: t.threshold,
354
+ evaluationPeriods: rollback.evaluationPeriods,
355
+ comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
356
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
357
+ });
358
+ this.rollbackAlarms.push(cloudwatch.Alarm.fromAlarmArn(this, `Rollback${t.key}-${region}-Ref`, alarm.alarmArn));
359
+ arns.push(alarm.alarmArn);
360
+ }
361
+ }
362
+ }
363
+ return arns;
364
+ }
212
365
  }
213
366
  exports.WebFunctionEndpoint = WebFunctionEndpoint;
214
367
  function normaliseRegions(scope, endpointType, homeRegion, regions) {
@@ -282,4 +435,4 @@ function defaultEndpointName(prefix, seed, endpointType, extraRegions) {
282
435
  const hash = (0, node_crypto_1.createHash)('sha256').update([...(seed !== undefined ? [seed] : []), endpointType, ...extraRegions].join(',')).digest('hex').slice(0, 8);
283
436
  return `${prefix}-${hash}`;
284
437
  }
285
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWZ1bmN0aW9uLWVuZHBvaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dlYi1mdW5jdGlvbi1lbmRwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQXlDO0FBQ3pDLDZDQUFxRTtBQUVyRSwrREFBaUQ7QUFDakQsMkNBQXVDO0FBQ3ZDLG1DQUF1RTtBQUN2RSwrREFBMkQ7QUFDM0QsMkRBQXVEO0FBQ3ZELHFEQUFxRjtBQUdyRiwrREFBMEQ7QUFxSTFEOzs7O0dBSUc7QUFDSCxNQUFhLG1CQUFvQixTQUFRLHNCQUFTOztJQUNoRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUErQjtRQUNqRixPQUFPLElBQUksbUJBQW1CLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsMkJBQTJCO0lBQ1gsWUFBWSxDQUFTO0lBRXJDLDBCQUEwQjtJQUNWLFdBQVcsQ0FBUztJQUVwQyw4Q0FBOEM7SUFDOUIsWUFBWSxDQUEwQjtJQUV0RCxxREFBcUQ7SUFDckMsUUFBUSxDQUFzQjtJQUU5QywyR0FBMkc7SUFDM0YsT0FBTyxDQUFXO0lBRWxDOztPQUVHO0lBQ2EsVUFBVSxDQUFTO0lBRW5DOztPQUVHO0lBQ2EsR0FBRyxDQUFTO0lBRTVCLGlFQUFpRTtJQUNqRCxNQUFNLENBQW9CO0lBRXpCLFVBQVUsQ0FBUztJQUNuQixXQUFXLENBQWU7SUFDMUIsUUFBUSxDQUFnQztJQUNqRCxPQUFPLENBQXlEO0lBQ2hFLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDTixPQUFPLENBQVU7SUFDMUIsTUFBTSxDQUFrQjtJQUVoQyxZQUFvQixLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUErQjtRQUMvRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFD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LENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDckosT0FBTyxHQUFHLE1BQU0sSUFBSSxJQUFJLEVBQUUsQ0FBQztBQUM3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IEFubm90YXRpb25zLCBTdGFjaywgVG9rZW4sIFZhbGlkYXRpb25zIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBXZWJGdW5jdGlvbkF1dGhUeXBlLCBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZSB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IHsgRW5kcG9pbnRMb29rdXAgfSBmcm9tICcuL3ByaXZhdGUvZW5kcG9pbnQtbG9va3VwJztcbmltcG9ydCB7IFRyYWZmaWNTaGlmdCB9IGZyb20gJy4vcHJpdmF0ZS90cmFmZmljLXNoaWZ0JztcbmltcG9ydCB7IENGTl9WQUxJREFURV9VTktOT1dOX1RZUEUsIGFzc2VydFJlc291cmNlTmFtZSB9IGZyb20gJy4vcHJpdmF0ZS92YWxpZGF0aW9uJztcbmltcG9ydCB0eXBlIHsgSVdlYkZ1bmN0aW9uIH0gZnJvbSAnLi93ZWItZnVuY3Rpb24nO1xuaW1wb3J0IHR5cGUgeyBXZWJGdW5jdGlvbkRlcGxveW1lbnQgfSBmcm9tICcuL3dlYi1mdW5jdGlvbi1kZXBsb3ltZW50JztcbmltcG9ydCB7IFdlYkZ1bmN0aW9uR3JhbnRzIH0gZnJvbSAnLi93ZWItZnVuY3Rpb24tZ3JhbnRzJztcbmltcG9ydCB0eXBlIHsgSVdlYkZ1bmN0aW9uUmV2aXNpb24gfSBmcm9tICcuL3dlYi1mdW5jdGlvbi1yZXZpc2lvbic7XG5cbi8qKlxuICogQSByZXZpc2lvbiBhbmQgdGhlIHNoYXJlIG9mIGFuIGVuZHBvaW50J3MgdHJhZmZpYyBpdCByZWNlaXZlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXZWJGdW5jdGlvblJldmlzaW9uV2VpZ2h0IHtcbiAgLyoqIFRoZSByZXZpc2lvbi4gKi9cbiAgcmVhZG9ubHkgcmV2aXNpb246IElXZWJGdW5jdGlvblJldmlzaW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgcmV2aXNpb24ncyBzaGFyZSBvZiB0aGUgZW5kcG9pbnQncyB0cmFmZmljLCBhcyBhIGZyYWN0aW9uIChsaWtlIGBsYW1iZGEuQWxpYXNgIGBhZGRpdGlvbmFsVmVyc2lvbnNgKS5cbiAgICogTXVzdCBiZSBhIHdob2xlIHBlcmNlbnRhZ2UgZnJvbSAwLjAxIHRvIDAuOTkuXG4gICAqL1xuICByZWFkb25seSB3ZWlnaHQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBhIFdlYiBGdW5jdGlvbidzIGVuZHBvaW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdlYkZ1bmN0aW9uRW5kcG9pbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXJlIHRoZSBlbmRwb2ludCBzZXJ2ZXMgdHJhZmZpYyBmcm9tLlxuICAgKlxuICAgKiBAZGVmYXVsdCBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZS5IT01FX1JFR0lPTlxuICAgKi9cbiAgcmVhZG9ubHkgZW5kcG9pbnRUeXBlPzogV2ViRnVuY3Rpb25FbmRwb2ludFR5cGU7XG5cbiAgLyoqXG4gICAqIFJlZ2lvbnMgdG8gc2VydmUgZnJvbSBpbiBhZGRpdGlvbiB0byB0aGUgaG9tZSByZWdpb24gKHRoZSBzdGFjaydzIHJlZ2lvbikuXG4gICAqIFJlcXVpcmVkIChhdCBsZWFzdCBvbmUpIGZvciBgTVVMVElfUkVHSU9OYCBhbmQgYFBFUl9SRUdJT05gOyBtdXN0IGJlIGVtcHR5IGZvciBgSE9NRV9SRUdJT05gLlxuICAgKlxuICAgKiBDaGFuZ2luZyB0aGlzIGNyZWF0ZXMgYSBuZXcgZW5kcG9pbnQgd2l0aCBhIG5ldyBVUkwuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZXh0cmEgcmVnaW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgcmVnaW9ucz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgZW5kcG9pbnQncyBuYW1lLCBzaG93biBpbiBsb2dzIChgZW5kcG9pbnROYW1lYCkgYW5kIGluIHRoZSBgbGFtYmRhLXdlYi1lbmRwb2ludC1uYW1lYCBoZWFkZXIuXG4gICAqIE5hbWVzIGFyZSB1bmlxdWUgcGVyIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBXaGVuIG9taXR0ZWQsIHRoZSBuYW1lIGVuZHMgaW4gYSBoYXNoIG9mIHRoZSBlbmRwb2ludCB0eXBlIGFuZCByZWdpb25zLCBzbyBjaGFuZ2luZyBlaXRoZXIgZGVwbG95c1xuICAgKiBhIG5ldyBlbmRwb2ludCBjbGVhbmx5LiBXaGVuIHNldCwgY2hhbmdpbmcgdGhlIGVuZHBvaW50IHR5cGUgb3IgcmVnaW9ucyBhbHNvIHJlcXVpcmVzIGEgbmV3IG5hbWU6XG4gICAqIHR3byBlbmRwb2ludHMgb2Ygb25lIGZ1bmN0aW9uIGNhbid0IHNoYXJlIGEgbmFtZSwgYW5kIENsb3VkRm9ybWF0aW9uIGNyZWF0ZXMgdGhlIHJlcGxhY2VtZW50XG4gICAqIGJlZm9yZSBkZWxldGluZyB0aGUgb2xkIG9uZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBgZGVmYXVsdC08aGFzaD5gIGZvciB0aGUgZnVuY3Rpb24ncyBkZWZhdWx0IGVuZHBvaW50LCBgPGlkPi08aGFzaD5gIGZvciBlbmRwb2ludHMgYWRkZWQgd2l0aCBgYWRkRW5kcG9pbnRgXG4gICAqL1xuICByZWFkb25seSBlbmRwb2ludE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgZGVzY3JpcHRpb24gb2YgdGhlIGVuZHBvaW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGRlc2NyaXB0aW9uXG4gICAqL1xuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG1vc3QgcmVxdWVzdHMgcGVyIHNlY29uZCB0aGUgZW5kcG9pbnQgYWNjZXB0czsgZXhjZXNzIHJlcXVlc3RzIGdldCBIVFRQIDQyOS5cbiAgICogQWxsb3dlZDogMCAoYmxvY2tzIGFsbCB0cmFmZmljKSwgMTAw4oCTMSwwMDAgaW4gc3RlcHMgb2YgMTAwLCBvciAyLDAwMOKAkzEwLDAwMCBpbiBzdGVwcyBvZiAxLDAwMC5cbiAgICpcbiAgICogRW5mb3JjZWQgc2VwYXJhdGVseSBpbiBlYWNoIHJlZ2lvbiB0aGUgZW5kcG9pbnQgc2VydmVzIGZyb20sIHNvIGEgbXVsdGktcmVnaW9uIGVuZHBvaW50XG4gICAqIGNhbiBhY2NlcHQgdGhpcyBtYW55IHJlcXVlc3RzIHBlciBzZWNvbmQgaW4gZXZlcnkgcmVnaW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGxpbWl0IGJleW9uZCB0aGUgc2VydmljZSBxdW90YSBvZiAxMCwwMDAgcmVxdWVzdHMgcGVyIHNlY29uZCBwZXIgZW5kcG9pbnQgKHBlciByZWdpb24pXG4gICAqL1xuICByZWFkb25seSByYXRlTGltaXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBtb3N0IGV4ZWN1dGlvbiBlbnZpcm9ubWVudHMgdGhlIGVuZHBvaW50IG1heSB1c2UgKDLigJMxMCwwMDApLiBFYWNoIG9uZSB1c2VzIDIgdkNQVXMgb2YgdGhlIGFjY291bnQncyBxdW90YS5cbiAgICpcbiAgICogRW5mb3JjZWQgc2VwYXJhdGVseSBpbiBlYWNoIHJlZ2lvbiB0aGUgZW5kcG9pbnQgc2VydmVzIGZyb20uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc2NhbGVzIHdpdGhpbiB0aGUgYWNjb3VudCdzIHZDUFUgcXVvdGFcbiAgICovXG4gIHJlYWRvbmx5IG1heEVudmlyb25tZW50cz86IG51bWJlcjtcblxuICAvKipcbiAgICogSG93IHRoZSBlbmRwb2ludCBtb3ZlcyBpdHMgdHJhZmZpYyB0byBhIG5ldyByZXZpc2lvbjogYWxsIGF0IG9uY2UsIG9yIGluIHN0ZXBzXG4gICAqIChgV2ViRnVuY3Rpb25EZXBsb3ltZW50LmNhbmFyeSgpYCBvciBgbGluZWFyKClgKSB0aGF0IHdhdGNoIENsb3VkV2F0Y2ggYWxhcm1zIGFuZCBtb3ZlXG4gICAqIHRoZSB0cmFmZmljIGJhY2sgd2hlbiBvbmUgZ29lcyBpbnRvIEFMQVJNLlxuICAgKlxuICAgKiBBIGRlcGxveW1lbnQgaW4gc3RlcHMgY2FuJ3QgYmUgY29tYmluZWQgd2l0aCBgcmV2aXNpb25gLCBgYWRkaXRpb25hbFJldmlzaW9uc2Agb3IgYHJvdXRlVHJhZmZpYygpYC5cbiAgICpcbiAgICogQGRlZmF1bHQgV2ViRnVuY3Rpb25EZXBsb3ltZW50LmFsbEF0T25jZSgpXG4gICAqL1xuICByZWFkb25seSBkZXBsb3ltZW50PzogV2ViRnVuY3Rpb25EZXBsb3ltZW50O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBXZWJGdW5jdGlvbi5hZGRFbmRwb2ludGAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWRkV2ViRnVuY3Rpb25FbmRwb2ludE9wdGlvbnMgZXh0ZW5kcyBXZWJGdW5jdGlvbkVuZHBvaW50T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIb3cgY2FsbGVycyBvZiB0aGlzIGVuZHBvaW50IGFyZSBhdXRoZW50aWNhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYXV0aFR5cGU6IFdlYkZ1bmN0aW9uQXV0aFR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSByZXZpc2lvbiB0aGUgZW5kcG9pbnQgc2VydmVzLCBlLmcuIGFuIGVhcmxpZXIgb25lIGZyb20gYFdlYkZ1bmN0aW9uUmV2aXNpb24uZnJvbVJldmlzaW9uQXR0cmlidXRlc2BcbiAgICogdG8ga2VlcCB0aGlzIGVuZHBvaW50IG9uIGl0IHdoaWxlIG90aGVycyBtb3ZlIG9uLiBTYW1lIGFzIGNhbGxpbmcgYHJvdXRlVHJhZmZpY2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGZ1bmN0aW9uJ3MgY3VycmVudCByZXZpc2lvbiAoYGN1cnJlbnRSZXZpc2lvbmApXG4gICAqL1xuICByZWFkb25seSByZXZpc2lvbj86IElXZWJGdW5jdGlvblJldmlzaW9uO1xuXG4gIC8qKlxuICAgKiBBIHNlY29uZCByZXZpc2lvbiBhbmQgaXRzIHNoYXJlIG9mIHRoZSBlbmRwb2ludCdzIHRyYWZmaWM7IGByZXZpc2lvbmAgZ2V0cyB0aGUgcmVzdC5cbiAgICogQW4gZW5kcG9pbnQgcm91dGVzIHRvIGF0IG1vc3QgdHdvIHJldmlzaW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhbGwgdHJhZmZpYyBnb2VzIHRvIGByZXZpc2lvbmBcbiAgICovXG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxSZXZpc2lvbnM/OiBXZWJGdW5jdGlvblJldmlzaW9uV2VpZ2h0W107XG59XG5cbi8qKlxuICogSW50ZXJuYWw6IGhvdyBgV2ViRnVuY3Rpb25gIGNyZWF0ZXMgaXRzIGVuZHBvaW50cy4gTm90IHBhcnQgb2YgdGhlIHB1YmxpYyBBUEkuXG4gKi9cbmludGVyZmFjZSBXZWJGdW5jdGlvbkVuZHBvaW50UHJvcHMgZXh0ZW5kcyBBZGRXZWJGdW5jdGlvbkVuZHBvaW50T3B0aW9ucyB7XG4gIC8qKiBUaGUgZnVuY3Rpb24gdGhhdCBvd25zIHRoZSBlbmRwb2ludC4gKi9cbiAgcmVhZG9ubHkgd2ViRnVuY3Rpb246IElXZWJGdW5jdGlvbjtcblxuICAvKiogVGhlIGZ1bmN0aW9uJ3MgY3VycmVudCByZXZpc2lvbiwgc2VydmVkIHVubGVzcyBgcmV2aXNpb25gIGlzIGdpdmVuLiAqL1xuICByZWFkb25seSBjdXJyZW50UmV2aXNpb246IElXZWJGdW5jdGlvblJldmlzaW9uO1xuXG4gIC8qKiBQcmVmaXggb2YgdGhlIGdlbmVyYXRlZCBlbmRwb2ludCBuYW1lLiAqL1xuICByZWFkb25seSBuYW1lUHJlZml4OiBzdHJpbmc7XG5cbiAgLyoqIEV4dHJhIGlucHV0IHRvIHRoZSBnZW5lcmF0ZWQgbmFtZSdzIGhhc2ggKHRoZSBjb25zdHJ1Y3QgSUQgb2YgYW4gYWRkZWQgZW5kcG9pbnQpLiAqL1xuICByZWFkb25seSBuYW1lU2VlZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBbiBIVFRQUyBlbmRwb2ludCBvZiBhIFdlYiBGdW5jdGlvbjogYGZuLmVuZHBvaW50YCAodGhlIGRlZmF1bHQgb25lKSBvciB0aGUgcmVzdWx0IG9mIGBmbi5hZGRFbmRwb2ludCgpYC5cbiAqXG4gKiBFbmRwb2ludHMgYXJlIGNyZWF0ZWQgb25seSB0aHJvdWdoIGBXZWJGdW5jdGlvbmAsIHdoaWNoIG93bnMgdGhlaXIgbG9nIGdyb3VwcyBpbiBldmVyeSByZWdpb24sIHNvIHRoZSBjb25zdHJ1Y3RvciBpcyBwcml2YXRlLlxuICovXG5leHBvcnQgY2xhc3MgV2ViRnVuY3Rpb25FbmRwb2ludCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGVuZHBvaW50IG9mIGEgV2ViIEZ1bmN0aW9uLiBVc2VkIGJ5IGBXZWJGdW5jdGlvbmAuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBfY3JlYXRlKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBXZWJGdW5jdGlvbkVuZHBvaW50UHJvcHMpOiBXZWJGdW5jdGlvbkVuZHBvaW50IHtcbiAgICByZXR1cm4gbmV3IFdlYkZ1bmN0aW9uRW5kcG9pbnQoc2NvcGUsIGlkLCBwcm9wcyk7XG4gIH1cblxuICAvKiogVGhlIGVuZHBvaW50J3MgbmFtZS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGVuZHBvaW50TmFtZTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgZW5kcG9pbnQncyBBUk4uICovXG4gIHB1YmxpYyByZWFkb25seSBlbmRwb2ludEFybjogc3RyaW5nO1xuXG4gIC8qKiBXaGVyZSB0aGUgZW5kcG9pbnQgc2VydmVzIHRyYWZmaWMgZnJvbS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGVuZHBvaW50VHlwZTogV2ViRnVuY3Rpb25FbmRwb2ludFR5cGU7XG5cbiAgLyoqIEhvdyBjYWxsZXJzIG9mIHRoZSBlbmRwb2ludCBhcmUgYXV0aGVudGljYXRlZC4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGF1dGhUeXBlOiBXZWJGdW5jdGlvbkF1dGhUeXBlO1xuXG4gIC8qKiBFdmVyeSByZWdpb24gdGhlIGVuZHBvaW50IHNlcnZlcyBmcm9tOiB0aGUgaG9tZSByZWdpb24gZmlyc3QsIHRoZW4gdGhlIG90aGVycyBpbiBhbHBoYWJldGljYWwgb3JkZXIuICovXG4gIHB1YmxpYyByZWFkb25seSByZWdpb25zOiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGVuZHBvaW50J3MgZG9tYWluIG5hbWU6IHRoZSBnbG9iYWwgZG9tYWluIGZvciBgTVVMVElfUkVHSU9OYCwgb3RoZXJ3aXNlIHRoZSBob21lIHJlZ2lvbidzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVuZHBvaW50J3MgVVJMOiB0aGUgZ2xvYmFsIFVSTCBmb3IgYE1VTFRJX1JFR0lPTmAsIG90aGVyd2lzZSB0aGUgaG9tZSByZWdpb24ncy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1cmw6IHN0cmluZztcblxuICAvKiogR3JhbnRzIG9uIHRoaXMgZW5kcG9pbnQgKGUuZy4gYGdyYW50cy5pbnZva2UocHJpbmNpcGFsKWApLiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRzOiBXZWJGdW5jdGlvbkdyYW50cztcblxuICBwcml2YXRlIHJlYWRvbmx5IGhvbWVSZWdpb246IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJGdW5jdGlvbjogSVdlYkZ1bmN0aW9uO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlOiBsYW1iZGEuQ2ZuV2ViRnVuY3Rpb25FbmRwb2ludDtcbiAgcHJpdmF0ZSB3ZWlnaHRzOiBsYW1iZGEuQ2ZuV2ViRnVuY3Rpb25FbmRwb2ludC5SZXZpc2lvbldlaWdodFByb3BlcnR5W107XG4gIHByaXZhdGUgcm91dGVkID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JhZHVhbDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBsb29rdXA/OiBFbmRwb2ludExvb2t1cDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBXZWJGdW5jdGlvbkVuZHBvaW50UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgaG9tZVJlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICBjb25zdCBlbmRwb2ludFR5cGUgPSBwcm9wcy5lbmRwb2ludFR5cGUgPz8gV2ViRnVuY3Rpb25FbmRwb2ludFR5cGUuSE9NRV9SRUdJT047XG4gICAgY29uc3QgZXh0cmFSZWdpb25zID0gbm9ybWFsaXNlUmVnaW9ucyh0aGlzLCBlbmRwb2ludFR5cGUsIGhvbWVSZWdpb24sIHByb3BzLnJlZ2lvbnMgPz8gW10pO1xuICAgIHZhbGlkYXRlUmF0ZUxpbWl0KHRoaXMsIHByb3BzLnJhdGVMaW1pdCk7XG4gICAgdmFsaWRhdGVNYXhFbnZpcm9ubWVudHModGhpcywgcHJvcHMubWF4RW52aXJvbm1lbnRzKTtcblxuICAgIGlmIChwcm9wcy5lbmRwb2ludE5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXNzZXJ0UmVzb3VyY2VOYW1lKHRoaXMsICdlbmRwb2ludE5hbWUnLCBwcm9wcy5lbmRwb2ludE5hbWUpO1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKCdAY2RrLWxhbWJkYS13ZWI6ZXhwbGljaXRFbmRwb2ludE5hbWUnLFxuICAgICAgICBgZW5kcG9pbnROYW1lICcke3Byb3BzLmVuZHBvaW50TmFtZX0nIGlzIHNldCBleHBsaWNpdGx5OiBjaGFuZ2luZyBlbmRwb2ludFR5cGUgb3IgcmVnaW9ucyBsYXRlciBhbHNvIHJlcXVpcmVzIGEgbmV3IGVuZHBvaW50TmFtZSwgb3RoZXJ3aXNlIHRoZSBkZXBsb3ltZW50IGZhaWxzIHdpdGggXCJhbHJlYWR5IGV4aXN0c1wiICh0aGUgc3RhY2sgcm9sbHMgYmFjayBzYWZlbHkpLiBPbWl0IGVuZHBvaW50TmFtZSB0byBnZXQgYSBuYW1lIHRoYXQgY2hhbmdlcyBhdXRvbWF0aWNhbGx5LmApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuYXV0aFR5cGUgPT09IFdlYkZ1bmN0aW9uQXV0aFR5cGUuTk9ORSkge1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKCdAY2RrLWxhbWJkYS13ZWI6YXV0aFR5cGVOb25lJyxcbiAgICAgICAgJ2F1dGhUeXBlIE5PTkUgbWFrZXMgdGhlIGVuZHBvaW50IHB1YmxpYzogTGFtYmRhIGRvZXMgbm8gYXV0aGVudGljYXRpb24sIHNvIHlvdXIgYXBwbGljYXRpb24gbXVzdCBhdXRoZW50aWNhdGUgcmVxdWVzdHMgaXRzZWxmLicpO1xuICAgIH1cblxuICAgIHRoaXMuZW5kcG9pbnRUeXBlID0gZW5kcG9pbnRUeXBlO1xuICAgIHRoaXMuYXV0aFR5cGUgPSBwcm9wcy5hdXRoVHlwZTtcbiAgICB0aGlzLmVuZHBvaW50TmFtZSA9IHByb3BzLmVuZHBvaW50TmFtZSA/PyBkZWZhdWx0RW5kcG9pbnROYW1lKHByb3BzLm5hbWVQcmVmaXgsIHByb3BzLm5hbWVTZWVkLCBlbmRwb2ludFR5cGUsIGV4dHJhUmVnaW9ucyk7XG4gICAgdGhpcy5yZWdpb25zID0gW2hvbWVSZWdpb24sIC4uLmV4dHJhUmVnaW9uc107XG4gICAgdGhpcy5ob21lUmVnaW9uID0gaG9tZVJlZ2lvbjtcbiAgICB0aGlzLndlYkZ1bmN0aW9uID0gcHJvcHMud2ViRnVuY3Rpb247XG4gICAgdGhpcy53ZWlnaHRzID0gW3sgcmV2aXNpb25JZDogcHJvcHMuY3VycmVudFJldmlzaW9uLnJldmlzaW9uSWQsIHdlaWdodDogMTAwIH1dO1xuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgbGFtYmRhLkNmbldlYkZ1bmN0aW9uRW5kcG9pbnQodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZnVuY3Rpb25OYW1lOiBwcm9wcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbkFybixcbiAgICAgIGVuZHBvaW50TmFtZTogdGhpcy5lbmRwb2ludE5hbWUsXG4gICAgICBlbmRwb2ludFR5cGUsXG4gICAgICBhdXRoVHlwZTogcHJvcHMuYXV0aFR5cGUsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICByZWdpb25zOiBleHRyYVJlZ2lvbnMubGVuZ3RoID4gMCA/IGV4dHJhUmVnaW9ucyA6IHVuZGVmaW5lZCxcbiAgICAgIHJldmlzaW9uV2VpZ2h0czogdGhpcy53ZWlnaHRzLFxuICAgICAgdGhyb3R0bGVDb25maWc6IHByb3BzLnJhdGVMaW1pdCAhPT0gdW5kZWZpbmVkID8geyByYXRlTGltaXQ6IHByb3BzLnJhdGVMaW1pdCB9IDogdW5kZWZpbmVkLFxuICAgICAgc2NhbGluZ0NvbmZpZzogcHJvcHMubWF4RW52aXJvbm1lbnRzICE9PSB1bmRlZmluZWQgPyB7IG1heEVudmlyb25tZW50czogcHJvcHMubWF4RW52aXJvbm1lbnRzIH0gOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gICAgVmFsaWRhdGlvbnMub2YocmVzb3VyY2UpLmFja25vd2xlZGdlKENGTl9WQUxJREFURV9VTktOT1dOX1RZUEUpO1xuICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTtcblxuICAgIHRoaXMuZ3JhZHVhbCA9IHByb3BzLmRlcGxveW1lbnQ/Ll9ncmFkdWFsID8/IGZhbHNlO1xuICAgIGlmIChwcm9wcy5kZXBsb3ltZW50Py5fZ3JhZHVhbCkge1xuICAgICAgaWYgKHByb3BzLnJldmlzaW9uICE9PSB1bmRlZmluZWQgfHwgcHJvcHMuYWRkaXRpb25hbFJldmlzaW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5vZGUucGF0aH06IGFuIGVuZHBvaW50IHdpdGggYSAke3Byb3BzLmRlcGxveW1lbnQuX2tpbmR9IGRlcGxveW1lbnQgYWx3YXlzIG1vdmVzIHRvIHRoZSBjdXJyZW50IHJldmlzaW9uOyBpdCBjYW4ndCBhbHNvIHNldCByZXZpc2lvbiBvciBhZGRpdGlvbmFsUmV2aXNpb25zYCk7XG4gICAgICB9XG4gICAgICAvLyBNb3ZlcyB0aGUgdHJhZmZpYyBpbiBzdGVwcyBiZWZvcmUgQ2xvdWRGb3JtYXRpb24gd3JpdGVzIHRoZSBlbmRwb2ludCwgd2hpY2ggdGhlbiBmaW5kcyBpdCBhbHJlYWR5IGRvbmUuXG4gICAgICBjb25zdCBzaGlmdCA9IG5ldyBUcmFmZmljU2hpZnQodGhpcywgJ0RlcGxveW1lbnQnLCB7XG4gICAgICAgIGZ1bmN0aW9uTmFtZTogcHJvcHMud2ViRnVuY3Rpb24ud2ViRnVuY3Rpb25OYW1lLFxuICAgICAgICBmdW5jdGlvbkFybjogcHJvcHMud2ViRnVuY3Rpb24ud2ViRnVuY3Rpb25Bcm4sXG4gICAgICAgIGVuZHBvaW50TmFtZTogdGhpcy5lbmRwb2ludE5hbWUsXG4gICAgICAgIHJldmlzaW9uSWQ6IHByb3BzLmN1cnJlbnRSZXZpc2lvbi5yZXZpc2lvbklkLFxuICAgICAgICBkZXBsb3ltZW50OiBwcm9wcy5kZXBsb3ltZW50LFxuICAgICAgICBlbmRwb2ludENvbmZpZzoge1xuICAgICAgICAgIGVuZHBvaW50VHlwZSxcbiAgICAgICAgICBhdXRoVHlwZTogcHJvcHMuYXV0aFR5cGUsXG4gICAgICAgICAgZGVzY3JpcHRpb246IHByb3BzLmRlc2NyaXB0aW9uLFxuICAgICAgICAgIHJlZ2lvbnM6IGV4dHJhUmVnaW9ucyxcbiAgICAgICAgICByYXRlTGltaXQ6IHByb3BzLnJhdGVMaW1pdCxcbiAgICAgICAgICBtYXhFbnZpcm9ubWVudHM6IHByb3BzLm1heEVudmlyb25tZW50cyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgcmVzb3VyY2Uubm9kZS5hZGREZXBlbmRlbmN5KHNoaWZ0KTtcbiAgICB9XG4gICAgaWYgKHByb3BzLnJldmlzaW9uICE9PSB1bmRlZmluZWQgfHwgcHJvcHMuYWRkaXRpb25hbFJldmlzaW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnJvdXRlVHJhZmZpYyhwcm9wcy5yZXZpc2lvbiA/PyBwcm9wcy5jdXJyZW50UmV2aXNpb24sIHByb3BzLmFkZGl0aW9uYWxSZXZpc2lvbnMpO1xuICAgIH1cblxuICAgIHRoaXMuZW5kcG9pbnRBcm4gPSByZXNvdXJjZS5hdHRyRW5kcG9pbnRBcm47XG4gICAgdGhpcy5kb21haW5OYW1lID0gcmVzb3VyY2UuYXR0ckRvbWFpbk5hbWU7XG4gICAgdGhpcy51cmwgPSBgaHR0cHM6Ly8ke3Jlc291cmNlLmF0dHJEb21haW5OYW1lfWA7XG4gICAgdGhpcy5ncmFudHMgPSBXZWJGdW5jdGlvbkdyYW50cy5fZm9yRW5kcG9pbnQodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIFVSTCBvZiB0aGlzIGVuZHBvaW50IGluIG9uZSByZWdpb24uIE9ubHkgZm9yIGBQRVJfUkVHSU9OYCBlbmRwb2ludHMuXG4gICAqXG4gICAqIEBwYXJhbSByZWdpb24gb25lIG9mIGByZWdpb25zYFxuICAgKi9cbiAgcHVibGljIHJlZ2lvbmFsVXJsKHJlZ2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5lbmRwb2ludFR5cGUgIT09IFdlYkZ1bmN0aW9uRW5kcG9pbnRUeXBlLlBFUl9SRUdJT04pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5vZGUucGF0aH06IHJlZ2lvbmFsVXJsKCkgaXMgb25seSBhdmFpbGFibGUgZm9yIFBFUl9SRUdJT04gZW5kcG9pbnRzICh0aGlzIG9uZSBpcyAke3RoaXMuZW5kcG9pbnRUeXBlfSk7IHVzZSB1cmxgKTtcbiAgICB9XG4gICAgaWYgKCF0aGlzLnJlZ2lvbnMuaW5jbHVkZXMocmVnaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMubm9kZS5wYXRofTogcmVnaW9uICR7cmVnaW9ufSBpcyBub3Qgb25lIG9mIHRoZSBlbmRwb2ludCdzIHJlZ2lvbnMgKCR7dGhpcy5yZWdpb25zLmpvaW4oJywgJyl9KWApO1xuICAgIH1cbiAgICBpZiAocmVnaW9uID09PSB0aGlzLmhvbWVSZWdpb24pIHtcbiAgICAgIHJldHVybiB0aGlzLnVybDtcbiAgICB9XG4gICAgdGhpcy5sb29rdXAgPz89IG5ldyBFbmRwb2ludExvb2t1cCh0aGlzLCAnTG9va3VwJywge1xuICAgICAgZnVuY3Rpb25OYW1lOiB0aGlzLndlYkZ1bmN0aW9uLndlYkZ1bmN0aW9uTmFtZSxcbiAgICAgIGZ1bmN0aW9uQXJuOiB0aGlzLndlYkZ1bmN0aW9uLndlYkZ1bmN0aW9uQXJuLFxuICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmVuZHBvaW50TmFtZSxcbiAgICAgIGVuZHBvaW50QXJuOiB0aGlzLmVuZHBvaW50QXJuLFxuICAgIH0pO1xuICAgIHJldHVybiBgaHR0cHM6Ly8ke3RoaXMubG9va3VwLnJlZ2lvbmFsRG9tYWluKHJlZ2lvbil9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSb3V0ZXMgdGhlIGVuZHBvaW50IHRvIGByZXZpc2lvbmAgaW5zdGVhZCBvZiB0aGUgZnVuY3Rpb24ncyBjdXJyZW50IHJldmlzaW9uLCBvcHRpb25hbGx5IHNoYXJpbmdcbiAgICogdHJhZmZpYyB3aXRoIG9uZSBtb3JlIHJldmlzaW9uIChgYWRkaXRpb25hbFJldmlzaW9uc2AsIHdoaWNoIGdldHMgaXRzIHdlaWdodDsgYHJldmlzaW9uYCBnZXRzIHRoZSByZXN0KS5cbiAgICpcbiAgICogVXNlIGl0IHRvIGtlZXAgYW4gZW5kcG9pbnQgb24gYW4gZWFybGllciByZXZpc2lvbiAoYFdlYkZ1bmN0aW9uUmV2aXNpb24uZnJvbVJldmlzaW9uQXR0cmlidXRlc2ApLFxuICAgKiBvciB0byBzZW5kIHBhcnQgb2YgdGhlIHRyYWZmaWMgdG8gdGhlIGN1cnJlbnQgcmV2aXNpb246XG4gICAqIGBmbi5lbmRwb2ludC5yb3V0ZVRyYWZmaWMocHJldmlvdXMsIFt7IHJldmlzaW9uOiBmbi5jdXJyZW50UmV2aXNpb24sIHdlaWdodDogMC4xIH1dKWAuXG4gICAqIENhbiBiZSBjYWxsZWQgb25jZSBwZXIgZW5kcG9pbnQsIGFuZCBub3Qgb24gb25lIGNyZWF0ZWQgd2l0aCBgcmV2aXNpb25gIG9yIGBhZGRpdGlvbmFsUmV2aXNpb25zYC5cbiAgICovXG4gIHB1YmxpYyByb3V0ZVRyYWZmaWMocmV2aXNpb246IElXZWJGdW5jdGlvblJldmlzaW9uLCBhZGRpdGlvbmFsUmV2aXNpb25zPzogV2ViRnVuY3Rpb25SZXZpc2lvbldlaWdodFtdKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ3JhZHVhbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMubm9kZS5wYXRofTogdGhlIGVuZHBvaW50IGhhcyBhIGRlcGxveW1lbnQgaW4gc3RlcHMsIHdoaWNoIGFsd2F5cyBtb3ZlcyBpdCB0byB0aGUgY3VycmVudCByZXZpc2lvbjsgcm91dGVUcmFmZmljKCkgY2FuJ3QgYmUgdXNlZCB3aXRoIGl0YCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnJvdXRlZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMubm9kZS5wYXRofTogdGhlIGVuZHBvaW50J3MgcmV2aXNpb25zIGFyZSBhbHJlYWR5IHNldCAocmV2aXNpb24sIGFkZGl0aW9uYWxSZXZpc2lvbnMgb3Igcm91dGVUcmFmZmljKWApO1xuICAgIH1cbiAgICB0aGlzLndlaWdodHMgPSByZXZpc2lvbldlaWdodHModGhpcywgdGhpcy53ZWJGdW5jdGlvbiwgcmV2aXNpb24sIGFkZGl0aW9uYWxSZXZpc2lvbnMgPz8gW10pO1xuICAgIHRoaXMucmVzb3VyY2UucmV2aXNpb25XZWlnaHRzID0gdGhpcy53ZWlnaHRzO1xuICAgIHRoaXMucm91dGVkID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgSURzIG9mIHRoZSByZXZpc2lvbnMgdGhpcyBlbmRwb2ludCByb3V0ZXMgdG8uXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9yZXZpc2lvbklkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMud2VpZ2h0cy5tYXAoKHcpID0+IHcucmV2aXNpb25JZCk7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3dzIGBncmFudGVlYCB0byBjYWxsIHRoaXMgZW5kcG9pbnQuIFNob3J0Y3V0IGZvciBgZ3JhbnRzLmludm9rZShncmFudGVlKWAuXG4gICAqIFtkaXNhYmxlLWF3c2xpbnQ6bm8tZ3JhbnRzXVxuICAgKi9cbiAgcHVibGljIGdyYW50SW52b2tlKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50IHtcbiAgICByZXR1cm4gdGhpcy5ncmFudHMuaW52b2tlKGdyYW50ZWUpO1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGlzZVJlZ2lvbnMoc2NvcGU6IENvbnN0cnVjdCwgZW5kcG9pbnRUeXBlOiBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZSwgaG9tZVJlZ2lvbjogc3RyaW5nLCByZWdpb25zOiBzdHJpbmdbXSk6IHN0cmluZ1tdIHtcbiAgY29uc3QgZXh0cmEgPSBbLi4ubmV3IFNldChyZWdpb25zKV0uZmlsdGVyKChyKSA9PiByICE9PSBob21lUmVnaW9uKS5zb3J0KCk7XG4gIGZvciAoY29uc3QgciBvZiByZWdpb25zKSB7XG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZChyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IHJlZ2lvbnMgbXVzdCBiZSBsaXRlcmFsIHJlZ2lvbiBuYW1lcywgZ290IGEgdG9rZW5gKTtcbiAgICB9XG4gICAgaWYgKCEvXlthLXpdezJ9KC1bYS16XSspKy1cXGQkLy50ZXN0KHIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogJyR7cn0nIGlzIG5vdCBhIHZhbGlkIHJlZ2lvbiBuYW1lYCk7XG4gICAgfVxuICB9XG4gIGlmIChlbmRwb2ludFR5cGUgPT09IFdlYkZ1bmN0aW9uRW5kcG9pbnRUeXBlLkhPTUVfUkVHSU9OICYmIGV4dHJhLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogYSBIT01FX1JFR0lPTiBlbmRwb2ludCBzZXJ2ZXMgb25seSB0aGUgaG9tZSByZWdpb24gKCR7aG9tZVJlZ2lvbn0pOyB1c2UgTVVMVElfUkVHSU9OIG9yIFBFUl9SRUdJT04gdG8gYWRkICR7ZXh0cmEuam9pbignLCAnKX1gKTtcbiAgfVxuICBpZiAoZW5kcG9pbnRUeXBlICE9PSBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZS5IT01FX1JFR0lPTikge1xuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoaG9tZVJlZ2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtzY29wZS5ub2RlLnBhdGh9OiAke2VuZHBvaW50VHlwZX0gZW5kcG9pbnRzIG5lZWQgYSBzdGFjayB3aXRoIGFuIGV4cGxpY2l0IHJlZ2lvbiAoZW52LnJlZ2lvbilgKTtcbiAgICB9XG4gICAgaWYgKGV4dHJhLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IGEgJHtlbmRwb2ludFR5cGV9IGVuZHBvaW50IG5lZWRzIGF0IGxlYXN0IG9uZSByZWdpb24gYmVzaWRlcyB0aGUgaG9tZSByZWdpb24gKCR7aG9tZVJlZ2lvbn0pYCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBleHRyYTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVSYXRlTGltaXQoc2NvcGU6IENvbnN0cnVjdCwgcmF0ZUxpbWl0OiBudW1iZXIgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgaWYgKHJhdGVMaW1pdCA9PT0gdW5kZWZpbmVkIHx8IFRva2VuLmlzVW5yZXNvbHZlZChyYXRlTGltaXQpKSByZXR1cm47XG4gIGNvbnN0IGFsbG93ZWQgPSByYXRlTGltaXQgPT09IDBcbiAgICB8fCAocmF0ZUxpbWl0ID49IDEwMCAmJiByYXRlTGltaXQgPD0gMTAwMCAmJiByYXRlTGltaXQgJSAxMDAgPT09IDApXG4gICAgfHwgKHJhdGVMaW1pdCA+PSAyMDAwICYmIHJhdGVMaW1pdCA8PSAxMDAwMCAmJiByYXRlTGltaXQgJSAxMDAwID09PSAwKTtcbiAgaWYgKCFhbGxvd2VkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IHJhdGVMaW1pdCBtdXN0IGJlIDAsIDEwMC0xLDAwMCBpbiBzdGVwcyBvZiAxMDAsIG9yIDIsMDAwLTEwLDAwMCBpbiBzdGVwcyBvZiAxLDAwMCwgZ290ICR7cmF0ZUxpbWl0fWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlTWF4RW52aXJvbm1lbnRzKHNjb3BlOiBDb25zdHJ1Y3QsIG1heEVudmlyb25tZW50czogbnVtYmVyIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIGlmIChtYXhFbnZpcm9ubWVudHMgPT09IHVuZGVmaW5lZCB8fCBUb2tlbi5pc1VucmVzb2x2ZWQobWF4RW52aXJvbm1lbnRzKSkgcmV0dXJuO1xuICBpZiAoIU51bWJlci5pc0ludGVnZXIobWF4RW52aXJvbm1lbnRzKSB8fCBtYXhFbnZpcm9ubWVudHMgPCAyIHx8IG1heEVudmlyb25tZW50cyA+IDEwMDAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IG1heEVudmlyb25tZW50cyBtdXN0IGJlIGFuIGludGVnZXIgZnJvbSAyIHRvIDEwLDAwMCwgZ290ICR7bWF4RW52aXJvbm1lbnRzfWApO1xuICB9XG59XG5cbi8qKiBgcHJpbWFyeWAgZ2V0cyB3aGF0IGBhZGRpdGlvbmFsYCBsZWF2ZXM7IHdlaWdodHMgYXJlIHdob2xlIHBlcmNlbnRhZ2VzIHN1bW1pbmcgdG8gMTAwLiAqL1xuZnVuY3Rpb24gcmV2aXNpb25XZWlnaHRzKFxuICBzY29wZTogQ29uc3RydWN0LFxuICB3ZWJGdW5jdGlvbjogSVdlYkZ1bmN0aW9uLFxuICBwcmltYXJ5OiBJV2ViRnVuY3Rpb25SZXZpc2lvbixcbiAgYWRkaXRpb25hbDogV2ViRnVuY3Rpb25SZXZpc2lvbldlaWdodFtdLFxuKTogbGFtYmRhLkNmbldlYkZ1bmN0aW9uRW5kcG9pbnQuUmV2aXNpb25XZWlnaHRQcm9wZXJ0eVtdIHtcbiAgZm9yIChjb25zdCByIG9mIFtwcmltYXJ5LCAuLi5hZGRpdGlvbmFsLm1hcCgoYSkgPT4gYS5yZXZpc2lvbildKSB7XG4gICAgaWYgKHIud2ViRnVuY3Rpb24gIT09IHdlYkZ1bmN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogcmV2aXNpb24gJHtyLnJldmlzaW9uSWR9IGJlbG9uZ3MgdG8gYW5vdGhlciBmdW5jdGlvbmApO1xuICAgIH1cbiAgfVxuICBpZiAoYWRkaXRpb25hbC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW3sgcmV2aXNpb25JZDogcHJpbWFyeS5yZXZpc2lvbklkLCB3ZWlnaHQ6IDEwMCB9XTtcbiAgfVxuICBpZiAoYWRkaXRpb25hbC5sZW5ndGggPiAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IGFuIGVuZHBvaW50IHJvdXRlcyB0byBhdCBtb3N0IHR3byByZXZpc2lvbnMsIHNvIGFkZGl0aW9uYWxSZXZpc2lvbnMgdGFrZXMgb25lYCk7XG4gIH1cbiAgY29uc3QgW3sgcmV2aXNpb24sIHdlaWdodCB9XSA9IGFkZGl0aW9uYWw7XG4gIGNvbnN0IHBlcmNlbnQgPSBNYXRoLnJvdW5kKHdlaWdodCAqIDEwMCk7XG4gIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQod2VpZ2h0KSB8fCBNYXRoLmFicyh3ZWlnaHQgKiAxMDAgLSBwZXJjZW50KSA+IDFlLTkgfHwgcGVyY2VudCA8IDEgfHwgcGVyY2VudCA+IDk5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IGFuIGFkZGl0aW9uYWwgcmV2aXNpb24ncyB3ZWlnaHQgbXVzdCBiZSBhIHdob2xlIHBlcmNlbnRhZ2UgZnJvbSAwLjAxIHRvIDAuOTksIGdvdCAke3dlaWdodH1gKTtcbiAgfVxuICBpZiAocmV2aXNpb24gPT09IHByaW1hcnkgfHwgKCFUb2tlbi5pc1VucmVzb2x2ZWQocmV2aXNpb24ucmV2aXNpb25JZCkgJiYgcmV2aXNpb24ucmV2aXNpb25JZCA9PT0gcHJpbWFyeS5yZXZpc2lvbklkKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtzY29wZS5ub2RlLnBhdGh9OiB0aGUgYWRkaXRpb25hbCByZXZpc2lvbiBpcyB0aGUgc2FtZSBhcyB0aGUgZW5kcG9pbnQncyByZXZpc2lvbmApO1xuICB9XG4gIHJldHVybiBbeyByZXZpc2lvbklkOiBwcmltYXJ5LnJldmlzaW9uSWQsIHdlaWdodDogMTAwIC0gcGVyY2VudCB9LCB7IHJldmlzaW9uSWQ6IHJldmlzaW9uLnJldmlzaW9uSWQsIHdlaWdodDogcGVyY2VudCB9XTtcbn1cblxuLyoqXG4gKiBgPHByZWZpeD4tPGhhc2g+YCwgd2l0aCB0aGUgaGFzaCBjb3ZlcmluZyB0aGUgZW5kcG9pbnQgdHlwZSBhbmQgcmVnaW9uczogYSB0eXBlIG9yIHJlZ2lvbiBjaGFuZ2UgcHJvZHVjZXNcbiAqIGEgbmV3IG5hbWUsIHNvIHRoZSByZXBsYWNlbWVudCBkb2Vzbid0IGNvbGxpZGUgd2l0aCB0aGUgZW5kcG9pbnQgaXQgcmVwbGFjZXMuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRFbmRwb2ludE5hbWUocHJlZml4OiBzdHJpbmcsIHNlZWQ6IHN0cmluZyB8IHVuZGVmaW5lZCwgZW5kcG9pbnRUeXBlOiBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZSwgZXh0cmFSZWdpb25zOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIGNvbnN0IGhhc2ggPSBjcmVhdGVIYXNoKCdzaGEyNTYnKS51cGRhdGUoWy4uLihzZWVkICE9PSB1bmRlZmluZWQgPyBbc2VlZF0gOiBbXSksIGVuZHBvaW50VHlwZSwgLi4uZXh0cmFSZWdpb25zXS5qb2luKCcsJykpLmRpZ2VzdCgnaGV4Jykuc2xpY2UoMCwgOCk7XG4gIHJldHVybiBgJHtwcmVmaXh9LSR7aGFzaH1gO1xufVxuIl19
438
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWZ1bmN0aW9uLWVuZHBvaW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3dlYi1mdW5jdGlvbi1lbmRwb2ludC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQXlDO0FBQ3pDLDZDQUErRTtBQUMvRSx1RUFBeUQ7QUFFekQsK0RBQWlEO0FBQ2pELDJDQUF1QztBQUN2QyxtQ0FBdUU7QUFDdkUsK0RBQTJEO0FBQzNELCtDQUcyQjtBQUMzQiw2REFBNEU7QUFFNUUsMkRBQXVEO0FBQ3ZELHFEQUFxRjtBQUdyRiwrREFBMEQ7QUFxSTFEOzs7O0dBSUc7QUFDSCxNQUFhLG1CQUFvQixTQUFRLHNCQUFTOztJQUNoRDs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUErQjtRQUNqRixPQUFPLElBQUksbUJBQW1CLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsMkJBQTJCO0lBQ1gsWUFBWSxDQUFTO0lBRXJDLDBCQUEwQjtJQUNWLFdBQVcsQ0FBUztJQUVwQyw4Q0FBOEM7SUFDOUIsWUFBWSxDQUEwQjtJQUV0RCxxREFBcUQ7SUFDckMsUUFBUSxDQUFzQjtJQUU5QywyR0FBMkc7SUFDM0YsT0FBTyxDQUFXO0lBRWxDOztPQUVHO0lBQ2EsVUFBVSxDQUFTO0lBRW5DOztPQUVHO0lBQ2EsR0FBRyxDQUFTO0lBRTVCLGlFQUFpRTtJQUNqRCxNQUFNLENBQW9CO0lBRTFDOzs7T0FHRztJQUNhLGNBQWMsR0FBd0IsRUFBRSxDQUFDO0lBRXhDLFVBQVUsQ0FBUztJQUNuQixXQUFXLENBQWU7SUFDMUIsUUFBUSxDQUFnQztJQUNqRCxPQUFPLENBQXlEO0lBQ2hFLE1BQU0sR0FBRyxLQUFLLENBQUM7SUFDTixPQUFPLENBQVU7SUFDMUIsTUFBTSxDQUFrQjtJ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QyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDckosT0FBTyxHQUFHLE1BQU0sSUFBSSxJQUFJLEVBQUUsQ0FBQztBQUM3QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ25vZGU6Y3J5cHRvJztcbmltcG9ydCB7IEFubm90YXRpb25zLCBEdXJhdGlvbiwgU3RhY2ssIFRva2VuLCBWYWxpZGF0aW9ucyB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBXZWJGdW5jdGlvbkF1dGhUeXBlLCBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZSB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IHsgRW5kcG9pbnRMb29rdXAgfSBmcm9tICcuL3ByaXZhdGUvZW5kcG9pbnQtbG9va3VwJztcbmltcG9ydCB7XG4gIENMSUVOVF9FUlJPUlMsIERFRkFVTFRfUEVSSU9ELCBSRVFVRVNUUywgU0VSVkVSX0VSUk9SUywgVVNBR0VfTkFNRVNQQUNFLCBXRUJfTkFNRVNQQUNFLFxuICBlbmRwb2ludERpbWVuc2lvbnMsIHJhdGVBbGFybVF1ZXJpZXMsIHJhdGVFeHByZXNzaW9uLFxufSBmcm9tICcuL3ByaXZhdGUvbWV0cmljcyc7XG5pbXBvcnQgeyBBTEFSTV9OQU1FX1BSRUZJWCwgUmVnaW9uYWxBbGFybSB9IGZyb20gJy4vcHJpdmF0ZS9yZWdpb25hbC1hbGFybSc7XG5pbXBvcnQgdHlwZSB7IFJlc29sdmVkUm9sbGJhY2tPcHRpb25zIH0gZnJvbSAnLi9wcml2YXRlL3JvbGxiYWNrJztcbmltcG9ydCB7IFRyYWZmaWNTaGlmdCB9IGZyb20gJy4vcHJpdmF0ZS90cmFmZmljLXNoaWZ0JztcbmltcG9ydCB7IENGTl9WQUxJREFURV9VTktOT1dOX1RZUEUsIGFzc2VydFJlc291cmNlTmFtZSB9IGZyb20gJy4vcHJpdmF0ZS92YWxpZGF0aW9uJztcbmltcG9ydCB0eXBlIHsgSVdlYkZ1bmN0aW9uIH0gZnJvbSAnLi93ZWItZnVuY3Rpb24nO1xuaW1wb3J0IHR5cGUgeyBXZWJGdW5jdGlvbkRlcGxveW1lbnQgfSBmcm9tICcuL3dlYi1mdW5jdGlvbi1kZXBsb3ltZW50JztcbmltcG9ydCB7IFdlYkZ1bmN0aW9uR3JhbnRzIH0gZnJvbSAnLi93ZWItZnVuY3Rpb24tZ3JhbnRzJztcbmltcG9ydCB0eXBlIHsgSVdlYkZ1bmN0aW9uUmV2aXNpb24gfSBmcm9tICcuL3dlYi1mdW5jdGlvbi1yZXZpc2lvbic7XG5cbi8qKlxuICogQSByZXZpc2lvbiBhbmQgdGhlIHNoYXJlIG9mIGFuIGVuZHBvaW50J3MgdHJhZmZpYyBpdCByZWNlaXZlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXZWJGdW5jdGlvblJldmlzaW9uV2VpZ2h0IHtcbiAgLyoqIFRoZSByZXZpc2lvbi4gKi9cbiAgcmVhZG9ubHkgcmV2aXNpb246IElXZWJGdW5jdGlvblJldmlzaW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgcmV2aXNpb24ncyBzaGFyZSBvZiB0aGUgZW5kcG9pbnQncyB0cmFmZmljLCBhcyBhIGZyYWN0aW9uIChsaWtlIGBsYW1iZGEuQWxpYXNgIGBhZGRpdGlvbmFsVmVyc2lvbnNgKS5cbiAgICogTXVzdCBiZSBhIHdob2xlIHBlcmNlbnRhZ2UgZnJvbSAwLjAxIHRvIDAuOTkuXG4gICAqL1xuICByZWFkb25seSB3ZWlnaHQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBhIFdlYiBGdW5jdGlvbidzIGVuZHBvaW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdlYkZ1bmN0aW9uRW5kcG9pbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXJlIHRoZSBlbmRwb2ludCBzZXJ2ZXMgdHJhZmZpYyBmcm9tLlxuICAgKlxuICAgKiBAZGVmYXVsdCBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZS5IT01FX1JFR0lPTlxuICAgKi9cbiAgcmVhZG9ubHkgZW5kcG9pbnRUeXBlPzogV2ViRnVuY3Rpb25FbmRwb2ludFR5cGU7XG5cbiAgLyoqXG4gICAqIFJlZ2lvbnMgdG8gc2VydmUgZnJvbSBpbiBhZGRpdGlvbiB0byB0aGUgaG9tZSByZWdpb24gKHRoZSBzdGFjaydzIHJlZ2lvbikuXG4gICAqIFJlcXVpcmVkIChhdCBsZWFzdCBvbmUpIGZvciBgTVVMVElfUkVHSU9OYCBhbmQgYFBFUl9SRUdJT05gOyBtdXN0IGJlIGVtcHR5IGZvciBgSE9NRV9SRUdJT05gLlxuICAgKlxuICAgKiBDaGFuZ2luZyB0aGlzIGNyZWF0ZXMgYSBuZXcgZW5kcG9pbnQgd2l0aCBhIG5ldyBVUkwuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZXh0cmEgcmVnaW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgcmVnaW9ucz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgZW5kcG9pbnQncyBuYW1lLCBzaG93biBpbiBsb2dzIChgZW5kcG9pbnROYW1lYCkgYW5kIGluIHRoZSBgbGFtYmRhLXdlYi1lbmRwb2ludC1uYW1lYCBoZWFkZXIuXG4gICAqIE5hbWVzIGFyZSB1bmlxdWUgcGVyIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBXaGVuIG9taXR0ZWQsIHRoZSBuYW1lIGVuZHMgaW4gYSBoYXNoIG9mIHRoZSBlbmRwb2ludCB0eXBlIGFuZCByZWdpb25zLCBzbyBjaGFuZ2luZyBlaXRoZXIgZGVwbG95c1xuICAgKiBhIG5ldyBlbmRwb2ludCBjbGVhbmx5LiBXaGVuIHNldCwgY2hhbmdpbmcgdGhlIGVuZHBvaW50IHR5cGUgb3IgcmVnaW9ucyBhbHNvIHJlcXVpcmVzIGEgbmV3IG5hbWU6XG4gICAqIHR3byBlbmRwb2ludHMgb2Ygb25lIGZ1bmN0aW9uIGNhbid0IHNoYXJlIGEgbmFtZSwgYW5kIENsb3VkRm9ybWF0aW9uIGNyZWF0ZXMgdGhlIHJlcGxhY2VtZW50XG4gICAqIGJlZm9yZSBkZWxldGluZyB0aGUgb2xkIG9uZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBgZGVmYXVsdC08aGFzaD5gIGZvciB0aGUgZnVuY3Rpb24ncyBkZWZhdWx0IGVuZHBvaW50LCBgPGlkPi08aGFzaD5gIGZvciBlbmRwb2ludHMgYWRkZWQgd2l0aCBgYWRkRW5kcG9pbnRgXG4gICAqL1xuICByZWFkb25seSBlbmRwb2ludE5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgZGVzY3JpcHRpb24gb2YgdGhlIGVuZHBvaW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGRlc2NyaXB0aW9uXG4gICAqL1xuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG1vc3QgcmVxdWVzdHMgcGVyIHNlY29uZCB0aGUgZW5kcG9pbnQgYWNjZXB0czsgZXhjZXNzIHJlcXVlc3RzIGdldCBIVFRQIDQyOS5cbiAgICogQWxsb3dlZDogMCAoYmxvY2tzIGFsbCB0cmFmZmljKSwgMTAw4oCTMSwwMDAgaW4gc3RlcHMgb2YgMTAwLCBvciAyLDAwMOKAkzEwLDAwMCBpbiBzdGVwcyBvZiAxLDAwMC5cbiAgICpcbiAgICogRW5mb3JjZWQgc2VwYXJhdGVseSBpbiBlYWNoIHJlZ2lvbiB0aGUgZW5kcG9pbnQgc2VydmVzIGZyb20sIHNvIGEgbXVsdGktcmVnaW9uIGVuZHBvaW50XG4gICAqIGNhbiBhY2NlcHQgdGhpcyBtYW55IHJlcXVlc3RzIHBlciBzZWNvbmQgaW4gZXZlcnkgcmVnaW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGxpbWl0IGJleW9uZCB0aGUgc2VydmljZSBxdW90YSBvZiAxMCwwMDAgcmVxdWVzdHMgcGVyIHNlY29uZCBwZXIgZW5kcG9pbnQgKHBlciByZWdpb24pXG4gICAqL1xuICByZWFkb25seSByYXRlTGltaXQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBtb3N0IGV4ZWN1dGlvbiBlbnZpcm9ubWVudHMgdGhlIGVuZHBvaW50IG1heSB1c2UgKDLigJMxMCwwMDApLiBFYWNoIG9uZSB1c2VzIDIgdkNQVXMgb2YgdGhlIGFjY291bnQncyBxdW90YS5cbiAgICpcbiAgICogRW5mb3JjZWQgc2VwYXJhdGVseSBpbiBlYWNoIHJlZ2lvbiB0aGUgZW5kcG9pbnQgc2VydmVzIGZyb20uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc2NhbGVzIHdpdGhpbiB0aGUgYWNjb3VudCdzIHZDUFUgcXVvdGFcbiAgICovXG4gIHJlYWRvbmx5IG1heEVudmlyb25tZW50cz86IG51bWJlcjtcblxuICAvKipcbiAgICogSG93IHRoZSBlbmRwb2ludCBtb3ZlcyBpdHMgdHJhZmZpYyB0byBhIG5ldyByZXZpc2lvbjogYWxsIGF0IG9uY2UsIG9yIGluIHN0ZXBzXG4gICAqIChgV2ViRnVuY3Rpb25EZXBsb3ltZW50LmNhbmFyeSgpYCBvciBgbGluZWFyKClgKSB0aGF0IHdhdGNoIENsb3VkV2F0Y2ggYWxhcm1zIGFuZCBtb3ZlXG4gICAqIHRoZSB0cmFmZmljIGJhY2sgd2hlbiBvbmUgZ29lcyBpbnRvIEFMQVJNLlxuICAgKlxuICAgKiBBIGRlcGxveW1lbnQgaW4gc3RlcHMgY2FuJ3QgYmUgY29tYmluZWQgd2l0aCBgcmV2aXNpb25gLCBgYWRkaXRpb25hbFJldmlzaW9uc2Agb3IgYHJvdXRlVHJhZmZpYygpYC5cbiAgICpcbiAgICogQGRlZmF1bHQgV2ViRnVuY3Rpb25EZXBsb3ltZW50LmFsbEF0T25jZSgpXG4gICAqL1xuICByZWFkb25seSBkZXBsb3ltZW50PzogV2ViRnVuY3Rpb25EZXBsb3ltZW50O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGBXZWJGdW5jdGlvbi5hZGRFbmRwb2ludGAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWRkV2ViRnVuY3Rpb25FbmRwb2ludE9wdGlvbnMgZXh0ZW5kcyBXZWJGdW5jdGlvbkVuZHBvaW50T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIb3cgY2FsbGVycyBvZiB0aGlzIGVuZHBvaW50IGFyZSBhdXRoZW50aWNhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgYXV0aFR5cGU6IFdlYkZ1bmN0aW9uQXV0aFR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSByZXZpc2lvbiB0aGUgZW5kcG9pbnQgc2VydmVzLCBlLmcuIGFuIGVhcmxpZXIgb25lIGZyb20gYFdlYkZ1bmN0aW9uUmV2aXNpb24uZnJvbVJldmlzaW9uQXR0cmlidXRlc2BcbiAgICogdG8ga2VlcCB0aGlzIGVuZHBvaW50IG9uIGl0IHdoaWxlIG90aGVycyBtb3ZlIG9uLiBTYW1lIGFzIGNhbGxpbmcgYHJvdXRlVHJhZmZpY2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIGZ1bmN0aW9uJ3MgY3VycmVudCByZXZpc2lvbiAoYGN1cnJlbnRSZXZpc2lvbmApXG4gICAqL1xuICByZWFkb25seSByZXZpc2lvbj86IElXZWJGdW5jdGlvblJldmlzaW9uO1xuXG4gIC8qKlxuICAgKiBBIHNlY29uZCByZXZpc2lvbiBhbmQgaXRzIHNoYXJlIG9mIHRoZSBlbmRwb2ludCdzIHRyYWZmaWM7IGByZXZpc2lvbmAgZ2V0cyB0aGUgcmVzdC5cbiAgICogQW4gZW5kcG9pbnQgcm91dGVzIHRvIGF0IG1vc3QgdHdvIHJldmlzaW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhbGwgdHJhZmZpYyBnb2VzIHRvIGByZXZpc2lvbmBcbiAgICovXG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxSZXZpc2lvbnM/OiBXZWJGdW5jdGlvblJldmlzaW9uV2VpZ2h0W107XG59XG5cbi8qKlxuICogSW50ZXJuYWw6IGhvdyBgV2ViRnVuY3Rpb25gIGNyZWF0ZXMgaXRzIGVuZHBvaW50cy4gTm90IHBhcnQgb2YgdGhlIHB1YmxpYyBBUEkuXG4gKi9cbmludGVyZmFjZSBXZWJGdW5jdGlvbkVuZHBvaW50UHJvcHMgZXh0ZW5kcyBBZGRXZWJGdW5jdGlvbkVuZHBvaW50T3B0aW9ucyB7XG4gIC8qKiBUaGUgZnVuY3Rpb24gdGhhdCBvd25zIHRoZSBlbmRwb2ludC4gKi9cbiAgcmVhZG9ubHkgd2ViRnVuY3Rpb246IElXZWJGdW5jdGlvbjtcblxuICAvKiogVGhlIGZ1bmN0aW9uJ3MgY3VycmVudCByZXZpc2lvbiwgc2VydmVkIHVubGVzcyBgcmV2aXNpb25gIGlzIGdpdmVuLiAqL1xuICByZWFkb25seSBjdXJyZW50UmV2aXNpb246IElXZWJGdW5jdGlvblJldmlzaW9uO1xuXG4gIC8qKiBQcmVmaXggb2YgdGhlIGdlbmVyYXRlZCBlbmRwb2ludCBuYW1lLiAqL1xuICByZWFkb25seSBuYW1lUHJlZml4OiBzdHJpbmc7XG5cbiAgLyoqIEV4dHJhIGlucHV0IHRvIHRoZSBnZW5lcmF0ZWQgbmFtZSdzIGhhc2ggKHRoZSBjb25zdHJ1Y3QgSUQgb2YgYW4gYWRkZWQgZW5kcG9pbnQpLiAqL1xuICByZWFkb25seSBuYW1lU2VlZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBbiBIVFRQUyBlbmRwb2ludCBvZiBhIFdlYiBGdW5jdGlvbjogYGZuLmVuZHBvaW50YCAodGhlIGRlZmF1bHQgb25lKSBvciB0aGUgcmVzdWx0IG9mIGBmbi5hZGRFbmRwb2ludCgpYC5cbiAqXG4gKiBFbmRwb2ludHMgYXJlIGNyZWF0ZWQgb25seSB0aHJvdWdoIGBXZWJGdW5jdGlvbmAsIHdoaWNoIG93bnMgdGhlaXIgbG9nIGdyb3VwcyBpbiBldmVyeSByZWdpb24sIHNvIHRoZSBjb25zdHJ1Y3RvciBpcyBwcml2YXRlLlxuICovXG5leHBvcnQgY2xhc3MgV2ViRnVuY3Rpb25FbmRwb2ludCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGVuZHBvaW50IG9mIGEgV2ViIEZ1bmN0aW9uLiBVc2VkIGJ5IGBXZWJGdW5jdGlvbmAuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBfY3JlYXRlKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBXZWJGdW5jdGlvbkVuZHBvaW50UHJvcHMpOiBXZWJGdW5jdGlvbkVuZHBvaW50IHtcbiAgICByZXR1cm4gbmV3IFdlYkZ1bmN0aW9uRW5kcG9pbnQoc2NvcGUsIGlkLCBwcm9wcyk7XG4gIH1cblxuICAvKiogVGhlIGVuZHBvaW50J3MgbmFtZS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGVuZHBvaW50TmFtZTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgZW5kcG9pbnQncyBBUk4uICovXG4gIHB1YmxpYyByZWFkb25seSBlbmRwb2ludEFybjogc3RyaW5nO1xuXG4gIC8qKiBXaGVyZSB0aGUgZW5kcG9pbnQgc2VydmVzIHRyYWZmaWMgZnJvbS4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGVuZHBvaW50VHlwZTogV2ViRnVuY3Rpb25FbmRwb2ludFR5cGU7XG5cbiAgLyoqIEhvdyBjYWxsZXJzIG9mIHRoZSBlbmRwb2ludCBhcmUgYXV0aGVudGljYXRlZC4gKi9cbiAgcHVibGljIHJlYWRvbmx5IGF1dGhUeXBlOiBXZWJGdW5jdGlvbkF1dGhUeXBlO1xuXG4gIC8qKiBFdmVyeSByZWdpb24gdGhlIGVuZHBvaW50IHNlcnZlcyBmcm9tOiB0aGUgaG9tZSByZWdpb24gZmlyc3QsIHRoZW4gdGhlIG90aGVycyBpbiBhbHBoYWJldGljYWwgb3JkZXIuICovXG4gIHB1YmxpYyByZWFkb25seSByZWdpb25zOiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGVuZHBvaW50J3MgZG9tYWluIG5hbWU6IHRoZSBnbG9iYWwgZG9tYWluIGZvciBgTVVMVElfUkVHSU9OYCwgb3RoZXJ3aXNlIHRoZSBob21lIHJlZ2lvbidzLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGVuZHBvaW50J3MgVVJMOiB0aGUgZ2xvYmFsIFVSTCBmb3IgYE1VTFRJX1JFR0lPTmAsIG90aGVyd2lzZSB0aGUgaG9tZSByZWdpb24ncy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1cmw6IHN0cmluZztcblxuICAvKiogR3JhbnRzIG9uIHRoaXMgZW5kcG9pbnQgKGUuZy4gYGdyYW50cy5pbnZva2UocHJpbmNpcGFsKWApLiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRzOiBXZWJGdW5jdGlvbkdyYW50cztcblxuICAvKipcbiAgICogVGhlIGFsYXJtcyB0aGlzIGVuZHBvaW50IGNyZWF0ZWQgZm9yIGl0cyBkZXBsb3ltZW50J3MgYHJvbGxiYWNrT25gLCBvbmUgcGVyIHRocmVzaG9sZCBpbiBldmVyeSByZWdpb24gaXQgc2VydmVzIGZyb21cbiAgICogKHRoZSBob21lIHJlZ2lvbidzIGZpcnN0KS4gRW1wdHkgd2l0aG91dCBgcm9sbGJhY2tPbmAuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcm9sbGJhY2tBbGFybXM6IGNsb3Vkd2F0Y2guSUFsYXJtW10gPSBbXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGhvbWVSZWdpb246IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJGdW5jdGlvbjogSVdlYkZ1bmN0aW9uO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlOiBsYW1iZGEuQ2ZuV2ViRnVuY3Rpb25FbmRwb2ludDtcbiAgcHJpdmF0ZSB3ZWlnaHRzOiBsYW1iZGEuQ2ZuV2ViRnVuY3Rpb25FbmRwb2ludC5SZXZpc2lvbldlaWdodFByb3BlcnR5W107XG4gIHByaXZhdGUgcm91dGVkID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JhZHVhbDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBsb29rdXA/OiBFbmRwb2ludExvb2t1cDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBXZWJGdW5jdGlvbkVuZHBvaW50UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgaG9tZVJlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICBjb25zdCBlbmRwb2ludFR5cGUgPSBwcm9wcy5lbmRwb2ludFR5cGUgPz8gV2ViRnVuY3Rpb25FbmRwb2ludFR5cGUuSE9NRV9SRUdJT047XG4gICAgY29uc3QgZXh0cmFSZWdpb25zID0gbm9ybWFsaXNlUmVnaW9ucyh0aGlzLCBlbmRwb2ludFR5cGUsIGhvbWVSZWdpb24sIHByb3BzLnJlZ2lvbnMgPz8gW10pO1xuICAgIHZhbGlkYXRlUmF0ZUxpbWl0KHRoaXMsIHByb3BzLnJhdGVMaW1pdCk7XG4gICAgdmFsaWRhdGVNYXhFbnZpcm9ubWVudHModGhpcywgcHJvcHMubWF4RW52aXJvbm1lbnRzKTtcblxuICAgIGlmIChwcm9wcy5lbmRwb2ludE5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXNzZXJ0UmVzb3VyY2VOYW1lKHRoaXMsICdlbmRwb2ludE5hbWUnLCBwcm9wcy5lbmRwb2ludE5hbWUpO1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKCdAY2RrLWxhbWJkYS13ZWI6ZXhwbGljaXRFbmRwb2ludE5hbWUnLFxuICAgICAgICBgZW5kcG9pbnROYW1lICcke3Byb3BzLmVuZHBvaW50TmFtZX0nIGlzIHNldCBleHBsaWNpdGx5OiBjaGFuZ2luZyBlbmRwb2ludFR5cGUgb3IgcmVnaW9ucyBsYXRlciBhbHNvIHJlcXVpcmVzIGEgbmV3IGVuZHBvaW50TmFtZSwgb3RoZXJ3aXNlIHRoZSBkZXBsb3ltZW50IGZhaWxzIHdpdGggXCJhbHJlYWR5IGV4aXN0c1wiICh0aGUgc3RhY2sgcm9sbHMgYmFjayBzYWZlbHkpLiBPbWl0IGVuZHBvaW50TmFtZSB0byBnZXQgYSBuYW1lIHRoYXQgY2hhbmdlcyBhdXRvbWF0aWNhbGx5LmApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuYXV0aFR5cGUgPT09IFdlYkZ1bmN0aW9uQXV0aFR5cGUuTk9ORSkge1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKCdAY2RrLWxhbWJkYS13ZWI6YXV0aFR5cGVOb25lJyxcbiAgICAgICAgJ2F1dGhUeXBlIE5PTkUgbWFrZXMgdGhlIGVuZHBvaW50IHB1YmxpYzogTGFtYmRhIGRvZXMgbm8gYXV0aGVudGljYXRpb24sIHNvIHlvdXIgYXBwbGljYXRpb24gbXVzdCBhdXRoZW50aWNhdGUgcmVxdWVzdHMgaXRzZWxmLicpO1xuICAgIH1cblxuICAgIHRoaXMuZW5kcG9pbnRUeXBlID0gZW5kcG9pbnRUeXBlO1xuICAgIHRoaXMuYXV0aFR5cGUgPSBwcm9wcy5hdXRoVHlwZTtcbiAgICB0aGlzLmVuZHBvaW50TmFtZSA9IHByb3BzLmVuZHBvaW50TmFtZSA/PyBkZWZhdWx0RW5kcG9pbnROYW1lKHByb3BzLm5hbWVQcmVmaXgsIHByb3BzLm5hbWVTZWVkLCBlbmRwb2ludFR5cGUsIGV4dHJhUmVnaW9ucyk7XG4gICAgdGhpcy5yZWdpb25zID0gW2hvbWVSZWdpb24sIC4uLmV4dHJhUmVnaW9uc107XG4gICAgdGhpcy5ob21lUmVnaW9uID0gaG9tZVJlZ2lvbjtcbiAgICB0aGlzLndlYkZ1bmN0aW9uID0gcHJvcHMud2ViRnVuY3Rpb247XG4gICAgdGhpcy53ZWlnaHRzID0gW3sgcmV2aXNpb25JZDogcHJvcHMuY3VycmVudFJldmlzaW9uLnJldmlzaW9uSWQsIHdlaWdodDogMTAwIH1dO1xuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgbGFtYmRhLkNmbldlYkZ1bmN0aW9uRW5kcG9pbnQodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZnVuY3Rpb25OYW1lOiBwcm9wcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbkFybixcbiAgICAgIGVuZHBvaW50TmFtZTogdGhpcy5lbmRwb2ludE5hbWUsXG4gICAgICBlbmRwb2ludFR5cGUsXG4gICAgICBhdXRoVHlwZTogcHJvcHMuYXV0aFR5cGUsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICByZWdpb25zOiBleHRyYVJlZ2lvbnMubGVuZ3RoID4gMCA/IGV4dHJhUmVnaW9ucyA6IHVuZGVmaW5lZCxcbiAgICAgIHJldmlzaW9uV2VpZ2h0czogdGhpcy53ZWlnaHRzLFxuICAgICAgdGhyb3R0bGVDb25maWc6IHByb3BzLnJhdGVMaW1pdCAhPT0gdW5kZWZpbmVkID8geyByYXRlTGltaXQ6IHByb3BzLnJhdGVMaW1pdCB9IDogdW5kZWZpbmVkLFxuICAgICAgc2NhbGluZ0NvbmZpZzogcHJvcHMubWF4RW52aXJvbm1lbnRzICE9PSB1bmRlZmluZWQgPyB7IG1heEVudmlyb25tZW50czogcHJvcHMubWF4RW52aXJvbm1lbnRzIH0gOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gICAgVmFsaWRhdGlvbnMub2YocmVzb3VyY2UpLmFja25vd2xlZGdlKENGTl9WQUxJREFURV9VTktOT1dOX1RZUEUpO1xuICAgIHRoaXMucmVzb3VyY2UgPSByZXNvdXJjZTtcblxuICAgIHRoaXMuZ3JhZHVhbCA9IHByb3BzLmRlcGxveW1lbnQ/Ll9ncmFkdWFsID8/IGZhbHNlO1xuICAgIGlmIChwcm9wcy5kZXBsb3ltZW50Py5fZ3JhZHVhbCkge1xuICAgICAgaWYgKHByb3BzLnJldmlzaW9uICE9PSB1bmRlZmluZWQgfHwgcHJvcHMuYWRkaXRpb25hbFJldmlzaW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5vZGUucGF0aH06IGFuIGVuZHBvaW50IHdpdGggYSAke3Byb3BzLmRlcGxveW1lbnQuX2tpbmR9IGRlcGxveW1lbnQgYWx3YXlzIG1vdmVzIHRvIHRoZSBjdXJyZW50IHJldmlzaW9uOyBpdCBjYW4ndCBhbHNvIHNldCByZXZpc2lvbiBvciBhZGRpdGlvbmFsUmV2aXNpb25zYCk7XG4gICAgICB9XG4gICAgICBjb25zdCByb2xsYmFja0FsYXJtQXJucyA9IHByb3BzLmRlcGxveW1lbnQuX3JvbGxiYWNrT24gPyB0aGlzLmNyZWF0ZVJvbGxiYWNrQWxhcm1zKHByb3BzLmRlcGxveW1lbnQuX3JvbGxiYWNrT24pIDogW107XG4gICAgICBjb25zdCB3YWl0U2Vjb25kcyA9IHByb3BzLmRlcGxveW1lbnQuX3dhaXRTZWNvbmRzO1xuICAgICAgY29uc3Qgcm9sbGJhY2sgPSBwcm9wcy5kZXBsb3ltZW50Ll9yb2xsYmFja09uO1xuICAgICAgaWYgKHJvbGxiYWNrICYmIHdhaXRTZWNvbmRzIDwgcm9sbGJhY2sucGVyaW9kLnRvU2Vjb25kcygpICogcm9sbGJhY2suZXZhbHVhdGlvblBlcmlvZHMgKyAxMjApIHtcbiAgICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKCdAY2RrLWxhbWJkYS13ZWI6cm9sbGJhY2tTbG93ZXJUaGFuU3RlcCcsXG4gICAgICAgICAgYHJvbGxiYWNrT24gbmVlZHMgJHtyb2xsYmFjay5ldmFsdWF0aW9uUGVyaW9kc30gcGVyaW9kKHMpIG9mICR7cm9sbGJhY2sucGVyaW9kLnRvSHVtYW5TdHJpbmcoKX0gcGx1cyBhYm91dCAyIG1pbnV0ZXMgb2YgQ2xvdWRXYXRjaCBkZWxheSB0byBmaXJlLCBsb25nZXIgdGhhbiBlYWNoICR7cHJvcHMuZGVwbG95bWVudC5fa2luZH0gc3RlcCAoJHtEdXJhdGlvbi5zZWNvbmRzKHdhaXRTZWNvbmRzKS50b0h1bWFuU3RyaW5nKCl9KTogYSBiYWQgcmV2aXNpb24gY2FuIHJlYWNoIHRoZSBuZXh0IHN0ZXAgYmVmb3JlIGl0cyBhbGFybSBmaXJlcy5gKTtcbiAgICAgIH1cbiAgICAgIC8vIE1vdmVzIHRoZSB0cmFmZmljIGluIHN0ZXBzIGJlZm9yZSBDbG91ZEZvcm1hdGlvbiB3cml0ZXMgdGhlIGVuZHBvaW50LCB3aGljaCB0aGVuIGZpbmRzIGl0IGFscmVhZHkgZG9uZS5cbiAgICAgIGNvbnN0IHNoaWZ0ID0gbmV3IFRyYWZmaWNTaGlmdCh0aGlzLCAnRGVwbG95bWVudCcsIHtcbiAgICAgICAgZnVuY3Rpb25OYW1lOiBwcm9wcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbk5hbWUsXG4gICAgICAgIGZ1bmN0aW9uQXJuOiBwcm9wcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbkFybixcbiAgICAgICAgZW5kcG9pbnROYW1lOiB0aGlzLmVuZHBvaW50TmFtZSxcbiAgICAgICAgcmV2aXNpb25JZDogcHJvcHMuY3VycmVudFJldmlzaW9uLnJldmlzaW9uSWQsXG4gICAgICAgIGRlcGxveW1lbnQ6IHByb3BzLmRlcGxveW1lbnQsXG4gICAgICAgIGFsYXJtQXJuczogcm9sbGJhY2tBbGFybUFybnMsXG4gICAgICAgIGVuZHBvaW50Q29uZmlnOiB7XG4gICAgICAgICAgZW5kcG9pbnRUeXBlLFxuICAgICAgICAgIGF1dGhUeXBlOiBwcm9wcy5hdXRoVHlwZSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24sXG4gICAgICAgICAgcmVnaW9uczogZXh0cmFSZWdpb25zLFxuICAgICAgICAgIHJhdGVMaW1pdDogcHJvcHMucmF0ZUxpbWl0LFxuICAgICAgICAgIG1heEVudmlyb25tZW50czogcHJvcHMubWF4RW52aXJvbm1lbnRzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICByZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koc2hpZnQpO1xuICAgICAgLy8gQWxhcm1zIGluIG90aGVyIHJlZ2lvbnMgYXJlIG9ubHkgcmVmZXJlbmNlZCBieSBBUk4uXG4gICAgICBmb3IgKGNvbnN0IGFsYXJtIG9mIHRoaXMubm9kZS5maW5kQWxsKCkuZmlsdGVyKChjKSA9PiBjIGluc3RhbmNlb2YgUmVnaW9uYWxBbGFybSkpIHNoaWZ0Lm5vZGUuYWRkRGVwZW5kZW5jeShhbGFybSk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5yZXZpc2lvbiAhPT0gdW5kZWZpbmVkIHx8IHByb3BzLmFkZGl0aW9uYWxSZXZpc2lvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5yb3V0ZVRyYWZmaWMocHJvcHMucmV2aXNpb24gPz8gcHJvcHMuY3VycmVudFJldmlzaW9uLCBwcm9wcy5hZGRpdGlvbmFsUmV2aXNpb25zKTtcbiAgICB9XG5cbiAgICB0aGlzLmVuZHBvaW50QXJuID0gcmVzb3VyY2UuYXR0ckVuZHBvaW50QXJuO1xuICAgIHRoaXMuZG9tYWluTmFtZSA9IHJlc291cmNlLmF0dHJEb21haW5OYW1lO1xuICAgIHRoaXMudXJsID0gYGh0dHBzOi8vJHtyZXNvdXJjZS5hdHRyRG9tYWluTmFtZX1gO1xuICAgIHRoaXMuZ3JhbnRzID0gV2ViRnVuY3Rpb25HcmFudHMuX2ZvckVuZHBvaW50KHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBVUkwgb2YgdGhpcyBlbmRwb2ludCBpbiBvbmUgcmVnaW9uLiBPbmx5IGZvciBgUEVSX1JFR0lPTmAgZW5kcG9pbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gcmVnaW9uIG9uZSBvZiBgcmVnaW9uc2BcbiAgICovXG4gIHB1YmxpYyByZWdpb25hbFVybChyZWdpb246IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuZW5kcG9pbnRUeXBlICE9PSBXZWJGdW5jdGlvbkVuZHBvaW50VHlwZS5QRVJfUkVHSU9OKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5ub2RlLnBhdGh9OiByZWdpb25hbFVybCgpIGlzIG9ubHkgYXZhaWxhYmxlIGZvciBQRVJfUkVHSU9OIGVuZHBvaW50cyAodGhpcyBvbmUgaXMgJHt0aGlzLmVuZHBvaW50VHlwZX0pOyB1c2UgdXJsYCk7XG4gICAgfVxuICAgIGlmICghdGhpcy5yZWdpb25zLmluY2x1ZGVzKHJlZ2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5vZGUucGF0aH06IHJlZ2lvbiAke3JlZ2lvbn0gaXMgbm90IG9uZSBvZiB0aGUgZW5kcG9pbnQncyByZWdpb25zICgke3RoaXMucmVnaW9ucy5qb2luKCcsICcpfSlgKTtcbiAgICB9XG4gICAgaWYgKHJlZ2lvbiA9PT0gdGhpcy5ob21lUmVnaW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy51cmw7XG4gICAgfVxuICAgIHRoaXMubG9va3VwID8/PSBuZXcgRW5kcG9pbnRMb29rdXAodGhpcywgJ0xvb2t1cCcsIHtcbiAgICAgIGZ1bmN0aW9uTmFtZTogdGhpcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbk5hbWUsXG4gICAgICBmdW5jdGlvbkFybjogdGhpcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbkFybixcbiAgICAgIGVuZHBvaW50TmFtZTogdGhpcy5lbmRwb2ludE5hbWUsXG4gICAgICBlbmRwb2ludEFybjogdGhpcy5lbmRwb2ludEFybixcbiAgICB9KTtcbiAgICByZXR1cm4gYGh0dHBzOi8vJHt0aGlzLmxvb2t1cC5yZWdpb25hbERvbWFpbihyZWdpb24pfWA7XG4gIH1cblxuICAvKipcbiAgICogUm91dGVzIHRoZSBlbmRwb2ludCB0byBgcmV2aXNpb25gIGluc3RlYWQgb2YgdGhlIGZ1bmN0aW9uJ3MgY3VycmVudCByZXZpc2lvbiwgb3B0aW9uYWxseSBzaGFyaW5nXG4gICAqIHRyYWZmaWMgd2l0aCBvbmUgbW9yZSByZXZpc2lvbiAoYGFkZGl0aW9uYWxSZXZpc2lvbnNgLCB3aGljaCBnZXRzIGl0cyB3ZWlnaHQ7IGByZXZpc2lvbmAgZ2V0cyB0aGUgcmVzdCkuXG4gICAqXG4gICAqIFVzZSBpdCB0byBrZWVwIGFuIGVuZHBvaW50IG9uIGFuIGVhcmxpZXIgcmV2aXNpb24gKGBXZWJGdW5jdGlvblJldmlzaW9uLmZyb21SZXZpc2lvbkF0dHJpYnV0ZXNgKSxcbiAgICogb3IgdG8gc2VuZCBwYXJ0IG9mIHRoZSB0cmFmZmljIHRvIHRoZSBjdXJyZW50IHJldmlzaW9uOlxuICAgKiBgZm4uZW5kcG9pbnQucm91dGVUcmFmZmljKHByZXZpb3VzLCBbeyByZXZpc2lvbjogZm4uY3VycmVudFJldmlzaW9uLCB3ZWlnaHQ6IDAuMSB9XSlgLlxuICAgKiBDYW4gYmUgY2FsbGVkIG9uY2UgcGVyIGVuZHBvaW50LCBhbmQgbm90IG9uIG9uZSBjcmVhdGVkIHdpdGggYHJldmlzaW9uYCBvciBgYWRkaXRpb25hbFJldmlzaW9uc2AuXG4gICAqL1xuICBwdWJsaWMgcm91dGVUcmFmZmljKHJldmlzaW9uOiBJV2ViRnVuY3Rpb25SZXZpc2lvbiwgYWRkaXRpb25hbFJldmlzaW9ucz86IFdlYkZ1bmN0aW9uUmV2aXNpb25XZWlnaHRbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmdyYWR1YWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5vZGUucGF0aH06IHRoZSBlbmRwb2ludCBoYXMgYSBkZXBsb3ltZW50IGluIHN0ZXBzLCB3aGljaCBhbHdheXMgbW92ZXMgaXQgdG8gdGhlIGN1cnJlbnQgcmV2aXNpb247IHJvdXRlVHJhZmZpYygpIGNhbid0IGJlIHVzZWQgd2l0aCBpdGApO1xuICAgIH1cbiAgICBpZiAodGhpcy5yb3V0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLm5vZGUucGF0aH06IHRoZSBlbmRwb2ludCdzIHJldmlzaW9ucyBhcmUgYWxyZWFkeSBzZXQgKHJldmlzaW9uLCBhZGRpdGlvbmFsUmV2aXNpb25zIG9yIHJvdXRlVHJhZmZpYylgKTtcbiAgICB9XG4gICAgdGhpcy53ZWlnaHRzID0gcmV2aXNpb25XZWlnaHRzKHRoaXMsIHRoaXMud2ViRnVuY3Rpb24sIHJldmlzaW9uLCBhZGRpdGlvbmFsUmV2aXNpb25zID8/IFtdKTtcbiAgICB0aGlzLnJlc291cmNlLnJldmlzaW9uV2VpZ2h0cyA9IHRoaXMud2VpZ2h0cztcbiAgICB0aGlzLnJvdXRlZCA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVGhlIElEcyBvZiB0aGUgcmV2aXNpb25zIHRoaXMgZW5kcG9pbnQgcm91dGVzIHRvLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfcmV2aXNpb25JZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLndlaWdodHMubWFwKCh3KSA9PiB3LnJldmlzaW9uSWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEEgbWV0cmljIG9mIHRoaXMgZW5kcG9pbnQgaW4gYEFXUy9MYW1iZGEvV2ViYCAoZGltZW5zaW9ucyBgRnVuY3Rpb25OYW1lYCBhbmQgYEVuZHBvaW50TmFtZWApLlxuICAgKlxuICAgKiBNZXRyaWNzIGFyZSBwdWJsaXNoZWQgaW4gdGhlIHJlZ2lvbiB0aGF0IHNlcnZlZCB0aGUgcmVxdWVzdDogcGFzcyBgcmVnaW9uYCBmb3Igb25lIG9mIHRoZSBlbmRwb2ludCdzXG4gICAqIG90aGVyIHJlZ2lvbnMuIEFuIGFsYXJtIGNhbiBvbmx5IHVzZSBtZXRyaWNzIGZyb20gaXRzIG93biBzdGFjaydzIHJlZ2lvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciAxIG1pbnV0ZSwgaW4gdGhlIGhvbWUgcmVnaW9uXG4gICAqL1xuICBwdWJsaWMgbWV0cmljKG1ldHJpY05hbWU6IHN0cmluZywgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBuYW1lc3BhY2U6IFdFQl9OQU1FU1BBQ0UsXG4gICAgICBtZXRyaWNOYW1lLFxuICAgICAgZGltZW5zaW9uc01hcDogZW5kcG9pbnREaW1lbnNpb25zKHRoaXMubWV0cmljSWRzKCkpLFxuICAgICAgc3RhdGlzdGljOiBjbG91ZHdhdGNoLlN0YXRzLlNVTSxcbiAgICAgIHBlcmlvZDogREVGQVVMVF9QRVJJT0QsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBSZXF1ZXN0cyB0aGUgZW5kcG9pbnQgc2VydmVkIChgRXhlY3V0ZWRSZXF1ZXN0c2ApLiBUaGVyZSdzIG5vIHNlcGFyYXRlIGNvdW50IG9mIHN1Y2Nlc3NmdWwgKDJYWCkgcmVzcG9uc2VzLiAqL1xuICBwdWJsaWMgbWV0cmljUmVxdWVzdHMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKFJFUVVFU1RTLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWVzdHMgYW5zd2VyZWQgd2l0aCBhIDRYWCBzdGF0dXMgKGBIVFRQUmVzcG9uc2VTdGF0dXNDbGFzczRYWGApLCBpbmNsdWRpbmcgNDI5cyBmcm9tIGByYXRlTGltaXRgIGFuZCBgbWF4RW52aXJvbm1lbnRzYC5cbiAgICogVGhlIG1ldHJpYyBvbmx5IGV4aXN0cyBvbmNlIGl0J3Mgbm9uLXplcm8sIHNvIGFsYXJtcyBzaG91bGQgdHJlYXQgbWlzc2luZyBkYXRhIGFzIG5vdCBicmVhY2hpbmcuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljQ2xpZW50RXJyb3JzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpYyhDTElFTlRfRVJST1JTLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogUmVxdWVzdHMgYW5zd2VyZWQgd2l0aCBhIDVYWCBzdGF0dXMgKGBIVFRQUmVzcG9uc2VTdGF0dXNDbGFzczVYWGApLiBJbmNsdWRlcyB0aGUgcGxhdGZvcm0ncyA1MDNzIHdoaWxlIHRoZSBlbmRwb2ludFxuICAgKiBzY2FsZXMgdXAgZm9yIGEgc3VkZGVuIGJ1cnN0LCBub3Qgb25seSB5b3VyIGFwcGxpY2F0aW9uJ3MgZXJyb3JzLiBUaGUgbWV0cmljIG9ubHkgZXhpc3RzIG9uY2UgaXQncyBub24temVyby5cbiAgICovXG4gIHB1YmxpYyBtZXRyaWNTZXJ2ZXJFcnJvcnMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKFNFUlZFUl9FUlJPUlMsIHByb3BzKTtcbiAgfVxuXG4gIC8qKiBUaGUgcGVyY2VudGFnZSBvZiByZXF1ZXN0cyBhbnN3ZXJlZCB3aXRoIGEgNFhYIHN0YXR1cyAobWF0aCBleHByZXNzaW9uOyBwZXJpb2RzIHdpdGggbm8gNFhYIGNvdW50IGFzIDApLiAqL1xuICBwdWJsaWMgbWV0cmljQ2xpZW50RXJyb3JSYXRlKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NYXRoRXhwcmVzc2lvbiB7XG4gICAgcmV0dXJuIHRoaXMucmF0ZShDTElFTlRfRVJST1JTLCAnQ2xpZW50IGVycm9yIHJhdGUgKCUpJywgcHJvcHMpO1xuICB9XG5cbiAgLyoqIFRoZSBwZXJjZW50YWdlIG9mIHJlcXVlc3RzIGFuc3dlcmVkIHdpdGggYSA1WFggc3RhdHVzIChtYXRoIGV4cHJlc3Npb247IHBlcmlvZHMgd2l0aCBubyA1WFggY291bnQgYXMgMCkuICovXG4gIHB1YmxpYyBtZXRyaWNTZXJ2ZXJFcnJvclJhdGUocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1hdGhFeHByZXNzaW9uIHtcbiAgICByZXR1cm4gdGhpcy5yYXRlKFNFUlZFUl9FUlJPUlMsICdTZXJ2ZXIgZXJyb3IgcmF0ZSAoJSknLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0aW9uIGVudmlyb25tZW50cyBzZXJ2aW5nIHRoZSBlbmRwb2ludCAoYEVuZHBvaW50QWN0aXZlRW52aXJvbm1lbnRzYCksIHRvIGNvbXBhcmUgd2l0aCBgbWF4RW52aXJvbm1lbnRzYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBtYXhpbXVtIG92ZXIgMSBtaW51dGUsIGluIHRoZSBob21lIHJlZ2lvblxuICAgKi9cbiAgcHVibGljIG1ldHJpY0FjdGl2ZUVudmlyb25tZW50cyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy51c2FnZU1ldHJpYygnRW5kcG9pbnRBY3RpdmVFbnZpcm9ubWVudHMnLCBjbG91ZHdhdGNoLlN0YXRzLk1BWElNVU0sIHByb3BzKTtcbiAgfVxuXG4gIC8qKiBSZXF1ZXN0cyByZWplY3RlZCB3aXRoIDQyOSBiZWNhdXNlIHRoZSBlbmRwb2ludCByZWFjaGVkIGl0cyBgcmF0ZUxpbWl0YCAoYEVuZHBvaW50UmVxdWVzdFRocm90dGxlc2ApLiAqL1xuICBwdWJsaWMgbWV0cmljUmVxdWVzdFRocm90dGxlcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy51c2FnZU1ldHJpYygnRW5kcG9pbnRSZXF1ZXN0VGhyb3R0bGVzJywgY2xvdWR3YXRjaC5TdGF0cy5TVU0sIHByb3BzKTtcbiAgfVxuXG4gIC8qKiBSZXF1ZXN0cyByZWplY3RlZCB3aXRoIDQyOSBiZWNhdXNlIHRoZSBlbmRwb2ludCByZWFjaGVkIGBtYXhFbnZpcm9ubWVudHNgIChgRW5kcG9pbnRBY3RpdmVFbnZpcm9ubWVudFRocm90dGxlc2ApLiAqL1xuICBwdWJsaWMgbWV0cmljRW52aXJvbm1lbnRUaHJvdHRsZXMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMudXNhZ2VNZXRyaWMoJ0VuZHBvaW50QWN0aXZlRW52aXJvbm1lbnRUaHJvdHRsZXMnLCBjbG91ZHdhdGNoLlN0YXRzLlNVTSwgcHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbG93cyBgZ3JhbnRlZWAgdG8gY2FsbCB0aGlzIGVuZHBvaW50LiBTaG9ydGN1dCBmb3IgYGdyYW50cy5pbnZva2UoZ3JhbnRlZSlgLlxuICAgKiBbZGlzYWJsZS1hd3NsaW50Om5vLWdyYW50c11cbiAgICovXG4gIHB1YmxpYyBncmFudEludm9rZShncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudCB7XG4gICAgcmV0dXJuIHRoaXMuZ3JhbnRzLmludm9rZShncmFudGVlKTtcbiAgfVxuXG4gIHByaXZhdGUgbWV0cmljSWRzKCkge1xuICAgIHJldHVybiB7IGZ1bmN0aW9uTmFtZTogdGhpcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbk5hbWUsIGVuZHBvaW50TmFtZTogdGhpcy5lbmRwb2ludE5hbWUgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmF0ZShlcnJvck1ldHJpYzogc3RyaW5nLCBsYWJlbDogc3RyaW5nLCBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWF0aEV4cHJlc3Npb24ge1xuICAgIGNvbnN0IHBlcmlvZCA9IHByb3BzPy5wZXJpb2QgPz8gREVGQVVMVF9QRVJJT0Q7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHsgcGVyaW9kLCByZWdpb246IHByb3BzPy5yZWdpb24sIGFjY291bnQ6IHByb3BzPy5hY2NvdW50IH07XG4gICAgcmV0dXJuIG5ldyBjbG91ZHdhdGNoLk1hdGhFeHByZXNzaW9uKHtcbiAgICAgIGV4cHJlc3Npb246IHJhdGVFeHByZXNzaW9uKDEpLFxuICAgICAgdXNpbmdNZXRyaWNzOiB7IHJlcXVlc3RzOiB0aGlzLm1ldHJpYyhSRVFVRVNUUywgb3B0aW9ucyksIGVycm9yczogdGhpcy5tZXRyaWMoZXJyb3JNZXRyaWMsIG9wdGlvbnMpIH0sXG4gICAgICBwZXJpb2QsXG4gICAgICBsYWJlbDogcHJvcHM/LmxhYmVsID8/IGxhYmVsLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1c2FnZU1ldHJpYyhtZXRyaWNOYW1lOiBzdHJpbmcsIHN0YXRpc3RpYzogc3RyaW5nLCBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgIG5hbWVzcGFjZTogVVNBR0VfTkFNRVNQQUNFLFxuICAgICAgbWV0cmljTmFtZSxcbiAgICAgIGRpbWVuc2lvbnNNYXA6IHsgLi4uZW5kcG9pbnREaW1lbnNpb25zKHRoaXMubWV0cmljSWRzKCkpLCBFeGVjdXRpb25SZWdpb246IHByb3BzPy5yZWdpb24gPz8gdGhpcy5ob21lUmVnaW9uIH0sXG4gICAgICBzdGF0aXN0aWMsXG4gICAgICBwZXJpb2Q6IERFRkFVTFRfUEVSSU9ELFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKiogT25lIGFsYXJtIHBlciB0aHJlc2hvbGQgaW4gZXZlcnkgc2VydmluZyByZWdpb246IGEgQ2xvdWRGb3JtYXRpb24gYWxhcm0gYXQgaG9tZSwgYSBjdXN0b20gcmVzb3VyY2UgZWxzZXdoZXJlLiBSZXR1cm5zIHRoZWlyIEFSTnMuICovXG4gIHByaXZhdGUgY3JlYXRlUm9sbGJhY2tBbGFybXMocm9sbGJhY2s6IFJlc29sdmVkUm9sbGJhY2tPcHRpb25zKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHRocmVzaG9sZHMgPSBbXG4gICAgICB7IGtleTogJ1NlcnZlckVycm9ycycsIHNob3J0OiAnNXh4JywgbWV0cmljOiBTRVJWRVJfRVJST1JTLCBzdGF0dXM6ICc1WFgnLCB0aHJlc2hvbGQ6IHJvbGxiYWNrLnNlcnZlckVycm9yUmF0ZSB9LFxuICAgICAgeyBrZXk6ICdDbGllbnRFcnJvcnMnLCBzaG9ydDogJzR4eCcsIG1ldHJpYzogQ0xJRU5UX0VSUk9SUywgc3RhdHVzOiAnNFhYJywgdGhyZXNob2xkOiByb2xsYmFjay5jbGllbnRFcnJvclJhdGUgfSxcbiAgICBdO1xuICAgIGNvbnN0IGFybnM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0IG9mIHRocmVzaG9sZHMpIHtcbiAgICAgIGlmICh0LnRocmVzaG9sZCA9PT0gdW5kZWZpbmVkKSBjb250aW51ZTtcbiAgICAgIGZvciAoY29uc3QgcmVnaW9uIG9mIHRoaXMucmVnaW9ucykge1xuICAgICAgICBjb25zdCBkZXNjcmlwdGlvbiA9IGBSb2xscyBiYWNrIGRlcGxveW1lbnRzIG9mIGVuZHBvaW50ICR7dGhpcy5lbmRwb2ludE5hbWV9IG9mICR7dGhpcy53ZWJGdW5jdGlvbi53ZWJGdW5jdGlvbk5hbWV9IHdoZW4gbW9yZSB0aGFuIGBcbiAgICAgICAgICArIGAke3QudGhyZXNob2xkfSUgb2YgaXRzIHJlcXVlc3RzIGluICR7cmVnaW9ufSBnZXQgYSAke3Quc3RhdHVzfSByZXNwb25zZSAoJHtyb2xsYmFjay5ldmFsdWF0aW9uUGVyaW9kc30geCAke3JvbGxiYWNrLnBlcmlvZC50b0h1bWFuU3RyaW5nKCl9LCBgXG4gICAgICAgICAgKyBgcGVyaW9kcyB3aXRoIGZld2VyIHRoYW4gJHtyb2xsYmFjay5taW5pbXVtUmVxdWVzdHN9IHJlcXVlc3RzIGlnbm9yZWQpLmA7XG4gICAgICAgIGlmIChyZWdpb24gPT09IHRoaXMuaG9tZVJlZ2lvbikge1xuICAgICAgICAgIGNvbnN0IGFsYXJtID0gbmV3IGNsb3Vkd2F0Y2guQWxhcm0odGhpcywgYFJvbGxiYWNrJHt0LmtleX1gLCB7XG4gICAgICAgICAgICBtZXRyaWM6IG5ldyBjbG91ZHdhdGNoLk1hdGhFeHByZXNzaW9uKHtcbiAgICAgICAgICAgICAgZXhwcmVzc2lvbjogcmF0ZUV4cHJlc3Npb24ocm9sbGJhY2subWluaW11bVJlcXVlc3RzKSxcbiAgICAgICAgICAgICAgdXNpbmdNZXRyaWNzOiB7XG4gICAgICAgICAgICAgICAgcmVxdWVzdHM6IHRoaXMubWV0cmljKFJFUVVFU1RTLCB7IHBlcmlvZDogcm9sbGJhY2sucGVyaW9kIH0pLFxuICAgICAgICAgICAgICAgIGVycm9yczogdGhpcy5tZXRyaWModC5tZXRyaWMsIHsgcGVyaW9kOiByb2xsYmFjay5wZXJpb2QgfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHBlcmlvZDogcm9sbGJhY2sucGVyaW9kLFxuICAgICAgICAgICAgICBsYWJlbDogYCR7dC5zdGF0dXN9IHJhdGUgKCUpYCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGhyZXNob2xkOiB0LnRocmVzaG9sZCxcbiAgICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiByb2xsYmFjay5ldmFsdWF0aW9uUGVyaW9kcyxcbiAgICAgICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5OT1RfQlJFQUNISU5HLFxuICAgICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjogZGVzY3JpcHRpb24sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5yb2xsYmFja0FsYXJtcy5wdXNoKGFsYXJtKTtcbiAgICAgICAgICBhcm5zLnB1c2goYWxhcm0uYWxhcm1Bcm4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGFsYXJtID0gbmV3IFJlZ2lvbmFsQWxhcm0odGhpcywgYFJvbGxiYWNrJHt0LmtleX0tJHtyZWdpb259YCwge1xuICAgICAgICAgICAgcmVnaW9uLFxuICAgICAgICAgICAgYWxhcm1OYW1lOiBgJHtBTEFSTV9OQU1FX1BSRUZJWH0ke3RoaXMud2ViRnVuY3Rpb24ud2ViRnVuY3Rpb25OYW1lfS0ke3RoaXMuZW5kcG9pbnROYW1lfS0ke3Quc2hvcnR9LXJhdGVgLFxuICAgICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjogZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBtZXRyaWNzOiByYXRlQWxhcm1RdWVyaWVzKHRoaXMubWV0cmljSWRzKCksIHQubWV0cmljLCByb2xsYmFjay5wZXJpb2QsIHJvbGxiYWNrLm1pbmltdW1SZXF1ZXN0cyksXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IHQudGhyZXNob2xkLFxuICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IHJvbGxiYWNrLmV2YWx1YXRpb25QZXJpb2RzLFxuICAgICAgICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVEhSRVNIT0xELFxuICAgICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk5PVF9CUkVBQ0hJTkcsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy5yb2xsYmFja0FsYXJtcy5wdXNoKGNsb3Vkd2F0Y2guQWxhcm0uZnJvbUFsYXJtQXJuKHRoaXMsIGBSb2xsYmFjayR7dC5rZXl9LSR7cmVnaW9ufS1SZWZgLCBhbGFybS5hbGFybUFybikpO1xuICAgICAgICAgIGFybnMucHVzaChhbGFybS5hbGFybUFybik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFybnM7XG4gIH1cbn1cblxuZnVuY3Rpb24gbm9ybWFsaXNlUmVnaW9ucyhzY29wZTogQ29uc3RydWN0LCBlbmRwb2ludFR5cGU6IFdlYkZ1bmN0aW9uRW5kcG9pbnRUeXBlLCBob21lUmVnaW9uOiBzdHJpbmcsIHJlZ2lvbnM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICBjb25zdCBleHRyYSA9IFsuLi5uZXcgU2V0KHJlZ2lvbnMpXS5maWx0ZXIoKHIpID0+IHIgIT09IGhvbWVSZWdpb24pLnNvcnQoKTtcbiAgZm9yIChjb25zdCByIG9mIHJlZ2lvbnMpIHtcbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKHIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogcmVnaW9ucyBtdXN0IGJlIGxpdGVyYWwgcmVnaW9uIG5hbWVzLCBnb3QgYSB0b2tlbmApO1xuICAgIH1cbiAgICBpZiAoIS9eW2Etel17Mn0oLVthLXpdKykrLVxcZCQvLnRlc3QocikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtzY29wZS5ub2RlLnBhdGh9OiAnJHtyfScgaXMgbm90IGEgdmFsaWQgcmVnaW9uIG5hbWVgKTtcbiAgICB9XG4gIH1cbiAgaWYgKGVuZHBvaW50VHlwZSA9PT0gV2ViRnVuY3Rpb25FbmRwb2ludFR5cGUuSE9NRV9SRUdJT04gJiYgZXh0cmEubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtzY29wZS5ub2RlLnBhdGh9OiBhIEhPTUVfUkVHSU9OIGVuZHBvaW50IHNlcnZlcyBvbmx5IHRoZSBob21lIHJlZ2lvbiAoJHtob21lUmVnaW9ufSk7IHVzZSBNVUxUSV9SRUdJT04gb3IgUEVSX1JFR0lPTiB0byBhZGQgJHtleHRyYS5qb2luKCcsICcpfWApO1xuICB9XG4gIGlmIChlbmRwb2ludFR5cGUgIT09IFdlYkZ1bmN0aW9uRW5kcG9pbnRUeXBlLkhPTUVfUkVHSU9OKSB7XG4gICAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZChob21lUmVnaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06ICR7ZW5kcG9pbnRUeXBlfSBlbmRwb2ludHMgbmVlZCBhIHN0YWNrIHdpdGggYW4gZXhwbGljaXQgcmVnaW9uIChlbnYucmVnaW9uKWApO1xuICAgIH1cbiAgICBpZiAoZXh0cmEubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogYSAke2VuZHBvaW50VHlwZX0gZW5kcG9pbnQgbmVlZHMgYXQgbGVhc3Qgb25lIHJlZ2lvbiBiZXNpZGVzIHRoZSBob21lIHJlZ2lvbiAoJHtob21lUmVnaW9ufSlgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGV4dHJhO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVJhdGVMaW1pdChzY29wZTogQ29uc3RydWN0LCByYXRlTGltaXQ6IG51bWJlciB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBpZiAocmF0ZUxpbWl0ID09PSB1bmRlZmluZWQgfHwgVG9rZW4uaXNVbnJlc29sdmVkKHJhdGVMaW1pdCkpIHJldHVybjtcbiAgY29uc3QgYWxsb3dlZCA9IHJhdGVMaW1pdCA9PT0gMFxuICAgIHx8IChyYXRlTGltaXQgPj0gMTAwICYmIHJhdGVMaW1pdCA8PSAxMDAwICYmIHJhdGVMaW1pdCAlIDEwMCA9PT0gMClcbiAgICB8fCAocmF0ZUxpbWl0ID49IDIwMDAgJiYgcmF0ZUxpbWl0IDw9IDEwMDAwICYmIHJhdGVMaW1pdCAlIDEwMDAgPT09IDApO1xuICBpZiAoIWFsbG93ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogcmF0ZUxpbWl0IG11c3QgYmUgMCwgMTAwLTEsMDAwIGluIHN0ZXBzIG9mIDEwMCwgb3IgMiwwMDAtMTAsMDAwIGluIHN0ZXBzIG9mIDEsMDAwLCBnb3QgJHtyYXRlTGltaXR9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVNYXhFbnZpcm9ubWVudHMoc2NvcGU6IENvbnN0cnVjdCwgbWF4RW52aXJvbm1lbnRzOiBudW1iZXIgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgaWYgKG1heEVudmlyb25tZW50cyA9PT0gdW5kZWZpbmVkIHx8IFRva2VuLmlzVW5yZXNvbHZlZChtYXhFbnZpcm9ubWVudHMpKSByZXR1cm47XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihtYXhFbnZpcm9ubWVudHMpIHx8IG1heEVudmlyb25tZW50cyA8IDIgfHwgbWF4RW52aXJvbm1lbnRzID4gMTAwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogbWF4RW52aXJvbm1lbnRzIG11c3QgYmUgYW4gaW50ZWdlciBmcm9tIDIgdG8gMTAsMDAwLCBnb3QgJHttYXhFbnZpcm9ubWVudHN9YCk7XG4gIH1cbn1cblxuLyoqIGBwcmltYXJ5YCBnZXRzIHdoYXQgYGFkZGl0aW9uYWxgIGxlYXZlczsgd2VpZ2h0cyBhcmUgd2hvbGUgcGVyY2VudGFnZXMgc3VtbWluZyB0byAxMDAuICovXG5mdW5jdGlvbiByZXZpc2lvbldlaWdodHMoXG4gIHNjb3BlOiBDb25zdHJ1Y3QsXG4gIHdlYkZ1bmN0aW9uOiBJV2ViRnVuY3Rpb24sXG4gIHByaW1hcnk6IElXZWJGdW5jdGlvblJldmlzaW9uLFxuICBhZGRpdGlvbmFsOiBXZWJGdW5jdGlvblJldmlzaW9uV2VpZ2h0W10sXG4pOiBsYW1iZGEuQ2ZuV2ViRnVuY3Rpb25FbmRwb2ludC5SZXZpc2lvbldlaWdodFByb3BlcnR5W10ge1xuICBmb3IgKGNvbnN0IHIgb2YgW3ByaW1hcnksIC4uLmFkZGl0aW9uYWwubWFwKChhKSA9PiBhLnJldmlzaW9uKV0pIHtcbiAgICBpZiAoci53ZWJGdW5jdGlvbiAhPT0gd2ViRnVuY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtzY29wZS5ub2RlLnBhdGh9OiByZXZpc2lvbiAke3IucmV2aXNpb25JZH0gYmVsb25ncyB0byBhbm90aGVyIGZ1bmN0aW9uYCk7XG4gICAgfVxuICB9XG4gIGlmIChhZGRpdGlvbmFsLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbeyByZXZpc2lvbklkOiBwcmltYXJ5LnJldmlzaW9uSWQsIHdlaWdodDogMTAwIH1dO1xuICB9XG4gIGlmIChhZGRpdGlvbmFsLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogYW4gZW5kcG9pbnQgcm91dGVzIHRvIGF0IG1vc3QgdHdvIHJldmlzaW9ucywgc28gYWRkaXRpb25hbFJldmlzaW9ucyB0YWtlcyBvbmVgKTtcbiAgfVxuICBjb25zdCBbeyByZXZpc2lvbiwgd2VpZ2h0IH1dID0gYWRkaXRpb25hbDtcbiAgY29uc3QgcGVyY2VudCA9IE1hdGgucm91bmQod2VpZ2h0ICogMTAwKTtcbiAgaWYgKFRva2VuLmlzVW5yZXNvbHZlZCh3ZWlnaHQpIHx8IE1hdGguYWJzKHdlaWdodCAqIDEwMCAtIHBlcmNlbnQpID4gMWUtOSB8fCBwZXJjZW50IDwgMSB8fCBwZXJjZW50ID4gOTkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7c2NvcGUubm9kZS5wYXRofTogYW4gYWRkaXRpb25hbCByZXZpc2lvbidzIHdlaWdodCBtdXN0IGJlIGEgd2hvbGUgcGVyY2VudGFnZSBmcm9tIDAuMDEgdG8gMC45OSwgZ290ICR7d2VpZ2h0fWApO1xuICB9XG4gIGlmIChyZXZpc2lvbiA9PT0gcHJpbWFyeSB8fCAoIVRva2VuLmlzVW5yZXNvbHZlZChyZXZpc2lvbi5yZXZpc2lvbklkKSAmJiByZXZpc2lvbi5yZXZpc2lvbklkID09PSBwcmltYXJ5LnJldmlzaW9uSWQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3Njb3BlLm5vZGUucGF0aH06IHRoZSBhZGRpdGlvbmFsIHJldmlzaW9uIGlzIHRoZSBzYW1lIGFzIHRoZSBlbmRwb2ludCdzIHJldmlzaW9uYCk7XG4gIH1cbiAgcmV0dXJuIFt7IHJldmlzaW9uSWQ6IHByaW1hcnkucmV2aXNpb25JZCwgd2VpZ2h0OiAxMDAgLSBwZXJjZW50IH0sIHsgcmV2aXNpb25JZDogcmV2aXNpb24ucmV2aXNpb25JZCwgd2VpZ2h0OiBwZXJjZW50IH1dO1xufVxuXG4vKipcbiAqIGA8cHJlZml4Pi08aGFzaD5gLCB3aXRoIHRoZSBoYXNoIGNvdmVyaW5nIHRoZSBlbmRwb2ludCB0eXBlIGFuZCByZWdpb25zOiBhIHR5cGUgb3IgcmVnaW9uIGNoYW5nZSBwcm9kdWNlc1xuICogYSBuZXcgbmFtZSwgc28gdGhlIHJlcGxhY2VtZW50IGRvZXNuJ3QgY29sbGlkZSB3aXRoIHRoZSBlbmRwb2ludCBpdCByZXBsYWNlcy5cbiAqL1xuZnVuY3Rpb24gZGVmYXVsdEVuZHBvaW50TmFtZShwcmVmaXg6IHN0cmluZywgc2VlZDogc3RyaW5nIHwgdW5kZWZpbmVkLCBlbmRwb2ludFR5cGU6IFdlYkZ1bmN0aW9uRW5kcG9pbnRUeXBlLCBleHRyYVJlZ2lvbnM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgY29uc3QgaGFzaCA9IGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShbLi4uKHNlZWQgIT09IHVuZGVmaW5lZCA/IFtzZWVkXSA6IFtdKSwgZW5kcG9pbnRUeXBlLCAuLi5leHRyYVJlZ2lvbnNdLmpvaW4oJywnKSkuZGlnZXN0KCdoZXgnKS5zbGljZSgwLCA4KTtcbiAgcmV0dXJuIGAke3ByZWZpeH0tJHtoYXNofWA7XG59XG4iXX0=
@@ -41,7 +41,7 @@ const iam = __importStar(require("aws-cdk-lib/aws-iam"));
41
41
  */
42
42
  class WebFunctionGrants {
43
43
  endpoint;
44
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@ashishpandeyone/cdk-lambda-web-function.WebFunctionGrants", version: "0.1.2" };
44
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@ashishpandeyone/cdk-lambda-web-function.WebFunctionGrants", version: "0.1.3" };
45
45
  /**
46
46
  * @internal
47
47
  */
@@ -11,7 +11,7 @@ const constructs_1 = require("constructs");
11
11
  * only revisions within `revisionRetention`, or that an endpoint routes to, are kept.
12
12
  */
13
13
  class WebFunctionRevision extends constructs_1.Construct {
14
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@ashishpandeyone/cdk-lambda-web-function.WebFunctionRevision", version: "0.1.2" };
14
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@ashishpandeyone/cdk-lambda-web-function.WebFunctionRevision", version: "0.1.3" };
15
15
  /**
16
16
  * References an existing revision of `webFunction`, e.g. to pin an endpoint to it or split traffic with it.
17
17
  */
@@ -1,4 +1,5 @@
1
1
  import { Duration, type IResource, RemovalPolicy, Resource } from 'aws-cdk-lib';
2
+ import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
2
3
  import * as iam from 'aws-cdk-lib/aws-iam';
3
4
  import * as lambda from 'aws-cdk-lib/aws-lambda';
4
5
  import * as logs from 'aws-cdk-lib/aws-logs';
@@ -202,6 +203,35 @@ export declare class WebFunction extends Resource implements IWebFunction, iam.I
202
203
  * [disable-awslint:no-grants]
203
204
  */
204
205
  grantInvoke(grantee: iam.IGrantable): iam.Grant;
206
+ /**
207
+ * A metric of this function's execution environments in `AWS/Lambda/Web` (dimension `FunctionName`), across all endpoints.
208
+ * For request and error counts, use the endpoint's metrics (`fn.endpoint.metricRequests()`).
209
+ *
210
+ * Metrics are published in the region that served the request: pass `region` for another serving region.
211
+ * An alarm can only use metrics from its own stack's region.
212
+ *
213
+ * @default - sum over 1 minute, in the home region
214
+ */
215
+ metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric;
216
+ /** Time the execution environments were active (`EnvironmentActiveTime`). */
217
+ metricActiveTime(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
218
+ /** CPU time the execution environments used (`EnvironmentCPUTime`). */
219
+ metricCpuTime(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
220
+ /**
221
+ * Requests an execution environment handled at once (`EnvironmentConcurrentRequests`), to compare with
222
+ * `maxConcurrencyPerEnvironment`.
223
+ *
224
+ * @default - maximum over 1 minute
225
+ */
226
+ metricConcurrentRequests(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
227
+ /**
228
+ * Peak memory an execution environment used (`EnvironmentMaxMemoryUsage`); each environment has 2 GB.
229
+ *
230
+ * @default - maximum over 1 minute
231
+ */
232
+ metricMaxMemoryUsage(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
233
+ /** Bytes sent in responses (`ResponseBytes`). */
234
+ metricResponseBytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric;
205
235
  private createEndpoint;
206
236
  private createLogGroups;
207
237
  private logGroupIn;