@aws-cdk/aws-mediaconnect-alpha 2.263.0-alpha.0

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.
@@ -0,0 +1,1095 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.RouterInput = exports.RouterInputConfiguration = exports.RouterInputProtocol = exports.SourcePriorityConfig = exports.PrimarySource = exports.ForwardErrorCorrection = exports.RouterInputTier = exports.RoutingScope = exports.RouterInputProtocolOptions = void 0;
38
+ const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
39
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
40
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
41
+ const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
42
+ const aws_mediaconnect_1 = require("aws-cdk-lib/aws-mediaconnect");
43
+ const helpers_internal_1 = require("aws-cdk-lib/core/lib/helpers-internal");
44
+ const metadata_resource_1 = require("aws-cdk-lib/core/lib/metadata-resource");
45
+ const prop_injectable_1 = require("aws-cdk-lib/core/lib/prop-injectable");
46
+ const mediaconnect_grants_generated_1 = require("./mediaconnect-grants.generated");
47
+ const shared_1 = require("./shared");
48
+ /**
49
+ * Protocol options available for Router Input configurations
50
+ */
51
+ class RouterInputProtocolOptions {
52
+ value;
53
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterInputProtocolOptions", version: "2.263.0-alpha.0" };
54
+ /** Real-time Transport Protocol */
55
+ static RTP = new RouterInputProtocolOptions('RTP');
56
+ /** Reliable Internet Stream Transport */
57
+ static RIST = new RouterInputProtocolOptions('RIST');
58
+ /** Secure Reliable Transport - Caller mode */
59
+ static SRT_CALLER = new RouterInputProtocolOptions('SRT_CALLER');
60
+ /** Secure Reliable Transport - Listener mode */
61
+ static SRT_LISTENER = new RouterInputProtocolOptions('SRT_LISTENER');
62
+ /**
63
+ * Use a custom protocol value
64
+ * @param value The protocol string value
65
+ */
66
+ static of(value) {
67
+ return new RouterInputProtocolOptions(value);
68
+ }
69
+ /** @param value The protocol string value */
70
+ constructor(value) {
71
+ this.value = value;
72
+ }
73
+ /** Returns the string value */
74
+ toString() {
75
+ return this.value;
76
+ }
77
+ }
78
+ exports.RouterInputProtocolOptions = RouterInputProtocolOptions;
79
+ /**
80
+ * Routing scope for the Router Input
81
+ */
82
+ class RoutingScope {
83
+ value;
84
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RoutingScope", version: "2.263.0-alpha.0" };
85
+ /** Route traffic within the same AWS region */
86
+ static REGIONAL = new RoutingScope('REGIONAL');
87
+ /** Route traffic globally across AWS regions */
88
+ static GLOBAL = new RoutingScope('GLOBAL');
89
+ /**
90
+ * Use a custom routing scope value
91
+ * @param value The routing scope string value
92
+ */
93
+ static of(value) {
94
+ return new RoutingScope(value);
95
+ }
96
+ /** @param value The routing scope string value */
97
+ constructor(value) {
98
+ this.value = value;
99
+ }
100
+ /** Returns the string value */
101
+ toString() {
102
+ return this.value;
103
+ }
104
+ }
105
+ exports.RoutingScope = RoutingScope;
106
+ /**
107
+ * Routing tier based on your maximum bitrate requirements.
108
+ */
109
+ class RouterInputTier {
110
+ value;
111
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterInputTier", version: "2.263.0-alpha.0" };
112
+ /** Supports a maximum bitrate up to 100 megabits per second. */
113
+ static INPUT_100 = new RouterInputTier('INPUT_100');
114
+ /** Supports a maximum bitrate up to 50 megabits per second. */
115
+ static INPUT_50 = new RouterInputTier('INPUT_50');
116
+ /** Supports a maximum bitrate up to 20 megabits per second. */
117
+ static INPUT_20 = new RouterInputTier('INPUT_20');
118
+ /**
119
+ * Use a custom tier value
120
+ * @param value The tier string value
121
+ */
122
+ static of(value) {
123
+ return new RouterInputTier(value);
124
+ }
125
+ /** @param value The tier string value */
126
+ constructor(value) {
127
+ this.value = value;
128
+ }
129
+ /** Returns the string value */
130
+ toString() {
131
+ return this.value;
132
+ }
133
+ }
134
+ exports.RouterInputTier = RouterInputTier;
135
+ /**
136
+ * Forward Error Correction (FEC) options for RTP protocol
137
+ */
138
+ var ForwardErrorCorrection;
139
+ (function (ForwardErrorCorrection) {
140
+ /** Enable Forward Error Correction */
141
+ ForwardErrorCorrection["ENABLED"] = "ENABLED";
142
+ /** Disable Forward Error Correction */
143
+ ForwardErrorCorrection["DISABLED"] = "DISABLED";
144
+ })(ForwardErrorCorrection || (exports.ForwardErrorCorrection = ForwardErrorCorrection = {}));
145
+ /**
146
+ * Identifies which protocol in a failover configuration's protocols array is primary.
147
+ */
148
+ var PrimarySource;
149
+ (function (PrimarySource) {
150
+ /** The first protocol in the failover protocols array. */
151
+ PrimarySource[PrimarySource["FIRST_SOURCE"] = 0] = "FIRST_SOURCE";
152
+ /** The second protocol in the failover protocols array. */
153
+ PrimarySource[PrimarySource["SECOND_SOURCE"] = 1] = "SECOND_SOURCE";
154
+ })(PrimarySource || (exports.PrimarySource = PrimarySource = {}));
155
+ /**
156
+ * Internal CFN-level values for the source priority mode.
157
+ * @internal
158
+ */
159
+ var SourcePriorityMode;
160
+ (function (SourcePriorityMode) {
161
+ /** Both sources are equal priority — the service picks one. */
162
+ SourcePriorityMode["NO_PRIORITY"] = "NO_PRIORITY";
163
+ /** One source is primary, the other is backup. */
164
+ SourcePriorityMode["PRIMARY_SECONDARY"] = "PRIMARY_SECONDARY";
165
+ })(SourcePriorityMode || (SourcePriorityMode = {}));
166
+ /**
167
+ * Source priority configuration for failover Router Input configurations.
168
+ */
169
+ class SourcePriorityConfig {
170
+ _mode;
171
+ _primary;
172
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.SourcePriorityConfig", version: "2.263.0-alpha.0" };
173
+ /**
174
+ * Treat both sources with equal priority — MediaConnect picks one when needed.
175
+ */
176
+ static none() {
177
+ return new SourcePriorityConfig(SourcePriorityMode.NO_PRIORITY, undefined);
178
+ }
179
+ /**
180
+ * Designate one of the two sources as primary; the other is treated as backup.
181
+ */
182
+ static primarySecondary(primary) {
183
+ try {
184
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_PrimarySource(primary);
185
+ }
186
+ catch (error) {
187
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
188
+ Error.captureStackTrace(error, this.primarySecondary);
189
+ }
190
+ throw error;
191
+ }
192
+ return new SourcePriorityConfig(SourcePriorityMode.PRIMARY_SECONDARY, primary);
193
+ }
194
+ constructor(_mode, _primary) {
195
+ this._mode = _mode;
196
+ this._primary = _primary;
197
+ }
198
+ /**
199
+ * Resolve the configuration to its CFN shape.
200
+ * @internal
201
+ */
202
+ _bind() {
203
+ return {
204
+ sourcePriorityMode: this._mode,
205
+ primarySourceIndex: this._primary,
206
+ };
207
+ }
208
+ }
209
+ exports.SourcePriorityConfig = SourcePriorityConfig;
210
+ /**
211
+ * Identifies which configuration type a port conflict check is being performed for.
212
+ * @internal
213
+ */
214
+ var ProtocolConfigType;
215
+ (function (ProtocolConfigType) {
216
+ /** Failover-mode router input configuration. */
217
+ ProtocolConfigType["FAILOVER"] = "failover";
218
+ /** Merge-mode router input configuration. */
219
+ ProtocolConfigType["MERGE"] = "merge";
220
+ })(ProtocolConfigType || (ProtocolConfigType = {}));
221
+ /**
222
+ * Factory class for creating Router Input protocol configurations
223
+ */
224
+ class RouterInputProtocol {
225
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterInputProtocol", version: "2.263.0-alpha.0" };
226
+ /**
227
+ * Create an RTP protocol configuration
228
+ * @param props RTP protocol properties
229
+ * @returns RouterInputProtocol instance configured for RTP
230
+ */
231
+ static rtp(props) {
232
+ try {
233
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RtpProtocolProps(props);
234
+ }
235
+ catch (error) {
236
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
237
+ Error.captureStackTrace(error, this.rtp);
238
+ }
239
+ throw error;
240
+ }
241
+ RouterInputProtocol.validatePort(props.port);
242
+ return new RouterInputProtocol(RouterInputProtocolOptions.RTP, {
243
+ rtp: {
244
+ port: props.port,
245
+ forwardErrorCorrection: props.forwardErrorCorrection,
246
+ },
247
+ }, props.port);
248
+ }
249
+ /**
250
+ * Create a RIST protocol configuration
251
+ * @param props RIST protocol properties
252
+ * @returns RouterInputProtocol instance configured for RIST
253
+ */
254
+ static rist(props) {
255
+ try {
256
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RistProtocolProps(props);
257
+ }
258
+ catch (error) {
259
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
260
+ Error.captureStackTrace(error, this.rist);
261
+ }
262
+ throw error;
263
+ }
264
+ RouterInputProtocol.validatePort(props.port);
265
+ return new RouterInputProtocol(RouterInputProtocolOptions.RIST, {
266
+ rist: {
267
+ port: props.port,
268
+ recoveryLatencyMilliseconds: props.recoveryLatency.toMilliseconds(),
269
+ },
270
+ }, props.port);
271
+ }
272
+ /**
273
+ * Create an SRT Listener protocol configuration
274
+ * @param props SRT Listener protocol properties
275
+ * @returns RouterInputProtocol instance configured for SRT Listener
276
+ */
277
+ static srtListener(props) {
278
+ try {
279
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_SrtListenerProtocolProps(props);
280
+ }
281
+ catch (error) {
282
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
283
+ Error.captureStackTrace(error, this.srtListener);
284
+ }
285
+ throw error;
286
+ }
287
+ RouterInputProtocol.validatePort(props.port);
288
+ return new RouterInputProtocol(RouterInputProtocolOptions.SRT_LISTENER, {
289
+ srtListener: {
290
+ port: props.port,
291
+ minimumLatencyMilliseconds: props.minimumLatency.toMilliseconds(),
292
+ },
293
+ }, props.port, props.decryptionConfiguration);
294
+ }
295
+ /**
296
+ * Create an SRT Caller protocol configuration
297
+ * @param props SRT Caller protocol properties
298
+ * @returns RouterInputProtocol instance configured for SRT Caller
299
+ */
300
+ static srtCaller(props) {
301
+ try {
302
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_SrtCallerProtocolProps(props);
303
+ }
304
+ catch (error) {
305
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
306
+ Error.captureStackTrace(error, this.srtCaller);
307
+ }
308
+ throw error;
309
+ }
310
+ RouterInputProtocol.validateSrtCallerPort(props.sourcePort);
311
+ return new RouterInputProtocol(RouterInputProtocolOptions.SRT_CALLER, {
312
+ srtCaller: {
313
+ sourceAddress: props.sourceAddress,
314
+ sourcePort: props.sourcePort,
315
+ minimumLatencyMilliseconds: props.minimumLatency.toMilliseconds(),
316
+ streamId: props.streamId,
317
+ },
318
+ }, undefined, props.decryptionConfiguration);
319
+ }
320
+ /**
321
+ * Validate that port is within the valid range (3000-30000)
322
+ */
323
+ static validatePort(port) {
324
+ if (!aws_cdk_lib_1.Token.isUnresolved(port) && (port < 3000 || port > 30000)) {
325
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `RouterInputPortRange`, `Port must be between 3000 and 30000, got ${port}`);
326
+ }
327
+ }
328
+ /**
329
+ * Validate that SRT Caller port is within the valid range (0-65535)
330
+ */
331
+ static validateSrtCallerPort(port) {
332
+ if (!aws_cdk_lib_1.Token.isUnresolved(port) && (port < 0 || port > 65535)) {
333
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `SrtCallerPortRange`, `SRT Caller port must be between 0 and 65535, got ${port}`);
334
+ }
335
+ }
336
+ _protocolName;
337
+ _config;
338
+ _port;
339
+ _decryption;
340
+ constructor(protocolName, config, port, decryption) {
341
+ this._protocolName = protocolName;
342
+ this._config = config;
343
+ this._port = port;
344
+ this._decryption = decryption;
345
+ }
346
+ /**
347
+ * Resolve this protocol to its CFN-ready form. Returns the protocol identifier,
348
+ * the CFN configuration shape (with SRT decryption auto-role materialized if needed),
349
+ * and the ingest port if the protocol has one.
350
+ *
351
+ * @param scope Construct that scopes the auto-created decryption role
352
+ * @param routerInputArn Optional ARN of the consuming router input — when provided,
353
+ * scopes the auto-created decryption role's trust policy.
354
+ *
355
+ * @internal
356
+ */
357
+ _bind(scope, routerInputArn) {
358
+ if (!this._decryption) {
359
+ return { name: this._protocolName, config: this._config, port: this._port };
360
+ }
361
+ const decryptionConfiguration = (0, shared_1.renderRouterSrtEncryption)(scope, 'DecryptionRole', this._decryption, routerInputArn);
362
+ if (this._config.srtListener) {
363
+ return {
364
+ name: this._protocolName,
365
+ port: this._port,
366
+ config: { srtListener: { ...this._config.srtListener, decryptionConfiguration } },
367
+ };
368
+ }
369
+ if (this._config.srtCaller) {
370
+ return {
371
+ name: this._protocolName,
372
+ port: this._port,
373
+ config: { srtCaller: { ...this._config.srtCaller, decryptionConfiguration } },
374
+ };
375
+ }
376
+ return { name: this._protocolName, config: this._config, port: this._port };
377
+ }
378
+ /**
379
+ * Compute the ingest URL (scheme://ipAddress:port) for this protocol, if it has
380
+ * a listening port.
381
+ *
382
+ * @internal
383
+ */
384
+ _ingestUrl(ipAddress) {
385
+ if (this._port === undefined)
386
+ return undefined;
387
+ return renderIngestUrl(this._protocolName.value, this._port, ipAddress);
388
+ }
389
+ /**
390
+ * The listening port for this protocol, if it has one. Undefined for SRT caller
391
+ * (which has a `sourcePort` pointing at the upstream listener, not a port the input
392
+ * itself listens on).
393
+ *
394
+ * @internal
395
+ */
396
+ _listeningPort() {
397
+ return this._port;
398
+ }
399
+ /**
400
+ * Whether two protocols share the same protocol identifier.
401
+ *
402
+ * @internal
403
+ */
404
+ _matchesKind(other) {
405
+ return this._protocolName.value === other._protocolName.value;
406
+ }
407
+ /**
408
+ * Whether this protocol is SRT (Caller or Listener).
409
+ *
410
+ * @internal
411
+ */
412
+ _isSrt() {
413
+ return this._protocolName.value === RouterInputProtocolOptions.SRT_CALLER.value
414
+ || this._protocolName.value === RouterInputProtocolOptions.SRT_LISTENER.value;
415
+ }
416
+ /**
417
+ * Validate port compatibility between this protocol and another in a failover or
418
+ * merge configuration. Throws on conflicts appropriate to the protocol kind.
419
+ *
420
+ * @internal
421
+ */
422
+ _validatePortConflicts(other, configType) {
423
+ const protocolValue = this._protocolName.value;
424
+ if (protocolValue === RouterInputProtocolOptions.RIST.value) {
425
+ const rist1 = this._config.rist;
426
+ const rist2 = other._config.rist;
427
+ if (rist1 && rist2 && 'port' in rist1 && 'port' in rist2) {
428
+ const port1 = rist1.port;
429
+ const port2 = rist2.port;
430
+ if (port1 === port2) {
431
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DuplicateRistPort`, `${configType} configuration cannot use the same RIST port ${port1} for both protocols, ` +
432
+ 'each protocol must use a different port number');
433
+ }
434
+ if (Math.abs(port1 - port2) < 2) {
435
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `ConsecutiveRistPort`, `${configType} configuration cannot use consecutive RIST ports ${Math.min(port1, port2)} and ${Math.max(port1, port2)}, ` +
436
+ 'RIST protocols require non-consecutive ports to avoid overlapping ranges (e.g., use 6000 and 6002)');
437
+ }
438
+ }
439
+ return;
440
+ }
441
+ if (protocolValue === RouterInputProtocolOptions.RTP.value) {
442
+ const rtp1 = this._config.rtp;
443
+ const rtp2 = other._config.rtp;
444
+ if (rtp1 && rtp2 && 'port' in rtp1 && 'port' in rtp2 && rtp1.port === rtp2.port) {
445
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DuplicateRtpPort`, `${configType} configuration cannot use the same RTP port ${rtp1.port} for both protocols, ` +
446
+ 'each protocol must use a different port number');
447
+ }
448
+ return;
449
+ }
450
+ if (protocolValue === RouterInputProtocolOptions.SRT_LISTENER.value) {
451
+ const srt1 = this._config.srtListener;
452
+ const srt2 = other._config.srtListener;
453
+ if (srt1 && srt2 && 'port' in srt1 && 'port' in srt2 && srt1.port === srt2.port) {
454
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `DuplicateSrtListenerPort`, `${configType} configuration cannot use the same SRT Listener port ${srt1.port} for both protocols, ` +
455
+ 'each protocol must use a different port number');
456
+ }
457
+ }
458
+ }
459
+ }
460
+ exports.RouterInputProtocol = RouterInputProtocol;
461
+ /**
462
+ * Factory class for creating Router Input configurations
463
+ */
464
+ class RouterInputConfiguration {
465
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterInputConfiguration", version: "2.263.0-alpha.0" };
466
+ /**
467
+ * Create a standard Router Input configuration with a single protocol
468
+ * @param props Standard configuration properties
469
+ * @returns RouterInputConfiguration instance for standard setup
470
+ */
471
+ static standard(props) {
472
+ try {
473
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_StandardConfigurationProps(props);
474
+ }
475
+ catch (error) {
476
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
477
+ Error.captureStackTrace(error, this.standard);
478
+ }
479
+ throw error;
480
+ }
481
+ return new StandardRouterInputConfig(props);
482
+ }
483
+ /**
484
+ * Create a failover Router Input configuration with two matching protocols
485
+ * @param props Failover configuration properties
486
+ * @returns RouterInputConfiguration instance for failover setup
487
+ * @throws Error if protocols don't match or count is not exactly 2
488
+ */
489
+ static failover(props) {
490
+ try {
491
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_FailoverConfigurationProps(props);
492
+ }
493
+ catch (error) {
494
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
495
+ Error.captureStackTrace(error, this.failover);
496
+ }
497
+ throw error;
498
+ }
499
+ if (!aws_cdk_lib_1.Token.isUnresolved(props.protocols) && props.protocols.length !== 2) {
500
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `FailoverProtocolCount`, `Failover configuration requires exactly 2 protocols, got ${props.protocols.length}`);
501
+ }
502
+ if (!props.protocols[0]._matchesKind(props.protocols[1])) {
503
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `FailoverProtocolMismatch`, 'Protocols must match');
504
+ }
505
+ props.protocols[0]._validatePortConflicts(props.protocols[1], ProtocolConfigType.FAILOVER);
506
+ return new FailoverRouterInputConfig(props);
507
+ }
508
+ /**
509
+ * Create a merge Router Input configuration with two matching non-SRT protocols
510
+ * @param props Merge configuration properties
511
+ * @returns RouterInputConfiguration instance for merge setup
512
+ * @throws Error if protocols don't match, count is not exactly 2, or SRT protocols are used
513
+ */
514
+ static merge(props) {
515
+ try {
516
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MergeConfigurationProps(props);
517
+ }
518
+ catch (error) {
519
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
520
+ Error.captureStackTrace(error, this.merge);
521
+ }
522
+ throw error;
523
+ }
524
+ if (!aws_cdk_lib_1.Token.isUnresolved(props.protocols) && props.protocols.length !== 2) {
525
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MergeProtocolCount`, `Merge configuration requires exactly 2 protocols, got ${props.protocols.length}`);
526
+ }
527
+ if (props.protocols.some(p => p._isSrt())) {
528
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MergeSrtNotSupported`, 'SRT protocols are not supported in merge configuration');
529
+ }
530
+ if (!props.protocols[0]._matchesKind(props.protocols[1])) {
531
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `MergeProtocolMismatch`, 'Protocols must match');
532
+ }
533
+ props.protocols[0]._validatePortConflicts(props.protocols[1], ProtocolConfigType.MERGE);
534
+ return new MergeRouterInputConfig(props);
535
+ }
536
+ /**
537
+ * Create a MediaConnect Flow Router Input configuration without connecting to a specific flow
538
+ * Use this when you want to prepare the router input for a flow connection later
539
+ * @param props MediaConnect Flow configuration properties without connection
540
+ * @returns RouterInputConfiguration instance for MediaConnect Flow setup without connection
541
+ */
542
+ static mediaConnectFlowWithoutConnection(props) {
543
+ try {
544
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaConnectFlowConfigurationWithoutConnectionProps(props);
545
+ }
546
+ catch (error) {
547
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
548
+ Error.captureStackTrace(error, this.mediaConnectFlowWithoutConnection);
549
+ }
550
+ throw error;
551
+ }
552
+ return new MediaConnectFlowRouterInputConfig({ sourceTransitDecryption: props.sourceTransitDecryption }, props.availabilityZone);
553
+ }
554
+ /**
555
+ * Create a MediaConnect Flow Router Input configuration.
556
+ *
557
+ * Use this when the source flow already exists and you want to connect immediately.
558
+ *
559
+ * @param props MediaConnect Flow configuration properties
560
+ * @returns RouterInputConfiguration instance for MediaConnect Flow setup
561
+ */
562
+ static mediaConnectFlow(props) {
563
+ try {
564
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaConnectFlowConfigurationProps(props);
565
+ }
566
+ catch (error) {
567
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
568
+ Error.captureStackTrace(error, this.mediaConnectFlow);
569
+ }
570
+ throw error;
571
+ }
572
+ return new MediaConnectFlowRouterInputConfig({
573
+ flow: props.flow,
574
+ flowOutput: props.flowOutput,
575
+ sourceTransitDecryption: props.sourceTransitDecryption,
576
+ });
577
+ }
578
+ /**
579
+ * Create a MediaLive Channel Router Input configuration.
580
+ *
581
+ * Use this when the source MediaLive channel already exists and you want to
582
+ * ingest from one of its outputs immediately.
583
+ *
584
+ * @param props MediaLive channel configuration properties
585
+ * @returns RouterInputConfiguration instance for MediaLive channel setup
586
+ */
587
+ static mediaLiveChannel(props) {
588
+ try {
589
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaLiveChannelConfigurationProps(props);
590
+ }
591
+ catch (error) {
592
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
593
+ Error.captureStackTrace(error, this.mediaLiveChannel);
594
+ }
595
+ throw error;
596
+ }
597
+ return new MediaLiveChannelRouterInputConfig({
598
+ mediaLiveChannelArn: props.mediaLiveChannelArn,
599
+ mediaLiveChannelOutputName: props.mediaLiveChannelOutputName,
600
+ mediaLivePipelineId: props.mediaLivePipelineId,
601
+ sourceTransitDecryption: props.sourceTransitDecryption,
602
+ });
603
+ }
604
+ /**
605
+ * Create a MediaLive Channel Router Input configuration without a specific channel connection.
606
+ *
607
+ * Use this when you want to set up the router input before the target MediaLive channel exists.
608
+ *
609
+ * @param props MediaLive channel no-connection properties
610
+ * @returns RouterInputConfiguration instance for MediaLive channel setup without connection
611
+ */
612
+ static mediaLiveChannelWithoutConnection(props) {
613
+ try {
614
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaLiveChannelConfigurationWithoutConnectionProps(props);
615
+ }
616
+ catch (error) {
617
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
618
+ Error.captureStackTrace(error, this.mediaLiveChannelWithoutConnection);
619
+ }
620
+ throw error;
621
+ }
622
+ return new MediaLiveChannelRouterInputConfig({ sourceTransitDecryption: props.sourceTransitDecryption }, props.availabilityZone);
623
+ }
624
+ }
625
+ exports.RouterInputConfiguration = RouterInputConfiguration;
626
+ /**
627
+ * Render an ingest URL string (scheme://ip:port). Used by `_ingestUrl()` on individual
628
+ * protocols and composed into the per-config-variant `_endpoints()` results.
629
+ *
630
+ * Extracts the base protocol for the URL scheme (e.g. SRT_LISTENER → srt, RTP → rtp).
631
+ */
632
+ function renderIngestUrl(protocolName, port, ipAddress) {
633
+ const scheme = protocolName.toLowerCase().split('_')[0];
634
+ return aws_cdk_lib_1.Fn.join('', [`${scheme}://`, ipAddress, `:${port}`]);
635
+ }
636
+ /**
637
+ * Concrete variant: standard (single-protocol) router input configuration.
638
+ * @internal
639
+ */
640
+ class StandardRouterInputConfig extends RouterInputConfiguration {
641
+ props;
642
+ constructor(props) {
643
+ super();
644
+ this.props = props;
645
+ }
646
+ _bind(scope, routerInputArn) {
647
+ const protocol = this.props.protocol._bind(scope, routerInputArn);
648
+ return {
649
+ config: {
650
+ standard: {
651
+ networkInterfaceArn: this.props.networkInterface.routerNetworkInterfaceArn,
652
+ protocol: protocol.name.value,
653
+ protocolConfiguration: protocol.config,
654
+ },
655
+ },
656
+ };
657
+ }
658
+ _endpoints(ipAddress) {
659
+ const url = this.props.protocol._ingestUrl(ipAddress);
660
+ const port = this.props.protocol._listeningPort();
661
+ if (url === undefined || port === undefined)
662
+ return undefined;
663
+ return [{ url, port }];
664
+ }
665
+ }
666
+ /**
667
+ * Concrete variant: failover router input configuration.
668
+ * @internal
669
+ */
670
+ class FailoverRouterInputConfig extends RouterInputConfiguration {
671
+ props;
672
+ constructor(props) {
673
+ super();
674
+ this.props = props;
675
+ }
676
+ _bind(scope, routerInputArn) {
677
+ const priority = (this.props.sourcePriority ?? SourcePriorityConfig.none())._bind();
678
+ return {
679
+ config: {
680
+ failover: {
681
+ networkInterfaceArn: this.props.networkInterface.routerNetworkInterfaceArn,
682
+ protocolConfigurations: this.props.protocols.map(p => p._bind(scope, routerInputArn).config),
683
+ sourcePriorityMode: priority.sourcePriorityMode,
684
+ primarySourceIndex: priority.primarySourceIndex,
685
+ },
686
+ },
687
+ };
688
+ }
689
+ _endpoints(ipAddress) {
690
+ const endpoints = [];
691
+ for (const p of this.props.protocols) {
692
+ const url = p._ingestUrl(ipAddress);
693
+ const port = p._listeningPort();
694
+ if (url === undefined || port === undefined)
695
+ return undefined;
696
+ endpoints.push({ url, port });
697
+ }
698
+ return endpoints;
699
+ }
700
+ }
701
+ /**
702
+ * Concrete variant: merge router input configuration.
703
+ * @internal
704
+ */
705
+ class MergeRouterInputConfig extends RouterInputConfiguration {
706
+ props;
707
+ constructor(props) {
708
+ super();
709
+ this.props = props;
710
+ }
711
+ _bind(scope, routerInputArn) {
712
+ return {
713
+ config: {
714
+ merge: {
715
+ networkInterfaceArn: this.props.networkInterface.routerNetworkInterfaceArn,
716
+ protocolConfigurations: this.props.protocols.map(p => p._bind(scope, routerInputArn).config),
717
+ mergeRecoveryWindowMilliseconds: this.props.mergeRecoveryWindow.toMilliseconds(),
718
+ },
719
+ },
720
+ };
721
+ }
722
+ _endpoints(ipAddress) {
723
+ const endpoints = [];
724
+ for (const p of this.props.protocols) {
725
+ const url = p._ingestUrl(ipAddress);
726
+ const port = p._listeningPort();
727
+ if (url === undefined || port === undefined)
728
+ return undefined;
729
+ endpoints.push({ url, port });
730
+ }
731
+ return endpoints;
732
+ }
733
+ }
734
+ /**
735
+ * Concrete variant: MediaConnect Flow router input configuration (with or without connection).
736
+ * @internal
737
+ */
738
+ class MediaConnectFlowRouterInputConfig extends RouterInputConfiguration {
739
+ options;
740
+ availabilityZone;
741
+ constructor(options, availabilityZone) {
742
+ super();
743
+ this.options = options;
744
+ this.availabilityZone = availabilityZone;
745
+ }
746
+ _bind(scope, routerInputArn) {
747
+ return {
748
+ config: {
749
+ mediaConnectFlow: {
750
+ flowArn: this.options.flow?.flowArn,
751
+ flowOutputArn: this.options.flowOutput?.flowOutputArn,
752
+ sourceTransitDecryption: (0, shared_1.renderTransitEncryption)(scope, 'SourceTransitDecryptionRole', this.options.sourceTransitDecryption, routerInputArn),
753
+ },
754
+ },
755
+ availabilityZone: this.availabilityZone,
756
+ };
757
+ }
758
+ _endpoints(_ipAddress) {
759
+ return undefined;
760
+ }
761
+ }
762
+ /**
763
+ * Concrete variant: MediaLive Channel router input configuration (with or without connection).
764
+ * @internal
765
+ */
766
+ class MediaLiveChannelRouterInputConfig extends RouterInputConfiguration {
767
+ options;
768
+ availabilityZone;
769
+ constructor(options, availabilityZone) {
770
+ super();
771
+ this.options = options;
772
+ this.availabilityZone = availabilityZone;
773
+ }
774
+ _bind(scope, routerInputArn) {
775
+ return {
776
+ config: {
777
+ mediaLiveChannel: {
778
+ mediaLiveChannelArn: this.options.mediaLiveChannelArn,
779
+ mediaLiveChannelOutputName: this.options.mediaLiveChannelOutputName,
780
+ mediaLivePipelineId: this.options.mediaLivePipelineId,
781
+ sourceTransitDecryption: (0, shared_1.renderTransitEncryption)(scope, 'SourceTransitDecryptionRole', this.options.sourceTransitDecryption, routerInputArn),
782
+ },
783
+ },
784
+ availabilityZone: this.availabilityZone,
785
+ };
786
+ }
787
+ _endpoints(_ipAddress) {
788
+ return undefined;
789
+ }
790
+ }
791
+ /**
792
+ * A MediaConnect Router Input that receives media streams and routes them to outputs.
793
+ *
794
+ * Router Inputs support multiple configuration types:
795
+ * - Standard: Single protocol input
796
+ * - Failover: Two matching protocols for redundancy
797
+ * - Merge: Two matching non-SRT protocols for stream merging
798
+ * - MediaConnect Flow: Input from an existing MediaConnect Flow
799
+ */
800
+ class RouterInputBase extends aws_cdk_lib_1.Resource {
801
+ /**
802
+ * A reference to this Router Input resource.
803
+ * Required by the auto-generated IRouterInputRef interface.
804
+ */
805
+ get routerInputRef() {
806
+ return { routerInputArn: this.routerInputArn };
807
+ }
808
+ /**
809
+ * Create a CloudWatch metric for this router input.
810
+ */
811
+ metric(metricName, props) {
812
+ return new aws_cloudwatch_1.Metric({
813
+ metricName,
814
+ namespace: 'AWS/MediaConnect',
815
+ ...props,
816
+ dimensionsMap: {
817
+ RouterInputARN: this.routerInputArn,
818
+ ...props?.dimensionsMap,
819
+ },
820
+ }).attachTo(this);
821
+ }
822
+ /**
823
+ * Metric for the bitrate of the router input's payload.
824
+ */
825
+ metricBitrate(props) {
826
+ return this.metric('RouterInputBitRate', {
827
+ statistic: 'avg',
828
+ period: aws_cdk_lib_1.Duration.seconds(60),
829
+ unit: aws_cloudwatch_1.Unit.BITS_PER_SECOND,
830
+ ...props,
831
+ });
832
+ }
833
+ /**
834
+ * Metric for packets lost in transit that were not recovered by error correction.
835
+ */
836
+ metricNotRecoveredPackets(props) {
837
+ return this.metric('RouterInputNotRecoveredPackets', {
838
+ statistic: 'sum',
839
+ period: aws_cdk_lib_1.Duration.seconds(60),
840
+ unit: aws_cloudwatch_1.Unit.COUNT,
841
+ ...props,
842
+ });
843
+ }
844
+ /**
845
+ * Metric for the total number of packets received by the router input.
846
+ */
847
+ metricTotalPackets(props) {
848
+ return this.metric('RouterInputTotalPackets', {
849
+ statistic: 'sum',
850
+ period: aws_cdk_lib_1.Duration.seconds(60),
851
+ unit: aws_cloudwatch_1.Unit.COUNT,
852
+ ...props,
853
+ });
854
+ }
855
+ /**
856
+ * Metric for the router input connection state (1 connected, 0 disconnected). Applies to SRT sources only.
857
+ */
858
+ metricConnected(props) {
859
+ return this.metric('RouterInputConnected', {
860
+ statistic: 'min',
861
+ period: aws_cdk_lib_1.Duration.seconds(60),
862
+ unit: aws_cloudwatch_1.Unit.NONE,
863
+ ...props,
864
+ });
865
+ }
866
+ /**
867
+ * Metric for continuity counter errors in the transport stream.
868
+ */
869
+ metricContinuityCounterErrors(props) {
870
+ return this.metric('RouterInputCCErrors', {
871
+ statistic: 'sum',
872
+ period: aws_cdk_lib_1.Duration.seconds(60),
873
+ unit: aws_cloudwatch_1.Unit.COUNT,
874
+ ...props,
875
+ });
876
+ }
877
+ /**
878
+ * Metric for the recovery latency of the input stream. Applies to RIST, SRT, and RTP-FEC.
879
+ */
880
+ metricLatency(props) {
881
+ return this.metric('RouterInputLatency', {
882
+ statistic: 'avg',
883
+ period: aws_cdk_lib_1.Duration.seconds(60),
884
+ unit: aws_cloudwatch_1.Unit.MILLISECONDS,
885
+ ...props,
886
+ });
887
+ }
888
+ /**
889
+ * Metric for the number of times the router input has switched sources in Failover mode.
890
+ */
891
+ metricFailoverSwitches(props) {
892
+ return this.metric('RouterInputFailoverSwitches', {
893
+ statistic: 'sum',
894
+ period: aws_cdk_lib_1.Duration.seconds(60),
895
+ unit: aws_cloudwatch_1.Unit.COUNT,
896
+ ...props,
897
+ });
898
+ }
899
+ }
900
+ /**
901
+ * Defines an AWS Elemental MediaConnect Router Input.
902
+ */
903
+ let RouterInput = (() => {
904
+ let _classDecorators = [prop_injectable_1.propertyInjectable];
905
+ let _classDescriptor;
906
+ let _classExtraInitializers = [];
907
+ let _classThis;
908
+ let _classSuper = RouterInputBase;
909
+ var RouterInput = class extends _classSuper {
910
+ static { _classThis = this; }
911
+ static {
912
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
913
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
914
+ RouterInput = _classThis = _classDescriptor.value;
915
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
916
+ }
917
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterInput", version: "2.263.0-alpha.0" };
918
+ /** Uniquely identifies this class. */
919
+ static PROPERTY_INJECTION_ID = '@aws-cdk.aws-mediaconnect-alpha.RouterInput';
920
+ /**
921
+ * Import an existing Router Input from its ARN.
922
+ *
923
+ * Use `fromRouterInputAttributes()` instead if you need to expose `routerInputId`
924
+ * or `ipAddress` on the imported construct.
925
+ *
926
+ * @param scope The parent construct
927
+ * @param id The construct id
928
+ * @param routerInputArn The ARN of the Router Input
929
+ * @returns A Router Input construct
930
+ */
931
+ static fromRouterInputArn(scope, id, routerInputArn) {
932
+ return RouterInput.fromRouterInputAttributes(scope, id, { routerInputArn });
933
+ }
934
+ /**
935
+ * Import an existing Router Input from its attributes.
936
+ *
937
+ * Provide `routerInputId` and/or `ipAddress` when importing an input that was deployed
938
+ * externally — otherwise accessing those properties on the imported construct will throw.
939
+ *
940
+ * @param scope The parent construct
941
+ * @param id The construct id
942
+ * @param attrs The Router Input attributes
943
+ * @returns A Router Input construct
944
+ */
945
+ static fromRouterInputAttributes(scope, id, attrs) {
946
+ try {
947
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RouterInputAttributes(attrs);
948
+ }
949
+ catch (error) {
950
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
951
+ Error.captureStackTrace(error, this.fromRouterInputAttributes);
952
+ }
953
+ throw error;
954
+ }
955
+ class Import extends RouterInputBase {
956
+ routerInputArn = attrs.routerInputArn;
957
+ createdAt = undefined;
958
+ updatedAt = undefined;
959
+ transitEncryptionSecret = undefined;
960
+ grants = mediaconnect_grants_generated_1.RouterInputGrants.fromRouterInput(this);
961
+ get endpoints() {
962
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputEndpointsNotAvailableImported`, `'endpoints' is not available on imported RouterInput ${this.node.path}; only RouterInputs constructed in this app for listening protocol variants (RTP, RIST, SRT listener, including failover and merge) expose ingest endpoints`, this);
963
+ }
964
+ get routerInputId() {
965
+ if (attrs.routerInputId)
966
+ return attrs.routerInputId;
967
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputIdNotProvided`, `'routerInputId' is not available on imported RouterInput ${this.node.path}; pass it via fromRouterInputAttributes`, this);
968
+ }
969
+ get ipAddress() {
970
+ if (attrs.ipAddress)
971
+ return attrs.ipAddress;
972
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputIpAddressNotProvided`, `'ipAddress' is not available on imported RouterInput ${this.node.path}; pass it via fromRouterInputAttributes`, this);
973
+ }
974
+ }
975
+ return new Import(scope, id);
976
+ }
977
+ /**
978
+ * Returns the maximum bitrate in Mbps for a known tier, or undefined for custom tiers.
979
+ */
980
+ static tierLimitMbps(tier) {
981
+ if (tier.value === RouterInputTier.INPUT_20.value)
982
+ return 20;
983
+ if (tier.value === RouterInputTier.INPUT_50.value)
984
+ return 50;
985
+ if (tier.value === RouterInputTier.INPUT_100.value)
986
+ return 100;
987
+ return undefined;
988
+ }
989
+ routerInputArn;
990
+ routerInputId;
991
+ ipAddress;
992
+ createdAt;
993
+ updatedAt;
994
+ _endpoints;
995
+ transitEncryptionSecret;
996
+ grants;
997
+ get endpoints() {
998
+ if (this._endpoints === undefined) {
999
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputEndpointsNotAvailableConfig`, `'endpoints' is not available on this RouterInput ${this.node.path}; only listening protocol variants (RTP, RIST, SRT listener — including failover and merge built from those) expose ingest endpoints — SRT caller, MediaConnect Flow, and MediaLive Channel inputs do not`, this);
1000
+ }
1001
+ return this._endpoints;
1002
+ }
1003
+ constructor(scope, id, props) {
1004
+ super(scope, id, {
1005
+ physicalName: props.routerInputName ?? aws_cdk_lib_1.Lazy.string({ produce: () => aws_cdk_lib_1.Names.uniqueResourceName(this, { maxLength: 128 }) }),
1006
+ });
1007
+ try {
1008
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RouterInputProps(props);
1009
+ }
1010
+ catch (error) {
1011
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1012
+ Error.captureStackTrace(error, RouterInput);
1013
+ }
1014
+ throw error;
1015
+ }
1016
+ // Validate router input name if provided
1017
+ if (props.routerInputName != null && props.routerInputName !== '' && !aws_cdk_lib_1.Token.isUnresolved(props.routerInputName)) {
1018
+ if (props.routerInputName.length > 128) {
1019
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputNameLength`, `Router input name must be between 1 and 128 characters, got ${props.routerInputName.length}`, this);
1020
+ }
1021
+ if (!/^[a-zA-Z0-9-]+$/.test(props.routerInputName)) {
1022
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputNameFormat`, `Router input name must contain only alphanumeric characters and hyphens, got '${props.routerInputName}'`, this);
1023
+ }
1024
+ }
1025
+ // Validate maximum bitrate
1026
+ if (!props.maximumBitrate.isUnresolved() && props.maximumBitrate.toBps() < 1000000) {
1027
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputMinBitrate`, `Maximum bitrate must be at least 1,000,000 bits/s (1 Mbps), got ${props.maximumBitrate.toBps()}`, this);
1028
+ }
1029
+ // Validate bitrate does not exceed tier limit
1030
+ const resolvedTier = props.tier ?? RouterInputTier.INPUT_20;
1031
+ const tierMbps = RouterInput.tierLimitMbps(resolvedTier);
1032
+ if ((0, shared_1.exceedsRouterTierBitrate)(tierMbps, props.maximumBitrate)) {
1033
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputBitrateExceedsTier`, `Maximum bitrate ${props.maximumBitrate.toBps() / 1_000_000} Mbps exceeds the ${resolvedTier.value} tier limit of ${tierMbps} Mbps`, this);
1034
+ }
1035
+ // Validate maintenance time format
1036
+ if (props.maintenanceConfiguration) {
1037
+ (0, shared_1.validateMaintenanceTime)(props.maintenanceConfiguration.time);
1038
+ }
1039
+ // Enhanced CDK Analytics Telemetry
1040
+ (0, metadata_resource_1.addConstructMetadata)(this, props);
1041
+ const stack = aws_cdk_lib_1.Stack.of(this);
1042
+ const targetRegion = props.regionName ?? stack.region;
1043
+ // Wildcard the id — pinning the live ARN (attrArn) would create a role → router-input → role cycle.
1044
+ const routerInputArn = stack.formatArn({
1045
+ service: 'mediaconnect',
1046
+ region: targetRegion,
1047
+ resource: 'routerInput',
1048
+ resourceName: '*',
1049
+ arnFormat: aws_cdk_lib_1.ArnFormat.COLON_RESOURCE_NAME,
1050
+ });
1051
+ const configBind = props.configuration._bind(this, routerInputArn);
1052
+ // Validate AZ matches region if provided
1053
+ if (configBind.availabilityZone && !configBind.availabilityZone.startsWith(targetRegion)) {
1054
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterInputAzRegionMismatch`, `Availability zone '${configBind.availabilityZone}' must be within region '${targetRegion}'`, this);
1055
+ }
1056
+ const transit = (0, shared_1.resolveTransitEncryption)(this, 'TransitEncryptionRole', props.transitEncryption, routerInputArn);
1057
+ const routerinput = new aws_mediaconnect_1.CfnRouterInput(this, 'Resource', {
1058
+ name: this.physicalName,
1059
+ maximumBitrate: props.maximumBitrate.toBps(),
1060
+ tier: (props.tier ?? RouterInputTier.INPUT_20).value,
1061
+ routingScope: props.routingScope.value,
1062
+ maintenanceConfiguration: props.maintenanceConfiguration ? {
1063
+ preferredDayTime: props.maintenanceConfiguration,
1064
+ } : {
1065
+ default: {},
1066
+ },
1067
+ configuration: configBind.config,
1068
+ transitEncryption: transit.config,
1069
+ regionName: targetRegion,
1070
+ availabilityZone: configBind.availabilityZone,
1071
+ tags: props.tags ? (0, shared_1.renderTags)(props.tags) : undefined,
1072
+ });
1073
+ this.routerInputArn = routerinput.attrArn;
1074
+ this.routerInputId = routerinput.attrId;
1075
+ this.ipAddress = routerinput.attrIpAddress;
1076
+ this.createdAt = routerinput.attrCreatedAt;
1077
+ this.updatedAt = routerinput.attrUpdatedAt;
1078
+ // Without this the router input can be created before the
1079
+ // policy is attached ("access denied" at create time). Ordering the grant before the
1080
+ // router input pulls the policy in as a dependency.
1081
+ transit.grant?.applyBefore(routerinput);
1082
+ // Compute ingest endpoints for protocol-based variants
1083
+ this._endpoints = props.configuration._endpoints(routerinput.attrIpAddress);
1084
+ // Store the transit encryption secret if explicitly provided
1085
+ this.transitEncryptionSecret = props.transitEncryption?.secret;
1086
+ this.grants = mediaconnect_grants_generated_1.RouterInputGrants.fromRouterInput(this);
1087
+ }
1088
+ static {
1089
+ __runInitializers(_classThis, _classExtraInitializers);
1090
+ }
1091
+ };
1092
+ return RouterInput = _classThis;
1093
+ })();
1094
+ exports.RouterInput = RouterInput;
1095
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLWlucHV0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicm91dGVyLWlucHV0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLDZDQUFxSTtBQUVySSwrREFBMEQ7QUFDMUQsbUVBQThEO0FBRzlELDRFQUE0RDtBQUM1RCw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBSTFFLG1GQUFvRTtBQUdwRSxxQ0FBdUs7QUFFdks7O0dBRUc7QUFDSCxNQUFhLDBCQUEwQjtJQW1CRDs7SUFsQnBDLG1DQUFtQztJQUM1QixNQUFNLENBQVUsR0FBRyxHQUFHLElBQUksMEJBQTBCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkUseUNBQXlDO0lBQ2xDLE1BQU0sQ0FBVSxJQUFJLEdBQUcsSUFBSSwwQkFBMEIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyRSw4Q0FBOEM7SUFDdkMsTUFBTSxDQUFVLFVBQVUsR0FBRyxJQUFJLDBCQUEwQixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2pGLGdEQUFnRDtJQUN6QyxNQUFNLENBQVUsWUFBWSxHQUFHLElBQUksMEJBQTBCLENBQUMsY0FBYyxDQUFDLENBQUM7SUFFckY7OztPQUdHO0lBQ0ksTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFhO1FBQzVCLE9BQU8sSUFBSSwwQkFBMEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUM5QztJQUVELDZDQUE2QztJQUM3QyxZQUFvQyxLQUFhO1FBQWIsVUFBSyxHQUFMLEtBQUssQ0FBUTtLQUFJO0lBRXJELCtCQUErQjtJQUN4QixRQUFRO1FBQ2IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0tBQ25COztBQXhCSCxnRUF5QkM7QUFrSkQ7O0dBRUc7QUFDSCxNQUFhLFlBQVk7SUFlYTs7SUFkcEMsK0NBQStDO0lBQ3hDLE1BQU0sQ0FBVSxRQUFRLEdBQUcsSUFBSSxZQUFZLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0QsZ0RBQWdEO0lBQ3pDLE1BQU0sQ0FBVSxNQUFNLEdBQUcsSUFBSSxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFM0Q7OztPQUdHO0lBQ0ksTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFhO1FBQzVCLE9BQU8sSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDaEM7SUFFRCxrREFBa0Q7SUFDbEQsWUFBb0MsS0FBYTtRQUFiLFVBQUssR0FBTCxLQUFLLENBQVE7S0FBSTtJQUVyRCwrQkFBK0I7SUFDeEIsUUFBUTtRQUNiLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztLQUNuQjs7QUFwQkgsb0NBcUJDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLGVBQWU7SUFpQlU7O0lBaEJwQyxnRUFBZ0U7SUFDekQsTUFBTSxDQUFVLFNBQVMsR0FBRyxJQUFJLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNwRSwrREFBK0Q7SUFDeEQsTUFBTSxDQUFVLFFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsRSwrREFBK0Q7SUFDeEQsTUFBTSxDQUFVLFFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUVsRTs7O09BR0c7SUFDSSxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQWE7UUFDNUIsT0FBTyxJQUFJLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNuQztJQUVELHlDQUF5QztJQUN6QyxZQUFvQyxLQUFhO1FBQWIsVUFBSyxHQUFMLEtBQUssQ0FBUTtLQUFJO0lBRXJELCtCQUErQjtJQUN4QixRQUFRO1FBQ2IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0tBQ25COztBQXRCSCwwQ0F1QkM7QUF1RkQ7O0dBRUc7QUFDSCxJQUFZLHNCQUtYO0FBTEQsV0FBWSxzQkFBc0I7SUFDaEMsc0NBQXNDO0lBQ3RDLDZDQUFpQixDQUFBO0lBQ2pCLHVDQUF1QztJQUN2QywrQ0FBbUIsQ0FBQTtBQUNyQixDQUFDLEVBTFcsc0JBQXNCLHNDQUF0QixzQkFBc0IsUUFLakM7QUFFRDs7R0FFRztBQUNILElBQVksYUFLWDtBQUxELFdBQVksYUFBYTtJQUN2QiwwREFBMEQ7SUFDMUQsaUVBQWdCLENBQUE7SUFDaEIsMkRBQTJEO0lBQzNELG1FQUFpQixDQUFBO0FBQ25CLENBQUMsRUFMVyxhQUFhLDZCQUFiLGFBQWEsUUFLeEI7QUFFRDs7O0dBR0c7QUFDSCxJQUFLLGtCQUtKO0FBTEQsV0FBSyxrQkFBa0I7SUFDckIsK0RBQStEO0lBQy9ELGlEQUEyQixDQUFBO0lBQzNCLGtEQUFrRDtJQUNsRCw2REFBdUMsQ0FBQTtBQUN6QyxDQUFDLEVBTEksa0JBQWtCLEtBQWxCLGtCQUFrQixRQUt0QjtBQUVEOztHQUVHO0FBQ0gsTUFBYSxvQkFBb0I7SUFnQlo7SUFDQTs7SUFoQm5COztPQUVHO0lBQ0ksTUFBTSxDQUFDLElBQUk7UUFDaEIsT0FBTyxJQUFJLG9CQUFvQixDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUM1RTtJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQXNCOzs7Ozs7Ozs7O1FBQ25ELE9BQU8sSUFBSSxvQkFBb0IsQ0FBQyxrQkFBa0IsQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQztLQUNoRjtJQUVELFlBQ21CLEtBQXlCLEVBQ3pCLFFBQW1DO1FBRG5DLFVBQUssR0FBTCxLQUFLLENBQW9CO1FBQ3pCLGFBQVEsR0FBUixRQUFRLENBQTJCO0tBQ2xEO0lBRUo7OztPQUdHO0lBQ0ksS0FBSztRQUNWLE9BQU87WUFDTCxrQkFBa0IsRUFBRSxJQUFJLENBQUMsS0FBSztZQUM5QixrQkFBa0IsRUFBRSxJQUFJLENBQUMsUUFBUTtTQUNsQyxDQUFDO0tBQ0g7O0FBN0JILG9EQThCQztBQThERDs7O0dBR0c7QUFDSCxJQUFLLGtCQUtKO0FBTEQsV0FBSyxrQkFBa0I7SUFDckIsZ0RBQWdEO0lBQ2hELDJDQUFxQixDQUFBO0lBQ3JCLDZDQUE2QztJQUM3QyxxQ0FBZSxDQUFBO0FBQ2pCLENBQUMsRUFMSSxrQkFBa0IsS0FBbEIsa0JBQWtCLFFBS3RCO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLG1CQUFtQjs7SUFDOUI7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBdUI7Ozs7Ozs7Ozs7UUFDdkMsbUJBQW1CLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxPQUFPLElBQUksbUJBQW1CLENBQUMsMEJBQTBCLENBQUMsR0FBRyxFQUFFO1lBQzdELEdBQUcsRUFBRTtnQkFDSCxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLHNCQUFzQixFQUFFLEtBQUssQ0FBQyxzQkFBc0I7YUFDckQ7U0FDRixFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUNoQjtJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQXdCOzs7Ozs7Ozs7O1FBQ3pDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0MsT0FBTyxJQUFJLG1CQUFtQixDQUFDLDBCQUEwQixDQUFDLElBQUksRUFBRTtZQUM5RCxJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO2dCQUNoQiwyQkFBMkIsRUFBRSxLQUFLLENBQUMsZUFBZSxDQUFDLGNBQWMsRUFBRTthQUNwRTtTQUNGLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2hCO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBK0I7Ozs7Ozs7Ozs7UUFDdkQsbUJBQW1CLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxPQUFPLElBQUksbUJBQW1CLENBQUMsMEJBQTBCLENBQUMsWUFBWSxFQUFFO1lBQ3RFLFdBQVcsRUFBRTtnQkFDWCxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ2hCLDBCQUEwQixFQUFFLEtBQUssQ0FBQyxjQUFjLENBQUMsY0FBYyxFQUFFO2FBQ2xFO1NBQ0YsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0tBQy9DO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBNkI7Ozs7Ozs7Ozs7UUFDbkQsbUJBQW1CLENBQUMscUJBQXFCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzVELE9BQU8sSUFBSSxtQkFBbUIsQ0FBQywwQkFBMEIsQ0FBQyxVQUFVLEVBQUU7WUFDcEUsU0FBUyxFQUFFO2dCQUNULGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtnQkFDbEMsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO2dCQUM1QiwwQkFBMEIsRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLGNBQWMsRUFBRTtnQkFDakUsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO2FBQ3pCO1NBQ0YsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7S0FDOUM7SUFFRDs7T0FFRztJQUNLLE1BQU0sQ0FBQyxZQUFZLENBQUMsSUFBWTtRQUN0QyxJQUFJLENBQUMsbUJBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9ELE1BQU0sSUFBSSxxQ0FBdUIsQ0FBQyxJQUFBLHNCQUFHLEVBQUEsc0JBQXNCLEVBQUUsNENBQTRDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkgsQ0FBQztLQUNGO0lBRUQ7O09BRUc7SUFDSyxNQUFNLENBQUMscUJBQXFCLENBQUMsSUFBWTtRQUMvQyxJQUFJLENBQUMsbUJBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVELE1BQU0sSUFBSSxxQ0FBdUIsQ0FBQyxJQUFBLHNCQUFHLEVBQUEsb0JBQW9CLEVBQUUsb0RBQW9ELElBQUksRUFBRSxDQUFDLENBQUM7UUFDekgsQ0FBQztLQUNGO0lBRWdCLGFBQWEsQ0FBNkI7SUFDMUMsT0FBTyxDQUEwRDtJQUNqRSxLQUFLLENBQVU7SUFDZixXQUFXLENBQXVCO0lBRW5ELFlBQ0UsWUFBd0MsRUFDeEMsTUFBK0QsRUFDL0QsSUFBYSxFQUNiLFVBQWdDO1FBRWhDLElBQUksQ0FBQyxhQUFhLEdBQUcsWUFBWSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDO0tBQy9CO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLEtBQUssQ0FBQyxLQUFnQixFQUFFLGNBQXVCO1FBS3BELElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDOUUsQ0FBQztRQUVELE1BQU0sdUJBQXVCLEdBQUcsSUFBQSxrQ0FBeUIsRUFBQyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUVySCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDN0IsT0FBTztnQkFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWE7Z0JBQ3hCLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSztnQkFDaEIsTUFBTSxFQUFFLEVBQUUsV0FBVyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSx1QkFBdUIsRUFBRSxFQUFFO2FBQ2xGLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQzNCLE9BQU87Z0JBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhO2dCQUN4QixJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUs7Z0JBQ2hCLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsdUJBQXVCLEVBQUUsRUFBRTthQUM5RSxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0tBQzdFO0lBRUQ7Ozs7O09BS0c7SUFDSSxVQUFVLENBQUMsU0FBaUI7UUFDakMsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUMvQyxPQUFPLGVBQWUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ3pFO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksY0FBYztRQUNuQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7S0FDbkI7SUFFRDs7OztPQUlHO0lBQ0ksWUFBWSxDQUFDLEtBQTBCO1FBQzVDLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7S0FDL0Q7SUFFRDs7OztPQUlHO0lBQ0ksTUFBTTtRQUNYLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEtBQUssMEJBQTBCLENBQUMsVUFBVSxDQUFDLEtBQUs7ZUFDMUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEtBQUssMEJBQTBCLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQztLQUNqRjtJQUVEOzs7OztPQUtHO0lBQ0ksc0JBQXNCLENBQUMsS0FBMEIsRUFBRSxVQUE4QjtRQUN0RixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztRQUUvQyxJQUFJLGFBQWEsS0FBSywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDNUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDaEMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDakMsSUFBSSxLQUFLLElBQUksS0FBSyxJQUFJLE1BQU0sSUFBSSxLQUFLLElBQUksTUFBTSxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUN6RCxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUN6QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUN6QixJQUFJLEtBQUssS0FBSyxLQUFLLEVBQUUsQ0FBQztvQkFDcEIsTUFBTSxJQUFJLHFDQUF1QixDQUMvQixJQUFBLHNCQUFHLEVBQUEsbUJBQW1CLEVBQ3RCLEdBQUcsVUFBVSxnREFBZ0QsS0FBSyx1QkFBdUI7d0JBQ3pGLGdEQUFnRCxDQUNqRCxDQUFDO2dCQUNKLENBQUM7Z0JBQ0QsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztvQkFDaEMsTUFBTSxJQUFJLHFDQUF1QixDQUMvQixJQUFBLHNCQUFHLEVBQUEscUJBQXFCLEVBQ3hCLEdBQUcsVUFBVSxvREFBb0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUk7d0JBQ3pILG9HQUFvRyxDQUNyRyxDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1lBQ0QsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLGFBQWEsS0FBSywwQkFBMEIsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDM0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDOUIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDL0IsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLE1BQU0sSUFBSSxJQUFJLElBQUksTUFBTSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDaEYsTUFBTSxJQUFJLHFDQUF1QixDQUMvQixJQUFBLHNCQUFHLEVBQUEsa0JBQWtCLEVBQ3JCLEdBQUcsVUFBVSwrQ0FBK0MsSUFBSSxDQUFDLElBQUksdUJBQXVCO29CQUM1RixnREFBZ0QsQ0FDakQsQ0FBQztZQUNKLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksYUFBYSxLQUFLLDBCQUEwQixDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNwRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztZQUN0QyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztZQUN2QyxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksTUFBTSxJQUFJLElBQUksSUFBSSxNQUFNLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNoRixNQUFNLElBQUkscUNBQXVCLENBQy9CLElBQUEsc0JBQUcsRUFBQSwwQkFBMEIsRUFDN0IsR0FBRyxVQUFVLHdEQUF3RCxJQUFJLENBQUMsSUFBSSx1QkFBdUI7b0JBQ3JHLGdEQUFnRCxDQUNqRCxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7S0FDRjs7QUEzT0gsa0RBNE9DO0FBMEhEOztHQUVHO0FBQ0gsTUFBc0Isd0JBQXdCOztJQUM1Qzs7OztPQUlHO0lBQ0ksTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFpQzs7Ozs7Ozs7OztRQUN0RCxPQUFPLElBQUkseUJBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDN0M7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBaUM7Ozs7Ozs7Ozs7UUFDdEQsSUFBSSxDQUFDLG1CQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6RSxNQUFNLElBQUkscUNBQXVCLENBQUMsSUFBQSxzQkFBRyxFQUFBLHVCQUF1QixFQUFFLDREQUE0RCxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEosQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUN6RCxNQUFNLElBQUkscUNBQXVCLENBQUMsSUFBQSxzQkFBRyxFQUFBLDBCQUEwQixFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUNELEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRixPQUFPLElBQUkseUJBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDN0M7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBOEI7Ozs7Ozs7Ozs7UUFDaEQsSUFBSSxDQUFDLG1CQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6RSxNQUFNLElBQUkscUNBQXVCLENBQUMsSUFBQSxzQkFBRyxFQUFBLG9CQUFvQixFQUFFLHlEQUF5RCxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDaEosQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQzFDLE1BQU0sSUFBSSxxQ0FBdUIsQ0FBQyxJQUFBLHNCQUFHLEVBQUEsc0JBQXNCLEVBQUUsd0RBQXdELENBQUMsQ0FBQztRQUN6SCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3pELE1BQU0sSUFBSSxxQ0FBdUIsQ0FBQyxJQUFBLHNCQUFHLEVBQUEsdUJBQXVCLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztRQUN4RixDQUFDO1FBQ0QsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hGLE9BQU8sSUFBSSxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUMxQztJQUVEOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLGlDQUFpQyxDQUFDLEtBQTBEOzs7Ozs7Ozs7O1FBQ3hHLE9BQU8sSUFBSSxpQ0FBaUMsQ0FBQyxFQUFFLHVCQUF1QixFQUFFLEtBQUssQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQ2xJO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxLQUF5Qzs7Ozs7Ozs7OztRQUN0RSxPQUFPLElBQUksaUNBQWlDLENBQUM7WUFDM0MsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1lBQ2hCLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtZQUM1Qix1QkFBdUIsRUFBRSxLQUFLLENBQUMsdUJBQXVCO1NBQ3ZELENBQUMsQ0FBQztLQUNKO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsS0FBeUM7Ozs7Ozs7Ozs7UUFDdEUsT0FBTyxJQUFJLGlDQUFpQyxDQUFDO1lBQzNDLG1CQUFtQixFQUFFLEtBQUssQ0FBQyxtQkFBbUI7WUFDOUMsMEJBQTBCLEVBQUUsS0FBSyxDQUFDLDBCQUEwQjtZQUM1RCxtQkFBbUIsRUFBRSxLQUFLLENBQUMsbUJBQW1CO1lBQzlDLHVCQUF1QixFQUFFLEtBQUssQ0FBQyx1QkFBdUI7U0FDdkQsQ0FBQyxDQUFDO0tBQ0o7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksTUFBTSxDQUFDLGlDQUFpQyxDQUFDLEtBQTBEOzs7Ozs7Ozs7O1FBQ3hHLE9BQU8sSUFBSSxpQ0FBaUMsQ0FBQyxFQUFFLHVCQUF1QixFQUFFLEtBQUssQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0tBQ2xJOztBQXJHSCw0REEwSEM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsZUFBZSxDQUFDLFlBQW9CLEVBQUUsSUFBWSxFQUFFLFNBQWlCO0lBQzVFLE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxnQkFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLE1BQU0sS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM5RCxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSx5QkFBMEIsU0FBUSx3QkFBd0I7SUFDakM7SUFBN0IsWUFBNkIsS0FBaUM7UUFBSSxLQUFLLEVBQUUsQ0FBQztRQUE3QyxVQUFLLEdBQUwsS0FBSyxDQUE0QjtLQUFjO0lBRXJFLEtBQUssQ0FBQyxLQUFnQixFQUFFLGNBQXVCO1FBQ3BELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDbEUsT0FBTztZQUNMLE1BQU0sRUFBRTtnQkFDTixRQUFRLEVBQUU7b0JBQ1IsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyx5QkFBeUI7b0JBQzFFLFFBQVEsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUs7b0JBQzdCLHFCQUFxQixFQUFFLFFBQVEsQ0FBQyxNQUFNO2lCQUN2QzthQUNGO1NBQ0YsQ0FBQztLQUNIO0lBRU0sVUFBVSxDQUFDLFNBQWlCO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNsRCxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksSUFBSSxLQUFLLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUM5RCxPQUFPLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztLQUN4QjtDQUNGO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSx5QkFBMEIsU0FBUSx3QkFBd0I7SUFDakM7SUFBN0IsWUFBNkIsS0FBaUM7UUFBSSxLQUFLLEVBQUUsQ0FBQztRQUE3QyxVQUFLLEdBQUwsS0FBSyxDQUE0QjtLQUFjO0lBRXJFLEtBQUssQ0FBQyxLQUFnQixFQUFFLGNBQXVCO1FBQ3BELE1BQU0sUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLElBQUksb0JBQW9CLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNwRixPQUFPO1lBQ0wsTUFBTSxFQUFFO2dCQUNOLFFBQVEsRUFBRTtvQkFDUixtQkFBbUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLHlCQUF5QjtvQkFDMUUsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsY0FBYyxDQUFDLENBQUMsTUFBTSxDQUFDO29CQUM1RixrQkFBa0IsRUFBRSxRQUFRLENBQUMsa0JBQWtCO29CQUMvQyxrQkFBa0IsRUFBRSxRQUFRLENBQUMsa0JBQWtCO2lCQUNoRDthQUNGO1NBQ0YsQ0FBQztLQUNIO0lBRU0sVUFBVSxDQUFDLFNBQWlCO1FBQ2pDLE1BQU0sU0FBUyxHQUEwQixFQUFFLENBQUM7UUFDNUMsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sR0FBRyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDcEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ2hDLElBQUksR0FBRyxLQUFLLFNBQVMsSUFBSSxJQUFJLEtBQUssU0FBUztnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM5RCxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0NBQ0Y7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLHNCQUF1QixTQUFRLHdCQUF3QjtJQUM5QjtJQUE3QixZQUE2QixLQUE4QjtRQUFJLEtBQUssRUFBRSxDQUFDO1FBQTFDLFVBQUssR0FBTCxLQUFLLENBQXlCO0tBQWM7SUFFbEUsS0FBSyxDQUFDLEtBQWdCLEVBQUUsY0FBdUI7UUFDcEQsT0FBTztZQUNMLE1BQU0sRUFBRTtnQkFDTixLQUFLLEVBQUU7b0JBQ0wsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyx5QkFBeUI7b0JBQzFFLHNCQUFzQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztvQkFDNUYsK0JBQStCLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLEVBQUU7aUJBQ2pGO2FBQ0Y7U0FDRixDQUFDO0tBQ0g7SUFFTSxVQUFVLENBQUMsU0FBaUI7UUFDakMsTUFBTSxTQUFTLEdBQTBCLEVBQUUsQ0FBQztRQUM1QyxLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNwQyxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDaEMsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLElBQUksS0FBSyxTQUFTO2dCQUFFLE9BQU8sU0FBUyxDQUFDO1lBQzlELFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7S0FDbEI7Q0FDRjtBQVdEOzs7R0FHRztBQUNILE1BQU0saUNBQWtDLFNBQVEsd0JBQXdCO0lBRW5EO0lBQ0E7SUFGbkIsWUFDbUIsT0FBMkMsRUFDM0MsZ0JBQXlCO1FBQ3hDLEtBQUssRUFBRSxDQUFDO1FBRk8sWUFBTyxHQUFQLE9BQU8sQ0FBb0M7UUFDM0MscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFTO0tBQzlCO0lBRVAsS0FBSyxDQUFDLEtBQWdCLEVBQUUsY0FBdUI7UUFDcEQsT0FBTztZQUNMLE1BQU0sRUFBRTtnQkFDTixnQkFBZ0IsRUFBRTtvQkFDaEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU87b0JBQ25DLGFBQWEsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxhQUFhO29CQUNyRCx1QkFBdUIsRUFBRSxJQUFBLGdDQUF1QixFQUFDLEtBQUssRUFBRSw2QkFBNkIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHVCQUF1QixFQUFFLGNBQWMsQ0FBQztpQkFDN0k7YUFDRjtZQUNELGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7U0FDeEMsQ0FBQztLQUNIO0lBRU0sVUFBVSxDQUFDLFVBQWtCO1FBQ2xDLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0NBQ0Y7QUFZRDs7O0dBR0c7QUFDSCxNQUFNLGlDQUFrQyxTQUFRLHdCQUF3QjtJQUVuRDtJQUNBO0lBRm5CLFlBQ21CLE9BQTJDLEVBQzNDLGdCQUF5QjtRQUN4QyxLQUFLLEVBQUUsQ0FBQztRQUZPLFlBQU8sR0FBUCxPQUFPLENBQW9DO1FBQzNDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBUztLQUM5QjtJQUVQLEtBQUssQ0FBQyxLQUFnQixFQUFFLGNBQXVCO1FBQ3BELE9BQU87WUFDTCxNQUFNLEVBQUU7Z0JBQ04sZ0JBQWdCLEVBQUU7b0JBQ2hCLG1CQUFtQixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsbUJBQW1CO29CQUNyRCwwQkFBMEIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLDBCQUEwQjtvQkFDbkUsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUI7b0JBQ3JELHVCQUF1QixFQUFFLElBQUEsZ0NBQXVCLEVBQUMsS0FBSyxFQUFFLDZCQUE2QixFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLEVBQUUsY0FBYyxDQUFDO2lCQUM3STthQUNGO1lBQ0QsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtTQUN4QyxDQUFDO0tBQ0g7SUFFTSxVQUFVLENBQUMsVUFBa0I7UUFDbEMsT0FBTyxTQUFTLENBQUM7S0FDbEI7Q0FDRjtBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBZSxlQUFnQixTQUFRLHNCQUFRO0lBVTdDOzs7T0FHRztJQUNILElBQVcsY0FBYztRQUN2QixPQUFPLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztLQUNoRDtJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLFVBQWtCLEVBQUUsS0FBcUI7UUFDckQsT0FBTyxJQUFJLHVCQUFNLENBQUM7WUFDaEIsVUFBVTtZQUNWLFNBQVMsRUFBRSxrQkFBa0I7WUFDN0IsR0FBRyxLQUFLO1lBQ1IsYUFBYSxFQUFFO2dCQUNiLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYztnQkFDbkMsR0FBRyxLQUFLLEVBQUUsYUFBYTthQUN4QjtTQUNGLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDbkI7SUFFRDs7T0FFRztJQUNJLGFBQWEsQ0FBQyxLQUFxQjtRQUN4QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUU7WUFDdkMsU0FBUyxFQUFFLEtBQUs7WUFDaEIsTUFBTSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLEVBQUUscUJBQUksQ0FBQyxlQUFlO1lBQzFCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztLQUNKO0lBRUQ7O09BRUc7SUFDSSx5QkFBeUIsQ0FBQyxLQUFxQjtRQUNwRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsZ0NBQWdDLEVBQUU7WUFDbkQsU0FBUyxFQUFFLEtBQUs7WUFDaEIsTUFBTSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLEVBQUUscUJBQUksQ0FBQyxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztLQUNKO0lBRUQ7O09BRUc7SUFDSSxrQkFBa0IsQ0FBQyxLQUFxQjtRQUM3QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMseUJBQXlCLEVBQUU7WUFDNUMsU0FBUyxFQUFFLEtBQUs7WUFDaEIsTUFBTSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLEVBQUUscUJBQUksQ0FBQyxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztLQUNKO0lBRUQ7O09BRUc7SUFDSSxlQUFlLENBQUMsS0FBcUI7UUFDMUMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLHNCQUFzQixFQUFFO1lBQ3pDLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDNUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsSUFBSTtZQUNmLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztLQUNKO0lBRUQ7O09BRUc7SUFDSSw2QkFBNkIsQ0FBQyxLQUFxQjtRQUN4RCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMscUJBQXFCLEVBQUU7WUFDeEMsU0FBUyxFQUFFLEtBQUs7WUFDaEIsTUFBTSxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUM1QixJQUFJLEVBQUUscUJBQUksQ0FBQyxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztLQUNKO0lBRUQ7O09BRUc7SUFDSSxhQUFhLENBQUMsS0FBcUI7UUFDeEMsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFO1lBQ3ZDLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDNUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsWUFBWTtZQUN2QixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7S0FDSjtJQUVEOztPQUVHO0lBQ0ksc0JBQXNCLENBQUMsS0FBcUI7UUFDakQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLDZCQUE2QixFQUFFO1lBQ2hELFNBQVMsRUFBRSxLQUFLO1lBQ2hCLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDNUIsSUFBSSxFQUFFLHFCQUFJLENBQUMsS0FBSztZQUNoQixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7S0FDSjtDQUNGO0FBRUQ7O0dBRUc7SUFFVSxXQUFXOzRCQUR2QixvQ0FBa0I7Ozs7c0JBQ2MsZUFBZTsyQkFBdkIsU0FBUSxXQUFlOzs7O1lBQWhELDZLQTRMQzs7Ozs7UUEzTEMsc0NBQXNDO1FBQy9CLE1BQU0sQ0FBVSxxQkFBcUIsR0FBVyw2Q0FBNkMsQ0FBQztRQUVyRzs7Ozs7Ozs7OztXQVVHO1FBQ0ksTUFBTSxDQUFDLGtCQUFrQixDQUFDLEtBQWdCLEVBQUUsRUFBVSxFQUFFLGNBQXNCO1lBQ25GLE9BQU8sV0FBVyxDQUFDLHlCQUF5QixDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1NBQzdFO1FBRUQ7Ozs7Ozs7Ozs7V0FVRztRQUNJLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUE0Qjs7Ozs7Ozs7OztZQUNoRyxNQUFNLE1BQU8sU0FBUSxlQUFlO2dCQUNsQixjQUFjLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQztnQkFDdEMsU0FBUyxHQUFHLFNBQVMsQ0FBQztnQkFDdEIsU0FBUyxHQUFHLFNBQVMsQ0FBQztnQkFDdEIsdUJBQXVCLEdBQUcsU0FBUyxDQUFDO2dCQUNwQyxNQUFNLEdBQUcsaURBQWlCLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVqRSxJQUFXLFNBQVM7b0JBQ2xCLE1BQU0sSUFBSSw2QkFBZSxDQUN2QixJQUFBLHNCQUFHLEVBQUEsMENBQTBDLEVBQzdDLHdEQUF3RCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksNkpBQTZKLEVBQ25PLElBQUksQ0FDTCxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsSUFBVyxhQUFhO29CQUN0QixJQUFJLEtBQUssQ0FBQyxhQUFhO3dCQUFFLE9BQU8sS0FBSyxDQUFDLGFBQWEsQ0FBQztvQkFDcEQsTUFBTSxJQUFJLDZCQUFlLENBQ3ZCLElBQUEsc0JBQUcsRUFBQSwwQkFBMEIsRUFDN0IsNERBQTRELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSx5Q0FBeUMsRUFDbkgsSUFBSSxDQUNMLENBQUM7Z0JBQ0osQ0FBQztnQkFFRCxJQUFXLFNBQVM7b0JBQ2xCLElBQUksS0FBSyxDQUFDLFNBQVM7d0JBQUUsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDO29CQUM1QyxNQUFNLElBQUksNkJBQWUsQ0FDdkIsSUFBQSxzQkFBRyxFQUFBLGlDQUFpQyxFQUNwQyx3REFBd0QsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLHlDQUF5QyxFQUMvRyxJQUFJLENBQ0wsQ0FBQztnQkFDSixDQUFDO2FBQ0Y7WUFDRCxPQUFPLElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztTQUM5QjtRQUVEOztXQUVHO1FBQ0ssTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFxQjtZQUNoRCxJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssZUFBZSxDQUFDLFFBQVEsQ0FBQyxLQUFLO2dCQUFFLE9BQU8sRUFBRSxDQUFDO1lBQzdELElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxlQUFlLENBQUMsUUFBUSxDQUFDLEtBQUs7Z0JBQUUsT0FBTyxFQUFFLENBQUM7WUFDN0QsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLGVBQWUsQ0FBQyxTQUFTLENBQUMsS0FBSztnQkFBRSxPQUFPLEdBQUcsQ0FBQztZQUMvRCxPQUFPLFNBQVMsQ0FBQztTQUNsQjtRQUVlLGNBQWMsQ0FBUztRQUN2QixhQUFhLENBQVM7UUFDdEIsU0FBUyxDQUFTO1FBQ2xCLFNBQVMsQ0FBVTtRQUNuQixTQUFTLENBQVU7UUFDbEIsVUFBVSxDQUFvQztRQUMvQyx1QkFBdUIsQ0FBVztRQUNsQyxNQUFNLENBQW9CO1FBRTFDLElBQVcsU0FBUztZQUNsQixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sSUFBSSw2QkFBZSxDQUN2QixJQUFBLHNCQUFHLEVBQUEsd0NBQXdDLEVBQzNDLG9EQUFvRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksMk1BQTJNLEVBQzdRLElBQUksQ0FDTCxDQUFDO1lBQ0osQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztTQUN4QjtRQUVELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUI7WUFDL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7Z0JBQ2YsWUFBWSxFQUFFLEtBQUssQ0FBQyxlQUFlLElBQUksa0JBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsbUJBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDO2FBQzFILENBQUMsQ0FBQzs7Ozs7O21EQXBHTSxXQUFXOzs7O1lBc0dwQix5Q0FBeUM7WUFDekMsSUFBSSxLQUFLLENBQUMsZUFBZSxJQUFJLElBQUksSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLEVBQUUsSUFBSSxDQUFDLG1CQUFLLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO2dCQUNoSCxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDO29CQUN2QyxNQUFNLElBQUksNkJBQWUsQ0FBQyxJQUFBLHNCQUFHLEVBQUEsdUJBQXVCLEVBQUUsK0RBQStELEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzdKLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQztvQkFDbkQsTUFBTSxJQUFJLDZCQUFlLENBQUMsSUFBQSxzQkFBRyxFQUFBLHVCQUF1QixFQUFFLGlGQUFpRixLQUFLLENBQUMsZUFBZSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3pLLENBQUM7WUFDSCxDQUFDO1lBRUQsMkJBQTJCO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLFlBQVksRUFBRSxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBSyxFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUM7Z0JBQ25GLE1BQU0sSUFBSSw2QkFBZSxDQUFDLElBQUEsc0JBQUcsRUFBQSx1QkFBdUIsRUFBRSxtRUFBbUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2pLLENBQUM7WUFFRCw4Q0FBOEM7WUFDOUMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxlQUFlLENBQUMsUUFBUSxDQUFDO1lBQzVELE1BQU0sUUFBUSxHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDekQsSUFBSSxJQUFBLGlDQUF3QixFQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztnQkFDN0QsTUFBTSxJQUFJLDZCQUFlLENBQUMsSUFBQSxzQkFBRyxFQUFBLCtCQUErQixFQUFFLG1CQUFtQixLQUFLLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxHQUFHLFNBQVMscUJBQXFCLFlBQVksQ0FBQyxLQUFLLGtCQUFrQixRQUFRLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMzTSxDQUFDO1lBRUQsbUNBQW1DO1lBQ25DLElBQUksS0FBSyxDQUFDLHdCQUF3QixFQUFFLENBQUM7Z0JBQ25DLElBQUEsZ0NBQXVCLEVBQUMsS0FBSyxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9ELENBQUM7WUFFRCxtQ0FBbUM7WUFDbkMsSUFBQSx3Q0FBb0IsRUFBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFbEMsTUFBTSxLQUFLLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDN0IsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFVBQVUsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDO1lBRXRELG9HQUFvRztZQUNwRyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO2dCQUNyQyxPQUFPLEVBQUUsY0FBYztnQkFDdkIsTUFBTSxFQUFFLFlBQVk7Z0JBQ3BCLFFBQVEsRUFBRSxhQUFhO2dCQUN2QixZQUFZLEVBQUUsR0FBRztnQkFDakIsU0FBUyxFQUFFLHVCQUFTLENBQUMsbUJBQW1CO2FBQ3pDLENBQUMsQ0FBQztZQUVILE1BQU0sVUFBVSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxjQUFjLENBQUMsQ0FBQztZQUVuRSx5Q0FBeUM7WUFDekMsSUFBSSxVQUFVLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7Z0JBQ3pGLE1BQU0sSUFBSSw2QkFBZSxDQUFDLElBQUEsc0JBQUcsRUFBQSw2QkFBNkIsRUFBRSxzQkFBc0IsVUFBVSxDQUFDLGdCQUFnQiw0QkFBNEIsWUFBWSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDbEssQ0FBQztZQUVELE1BQU0sT0FBTyxHQUFHLElBQUEsaUNBQXdCLEVBQUMsSUFBSSxFQUFFLHVCQUF1QixFQUFFLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUVqSCxNQUFNLFdBQVcsR0FBRyxJQUFJLGlDQUFjLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtnQkFDdkQsSUFBSSxFQUFFLElBQUksQ0FBQyxZQUFZO2dCQUN2QixjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFLLEVBQUU7Z0JBQzVDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUs7Z0JBQ3BELFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLEtBQUs7Z0JBQ3RDLHdCQUF3QixFQUFFLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDLENBQUM7b0JBQ3pELGdCQUFnQixFQUFFLEtBQUssQ0FBQyx3QkFBd0I7aUJBQ2pELENBQUMsQ0FBQyxDQUFDO29CQUNGLE9BQU8sRUFBRSxFQUFFO2lCQUNaO2dCQUNELGFBQWEsRUFBRSxVQUFVLENBQUMsTUFBTTtnQkFDaEMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLE1BQU07Z0JBQ2pDLFVBQVUsRUFBRSxZQUFZO2dCQUN4QixnQkFBZ0IsRUFBRSxVQUFVLENBQUMsZ0JBQWdCO2dCQUM3QyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBQSxtQkFBVSxFQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUzthQUN0RCxDQUFDLENBQUM7WUFFSCxJQUFJLENBQUMsY0FBYyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7WUFDMUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDO1lBQ3hDLElBQUksQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDLGFBQWEsQ0FBQztZQUMzQyxJQUFJLENBQUMsU0FBUyxHQUFHLFdBQVcsQ0FBQyxhQUFhLENBQUM7WUFDM0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxXQUFXLENBQUMsYUFBYSxDQUFDO1lBRTNDLDBEQUEwRDtZQUMxRCxxRkFBcUY7WUFDckYsb0RBQW9EO1lBQ3BELE9BQU8sQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBRXhDLHVEQUF1RDtZQUN2RCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUU1RSw2REFBNkQ7WUFDN0QsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLENBQUM7WUFDL0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxpREFBaUIsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdkQ7O1lBM0xVLHVEQUFXOzs7OztBQUFYLGtDQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBCaXRyYXRlLCBJUmVzb3VyY2UgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBBcm5Gb3JtYXQsIER1cmF0aW9uLCBGbiwgTGF6eSwgTmFtZXMsIFJlc291cmNlLCBTdGFjaywgVG9rZW4sIFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yLCBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgdHlwZSB7IE1ldHJpY09wdGlvbnMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgeyBNZXRyaWMsIFVuaXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgeyBDZm5Sb3V0ZXJJbnB1dCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1tZWRpYWNvbm5lY3QnO1xuaW1wb3J0IHR5cGUgeyBJUm91dGVySW5wdXRSZWYsIFJvdXRlcklucHV0UmVmZXJlbmNlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLW1lZGlhY29ubmVjdCc7XG5pbXBvcnQgdHlwZSB7IElTZWNyZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXInO1xuaW1wb3J0IHsgbGl0IH0gZnJvbSAnYXdzLWNkay1saWIvY29yZS9saWIvaGVscGVycy1pbnRlcm5hbCc7XG5pbXBvcnQgeyBhZGRDb25zdHJ1Y3RNZXRhZGF0YSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL21ldGFkYXRhLXJlc291cmNlJztcbmltcG9ydCB7IHByb3BlcnR5SW5qZWN0YWJsZSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL3Byb3AtaW5qZWN0YWJsZSc7XG5pbXBvcnQgdHlwZSB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHR5cGUgeyBJRmxvdyB9IGZyb20gJy4vZmxvdyc7XG5pbXBvcnQgdHlwZSB7IElGbG93T3V0cHV0IH0gZnJvbSAnLi9mbG93LW91dHB1dCc7XG5pbXBvcnQgeyBSb3V0ZXJJbnB1dEdyYW50cyB9IGZyb20gJy4vbWVkaWFjb25uZWN0LWdyYW50cy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHR5cGUgeyBJUm91dGVyTmV0d29ya0ludGVyZmFjZSB9IGZyb20gJy4vcm91dGVyLW5ldHdvcmstaW50ZXJmYWNlJztcbmltcG9ydCB0eXBlIHsgTWFpbnRlbmFuY2VEYXksIE1lZGlhTGl2ZVBpcGVsaW5lLCBSb3V0ZXJTcnRFbmNyeXB0aW9uLCBUcmFuc2l0RW5jcnlwdGlvbiB9IGZyb20gJy4vc2hhcmVkJztcbmltcG9ydCB7IHJlbmRlclRhZ3MsIGV4Y2VlZHNSb3V0ZXJUaWVyQml0cmF0ZSwgcmVuZGVyUm91dGVyU3J0RW5jcnlwdGlvbiwgcmVuZGVyVHJhbnNpdEVuY3J5cHRpb24sIHJlc29sdmVUcmFuc2l0RW5jcnlwdGlvbiwgdmFsaWRhdGVNYWludGVuYW5jZVRpbWUgfSBmcm9tICcuL3NoYXJlZCc7XG5cbi8qKlxuICogUHJvdG9jb2wgb3B0aW9ucyBhdmFpbGFibGUgZm9yIFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgUm91dGVySW5wdXRQcm90b2NvbE9wdGlvbnMge1xuICAvKiogUmVhbC10aW1lIFRyYW5zcG9ydCBQcm90b2NvbCAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFJUUCA9IG5ldyBSb3V0ZXJJbnB1dFByb3RvY29sT3B0aW9ucygnUlRQJyk7XG4gIC8qKiBSZWxpYWJsZSBJbnRlcm5ldCBTdHJlYW0gVHJhbnNwb3J0ICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUklTVCA9IG5ldyBSb3V0ZXJJbnB1dFByb3RvY29sT3B0aW9ucygnUklTVCcpO1xuICAvKiogU2VjdXJlIFJlbGlhYmxlIFRyYW5zcG9ydCAtIENhbGxlciBtb2RlICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgU1JUX0NBTExFUiA9IG5ldyBSb3V0ZXJJbnB1dFByb3RvY29sT3B0aW9ucygnU1JUX0NBTExFUicpO1xuICAvKiogU2VjdXJlIFJlbGlhYmxlIFRyYW5zcG9ydCAtIExpc3RlbmVyIG1vZGUgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTUlRfTElTVEVORVIgPSBuZXcgUm91dGVySW5wdXRQcm90b2NvbE9wdGlvbnMoJ1NSVF9MSVNURU5FUicpO1xuXG4gIC8qKlxuICAgKiBVc2UgYSBjdXN0b20gcHJvdG9jb2wgdmFsdWVcbiAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90b2NvbCBzdHJpbmcgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgb2YodmFsdWU6IHN0cmluZyk6IFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zIHtcbiAgICByZXR1cm4gbmV3IFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zKHZhbHVlKTtcbiAgfVxuXG4gIC8qKiBAcGFyYW0gdmFsdWUgVGhlIHByb3RvY29sIHN0cmluZyB2YWx1ZSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB2YWx1ZTogc3RyaW5nKSB7fVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBBIHNpbmdsZSBpbmdlc3QgZW5kcG9pbnQgd2hlcmUgdGhlIHJvdXRlciBpbnB1dCBsaXN0ZW5zIGZvciB1cHN0cmVhbSBjb250ZW50LlxuICpcbiAqIEZhaWxvdmVyIGFuZCBtZXJnZSBjb25maWd1cmF0aW9ucyBleHBvc2UgdHdvIGVuZHBvaW50czsgc3RhbmRhcmQgY29uZmlndXJhdGlvbnNcbiAqIGV4cG9zZSBvbmUuIFJldHVybmVkIGJ5IHtAbGluayBJUm91dGVySW5wdXQuZW5kcG9pbnRzfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSb3V0ZXJJbnB1dEVuZHBvaW50IHtcbiAgLyoqXG4gICAqIFRoZSBmdWxsIGluZ2VzdCBVUkwgY29tYmluaW5nIHByb3RvY29sIHNjaGVtZSwgSVAsIGFuZCBwb3J0LiBGb3IgZXhhbXBsZTpcbiAgICogYHNydDovLzIwMy4wLjExMy4xMDo1MDAwYCBvciBgcnRwOi8vMjAzLjAuMTEzLjEwOjUwMDFgLlxuICAgKi9cbiAgcmVhZG9ubHkgdXJsOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0ZW5pbmcgcG9ydCBhdCB3aGljaCB0aGUgcm91dGVyIGlucHV0IGFjY2VwdHMgdXBzdHJlYW0gY29udGVudC5cbiAgICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBJbnRlcmZhY2UgZm9yIFJvdXRlciBJbnB1dFxuICovXG5leHBvcnQgaW50ZXJmYWNlIElSb3V0ZXJJbnB1dCBleHRlbmRzIElSZXNvdXJjZSwgSVJvdXRlcklucHV0UmVmIHtcbiAgLyoqXG4gICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgcm91dGVyIGlucHV0LlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSByb3V0ZXJJbnB1dEFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHJvdXRlciBpbnB1dC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgcm91dGVySW5wdXRJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgcm91dGVyIGlucHV0LlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBpcEFkZHJlc3M6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHRpbWVzdGFtcCB3aGVuIHRoZSByb3V0ZXIgaW5wdXQgd2FzIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGNyZWF0ZWRBdD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHRpbWVzdGFtcCB3aGVuIHRoZSByb3V0ZXIgaW5wdXQgd2FzIGxhc3QgdXBkYXRlZC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgdXBkYXRlZEF0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgaW5nZXN0IGVuZHBvaW50cyAoVVJMICsgcG9ydCkgd2hlcmUgdGhlIHJvdXRlciBpbnB1dCBsaXN0ZW5zLlxuICAgKlxuICAgKiBSZXR1cm5zIG9uZSBlbnRyeSBmb3Igc3RhbmRhcmQgcHJvdG9jb2wtYmFzZWQgdmFyaWFudHMgKFJUUCwgUklTVCwgU1JUIGxpc3RlbmVyKSxcbiAgICogYW5kIG9uZSBlbnRyeSBwZXIgc291cmNlIGZvciBmYWlsb3ZlciBhbmQgbWVyZ2UgY29uZmlndXJhdGlvbnMgYnVpbHQgZnJvbSB0aG9zZVxuICAgKiBwcm90b2NvbHMuIEZvciBleGFtcGxlIGEgZmFpbG92ZXIgUlRQIGlucHV0IHdpbGwgcmV0dXJuOlxuICAgKlxuICAgKiBgYGBcbiAgICogW1xuICAgKiAgIHsgdXJsOiAncnRwOi8vMjAzLjAuMTEzLjEwOjUwMDAnLCBwb3J0OiA1MDAwIH0sXG4gICAqICAgeyB1cmw6ICdydHA6Ly8yMDMuMC4xMTMuMTA6NTAwMScsIHBvcnQ6IDUwMDEgfSxcbiAgICogXVxuICAgKiBgYGBcbiAgICpcbiAgICogQWNjZXNzaW5nIHRoaXMgb24gU1JUIGNhbGxlciAod2hlcmUgdGhlIHJvdXRlciBpbnB1dCBkaWFscyBvdXQgdG8gYSByZW1vdGVcbiAgICogc291cmNlKSwgTWVkaWFDb25uZWN0IEZsb3csIE1lZGlhTGl2ZSBDaGFubmVsLCBvciBpbXBvcnRlZCBpbnB1dHMgdGhyb3dzIOKAlCB0aG9zZVxuICAgKiB2YXJpYW50cyBkbyBub3QgZXhwb3NlIGhvc3Q6cG9ydCBwYWlycyB0aGUgaW5wdXQgbGlzdGVucyBvbi5cbiAgICovXG4gIHJlYWRvbmx5IGVuZHBvaW50czogUm91dGVySW5wdXRFbmRwb2ludFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgU2VjcmV0cyBNYW5hZ2VyIHNlY3JldCBjb250YWluaW5nIHRoZSB0cmFuc2l0IGVuY3J5cHRpb24gcGFzc3BocmFzZS5cbiAgICpcbiAgICogT25seSBhdmFpbGFibGUgd2hlbiB0aGUgUm91dGVyIElucHV0IHdhcyBjcmVhdGVkIHdpdGggZXhwbGljaXRcbiAgICogYHRyYW5zaXRFbmNyeXB0aW9uYCBjb25maWd1cmF0aW9uLiBOb3QgYXZhaWxhYmxlIGZvclxuICAgKiBhdXRvbWF0aWMgZW5jcnlwdGlvbiBvciBpbXBvcnRlZCBpbnB1dHMuXG4gICAqL1xuICByZWFkb25seSB0cmFuc2l0RW5jcnlwdGlvblNlY3JldD86IElTZWNyZXQ7XG5cbiAgLyoqXG4gICAqIENvbGxlY3Rpb24gb2YgZ3JhbnQgbWV0aG9kcyBmb3IgdGhpcyByb3V0ZXIgaW5wdXQuXG4gICAqL1xuICByZWFkb25seSBncmFudHM6IFJvdXRlcklucHV0R3JhbnRzO1xuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIG1ldHJpYyBmb3IgdGhpcyByb3V0ZXIgaW5wdXQuXG4gICAqXG4gICAqIFJvdXRlciBpbnB1dCBtZXRyaWNzIGFyZSBkaW1lbnNpb25lZCBieSBgUm91dGVySW5wdXRBUk5gLiBTZWUgdGhlIE1lZGlhQ29ubmVjdFxuICAgKiBkb2N1bWVudGF0aW9uIGZvciBhdmFpbGFibGUgbWV0cmljIG5hbWVzIChlLmcuIGBSb3V0ZXJJbnB1dEJpdFJhdGVgLFxuICAgKiBgUm91dGVySW5wdXROb3RSZWNvdmVyZWRQYWNrZXRzYCkuXG4gICAqL1xuICBtZXRyaWMobWV0cmljTmFtZTogc3RyaW5nLCBwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIGJpdHJhdGUgb2YgdGhlIHJvdXRlciBpbnB1dCdzIHBheWxvYWQuXG4gICAqIEBkZWZhdWx0IC0gYXZlcmFnZSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIG1ldHJpY0JpdHJhdGUocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHBhY2tldHMgbG9zdCBpbiB0cmFuc2l0IHRoYXQgd2VyZSBub3QgcmVjb3ZlcmVkIGJ5IGVycm9yIGNvcnJlY3Rpb24uXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljTm90UmVjb3ZlcmVkUGFja2V0cyhwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIHRvdGFsIG51bWJlciBvZiBwYWNrZXRzIHJlY2VpdmVkIGJ5IHRoZSByb3V0ZXIgaW5wdXQuXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljVG90YWxQYWNrZXRzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgcm91dGVyIGlucHV0IGNvbm5lY3Rpb24gc3RhdGUgKDEgY29ubmVjdGVkLCAwIGRpc2Nvbm5lY3RlZCkuIEFwcGxpZXMgdG8gU1JUIHNvdXJjZXMgb25seS5cbiAgICogQGRlZmF1bHQgLSBtaW5pbXVtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljQ29ubmVjdGVkKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciBjb250aW51aXR5IGNvdW50ZXIgZXJyb3JzIGluIHRoZSB0cmFuc3BvcnQgc3RyZWFtLlxuICAgKiBAZGVmYXVsdCAtIHN1bSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIG1ldHJpY0NvbnRpbnVpdHlDb3VudGVyRXJyb3JzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgcmVjb3ZlcnkgbGF0ZW5jeSBvZiB0aGUgaW5wdXQgc3RyZWFtLiBBcHBsaWVzIHRvIFJJU1QsIFNSVCwgYW5kIFJUUC1GRUMuXG4gICAqIEBkZWZhdWx0IC0gYXZlcmFnZSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIG1ldHJpY0xhdGVuY3kocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSBudW1iZXIgb2YgdGltZXMgdGhlIHJvdXRlciBpbnB1dCBoYXMgc3dpdGNoZWQgc291cmNlcyBpbiBGYWlsb3ZlciBtb2RlLlxuICAgKiBAZGVmYXVsdCAtIHN1bSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIG1ldHJpY0ZhaWxvdmVyU3dpdGNoZXMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xufVxuXG4vKipcbiAqIFJvdXRpbmcgc2NvcGUgZm9yIHRoZSBSb3V0ZXIgSW5wdXRcbiAqL1xuZXhwb3J0IGNsYXNzIFJvdXRpbmdTY29wZSB7XG4gIC8qKiBSb3V0ZSB0cmFmZmljIHdpdGhpbiB0aGUgc2FtZSBBV1MgcmVnaW9uICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUkVHSU9OQUwgPSBuZXcgUm91dGluZ1Njb3BlKCdSRUdJT05BTCcpO1xuICAvKiogUm91dGUgdHJhZmZpYyBnbG9iYWxseSBhY3Jvc3MgQVdTIHJlZ2lvbnMgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBHTE9CQUwgPSBuZXcgUm91dGluZ1Njb3BlKCdHTE9CQUwnKTtcblxuICAvKipcbiAgICogVXNlIGEgY3VzdG9tIHJvdXRpbmcgc2NvcGUgdmFsdWVcbiAgICogQHBhcmFtIHZhbHVlIFRoZSByb3V0aW5nIHNjb3BlIHN0cmluZyB2YWx1ZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBvZih2YWx1ZTogc3RyaW5nKTogUm91dGluZ1Njb3BlIHtcbiAgICByZXR1cm4gbmV3IFJvdXRpbmdTY29wZSh2YWx1ZSk7XG4gIH1cblxuICAvKiogQHBhcmFtIHZhbHVlIFRoZSByb3V0aW5nIHNjb3BlIHN0cmluZyB2YWx1ZSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB2YWx1ZTogc3RyaW5nKSB7fVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBSb3V0aW5nIHRpZXIgYmFzZWQgb24geW91ciBtYXhpbXVtIGJpdHJhdGUgcmVxdWlyZW1lbnRzLlxuICovXG5leHBvcnQgY2xhc3MgUm91dGVySW5wdXRUaWVyIHtcbiAgLyoqIFN1cHBvcnRzIGEgbWF4aW11bSBiaXRyYXRlIHVwIHRvIDEwMCBtZWdhYml0cyBwZXIgc2Vjb25kLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IElOUFVUXzEwMCA9IG5ldyBSb3V0ZXJJbnB1dFRpZXIoJ0lOUFVUXzEwMCcpO1xuICAvKiogU3VwcG9ydHMgYSBtYXhpbXVtIGJpdHJhdGUgdXAgdG8gNTAgbWVnYWJpdHMgcGVyIHNlY29uZC4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTlBVVF81MCA9IG5ldyBSb3V0ZXJJbnB1dFRpZXIoJ0lOUFVUXzUwJyk7XG4gIC8qKiBTdXBwb3J0cyBhIG1heGltdW0gYml0cmF0ZSB1cCB0byAyMCBtZWdhYml0cyBwZXIgc2Vjb25kLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IElOUFVUXzIwID0gbmV3IFJvdXRlcklucHV0VGllcignSU5QVVRfMjAnKTtcblxuICAvKipcbiAgICogVXNlIGEgY3VzdG9tIHRpZXIgdmFsdWVcbiAgICogQHBhcmFtIHZhbHVlIFRoZSB0aWVyIHN0cmluZyB2YWx1ZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBvZih2YWx1ZTogc3RyaW5nKTogUm91dGVySW5wdXRUaWVyIHtcbiAgICByZXR1cm4gbmV3IFJvdXRlcklucHV0VGllcih2YWx1ZSk7XG4gIH1cblxuICAvKiogQHBhcmFtIHZhbHVlIFRoZSB0aWVyIHN0cmluZyB2YWx1ZSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB2YWx1ZTogc3RyaW5nKSB7fVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBzY2hlZHVsZWQgbWFpbnRlbmFuY2Ugd2luZG93c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIE1haW50ZW5hbmNlQ29uZmlndXJhdGlvbiB7XG4gIC8qKiBEYXkgb2YgdGhlIHdlZWsgZm9yIG1haW50ZW5hbmNlIChlLmcuLCAnTW9uZGF5JywgJ1R1ZXNkYXknKSAqL1xuICByZWFkb25seSBkYXk6IE1haW50ZW5hbmNlRGF5O1xuICAvKiogVGltZSBvZiBkYXkgZm9yIG1haW50ZW5hbmNlIGluIEhIOk1NIGZvcm1hdCAoZS5nLiwgJzAyOjAwJykgKi9cbiAgcmVhZG9ubHkgdGltZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGEgUm91dGVyIElucHV0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGVySW5wdXRQcm9wcyB7XG4gIC8qKlxuICAgKiBOYW1lIG9mIHRoZSBSb3V0ZXIgSW5wdXRcbiAgICogQGRlZmF1bHQgLSBHZW5lcmF0ZWQgYXV0b21hdGljYWxseVxuICAgKi9cbiAgcmVhZG9ubHkgcm91dGVySW5wdXROYW1lPzogc3RyaW5nO1xuICAvKiogTWF4aW11bSBiaXRyYXRlIGluIGJpdHMgcGVyIHNlY29uZCB0aGF0IHRoZSBSb3V0ZXIgSW5wdXQgY2FuIGhhbmRsZSAqL1xuICByZWFkb25seSBtYXhpbXVtQml0cmF0ZTogQml0cmF0ZTtcbiAgLyoqIFJvdXRpbmcgc2NvcGUgZm9yIHRoZSBSb3V0ZXIgSW5wdXQgKi9cbiAgcmVhZG9ubHkgcm91dGluZ1Njb3BlOiBSb3V0aW5nU2NvcGU7XG4gIC8qKlxuICAgKiBTZWxlY3QgYSB0aWVyIGJhc2VkIG9uIHlvdXIgbWF4aW11bSBiaXRyYXRlIHJlcXVpcmVtZW50cy5cbiAgICpcbiAgICogQGRlZmF1bHQgUm91dGVySW5wdXRUaWVyLklOUFVUXzIwXG4gICAqL1xuICByZWFkb25seSB0aWVyPzogUm91dGVySW5wdXRUaWVyO1xuICAvKiogQ29uZmlndXJhdGlvbiBmb3IgdGhlIFJvdXRlciBJbnB1dCAoc3RhbmRhcmQsIGZhaWxvdmVyLCBtZXJnZSwgb3IgTWVkaWFDb25uZWN0IGZsb3cpICovXG4gIHJlYWRvbmx5IGNvbmZpZ3VyYXRpb246IFJvdXRlcklucHV0Q29uZmlndXJhdGlvbjtcbiAgLyoqXG4gICAqIE1haW50ZW5hbmNlIHdpbmRvdyBjb25maWd1cmF0aW9uXG4gICAqIEBkZWZhdWx0IC0gRGVmYXVsdCBtYWludGVuYW5jZSB3aW5kb3cgd2lsbCBiZSB1c2VkXG4gICAqL1xuICByZWFkb25seSBtYWludGVuYW5jZUNvbmZpZ3VyYXRpb24/OiBNYWludGVuYW5jZUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBBV1MgcmVnaW9uIHdoZXJlIHRoZSBSb3V0ZXIgSW5wdXQgd2lsbCBiZSBjcmVhdGVkIChpLmUuIHVzLWVhc3QtMSkuXG4gICAqXG4gICAqIE11c3QgbWF0Y2ggdGhlIHJlZ2lvbiBvZiB0aGUgZmxvd3MsIGZsb3cgb3V0cHV0cywgYW5kIG5ldHdvcmsgaW50ZXJmYWNlcyBpdCBjb25uZWN0cyB0byDigJRcbiAgICogTWVkaWFDb25uZWN0IHJlamVjdHMgYSBjcm9zcy1yZWdpb24gY29ubmVjdGlvbiBhdCBkZXBsb3kuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gU2FtZSBhcyB0aGUgc3RhY2sncyByZWdpb25cbiAgICovXG4gIHJlYWRvbmx5IHJlZ2lvbk5hbWU/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUYWdzIHRvIGFkZCB0byB0aGUgUm91dGVyIElucHV0XG4gICAqIEBkZWZhdWx0IC0gTm8gdGFnZ2luZ1xuICAgKi9cbiAgcmVhZG9ubHkgdGFncz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG4gIC8qKlxuICAgKiBUcmFuc2l0IGVuY3J5cHRpb24gY29uZmlndXJhdGlvbiB1c2luZyBBV1MgU2VjcmV0cyBNYW5hZ2VyLlxuICAgKlxuICAgKiBXaGVuIHByb3ZpZGVkIHdpdGhvdXQgYSByb2xlLCBhIHNjb3BlZCBJQU0gcm9sZSBpcyBhdXRvbWF0aWNhbGx5IGNyZWF0ZWQgd2l0aCByZWFkXG4gICAqIGFjY2VzcyB0byB0aGUgc2VjcmV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEF1dG9tYXRpYyBlbmNyeXB0aW9uIHdpbGwgYmUgY29uZmlndXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgdHJhbnNpdEVuY3J5cHRpb24/OiBUcmFuc2l0RW5jcnlwdGlvbjtcbn1cblxuLyoqXG4gKiBBdHRyaWJ1dGVzIGZvciBpbXBvcnRpbmcgYW4gZXhpc3RpbmcgUm91dGVyIElucHV0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJvdXRlcklucHV0QXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIHJvdXRlciBpbnB1dC5cbiAgICovXG4gIHJlYWRvbmx5IHJvdXRlcklucHV0QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgcm91dGVyIGlucHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGFjY2Vzc2luZyBgcm91dGVySW5wdXRJZGAgb24gdGhlIGltcG9ydGVkIGlucHV0IHRocm93czsgb25seSBwcm92aWRlIHdoZW4gYXZhaWxhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcm91dGVySW5wdXRJZD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQIGFkZHJlc3MgdGhhdCB0aGUgcm91dGVyIGlucHV0IHVzZXMgdG8gaW5nZXN0IGNvbnRlbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWNjZXNzaW5nIGBpcEFkZHJlc3NgIG9uIHRoZSBpbXBvcnRlZCBpbnB1dCB0aHJvd3M7IG9ubHkgcHJvdmlkZSB3aGVuIGF2YWlsYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IGlwQWRkcmVzcz86IHN0cmluZztcbn1cblxuLyoqXG4gKiBGb3J3YXJkIEVycm9yIENvcnJlY3Rpb24gKEZFQykgb3B0aW9ucyBmb3IgUlRQIHByb3RvY29sXG4gKi9cbmV4cG9ydCBlbnVtIEZvcndhcmRFcnJvckNvcnJlY3Rpb24ge1xuICAvKiogRW5hYmxlIEZvcndhcmQgRXJyb3IgQ29ycmVjdGlvbiAqL1xuICBFTkFCTEVEPSdFTkFCTEVEJyxcbiAgLyoqIERpc2FibGUgRm9yd2FyZCBFcnJvciBDb3JyZWN0aW9uICovXG4gIERJU0FCTEVEPSdESVNBQkxFRCcsXG59XG5cbi8qKlxuICogSWRlbnRpZmllcyB3aGljaCBwcm90b2NvbCBpbiBhIGZhaWxvdmVyIGNvbmZpZ3VyYXRpb24ncyBwcm90b2NvbHMgYXJyYXkgaXMgcHJpbWFyeS5cbiAqL1xuZXhwb3J0IGVudW0gUHJpbWFyeVNvdXJjZSB7XG4gIC8qKiBUaGUgZmlyc3QgcHJvdG9jb2wgaW4gdGhlIGZhaWxvdmVyIHByb3RvY29scyBhcnJheS4gKi9cbiAgRklSU1RfU09VUkNFID0gMCxcbiAgLyoqIFRoZSBzZWNvbmQgcHJvdG9jb2wgaW4gdGhlIGZhaWxvdmVyIHByb3RvY29scyBhcnJheS4gKi9cbiAgU0VDT05EX1NPVVJDRSA9IDEsXG59XG5cbi8qKlxuICogSW50ZXJuYWwgQ0ZOLWxldmVsIHZhbHVlcyBmb3IgdGhlIHNvdXJjZSBwcmlvcml0eSBtb2RlLlxuICogQGludGVybmFsXG4gKi9cbmVudW0gU291cmNlUHJpb3JpdHlNb2RlIHtcbiAgLyoqIEJvdGggc291cmNlcyBhcmUgZXF1YWwgcHJpb3JpdHkg4oCUIHRoZSBzZXJ2aWNlIHBpY2tzIG9uZS4gKi9cbiAgTk9fUFJJT1JJVFkgPSAnTk9fUFJJT1JJVFknLFxuICAvKiogT25lIHNvdXJjZSBpcyBwcmltYXJ5LCB0aGUgb3RoZXIgaXMgYmFja3VwLiAqL1xuICBQUklNQVJZX1NFQ09OREFSWSA9ICdQUklNQVJZX1NFQ09OREFSWScsXG59XG5cbi8qKlxuICogU291cmNlIHByaW9yaXR5IGNvbmZpZ3VyYXRpb24gZm9yIGZhaWxvdmVyIFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNvdXJjZVByaW9yaXR5Q29uZmlnIHtcbiAgLyoqXG4gICAqIFRyZWF0IGJvdGggc291cmNlcyB3aXRoIGVxdWFsIHByaW9yaXR5IOKAlCBNZWRpYUNvbm5lY3QgcGlja3Mgb25lIHdoZW4gbmVlZGVkLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBub25lKCk6IFNvdXJjZVByaW9yaXR5Q29uZmlnIHtcbiAgICByZXR1cm4gbmV3IFNvdXJjZVByaW9yaXR5Q29uZmlnKFNvdXJjZVByaW9yaXR5TW9kZS5OT19QUklPUklUWSwgdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXNpZ25hdGUgb25lIG9mIHRoZSB0d28gc291cmNlcyBhcyBwcmltYXJ5OyB0aGUgb3RoZXIgaXMgdHJlYXRlZCBhcyBiYWNrdXAuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHByaW1hcnlTZWNvbmRhcnkocHJpbWFyeTogUHJpbWFyeVNvdXJjZSk6IFNvdXJjZVByaW9yaXR5Q29uZmlnIHtcbiAgICByZXR1cm4gbmV3IFNvdXJjZVByaW9yaXR5Q29uZmlnKFNvdXJjZVByaW9yaXR5TW9kZS5QUklNQVJZX1NFQ09OREFSWSwgcHJpbWFyeSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX21vZGU6IFNvdXJjZVByaW9yaXR5TW9kZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9wcmltYXJ5OiBQcmltYXJ5U291cmNlIHwgdW5kZWZpbmVkLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIGNvbmZpZ3VyYXRpb24gdG8gaXRzIENGTiBzaGFwZS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX2JpbmQoKTogeyBzb3VyY2VQcmlvcml0eU1vZGU6IHN0cmluZzsgcHJpbWFyeVNvdXJjZUluZGV4PzogbnVtYmVyIH0ge1xuICAgIHJldHVybiB7XG4gICAgICBzb3VyY2VQcmlvcml0eU1vZGU6IHRoaXMuX21vZGUsXG4gICAgICBwcmltYXJ5U291cmNlSW5kZXg6IHRoaXMuX3ByaW1hcnksXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIFJUUCBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnRwUHJvdG9jb2xQcm9wcyB7XG4gIC8qKiBQb3J0IG51bWJlciBmb3IgUlRQIHRyYWZmaWMgKi9cbiAgcmVhZG9ubHkgcG9ydDogbnVtYmVyO1xuICAvKipcbiAgICogRm9yd2FyZCBFcnJvciBDb3JyZWN0aW9uIHNldHRpbmdcbiAgICogQGRlZmF1bHQgLSB1bmRlZmluZWQ7IHdoZW4gb21pdHRlZCwgTWVkaWFDb25uZWN0IGFwcGxpZXMgRm9yd2FyZEVycm9yQ29ycmVjdGlvbi5ESVNBQkxFRCBhdCBkZXBsb3kgdGltZVxuICAgKi9cbiAgcmVhZG9ubHkgZm9yd2FyZEVycm9yQ29ycmVjdGlvbj86IEZvcndhcmRFcnJvckNvcnJlY3Rpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgUklTVCBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmlzdFByb3RvY29sUHJvcHMge1xuICAvKiogUG9ydCBudW1iZXIgZm9yIFJJU1QgdHJhZmZpYyAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG4gIC8qKiBSZWNvdmVyeSBsYXRlbmN5IGZvciBSSVNUICovXG4gIHJlYWRvbmx5IHJlY292ZXJ5TGF0ZW5jeTogRHVyYXRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgU1JUIExpc3RlbmVyIHByb3RvY29sIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcnRMaXN0ZW5lclByb3RvY29sUHJvcHMge1xuICAvKiogUG9ydCBudW1iZXIgZm9yIFNSVCBsaXN0ZW5lciAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG4gIC8qKiBNaW5pbXVtIGxhdGVuY3kgZm9yIFNSVCAqL1xuICByZWFkb25seSBtaW5pbXVtTGF0ZW5jeTogRHVyYXRpb247XG4gIC8qKlxuICAgKiBPcHRpb25hbCBkZWNyeXB0aW9uIGNvbmZpZ3VyYXRpb24gZm9yIGVuY3J5cHRlZCBTUlQgc3RyZWFtc1xuICAgKiBAZGVmYXVsdCAtIE5vIGRlY3J5cHRpb25cbiAgICovXG4gIHJlYWRvbmx5IGRlY3J5cHRpb25Db25maWd1cmF0aW9uPzogUm91dGVyU3J0RW5jcnlwdGlvbjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBTUlQgQ2FsbGVyIHByb3RvY29sIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTcnRDYWxsZXJQcm90b2NvbFByb3BzIHtcbiAgLyoqIFNvdXJjZSBJUCBhZGRyZXNzIHRvIGNvbm5lY3QgdG8gKi9cbiAgcmVhZG9ubHkgc291cmNlQWRkcmVzczogc3RyaW5nO1xuICAvKiogU291cmNlIHBvcnQgdG8gY29ubmVjdCB0byAqL1xuICByZWFkb25seSBzb3VyY2VQb3J0OiBudW1iZXI7XG4gIC8qKiBNaW5pbXVtIGxhdGVuY3kgZm9yIFNSVCAqL1xuICByZWFkb25seSBtaW5pbXVtTGF0ZW5jeTogRHVyYXRpb247XG4gIC8qKlxuICAgKiBPcHRpb25hbCBzdHJlYW0gSUQgZm9yIFNSVCBjb25uZWN0aW9uXG4gICAqIEBkZWZhdWx0IC0gTm8gc3RyZWFtIElEXG4gICAqL1xuICByZWFkb25seSBzdHJlYW1JZD86IHN0cmluZztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGRlY3J5cHRpb24gY29uZmlndXJhdGlvbiBmb3IgZW5jcnlwdGVkIFNSVCBzdHJlYW1zXG4gICAqIEBkZWZhdWx0IC0gTm8gZGVjcnlwdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgZGVjcnlwdGlvbkNvbmZpZ3VyYXRpb24/OiBSb3V0ZXJTcnRFbmNyeXB0aW9uO1xufVxuXG4vKipcbiAqIElkZW50aWZpZXMgd2hpY2ggY29uZmlndXJhdGlvbiB0eXBlIGEgcG9ydCBjb25mbGljdCBjaGVjayBpcyBiZWluZyBwZXJmb3JtZWQgZm9yLlxuICogQGludGVybmFsXG4gKi9cbmVudW0gUHJvdG9jb2xDb25maWdUeXBlIHtcbiAgLyoqIEZhaWxvdmVyLW1vZGUgcm91dGVyIGlucHV0IGNvbmZpZ3VyYXRpb24uICovXG4gIEZBSUxPVkVSID0gJ2ZhaWxvdmVyJyxcbiAgLyoqIE1lcmdlLW1vZGUgcm91dGVyIGlucHV0IGNvbmZpZ3VyYXRpb24uICovXG4gIE1FUkdFID0gJ21lcmdlJyxcbn1cblxuLyoqXG4gKiBGYWN0b3J5IGNsYXNzIGZvciBjcmVhdGluZyBSb3V0ZXIgSW5wdXQgcHJvdG9jb2wgY29uZmlndXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIFJvdXRlcklucHV0UHJvdG9jb2wge1xuICAvKipcbiAgICogQ3JlYXRlIGFuIFJUUCBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSBwcm9wcyBSVFAgcHJvdG9jb2wgcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJJbnB1dFByb3RvY29sIGluc3RhbmNlIGNvbmZpZ3VyZWQgZm9yIFJUUFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBydHAocHJvcHM6IFJ0cFByb3RvY29sUHJvcHMpOiBSb3V0ZXJJbnB1dFByb3RvY29sIHtcbiAgICBSb3V0ZXJJbnB1dFByb3RvY29sLnZhbGlkYXRlUG9ydChwcm9wcy5wb3J0KTtcbiAgICByZXR1cm4gbmV3IFJvdXRlcklucHV0UHJvdG9jb2woUm91dGVySW5wdXRQcm90b2NvbE9wdGlvbnMuUlRQLCB7XG4gICAgICBydHA6IHtcbiAgICAgICAgcG9ydDogcHJvcHMucG9ydCxcbiAgICAgICAgZm9yd2FyZEVycm9yQ29ycmVjdGlvbjogcHJvcHMuZm9yd2FyZEVycm9yQ29ycmVjdGlvbixcbiAgICAgIH0sXG4gICAgfSwgcHJvcHMucG9ydCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgUklTVCBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSBwcm9wcyBSSVNUIHByb3RvY29sIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVySW5wdXRQcm90b2NvbCBpbnN0YW5jZSBjb25maWd1cmVkIGZvciBSSVNUXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJpc3QocHJvcHM6IFJpc3RQcm90b2NvbFByb3BzKTogUm91dGVySW5wdXRQcm90b2NvbCB7XG4gICAgUm91dGVySW5wdXRQcm90b2NvbC52YWxpZGF0ZVBvcnQocHJvcHMucG9ydCk7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZXJJbnB1dFByb3RvY29sKFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zLlJJU1QsIHtcbiAgICAgIHJpc3Q6IHtcbiAgICAgICAgcG9ydDogcHJvcHMucG9ydCxcbiAgICAgICAgcmVjb3ZlcnlMYXRlbmN5TWlsbGlzZWNvbmRzOiBwcm9wcy5yZWNvdmVyeUxhdGVuY3kudG9NaWxsaXNlY29uZHMoKSxcbiAgICAgIH0sXG4gICAgfSwgcHJvcHMucG9ydCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIFNSVCBMaXN0ZW5lciBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSBwcm9wcyBTUlQgTGlzdGVuZXIgcHJvdG9jb2wgcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJJbnB1dFByb3RvY29sIGluc3RhbmNlIGNvbmZpZ3VyZWQgZm9yIFNSVCBMaXN0ZW5lclxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBzcnRMaXN0ZW5lcihwcm9wczogU3J0TGlzdGVuZXJQcm90b2NvbFByb3BzKTogUm91dGVySW5wdXRQcm90b2NvbCB7XG4gICAgUm91dGVySW5wdXRQcm90b2NvbC52YWxpZGF0ZVBvcnQocHJvcHMucG9ydCk7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZXJJbnB1dFByb3RvY29sKFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zLlNSVF9MSVNURU5FUiwge1xuICAgICAgc3J0TGlzdGVuZXI6IHtcbiAgICAgICAgcG9ydDogcHJvcHMucG9ydCxcbiAgICAgICAgbWluaW11bUxhdGVuY3lNaWxsaXNlY29uZHM6IHByb3BzLm1pbmltdW1MYXRlbmN5LnRvTWlsbGlzZWNvbmRzKCksXG4gICAgICB9LFxuICAgIH0sIHByb3BzLnBvcnQsIHByb3BzLmRlY3J5cHRpb25Db25maWd1cmF0aW9uKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gU1JUIENhbGxlciBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSBwcm9wcyBTUlQgQ2FsbGVyIHByb3RvY29sIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVySW5wdXRQcm90b2NvbCBpbnN0YW5jZSBjb25maWd1cmVkIGZvciBTUlQgQ2FsbGVyXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHNydENhbGxlcihwcm9wczogU3J0Q2FsbGVyUHJvdG9jb2xQcm9wcyk6IFJvdXRlcklucHV0UHJvdG9jb2wge1xuICAgIFJvdXRlcklucHV0UHJvdG9jb2wudmFsaWRhdGVTcnRDYWxsZXJQb3J0KHByb3BzLnNvdXJjZVBvcnQpO1xuICAgIHJldHVybiBuZXcgUm91dGVySW5wdXRQcm90b2NvbChSb3V0ZXJJbnB1dFByb3RvY29sT3B0aW9ucy5TUlRfQ0FMTEVSLCB7XG4gICAgICBzcnRDYWxsZXI6IHtcbiAgICAgICAgc291cmNlQWRkcmVzczogcHJvcHMuc291cmNlQWRkcmVzcyxcbiAgICAgICAgc291cmNlUG9ydDogcHJvcHMuc291cmNlUG9ydCxcbiAgICAgICAgbWluaW11bUxhdGVuY3lNaWxsaXNlY29uZHM6IHByb3BzLm1pbmltdW1MYXRlbmN5LnRvTWlsbGlzZWNvbmRzKCksXG4gICAgICAgIHN0cmVhbUlkOiBwcm9wcy5zdHJlYW1JZCxcbiAgICAgIH0sXG4gICAgfSwgdW5kZWZpbmVkLCBwcm9wcy5kZWNyeXB0aW9uQ29uZmlndXJhdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhhdCBwb3J0IGlzIHdpdGhpbiB0aGUgdmFsaWQgcmFuZ2UgKDMwMDAtMzAwMDApXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZVBvcnQocG9ydDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQocG9ydCkgJiYgKHBvcnQgPCAzMDAwIHx8IHBvcnQgPiAzMDAwMCkpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVySW5wdXRQb3J0UmFuZ2VgLCBgUG9ydCBtdXN0IGJlIGJldHdlZW4gMzAwMCBhbmQgMzAwMDAsIGdvdCAke3BvcnR9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgU1JUIENhbGxlciBwb3J0IGlzIHdpdGhpbiB0aGUgdmFsaWQgcmFuZ2UgKDAtNjU1MzUpXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0ZVNydENhbGxlclBvcnQocG9ydDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKCFUb2tlbi5pc1VucmVzb2x2ZWQocG9ydCkgJiYgKHBvcnQgPCAwIHx8IHBvcnQgPiA2NTUzNSkpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgU3J0Q2FsbGVyUG9ydFJhbmdlYCwgYFNSVCBDYWxsZXIgcG9ydCBtdXN0IGJlIGJldHdlZW4gMCBhbmQgNjU1MzUsIGdvdCAke3BvcnR9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfcHJvdG9jb2xOYW1lOiBSb3V0ZXJJbnB1dFByb3RvY29sT3B0aW9ucztcbiAgcHJpdmF0ZSByZWFkb25seSBfY29uZmlnOiBDZm5Sb3V0ZXJJbnB1dC5Sb3V0ZXJJbnB1dFByb3RvY29sQ29uZmlndXJhdGlvblByb3BlcnR5O1xuICBwcml2YXRlIHJlYWRvbmx5IF9wb3J0PzogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZWNyeXB0aW9uPzogUm91dGVyU3J0RW5jcnlwdGlvbjtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHByb3RvY29sTmFtZTogUm91dGVySW5wdXRQcm90b2NvbE9wdGlvbnMsXG4gICAgY29uZmlnOiBDZm5Sb3V0ZXJJbnB1dC5Sb3V0ZXJJbnB1dFByb3RvY29sQ29uZmlndXJhdGlvblByb3BlcnR5LFxuICAgIHBvcnQ/OiBudW1iZXIsXG4gICAgZGVjcnlwdGlvbj86IFJvdXRlclNydEVuY3J5cHRpb24sXG4gICkge1xuICAgIHRoaXMuX3Byb3RvY29sTmFtZSA9IHByb3RvY29sTmFtZTtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5fcG9ydCA9IHBvcnQ7XG4gICAgdGhpcy5fZGVjcnlwdGlvbiA9IGRlY3J5cHRpb247XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGlzIHByb3RvY29sIHRvIGl0cyBDRk4tcmVhZHkgZm9ybS4gUmV0dXJucyB0aGUgcHJvdG9jb2wgaWRlbnRpZmllcixcbiAgICogdGhlIENGTiBjb25maWd1cmF0aW9uIHNoYXBlICh3aXRoIFNSVCBkZWNyeXB0aW9uIGF1dG8tcm9sZSBtYXRlcmlhbGl6ZWQgaWYgbmVlZGVkKSxcbiAgICogYW5kIHRoZSBpbmdlc3QgcG9ydCBpZiB0aGUgcHJvdG9jb2wgaGFzIG9uZS5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlICAgICAgICAgQ29uc3RydWN0IHRoYXQgc2NvcGVzIHRoZSBhdXRvLWNyZWF0ZWQgZGVjcnlwdGlvbiByb2xlXG4gICAqIEBwYXJhbSByb3V0ZXJJbnB1dEFybiAgT3B0aW9uYWwgQVJOIG9mIHRoZSBjb25zdW1pbmcgcm91dGVyIGlucHV0IOKAlCB3aGVuIHByb3ZpZGVkLFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgIHNjb3BlcyB0aGUgYXV0by1jcmVhdGVkIGRlY3J5cHRpb24gcm9sZSdzIHRydXN0IHBvbGljeS5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX2JpbmQoc2NvcGU6IENvbnN0cnVjdCwgcm91dGVySW5wdXRBcm4/OiBzdHJpbmcpOiB7XG4gICAgbmFtZTogUm91dGVySW5wdXRQcm90b2NvbE9wdGlvbnM7XG4gICAgY29uZmlnOiBDZm5Sb3V0ZXJJbnB1dC5Sb3V0ZXJJbnB1dFByb3RvY29sQ29uZmlndXJhdGlvblByb3BlcnR5O1xuICAgIHBvcnQ/OiBudW1iZXI7XG4gIH0ge1xuICAgIGlmICghdGhpcy5fZGVjcnlwdGlvbikge1xuICAgICAgcmV0dXJuIHsgbmFtZTogdGhpcy5fcHJvdG9jb2xOYW1lLCBjb25maWc6IHRoaXMuX2NvbmZpZywgcG9ydDogdGhpcy5fcG9ydCB9O1xuICAgIH1cblxuICAgIGNvbnN0IGRlY3J5cHRpb25Db25maWd1cmF0aW9uID0gcmVuZGVyUm91dGVyU3J0RW5jcnlwdGlvbihzY29wZSwgJ0RlY3J5cHRpb25Sb2xlJywgdGhpcy5fZGVjcnlwdGlvbiwgcm91dGVySW5wdXRBcm4pO1xuXG4gICAgaWYgKHRoaXMuX2NvbmZpZy5zcnRMaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogdGhpcy5fcHJvdG9jb2xOYW1lLFxuICAgICAgICBwb3J0OiB0aGlzLl9wb3J0LFxuICAgICAgICBjb25maWc6IHsgc3J0TGlzdGVuZXI6IHsgLi4udGhpcy5fY29uZmlnLnNydExpc3RlbmVyLCBkZWNyeXB0aW9uQ29uZmlndXJhdGlvbiB9IH0sXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodGhpcy5fY29uZmlnLnNydENhbGxlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogdGhpcy5fcHJvdG9jb2xOYW1lLFxuICAgICAgICBwb3J0OiB0aGlzLl9wb3J0LFxuICAgICAgICBjb25maWc6IHsgc3J0Q2FsbGVyOiB7IC4uLnRoaXMuX2NvbmZpZy5zcnRDYWxsZXIsIGRlY3J5cHRpb25Db25maWd1cmF0aW9uIH0gfSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB7IG5hbWU6IHRoaXMuX3Byb3RvY29sTmFtZSwgY29uZmlnOiB0aGlzLl9jb25maWcsIHBvcnQ6IHRoaXMuX3BvcnQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb21wdXRlIHRoZSBpbmdlc3QgVVJMIChzY2hlbWU6Ly9pcEFkZHJlc3M6cG9ydCkgZm9yIHRoaXMgcHJvdG9jb2wsIGlmIGl0IGhhc1xuICAgKiBhIGxpc3RlbmluZyBwb3J0LlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfaW5nZXN0VXJsKGlwQWRkcmVzczogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5fcG9ydCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZW5kZXJJbmdlc3RVcmwodGhpcy5fcHJvdG9jb2xOYW1lLnZhbHVlLCB0aGlzLl9wb3J0LCBpcEFkZHJlc3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0ZW5pbmcgcG9ydCBmb3IgdGhpcyBwcm90b2NvbCwgaWYgaXQgaGFzIG9uZS4gVW5kZWZpbmVkIGZvciBTUlQgY2FsbGVyXG4gICAqICh3aGljaCBoYXMgYSBgc291cmNlUG9ydGAgcG9pbnRpbmcgYXQgdGhlIHVwc3RyZWFtIGxpc3RlbmVyLCBub3QgYSBwb3J0IHRoZSBpbnB1dFxuICAgKiBpdHNlbGYgbGlzdGVucyBvbikuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9saXN0ZW5pbmdQb3J0KCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX3BvcnQ7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0d28gcHJvdG9jb2xzIHNoYXJlIHRoZSBzYW1lIHByb3RvY29sIGlkZW50aWZpZXIuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9tYXRjaGVzS2luZChvdGhlcjogUm91dGVySW5wdXRQcm90b2NvbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9wcm90b2NvbE5hbWUudmFsdWUgPT09IG90aGVyLl9wcm90b2NvbE5hbWUudmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHByb3RvY29sIGlzIFNSVCAoQ2FsbGVyIG9yIExpc3RlbmVyKS5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgX2lzU3J0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9wcm90b2NvbE5hbWUudmFsdWUgPT09IFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zLlNSVF9DQUxMRVIudmFsdWVcbiAgICAgIHx8IHRoaXMuX3Byb3RvY29sTmFtZS52YWx1ZSA9PT0gUm91dGVySW5wdXRQcm90b2NvbE9wdGlvbnMuU1JUX0xJU1RFTkVSLnZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHBvcnQgY29tcGF0aWJpbGl0eSBiZXR3ZWVuIHRoaXMgcHJvdG9jb2wgYW5kIGFub3RoZXIgaW4gYSBmYWlsb3ZlciBvclxuICAgKiBtZXJnZSBjb25maWd1cmF0aW9uLiBUaHJvd3Mgb24gY29uZmxpY3RzIGFwcHJvcHJpYXRlIHRvIHRoZSBwcm90b2NvbCBraW5kLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdmFsaWRhdGVQb3J0Q29uZmxpY3RzKG90aGVyOiBSb3V0ZXJJbnB1dFByb3RvY29sLCBjb25maWdUeXBlOiBQcm90b2NvbENvbmZpZ1R5cGUpOiB2b2lkIHtcbiAgICBjb25zdCBwcm90b2NvbFZhbHVlID0gdGhpcy5fcHJvdG9jb2xOYW1lLnZhbHVlO1xuXG4gICAgaWYgKHByb3RvY29sVmFsdWUgPT09IFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zLlJJU1QudmFsdWUpIHtcbiAgICAgIGNvbnN0IHJpc3QxID0gdGhpcy5fY29uZmlnLnJpc3Q7XG4gICAgICBjb25zdCByaXN0MiA9IG90aGVyLl9jb25maWcucmlzdDtcbiAgICAgIGlmIChyaXN0MSAmJiByaXN0MiAmJiAncG9ydCcgaW4gcmlzdDEgJiYgJ3BvcnQnIGluIHJpc3QyKSB7XG4gICAgICAgIGNvbnN0IHBvcnQxID0gcmlzdDEucG9ydDtcbiAgICAgICAgY29uc3QgcG9ydDIgPSByaXN0Mi5wb3J0O1xuICAgICAgICBpZiAocG9ydDEgPT09IHBvcnQyKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgICAgbGl0YER1cGxpY2F0ZVJpc3RQb3J0YCxcbiAgICAgICAgICAgIGAke2NvbmZpZ1R5cGV9IGNvbmZpZ3VyYXRpb24gY2Fubm90IHVzZSB0aGUgc2FtZSBSSVNUIHBvcnQgJHtwb3J0MX0gZm9yIGJvdGggcHJvdG9jb2xzLCBgICtcbiAgICAgICAgICAgICdlYWNoIHByb3RvY29sIG11c3QgdXNlIGEgZGlmZmVyZW50IHBvcnQgbnVtYmVyJyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChNYXRoLmFicyhwb3J0MSAtIHBvcnQyKSA8IDIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgICBsaXRgQ29uc2VjdXRpdmVSaXN0UG9ydGAsXG4gICAgICAgICAgICBgJHtjb25maWdUeXBlfSBjb25maWd1cmF0aW9uIGNhbm5vdCB1c2UgY29uc2VjdXRpdmUgUklTVCBwb3J0cyAke01hdGgubWluKHBvcnQxLCBwb3J0Mil9IGFuZCAke01hdGgubWF4KHBvcnQxLCBwb3J0Mil9LCBgICtcbiAgICAgICAgICAgICdSSVNUIHByb3RvY29scyByZXF1aXJlIG5vbi1jb25zZWN1dGl2ZSBwb3J0cyB0byBhdm9pZCBvdmVybGFwcGluZyByYW5nZXMgKGUuZy4sIHVzZSA2MDAwIGFuZCA2MDAyKScsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChwcm90b2NvbFZhbHVlID09PSBSb3V0ZXJJbnB1dFByb3RvY29sT3B0aW9ucy5SVFAudmFsdWUpIHtcbiAgICAgIGNvbnN0IHJ0cDEgPSB0aGlzLl9jb25maWcucnRwO1xuICAgICAgY29uc3QgcnRwMiA9IG90aGVyLl9jb25maWcucnRwO1xuICAgICAgaWYgKHJ0cDEgJiYgcnRwMiAmJiAncG9ydCcgaW4gcnRwMSAmJiAncG9ydCcgaW4gcnRwMiAmJiBydHAxLnBvcnQgPT09IHJ0cDIucG9ydCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YER1cGxpY2F0ZVJ0cFBvcnRgLFxuICAgICAgICAgIGAke2NvbmZpZ1R5cGV9IGNvbmZpZ3VyYXRpb24gY2Fubm90IHVzZSB0aGUgc2FtZSBSVFAgcG9ydCAke3J0cDEucG9ydH0gZm9yIGJvdGggcHJvdG9jb2xzLCBgICtcbiAgICAgICAgICAnZWFjaCBwcm90b2NvbCBtdXN0IHVzZSBhIGRpZmZlcmVudCBwb3J0IG51bWJlcicsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHByb3RvY29sVmFsdWUgPT09IFJvdXRlcklucHV0UHJvdG9jb2xPcHRpb25zLlNSVF9MSVNURU5FUi52YWx1ZSkge1xuICAgICAgY29uc3Qgc3J0MSA9IHRoaXMuX2NvbmZpZy5zcnRMaXN0ZW5lcjtcbiAgICAgIGNvbnN0IHNydDIgPSBvdGhlci5fY29uZmlnLnNydExpc3RlbmVyO1xuICAgICAgaWYgKHNydDEgJiYgc3J0MiAmJiAncG9ydCcgaW4gc3J0MSAmJiAncG9ydCcgaW4gc3J0MiAmJiBzcnQxLnBvcnQgPT09IHNydDIucG9ydCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YER1cGxpY2F0ZVNydExpc3RlbmVyUG9ydGAsXG4gICAgICAgICAgYCR7Y29uZmlnVHlwZX0gY29uZmlndXJhdGlvbiBjYW5ub3QgdXNlIHRoZSBzYW1lIFNSVCBMaXN0ZW5lciBwb3J0ICR7c3J0MS5wb3J0fSBmb3IgYm90aCBwcm90b2NvbHMsIGAgK1xuICAgICAgICAgICdlYWNoIHByb3RvY29sIG11c3QgdXNlIGEgZGlmZmVyZW50IHBvcnQgbnVtYmVyJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBzdGFuZGFyZCBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YW5kYXJkQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqIE5ldHdvcmsgaW50ZXJmYWNlIGZvciB0aGUgUm91dGVyIElucHV0ICovXG4gIHJlYWRvbmx5IG5ldHdvcmtJbnRlcmZhY2U6IElSb3V0ZXJOZXR3b3JrSW50ZXJmYWNlO1xuICAvKiogUHJvdG9jb2wgY29uZmlndXJhdGlvbiBmb3IgdGhlIGlucHV0ICovXG4gIHJlYWRvbmx5IHByb3RvY29sOiBSb3V0ZXJJbnB1dFByb3RvY29sO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGZhaWxvdmVyIFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmFpbG92ZXJDb25maWd1cmF0aW9uUHJvcHMge1xuICAvKiogTmV0d29yayBpbnRlcmZhY2UgZm9yIHRoZSBSb3V0ZXIgSW5wdXQgKi9cbiAgcmVhZG9ubHkgbmV0d29ya0ludGVyZmFjZTogSVJvdXRlck5ldHdvcmtJbnRlcmZhY2U7XG4gIC8qKiBBcnJheSBvZiBleGFjdGx5IDIgcHJvdG9jb2wgY29uZmlndXJhdGlvbnMgZm9yIGZhaWxvdmVyIChtdXN0IGJlIHNhbWUgcHJvdG9jb2wgdHlwZSkgKi9cbiAgcmVhZG9ubHkgcHJvdG9jb2xzOiBSb3V0ZXJJbnB1dFByb3RvY29sW107XG4gIC8qKlxuICAgKiBTb3VyY2UgcHJpb3JpdHkgY29uZmlndXJhdGlvbiBmb3IgZmFpbG92ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IFNvdXJjZVByaW9yaXR5Q29uZmlnLm5vbmUoKVxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlUHJpb3JpdHk/OiBTb3VyY2VQcmlvcml0eUNvbmZpZztcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBtZXJnZSBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lcmdlQ29uZmlndXJhdGlvblByb3BzIHtcbiAgLyoqIE5ldHdvcmsgaW50ZXJmYWNlIGZvciB0aGUgUm91dGVyIElucHV0ICovXG4gIHJlYWRvbmx5IG5ldHdvcmtJbnRlcmZhY2U6IElSb3V0ZXJOZXR3b3JrSW50ZXJmYWNlO1xuICAvKiogQXJyYXkgb2YgZXhhY3RseSAyIHByb3RvY29sIGNvbmZpZ3VyYXRpb25zIGZvciBtZXJnZSAobXVzdCBiZSBzYW1lIG5vbi1TUlQgcHJvdG9jb2wgdHlwZSkgKi9cbiAgcmVhZG9ubHkgcHJvdG9jb2xzOiBSb3V0ZXJJbnB1dFByb3RvY29sW107XG4gIC8qKiBSZWNvdmVyeSB3aW5kb3cgZm9yIG1lcmdlIG9wZXJhdGlvbiAqL1xuICByZWFkb25seSBtZXJnZVJlY292ZXJ5V2luZG93OiBEdXJhdGlvbjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBNZWRpYUNvbm5lY3QgRmxvdyBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lZGlhQ29ubmVjdEZsb3dDb25maWd1cmF0aW9uUHJvcHMge1xuICAvKiogVGhlIE1lZGlhQ29ubmVjdCBmbG93IHRvIHVzZSBhcyBpbnB1dCAqL1xuICByZWFkb25seSBmbG93OiBJRmxvdztcbiAgLyoqIFRoZSBmbG93IG91dHB1dCB0aGF0IGZlZWRzIHRoaXMgcm91dGVyIGlucHV0ICovXG4gIHJlYWRvbmx5IGZsb3dPdXRwdXQ6IElGbG93T3V0cHV0O1xuICAvKipcbiAgICogT3B0aW9uYWwgdHJhbnNpdCBlbmNyeXB0aW9uIGNvbmZpZ3VyYXRpb25cbiAgICogQGRlZmF1bHQgLSBBdXRvbWF0aWMgZW5jcnlwdGlvbiB3aWxsIGJlIHVzZWRcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uPzogVHJhbnNpdEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgTWVkaWFDb25uZWN0IEZsb3cgUm91dGVyIElucHV0IGNvbmZpZ3VyYXRpb24gLSB3aXRob3V0IGEgY29ubmVjdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lZGlhQ29ubmVjdEZsb3dDb25maWd1cmF0aW9uV2l0aG91dENvbm5lY3Rpb25Qcm9wcyB7XG4gIC8qKlxuICAgKiBBdmFpbGFiaWxpdHkgWm9uZSB0aGUgcm91dGVyIGlucHV0IHdpbGwgYmUgcGxhY2VkIGluLlxuICAgKi9cbiAgcmVhZG9ubHkgYXZhaWxhYmlsaXR5Wm9uZTogc3RyaW5nO1xuICAvKipcbiAgICogT3B0aW9uYWwgdHJhbnNpdCBlbmNyeXB0aW9uIGNvbmZpZ3VyYXRpb25cbiAgICogQGRlZmF1bHQgLSBBdXRvbWF0aWMgZW5jcnlwdGlvbiB3aWxsIGJlIHVzZWRcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uPzogVHJhbnNpdEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgTWVkaWFMaXZlIENoYW5uZWwgUm91dGVyIElucHV0IGNvbmZpZ3VyYXRpb24uXG4gKlxuICogVXNlIHRoaXMgd2hlbiB0aGUgTWVkaWFMaXZlIGNoYW5uZWwgYWxyZWFkeSBleGlzdHMgYW5kIHlvdSB3YW50IHRvIGluZ2VzdFxuICogZnJvbSBvbmUgb2YgaXRzIG91dHB1dHMgaW1tZWRpYXRlbHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVkaWFMaXZlQ2hhbm5lbENvbmZpZ3VyYXRpb25Qcm9wcyB7XG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIE1lZGlhTGl2ZSBjaGFubmVsIHRvIHVzZSBhcyBpbnB1dC5cbiAgICpcbiAgICogTm90ZTogVGhpcyB3aWxsIGNoYW5nZSB0byBhY2NlcHQgYSB0eXBlZCBNZWRpYUxpdmUgY2hhbm5lbCByZWZlcmVuY2VcbiAgICogd2hlbiB0aGUgQGF3cy1jZGsvYXdzLW1lZGlhbGl2ZS1hbHBoYSBMMiBjb25zdHJ1Y3QgaXMgcmVsZWFzZWQuXG4gICAqL1xuICByZWFkb25seSBtZWRpYUxpdmVDaGFubmVsQXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBNZWRpYUxpdmUgY2hhbm5lbCBvdXRwdXQgdG8gY29ubmVjdCB0byB0aGlzIHJvdXRlciBpbnB1dC5cbiAgICovXG4gIHJlYWRvbmx5IG1lZGlhTGl2ZUNoYW5uZWxPdXRwdXROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBNZWRpYUxpdmUgcGlwZWxpbmUgdG8gY29ubmVjdCB0byB0aGlzIHJvdXRlciBpbnB1dC5cbiAgICovXG4gIHJlYWRvbmx5IG1lZGlhTGl2ZVBpcGVsaW5lSWQ6IE1lZGlhTGl2ZVBpcGVsaW5lO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCB0cmFuc2l0IGVuY3J5cHRpb24gY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBdXRvbWF0aWMgZW5jcnlwdGlvbiB3aWxsIGJlIHVzZWRcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uPzogVHJhbnNpdEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgTWVkaWFMaXZlIENoYW5uZWwgUm91dGVyIElucHV0IGNvbmZpZ3VyYXRpb24gd2l0aG91dCBhIHNwZWNpZmljIGNoYW5uZWwgY29ubmVjdGlvbi5cbiAqXG4gKiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IHRvIHNldCB1cCB0aGUgcm91dGVyIGlucHV0IGJlZm9yZSB0aGUgdGFyZ2V0IE1lZGlhTGl2ZSBjaGFubmVsIGV4aXN0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZWRpYUxpdmVDaGFubmVsQ29uZmlndXJhdGlvbldpdGhvdXRDb25uZWN0aW9uUHJvcHMge1xuICAvKipcbiAgICogQXZhaWxhYmlsaXR5IFpvbmUgdGhlIHJvdXRlciBpbnB1dCB3aWxsIGJlIHBsYWNlZCBpbi5cbiAgICovXG4gIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZztcblxuICAvKipcbiAgICogT3B0aW9uYWwgdHJhbnNpdCBlbmNyeXB0aW9uIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQXV0b21hdGljIGVuY3J5cHRpb24gd2lsbCBiZSB1c2VkXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VUcmFuc2l0RGVjcnlwdGlvbj86IFRyYW5zaXRFbmNyeXB0aW9uO1xufVxuXG4vKipcbiAqIEZhY3RvcnkgY2xhc3MgZm9yIGNyZWF0aW5nIFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9uc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUm91dGVySW5wdXRDb25maWd1cmF0aW9uIHtcbiAgLyoqXG4gICAqIENyZWF0ZSBhIHN0YW5kYXJkIFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9uIHdpdGggYSBzaW5nbGUgcHJvdG9jb2xcbiAgICogQHBhcmFtIHByb3BzIFN0YW5kYXJkIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJJbnB1dENvbmZpZ3VyYXRpb24gaW5zdGFuY2UgZm9yIHN0YW5kYXJkIHNldHVwXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHN0YW5kYXJkKHByb3BzOiBTdGFuZGFyZENvbmZpZ3VyYXRpb25Qcm9wcyk6IFJvdXRlcklucHV0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBTdGFuZGFyZFJvdXRlcklucHV0Q29uZmlnKHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBmYWlsb3ZlciBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvbiB3aXRoIHR3byBtYXRjaGluZyBwcm90b2NvbHNcbiAgICogQHBhcmFtIHByb3BzIEZhaWxvdmVyIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJJbnB1dENvbmZpZ3VyYXRpb24gaW5zdGFuY2UgZm9yIGZhaWxvdmVyIHNldHVwXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgcHJvdG9jb2xzIGRvbid0IG1hdGNoIG9yIGNvdW50IGlzIG5vdCBleGFjdGx5IDJcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZmFpbG92ZXIocHJvcHM6IEZhaWxvdmVyQ29uZmlndXJhdGlvblByb3BzKTogUm91dGVySW5wdXRDb25maWd1cmF0aW9uIHtcbiAgICBpZiAoIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5wcm90b2NvbHMpICYmIHByb3BzLnByb3RvY29scy5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgRmFpbG92ZXJQcm90b2NvbENvdW50YCwgYEZhaWxvdmVyIGNvbmZpZ3VyYXRpb24gcmVxdWlyZXMgZXhhY3RseSAyIHByb3RvY29scywgZ290ICR7cHJvcHMucHJvdG9jb2xzLmxlbmd0aH1gKTtcbiAgICB9XG4gICAgaWYgKCFwcm9wcy5wcm90b2NvbHNbMF0uX21hdGNoZXNLaW5kKHByb3BzLnByb3RvY29sc1sxXSkpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgRmFpbG92ZXJQcm90b2NvbE1pc21hdGNoYCwgJ1Byb3RvY29scyBtdXN0IG1hdGNoJyk7XG4gICAgfVxuICAgIHByb3BzLnByb3RvY29sc1swXS5fdmFsaWRhdGVQb3J0Q29uZmxpY3RzKHByb3BzLnByb3RvY29sc1sxXSwgUHJvdG9jb2xDb25maWdUeXBlLkZBSUxPVkVSKTtcbiAgICByZXR1cm4gbmV3IEZhaWxvdmVyUm91dGVySW5wdXRDb25maWcocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG1lcmdlIFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9uIHdpdGggdHdvIG1hdGNoaW5nIG5vbi1TUlQgcHJvdG9jb2xzXG4gICAqIEBwYXJhbSBwcm9wcyBNZXJnZSBjb25maWd1cmF0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVySW5wdXRDb25maWd1cmF0aW9uIGluc3RhbmNlIGZvciBtZXJnZSBzZXR1cFxuICAgKiBAdGhyb3dzIEVycm9yIGlmIHByb3RvY29scyBkb24ndCBtYXRjaCwgY291bnQgaXMgbm90IGV4YWN0bHkgMiwgb3IgU1JUIHByb3RvY29scyBhcmUgdXNlZFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtZXJnZShwcm9wczogTWVyZ2VDb25maWd1cmF0aW9uUHJvcHMpOiBSb3V0ZXJJbnB1dENvbmZpZ3VyYXRpb24ge1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKHByb3BzLnByb3RvY29scykgJiYgcHJvcHMucHJvdG9jb2xzLmxlbmd0aCAhPT0gMikge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBNZXJnZVByb3RvY29sQ291bnRgLCBgTWVyZ2UgY29uZmlndXJhdGlvbiByZXF1aXJlcyBleGFjdGx5IDIgcHJvdG9jb2xzLCBnb3QgJHtwcm9wcy5wcm90b2NvbHMubGVuZ3RofWApO1xuICAgIH1cbiAgICBpZiAocHJvcHMucHJvdG9jb2xzLnNvbWUocCA9PiBwLl9pc1NydCgpKSkge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBNZXJnZVNydE5vdFN1cHBvcnRlZGAsICdTUlQgcHJvdG9jb2xzIGFyZSBub3Qgc3VwcG9ydGVkIGluIG1lcmdlIGNvbmZpZ3VyYXRpb24nKTtcbiAgICB9XG4gICAgaWYgKCFwcm9wcy5wcm90b2NvbHNbMF0uX21hdGNoZXNLaW5kKHByb3BzLnByb3RvY29sc1sxXSkpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgTWVyZ2VQcm90b2NvbE1pc21hdGNoYCwgJ1Byb3RvY29scyBtdXN0IG1hdGNoJyk7XG4gICAgfVxuICAgIHByb3BzLnByb3RvY29sc1swXS5fdmFsaWRhdGVQb3J0Q29uZmxpY3RzKHByb3BzLnByb3RvY29sc1sxXSwgUHJvdG9jb2xDb25maWdUeXBlLk1FUkdFKTtcbiAgICByZXR1cm4gbmV3IE1lcmdlUm91dGVySW5wdXRDb25maWcocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIE1lZGlhQ29ubmVjdCBGbG93IFJvdXRlciBJbnB1dCBjb25maWd1cmF0aW9uIHdpdGhvdXQgY29ubmVjdGluZyB0byBhIHNwZWNpZmljIGZsb3dcbiAgICogVXNlIHRoaXMgd2hlbiB5b3Ugd2FudCB0byBwcmVwYXJlIHRoZSByb3V0ZXIgaW5wdXQgZm9yIGEgZmxvdyBjb25uZWN0aW9uIGxhdGVyXG4gICAqIEBwYXJhbSBwcm9wcyBNZWRpYUNvbm5lY3QgRmxvdyBjb25maWd1cmF0aW9uIHByb3BlcnRpZXMgd2l0aG91dCBjb25uZWN0aW9uXG4gICAqIEByZXR1cm5zIFJvdXRlcklucHV0Q29uZmlndXJhdGlvbiBpbnN0YW5jZSBmb3IgTWVkaWFDb25uZWN0IEZsb3cgc2V0dXAgd2l0aG91dCBjb25uZWN0aW9uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG1lZGlhQ29ubmVjdEZsb3dXaXRob3V0Q29ubmVjdGlvbihwcm9wczogTWVkaWFDb25uZWN0Rmxvd0NvbmZpZ3VyYXRpb25XaXRob3V0Q29ubmVjdGlvblByb3BzKTogUm91dGVySW5wdXRDb25maWd1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJJbnB1dENvbmZpZyh7IHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uOiBwcm9wcy5zb3VyY2VUcmFuc2l0RGVjcnlwdGlvbiB9LCBwcm9wcy5hdmFpbGFiaWxpdHlab25lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBNZWRpYUNvbm5lY3QgRmxvdyBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogVXNlIHRoaXMgd2hlbiB0aGUgc291cmNlIGZsb3cgYWxyZWFkeSBleGlzdHMgYW5kIHlvdSB3YW50IHRvIGNvbm5lY3QgaW1tZWRpYXRlbHkuXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBNZWRpYUNvbm5lY3QgRmxvdyBjb25maWd1cmF0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVySW5wdXRDb25maWd1cmF0aW9uIGluc3RhbmNlIGZvciBNZWRpYUNvbm5lY3QgRmxvdyBzZXR1cFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtZWRpYUNvbm5lY3RGbG93KHByb3BzOiBNZWRpYUNvbm5lY3RGbG93Q29uZmlndXJhdGlvblByb3BzKTogUm91dGVySW5wdXRDb25maWd1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJJbnB1dENvbmZpZyh7XG4gICAgICBmbG93OiBwcm9wcy5mbG93LFxuICAgICAgZmxvd091dHB1dDogcHJvcHMuZmxvd091dHB1dCxcbiAgICAgIHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uOiBwcm9wcy5zb3VyY2VUcmFuc2l0RGVjcnlwdGlvbixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBNZWRpYUxpdmUgQ2hhbm5lbCBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvbi5cbiAgICpcbiAgICogVXNlIHRoaXMgd2hlbiB0aGUgc291cmNlIE1lZGlhTGl2ZSBjaGFubmVsIGFscmVhZHkgZXhpc3RzIGFuZCB5b3Ugd2FudCB0b1xuICAgKiBpbmdlc3QgZnJvbSBvbmUgb2YgaXRzIG91dHB1dHMgaW1tZWRpYXRlbHkuXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBNZWRpYUxpdmUgY2hhbm5lbCBjb25maWd1cmF0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVySW5wdXRDb25maWd1cmF0aW9uIGluc3RhbmNlIGZvciBNZWRpYUxpdmUgY2hhbm5lbCBzZXR1cFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtZWRpYUxpdmVDaGFubmVsKHByb3BzOiBNZWRpYUxpdmVDaGFubmVsQ29uZmlndXJhdGlvblByb3BzKTogUm91dGVySW5wdXRDb25maWd1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhTGl2ZUNoYW5uZWxSb3V0ZXJJbnB1dENvbmZpZyh7XG4gICAgICBtZWRpYUxpdmVDaGFubmVsQXJuOiBwcm9wcy5tZWRpYUxpdmVDaGFubmVsQXJuLFxuICAgICAgbWVkaWFMaXZlQ2hhbm5lbE91dHB1dE5hbWU6IHByb3BzLm1lZGlhTGl2ZUNoYW5uZWxPdXRwdXROYW1lLFxuICAgICAgbWVkaWFMaXZlUGlwZWxpbmVJZDogcHJvcHMubWVkaWFMaXZlUGlwZWxpbmVJZCxcbiAgICAgIHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uOiBwcm9wcy5zb3VyY2VUcmFuc2l0RGVjcnlwdGlvbixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBNZWRpYUxpdmUgQ2hhbm5lbCBSb3V0ZXIgSW5wdXQgY29uZmlndXJhdGlvbiB3aXRob3V0IGEgc3BlY2lmaWMgY2hhbm5lbCBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IHRvIHNldCB1cCB0aGUgcm91dGVyIGlucHV0IGJlZm9yZSB0aGUgdGFyZ2V0IE1lZGlhTGl2ZSBjaGFubmVsIGV4aXN0cy5cbiAgICpcbiAgICogQHBhcmFtIHByb3BzIE1lZGlhTGl2ZSBjaGFubmVsIG5vLWNvbm5lY3Rpb24gcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJJbnB1dENvbmZpZ3VyYXRpb24gaW5zdGFuY2UgZm9yIE1lZGlhTGl2ZSBjaGFubmVsIHNldHVwIHdpdGhvdXQgY29ubmVjdGlvblxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtZWRpYUxpdmVDaGFubmVsV2l0aG91dENvbm5lY3Rpb24ocHJvcHM6IE1lZGlhTGl2ZUNoYW5uZWxDb25maWd1cmF0aW9uV2l0aG91dENvbm5lY3Rpb25Qcm9wcyk6IFJvdXRlcklucHV0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBNZWRpYUxpdmVDaGFubmVsUm91dGVySW5wdXRDb25maWcoeyBzb3VyY2VUcmFuc2l0RGVjcnlwdGlvbjogcHJvcHMuc291cmNlVHJhbnNpdERlY3J5cHRpb24gfSwgcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGlzIGNvbmZpZ3VyYXRpb24gdG8gaXRzIENsb3VkRm9ybWF0aW9uIHNoYXBlLiBDYWxsZWQgYnkgdGhlIFJvdXRlcklucHV0XG4gICAqIGNvbnN0cnVjdG9yIOKAlCBlYWNoIGNvbmNyZXRlIHN1YmNsYXNzIHN1cHBsaWVzIGl0cyBvd24gdmFyaWFudC1zcGVjaWZpYyByZW5kZXJpbmcuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIGFic3RyYWN0IF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIHJvdXRlcklucHV0QXJuPzogc3RyaW5nKToge1xuICAgIGNvbmZpZzogQ2ZuUm91dGVySW5wdXQuUm91dGVySW5wdXRDb25maWd1cmF0aW9uUHJvcGVydHk7IGF2YWlsYWJpbGl0eVpvbmU/OiBzdHJpbmc7XG4gIH07XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgdGhlIGluZ2VzdCBlbmRwb2ludHMgZm9yIHByb3RvY29sLWJhc2VkIGlucHV0cyB0aGF0IGxpc3RlbiBvbiBvbmUgb3IgbW9yZVxuICAgKiBwb3J0cy5cbiAgICpcbiAgICogUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoZSB2YXJpYW50IGhhcyBubyBjb25jZXB0IG9mIGEgbGlzdGVuIHBvcnQgKFNSVCBjYWxsZXIsXG4gICAqIE1lZGlhQ29ubmVjdCBGbG93LCBNZWRpYUxpdmUgQ2hhbm5lbCkuIFJldHVybnMgYW4gYXJyYXkgd2l0aCBvbmUgZW50cnkgZm9yXG4gICAqIHN0YW5kYXJkIHZhcmlhbnRzLCBhbmQgb25lIGVudHJ5IHBlciBzb3VyY2UgZm9yIGZhaWxvdmVyIGFuZCBtZXJnZS5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgX2VuZHBvaW50cyhpcEFkZHJlc3M6IHN0cmluZyk6IFJvdXRlcklucHV0RW5kcG9pbnRbXSB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBSZW5kZXIgYW4gaW5nZXN0IFVSTCBzdHJpbmcgKHNjaGVtZTovL2lwOnBvcnQpLiBVc2VkIGJ5IGBfaW5nZXN0VXJsKClgIG9uIGluZGl2aWR1YWxcbiAqIHByb3RvY29scyBhbmQgY29tcG9zZWQgaW50byB0aGUgcGVyLWNvbmZpZy12YXJpYW50IGBfZW5kcG9pbnRzKClgIHJlc3VsdHMuXG4gKlxuICogRXh0cmFjdHMgdGhlIGJhc2UgcHJvdG9jb2wgZm9yIHRoZSBVUkwgc2NoZW1lIChlLmcuIFNSVF9MSVNURU5FUiDihpIgc3J0LCBSVFAg4oaSIHJ0cCkuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlckluZ2VzdFVybChwcm90b2NvbE5hbWU6IHN0cmluZywgcG9ydDogbnVtYmVyLCBpcEFkZHJlc3M6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHNjaGVtZSA9IHByb3RvY29sTmFtZS50b0xvd2VyQ2FzZSgpLnNwbGl0KCdfJylbMF07XG4gIHJldHVybiBGbi5qb2luKCcnLCBbYCR7c2NoZW1lfTovL2AsIGlwQWRkcmVzcywgYDoke3BvcnR9YF0pO1xufVxuXG4vKipcbiAqIENvbmNyZXRlIHZhcmlhbnQ6IHN0YW5kYXJkIChzaW5nbGUtcHJvdG9jb2wpIHJvdXRlciBpbnB1dCBjb25maWd1cmF0aW9uLlxuICogQGludGVybmFsXG4gKi9cbmNsYXNzIFN0YW5kYXJkUm91dGVySW5wdXRDb25maWcgZXh0ZW5kcyBSb3V0ZXJJbnB1dENvbmZpZ3VyYXRpb24ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBTdGFuZGFyZENvbmZpZ3VyYXRpb25Qcm9wcykgeyBzdXBlcigpOyB9XG5cbiAgcHVibGljIF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIHJvdXRlcklucHV0QXJuPzogc3RyaW5nKSB7XG4gICAgY29uc3QgcHJvdG9jb2wgPSB0aGlzLnByb3BzLnByb3RvY29sLl9iaW5kKHNjb3BlLCByb3V0ZXJJbnB1dEFybik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBzdGFuZGFyZDoge1xuICAgICAgICAgIG5ldHdvcmtJbnRlcmZhY2VBcm46IHRoaXMucHJvcHMubmV0d29ya0ludGVyZmFjZS5yb3V0ZXJOZXR3b3JrSW50ZXJmYWNlQXJuLFxuICAgICAgICAgIHByb3RvY29sOiBwcm90b2NvbC5uYW1lLnZhbHVlLFxuICAgICAgICAgIHByb3RvY29sQ29uZmlndXJhdGlvbjogcHJvdG9jb2wuY29uZmlnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIF9lbmRwb2ludHMoaXBBZGRyZXNzOiBzdHJpbmcpOiBSb3V0ZXJJbnB1dEVuZHBvaW50W10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHVybCA9IHRoaXMucHJvcHMucHJvdG9jb2wuX2luZ2VzdFVybChpcEFkZHJlc3MpO1xuICAgIGNvbnN0IHBvcnQgPSB0aGlzLnByb3BzLnByb3RvY29sLl9saXN0ZW5pbmdQb3J0KCk7XG4gICAgaWYgKHVybCA9PT0gdW5kZWZpbmVkIHx8IHBvcnQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gW3sgdXJsLCBwb3J0IH1dO1xuICB9XG59XG5cbi8qKlxuICogQ29uY3JldGUgdmFyaWFudDogZmFpbG92ZXIgcm91dGVyIGlucHV0IGNvbmZpZ3VyYXRpb24uXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgRmFpbG92ZXJSb3V0ZXJJbnB1dENvbmZpZyBleHRlbmRzIFJvdXRlcklucHV0Q29uZmlndXJhdGlvbiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IEZhaWxvdmVyQ29uZmlndXJhdGlvblByb3BzKSB7IHN1cGVyKCk7IH1cblxuICBwdWJsaWMgX2JpbmQoc2NvcGU6IENvbnN0cnVjdCwgcm91dGVySW5wdXRBcm4/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBwcmlvcml0eSA9ICh0aGlzLnByb3BzLnNvdXJjZVByaW9yaXR5ID8/IFNvdXJjZVByaW9yaXR5Q29uZmlnLm5vbmUoKSkuX2JpbmQoKTtcbiAgICByZXR1cm4ge1xuICAgICAgY29uZmlnOiB7XG4gICAgICAgIGZhaWxvdmVyOiB7XG4gICAgICAgICAgbmV0d29ya0ludGVyZmFjZUFybjogdGhpcy5wcm9wcy5uZXR3b3JrSW50ZXJmYWNlLnJvdXRlck5ldHdvcmtJbnRlcmZhY2VBcm4sXG4gICAgICAgICAgcHJvdG9jb2xDb25maWd1cmF0aW9uczogdGhpcy5wcm9wcy5wcm90b2NvbHMubWFwKHAgPT4gcC5fYmluZChzY29wZSwgcm91dGVySW5wdXRBcm4pLmNvbmZpZyksXG4gICAgICAgICAgc291cmNlUHJpb3JpdHlNb2RlOiBwcmlvcml0eS5zb3VyY2VQcmlvcml0eU1vZGUsXG4gICAgICAgICAgcHJpbWFyeVNvdXJjZUluZGV4OiBwcmlvcml0eS5wcmltYXJ5U291cmNlSW5kZXgsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgX2VuZHBvaW50cyhpcEFkZHJlc3M6IHN0cmluZyk6IFJvdXRlcklucHV0RW5kcG9pbnRbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZW5kcG9pbnRzOiBSb3V0ZXJJbnB1dEVuZHBvaW50W10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHAgb2YgdGhpcy5wcm9wcy5wcm90b2NvbHMpIHtcbiAgICAgIGNvbnN0IHVybCA9IHAuX2luZ2VzdFVybChpcEFkZHJlc3MpO1xuICAgICAgY29uc3QgcG9ydCA9IHAuX2xpc3RlbmluZ1BvcnQoKTtcbiAgICAgIGlmICh1cmwgPT09IHVuZGVmaW5lZCB8fCBwb3J0ID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBlbmRwb2ludHMucHVzaCh7IHVybCwgcG9ydCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGVuZHBvaW50cztcbiAgfVxufVxuXG4vKipcbiAqIENvbmNyZXRlIHZhcmlhbnQ6IG1lcmdlIHJvdXRlciBpbnB1dCBjb25maWd1cmF0aW9uLlxuICogQGludGVybmFsXG4gKi9cbmNsYXNzIE1lcmdlUm91dGVySW5wdXRDb25maWcgZXh0ZW5kcyBSb3V0ZXJJbnB1dENvbmZpZ3VyYXRpb24ge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBNZXJnZUNvbmZpZ3VyYXRpb25Qcm9wcykgeyBzdXBlcigpOyB9XG5cbiAgcHVibGljIF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIHJvdXRlcklucHV0QXJuPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBtZXJnZToge1xuICAgICAgICAgIG5ldHdvcmtJbnRlcmZhY2VBcm46IHRoaXMucHJvcHMubmV0d29ya0ludGVyZmFjZS5yb3V0ZXJOZXR3b3JrSW50ZXJmYWNlQXJuLFxuICAgICAgICAgIHByb3RvY29sQ29uZmlndXJhdGlvbnM6IHRoaXMucHJvcHMucHJvdG9jb2xzLm1hcChwID0+IHAuX2JpbmQoc2NvcGUsIHJvdXRlcklucHV0QXJuKS5jb25maWcpLFxuICAgICAgICAgIG1lcmdlUmVjb3ZlcnlXaW5kb3dNaWxsaXNlY29uZHM6IHRoaXMucHJvcHMubWVyZ2VSZWNvdmVyeVdpbmRvdy50b01pbGxpc2Vjb25kcygpLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIF9lbmRwb2ludHMoaXBBZGRyZXNzOiBzdHJpbmcpOiBSb3V0ZXJJbnB1dEVuZHBvaW50W10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGVuZHBvaW50czogUm91dGVySW5wdXRFbmRwb2ludFtdID0gW107XG4gICAgZm9yIChjb25zdCBwIG9mIHRoaXMucHJvcHMucHJvdG9jb2xzKSB7XG4gICAgICBjb25zdCB1cmwgPSBwLl9pbmdlc3RVcmwoaXBBZGRyZXNzKTtcbiAgICAgIGNvbnN0IHBvcnQgPSBwLl9saXN0ZW5pbmdQb3J0KCk7XG4gICAgICBpZiAodXJsID09PSB1bmRlZmluZWQgfHwgcG9ydCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgZW5kcG9pbnRzLnB1c2goeyB1cmwsIHBvcnQgfSk7XG4gICAgfVxuICAgIHJldHVybiBlbmRwb2ludHM7XG4gIH1cbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBvcHRpb25zIGZvciB7QGxpbmsgTWVkaWFDb25uZWN0Rmxvd1JvdXRlcklucHV0Q29uZmlnfS4gTm90IGV4cG9ydGVkOyBqc2lpIG5ldmVyIHNlZXMgdGhpcy5cbiAqL1xuaW50ZXJmYWNlIE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJJbnB1dE9wdGlvbnMge1xuICByZWFkb25seSBmbG93PzogSUZsb3c7XG4gIHJlYWRvbmx5IGZsb3dPdXRwdXQ/OiBJRmxvd091dHB1dDtcbiAgcmVhZG9ubHkgc291cmNlVHJhbnNpdERlY3J5cHRpb24/OiBUcmFuc2l0RW5jcnlwdGlvbjtcbn1cblxuLyoqXG4gKiBDb25jcmV0ZSB2YXJpYW50OiBNZWRpYUNvbm5lY3QgRmxvdyByb3V0ZXIgaW5wdXQgY29uZmlndXJhdGlvbiAod2l0aCBvciB3aXRob3V0IGNvbm5lY3Rpb24pLlxuICogQGludGVybmFsXG4gKi9cbmNsYXNzIE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJJbnB1dENvbmZpZyBleHRlbmRzIFJvdXRlcklucHV0Q29uZmlndXJhdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogTWVkaWFDb25uZWN0Rmxvd1JvdXRlcklucHV0T3B0aW9ucyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmU/OiBzdHJpbmcsXG4gICkgeyBzdXBlcigpOyB9XG5cbiAgcHVibGljIF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIHJvdXRlcklucHV0QXJuPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBtZWRpYUNvbm5lY3RGbG93OiB7XG4gICAgICAgICAgZmxvd0FybjogdGhpcy5vcHRpb25zLmZsb3c/LmZsb3dBcm4sXG4gICAgICAgICAgZmxvd091dHB1dEFybjogdGhpcy5vcHRpb25zLmZsb3dPdXRwdXQ/LmZsb3dPdXRwdXRBcm4sXG4gICAgICAgICAgc291cmNlVHJhbnNpdERlY3J5cHRpb246IHJlbmRlclRyYW5zaXRFbmNyeXB0aW9uKHNjb3BlLCAnU291cmNlVHJhbnNpdERlY3J5cHRpb25Sb2xlJywgdGhpcy5vcHRpb25zLnNvdXJjZVRyYW5zaXREZWNyeXB0aW9uLCByb3V0ZXJJbnB1dEFybiksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogdGhpcy5hdmFpbGFiaWxpdHlab25lLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgX2VuZHBvaW50cyhfaXBBZGRyZXNzOiBzdHJpbmcpOiBSb3V0ZXJJbnB1dEVuZHBvaW50W10gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBvcHRpb25zIGZvciB7QGxpbmsgTWVkaWFMaXZlQ2hhbm5lbFJvdXRlcklucHV0Q29uZmlnfS4gTm90IGV4cG9ydGVkOyBqc2lpIG5ldmVyIHNlZXMgdGhpcy5cbiAqL1xuaW50ZXJmYWNlIE1lZGlhTGl2ZUNoYW5uZWxSb3V0ZXJJbnB1dE9wdGlvbnMge1xuICByZWFkb25seSBtZWRpYUxpdmVDaGFubmVsQXJuPzogc3RyaW5nO1xuICByZWFkb25seSBtZWRpYUxpdmVDaGFubmVsT3V0cHV0TmFtZT86IHN0cmluZztcbiAgcmVhZG9ubHkgbWVkaWFMaXZlUGlwZWxpbmVJZD86IE1lZGlhTGl2ZVBpcGVsaW5lO1xuICByZWFkb25seSBzb3VyY2VUcmFuc2l0RGVjcnlwdGlvbj86IFRyYW5zaXRFbmNyeXB0aW9uO1xufVxuXG4vKipcbiAqIENvbmNyZXRlIHZhcmlhbnQ6IE1lZGlhTGl2ZSBDaGFubmVsIHJvdXRlciBpbnB1dCBjb25maWd1cmF0aW9uICh3aXRoIG9yIHdpdGhvdXQgY29ubmVjdGlvbikuXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgTWVkaWFMaXZlQ2hhbm5lbFJvdXRlcklucHV0Q29uZmlnIGV4dGVuZHMgUm91dGVySW5wdXRDb25maWd1cmF0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBNZWRpYUxpdmVDaGFubmVsUm91dGVySW5wdXRPcHRpb25zLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXZhaWxhYmlsaXR5Wm9uZT86IHN0cmluZyxcbiAgKSB7IHN1cGVyKCk7IH1cblxuICBwdWJsaWMgX2JpbmQoc2NvcGU6IENvbnN0cnVjdCwgcm91dGVySW5wdXRBcm4/OiBzdHJpbmcpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29uZmlnOiB7XG4gICAgICAgIG1lZGlhTGl2ZUNoYW5uZWw6IHtcbiAgICAgICAgICBtZWRpYUxpdmVDaGFubmVsQXJuOiB0aGlzLm9wdGlvbnMubWVkaWFMaXZlQ2hhbm5lbEFybixcbiAgICAgICAgICBtZWRpYUxpdmVDaGFubmVsT3V0cHV0TmFtZTogdGhpcy5vcHRpb25zLm1lZGlhTGl2ZUNoYW5uZWxPdXRwdXROYW1lLFxuICAgICAgICAgIG1lZGlhTGl2ZVBpcGVsaW5lSWQ6IHRoaXMub3B0aW9ucy5tZWRpYUxpdmVQaXBlbGluZUlkLFxuICAgICAgICAgIHNvdXJjZVRyYW5zaXREZWNyeXB0aW9uOiByZW5kZXJUcmFuc2l0RW5jcnlwdGlvbihzY29wZSwgJ1NvdXJjZVRyYW5zaXREZWNyeXB0aW9uUm9sZScsIHRoaXMub3B0aW9ucy5zb3VyY2VUcmFuc2l0RGVjcnlwdGlvbiwgcm91dGVySW5wdXRBcm4pLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHRoaXMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIF9lbmRwb2ludHMoX2lwQWRkcmVzczogc3RyaW5nKTogUm91dGVySW5wdXRFbmRwb2ludFtdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogQSBNZWRpYUNvbm5lY3QgUm91dGVyIElucHV0IHRoYXQgcmVjZWl2ZXMgbWVkaWEgc3RyZWFtcyBhbmQgcm91dGVzIHRoZW0gdG8gb3V0cHV0cy5cbiAqXG4gKiBSb3V0ZXIgSW5wdXRzIHN1cHBvcnQgbXVsdGlwbGUgY29uZmlndXJhdGlvbiB0eXBlczpcbiAqIC0gU3RhbmRhcmQ6IFNpbmdsZSBwcm90b2NvbCBpbnB1dFxuICogLSBGYWlsb3ZlcjogVHdvIG1hdGNoaW5nIHByb3RvY29scyBmb3IgcmVkdW5kYW5jeVxuICogLSBNZXJnZTogVHdvIG1hdGNoaW5nIG5vbi1TUlQgcHJvdG9jb2xzIGZvciBzdHJlYW0gbWVyZ2luZ1xuICogLSBNZWRpYUNvbm5lY3QgRmxvdzogSW5wdXQgZnJvbSBhbiBleGlzdGluZyBNZWRpYUNvbm5lY3QgRmxvd1xuICovXG5hYnN0cmFjdCBjbGFzcyBSb3V0ZXJJbnB1dEJhc2UgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElSb3V0ZXJJbnB1dCB7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSByb3V0ZXJJbnB1dEFybjogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgcm91dGVySW5wdXRJZDogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgaXBBZGRyZXNzOiBzdHJpbmc7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBjcmVhdGVkQXQ/OiBzdHJpbmc7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSB1cGRhdGVkQXQ/OiBzdHJpbmc7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBlbmRwb2ludHM6IFJvdXRlcklucHV0RW5kcG9pbnRbXTtcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHRyYW5zaXRFbmNyeXB0aW9uU2VjcmV0PzogSVNlY3JldDtcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGdyYW50czogUm91dGVySW5wdXRHcmFudHM7XG5cbiAgLyoqXG4gICAqIEEgcmVmZXJlbmNlIHRvIHRoaXMgUm91dGVyIElucHV0IHJlc291cmNlLlxuICAgKiBSZXF1aXJlZCBieSB0aGUgYXV0by1nZW5lcmF0ZWQgSVJvdXRlcklucHV0UmVmIGludGVyZmFjZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgcm91dGVySW5wdXRSZWYoKTogUm91dGVySW5wdXRSZWZlcmVuY2Uge1xuICAgIHJldHVybiB7IHJvdXRlcklucHV0QXJuOiB0aGlzLnJvdXRlcklucHV0QXJuIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgQ2xvdWRXYXRjaCBtZXRyaWMgZm9yIHRoaXMgcm91dGVyIGlucHV0LlxuICAgKi9cbiAgcHVibGljIG1ldHJpYyhtZXRyaWNOYW1lOiBzdHJpbmcsIHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgbWV0cmljTmFtZSxcbiAgICAgIG5hbWVzcGFjZTogJ0FXUy9NZWRpYUNvbm5lY3QnLFxuICAgICAgLi4ucHJvcHMsXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIFJvdXRlcklucHV0QVJOOiB0aGlzLnJvdXRlcklucHV0QXJuLFxuICAgICAgICAuLi5wcm9wcz8uZGltZW5zaW9uc01hcCxcbiAgICAgIH0sXG4gICAgfSkuYXR0YWNoVG8odGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgYml0cmF0ZSBvZiB0aGUgcm91dGVyIGlucHV0J3MgcGF5bG9hZC5cbiAgICovXG4gIHB1YmxpYyBtZXRyaWNCaXRyYXRlKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdSb3V0ZXJJbnB1dEJpdFJhdGUnLCB7XG4gICAgICBzdGF0aXN0aWM6ICdhdmcnLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIHVuaXQ6IFVuaXQuQklUU19QRVJfU0VDT05ELFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciBwYWNrZXRzIGxvc3QgaW4gdHJhbnNpdCB0aGF0IHdlcmUgbm90IHJlY292ZXJlZCBieSBlcnJvciBjb3JyZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIG1ldHJpY05vdFJlY292ZXJlZFBhY2tldHMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWMoJ1JvdXRlcklucHV0Tm90UmVjb3ZlcmVkUGFja2V0cycsIHtcbiAgICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIHRvdGFsIG51bWJlciBvZiBwYWNrZXRzIHJlY2VpdmVkIGJ5IHRoZSByb3V0ZXIgaW5wdXQuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljVG90YWxQYWNrZXRzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdSb3V0ZXJJbnB1dFRvdGFsUGFja2V0cycsIHtcbiAgICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIHJvdXRlciBpbnB1dCBjb25uZWN0aW9uIHN0YXRlICgxIGNvbm5lY3RlZCwgMCBkaXNjb25uZWN0ZWQpLiBBcHBsaWVzIHRvIFNSVCBzb3VyY2VzIG9ubHkuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljQ29ubmVjdGVkKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdSb3V0ZXJJbnB1dENvbm5lY3RlZCcsIHtcbiAgICAgIHN0YXRpc3RpYzogJ21pbicsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5OT05FLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciBjb250aW51aXR5IGNvdW50ZXIgZXJyb3JzIGluIHRoZSB0cmFuc3BvcnQgc3RyZWFtLlxuICAgKi9cbiAgcHVibGljIG1ldHJpY0NvbnRpbnVpdHlDb3VudGVyRXJyb3JzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdSb3V0ZXJJbnB1dENDRXJyb3JzJywge1xuICAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgcmVjb3ZlcnkgbGF0ZW5jeSBvZiB0aGUgaW5wdXQgc3RyZWFtLiBBcHBsaWVzIHRvIFJJU1QsIFNSVCwgYW5kIFJUUC1GRUMuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljTGF0ZW5jeShwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpYygnUm91dGVySW5wdXRMYXRlbmN5Jywge1xuICAgICAgc3RhdGlzdGljOiAnYXZnJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0Lk1JTExJU0VDT05EUyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUgcm91dGVyIGlucHV0IGhhcyBzd2l0Y2hlZCBzb3VyY2VzIGluIEZhaWxvdmVyIG1vZGUuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljRmFpbG92ZXJTd2l0Y2hlcyhwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpYygnUm91dGVySW5wdXRGYWlsb3ZlclN3aXRjaGVzJywge1xuICAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZWZpbmVzIGFuIEFXUyBFbGVtZW50YWwgTWVkaWFDb25uZWN0IFJvdXRlciBJbnB1dC5cbiAqL1xuQHByb3BlcnR5SW5qZWN0YWJsZVxuZXhwb3J0IGNsYXNzIFJvdXRlcklucHV0IGV4dGVuZHMgUm91dGVySW5wdXRCYXNlIGltcGxlbWVudHMgSVJvdXRlcklucHV0IHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtbWVkaWFjb25uZWN0LWFscGhhLlJvdXRlcklucHV0JztcblxuICAvKipcbiAgICogSW1wb3J0IGFuIGV4aXN0aW5nIFJvdXRlciBJbnB1dCBmcm9tIGl0cyBBUk4uXG4gICAqXG4gICAqIFVzZSBgZnJvbVJvdXRlcklucHV0QXR0cmlidXRlcygpYCBpbnN0ZWFkIGlmIHlvdSBuZWVkIHRvIGV4cG9zZSBgcm91dGVySW5wdXRJZGBcbiAgICogb3IgYGlwQWRkcmVzc2Agb24gdGhlIGltcG9ydGVkIGNvbnN0cnVjdC5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIFRoZSBwYXJlbnQgY29uc3RydWN0XG4gICAqIEBwYXJhbSBpZCBUaGUgY29uc3RydWN0IGlkXG4gICAqIEBwYXJhbSByb3V0ZXJJbnB1dEFybiBUaGUgQVJOIG9mIHRoZSBSb3V0ZXIgSW5wdXRcbiAgICogQHJldHVybnMgQSBSb3V0ZXIgSW5wdXQgY29uc3RydWN0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Sb3V0ZXJJbnB1dEFybihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCByb3V0ZXJJbnB1dEFybjogc3RyaW5nKTogSVJvdXRlcklucHV0IHtcbiAgICByZXR1cm4gUm91dGVySW5wdXQuZnJvbVJvdXRlcklucHV0QXR0cmlidXRlcyhzY29wZSwgaWQsIHsgcm91dGVySW5wdXRBcm4gfSk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGFuIGV4aXN0aW5nIFJvdXRlciBJbnB1dCBmcm9tIGl0cyBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBQcm92aWRlIGByb3V0ZXJJbnB1dElkYCBhbmQvb3IgYGlwQWRkcmVzc2Agd2hlbiBpbXBvcnRpbmcgYW4gaW5wdXQgdGhhdCB3YXMgZGVwbG95ZWRcbiAgICogZXh0ZXJuYWxseSDigJQgb3RoZXJ3aXNlIGFjY2Vzc2luZyB0aG9zZSBwcm9wZXJ0aWVzIG9uIHRoZSBpbXBvcnRlZCBjb25zdHJ1Y3Qgd2lsbCB0aHJvdy5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIFRoZSBwYXJlbnQgY29uc3RydWN0XG4gICAqIEBwYXJhbSBpZCBUaGUgY29uc3RydWN0IGlkXG4gICAqIEBwYXJhbSBhdHRycyBUaGUgUm91dGVyIElucHV0IGF0dHJpYnV0ZXNcbiAgICogQHJldHVybnMgQSBSb3V0ZXIgSW5wdXQgY29uc3RydWN0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Sb3V0ZXJJbnB1dEF0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IFJvdXRlcklucHV0QXR0cmlidXRlcyk6IElSb3V0ZXJJbnB1dCB7XG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgUm91dGVySW5wdXRCYXNlIGltcGxlbWVudHMgSVJvdXRlcklucHV0IHtcbiAgICAgIHB1YmxpYyByZWFkb25seSByb3V0ZXJJbnB1dEFybiA9IGF0dHJzLnJvdXRlcklucHV0QXJuO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGNyZWF0ZWRBdCA9IHVuZGVmaW5lZDtcbiAgICAgIHB1YmxpYyByZWFkb25seSB1cGRhdGVkQXQgPSB1bmRlZmluZWQ7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgdHJhbnNpdEVuY3J5cHRpb25TZWNyZXQgPSB1bmRlZmluZWQ7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRzID0gUm91dGVySW5wdXRHcmFudHMuZnJvbVJvdXRlcklucHV0KHRoaXMpO1xuXG4gICAgICBwdWJsaWMgZ2V0IGVuZHBvaW50cygpOiBSb3V0ZXJJbnB1dEVuZHBvaW50W10ge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBSb3V0ZXJJbnB1dEVuZHBvaW50c05vdEF2YWlsYWJsZUltcG9ydGVkYCxcbiAgICAgICAgICBgJ2VuZHBvaW50cycgaXMgbm90IGF2YWlsYWJsZSBvbiBpbXBvcnRlZCBSb3V0ZXJJbnB1dCAke3RoaXMubm9kZS5wYXRofTsgb25seSBSb3V0ZXJJbnB1dHMgY29uc3RydWN0ZWQgaW4gdGhpcyBhcHAgZm9yIGxpc3RlbmluZyBwcm90b2NvbCB2YXJpYW50cyAoUlRQLCBSSVNULCBTUlQgbGlzdGVuZXIsIGluY2x1ZGluZyBmYWlsb3ZlciBhbmQgbWVyZ2UpIGV4cG9zZSBpbmdlc3QgZW5kcG9pbnRzYCxcbiAgICAgICAgICB0aGlzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwdWJsaWMgZ2V0IHJvdXRlcklucHV0SWQoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGF0dHJzLnJvdXRlcklucHV0SWQpIHJldHVybiBhdHRycy5yb3V0ZXJJbnB1dElkO1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBSb3V0ZXJJbnB1dElkTm90UHJvdmlkZWRgLFxuICAgICAgICAgIGAncm91dGVySW5wdXRJZCcgaXMgbm90IGF2YWlsYWJsZSBvbiBpbXBvcnRlZCBSb3V0ZXJJbnB1dCAke3RoaXMubm9kZS5wYXRofTsgcGFzcyBpdCB2aWEgZnJvbVJvdXRlcklucHV0QXR0cmlidXRlc2AsXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcHVibGljIGdldCBpcEFkZHJlc3MoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGF0dHJzLmlwQWRkcmVzcykgcmV0dXJuIGF0dHJzLmlwQWRkcmVzcztcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgUm91dGVySW5wdXRJcEFkZHJlc3NOb3RQcm92aWRlZGAsXG4gICAgICAgICAgYCdpcEFkZHJlc3MnIGlzIG5vdCBhdmFpbGFibGUgb24gaW1wb3J0ZWQgUm91dGVySW5wdXQgJHt0aGlzLm5vZGUucGF0aH07IHBhc3MgaXQgdmlhIGZyb21Sb3V0ZXJJbnB1dEF0dHJpYnV0ZXNgLFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgSW1wb3J0KHNjb3BlLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbWF4aW11bSBiaXRyYXRlIGluIE1icHMgZm9yIGEga25vd24gdGllciwgb3IgdW5kZWZpbmVkIGZvciBjdXN0b20gdGllcnMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB0aWVyTGltaXRNYnBzKHRpZXI6IFJvdXRlcklucHV0VGllcik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRpZXIudmFsdWUgPT09IFJvdXRlcklucHV0VGllci5JTlBVVF8yMC52YWx1ZSkgcmV0dXJuIDIwO1xuICAgIGlmICh0aWVyLnZhbHVlID09PSBSb3V0ZXJJbnB1dFRpZXIuSU5QVVRfNTAudmFsdWUpIHJldHVybiA1MDtcbiAgICBpZiAodGllci52YWx1ZSA9PT0gUm91dGVySW5wdXRUaWVyLklOUFVUXzEwMC52YWx1ZSkgcmV0dXJuIDEwMDtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHJvdXRlcklucHV0QXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSByb3V0ZXJJbnB1dElkOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBpcEFkZHJlc3M6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGNyZWF0ZWRBdD86IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHVwZGF0ZWRBdD86IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBfZW5kcG9pbnRzOiBSb3V0ZXJJbnB1dEVuZHBvaW50W10gfCB1bmRlZmluZWQ7XG4gIHB1YmxpYyByZWFkb25seSB0cmFuc2l0RW5jcnlwdGlvblNlY3JldD86IElTZWNyZXQ7XG4gIHB1YmxpYyByZWFkb25seSBncmFudHM6IFJvdXRlcklucHV0R3JhbnRzO1xuXG4gIHB1YmxpYyBnZXQgZW5kcG9pbnRzKCk6IFJvdXRlcklucHV0RW5kcG9pbnRbXSB7XG4gICAgaWYgKHRoaXMuX2VuZHBvaW50cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgUm91dGVySW5wdXRFbmRwb2ludHNOb3RBdmFpbGFibGVDb25maWdgLFxuICAgICAgICBgJ2VuZHBvaW50cycgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGlzIFJvdXRlcklucHV0ICR7dGhpcy5ub2RlLnBhdGh9OyBvbmx5IGxpc3RlbmluZyBwcm90b2NvbCB2YXJpYW50cyAoUlRQLCBSSVNULCBTUlQgbGlzdGVuZXIg4oCUIGluY2x1ZGluZyBmYWlsb3ZlciBhbmQgbWVyZ2UgYnVpbHQgZnJvbSB0aG9zZSkgZXhwb3NlIGluZ2VzdCBlbmRwb2ludHMg4oCUIFNSVCBjYWxsZXIsIE1lZGlhQ29ubmVjdCBGbG93LCBhbmQgTWVkaWFMaXZlIENoYW5uZWwgaW5wdXRzIGRvIG5vdGAsXG4gICAgICAgIHRoaXMsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fZW5kcG9pbnRzO1xuICB9XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFJvdXRlcklucHV0UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMucm91dGVySW5wdXROYW1lID8/IExhenkuc3RyaW5nKHsgcHJvZHVjZTogKCkgPT4gTmFtZXMudW5pcXVlUmVzb3VyY2VOYW1lKHRoaXMsIHsgbWF4TGVuZ3RoOiAxMjggfSkgfSksXG4gICAgfSk7XG5cbiAgICAvLyBWYWxpZGF0ZSByb3V0ZXIgaW5wdXQgbmFtZSBpZiBwcm92aWRlZFxuICAgIGlmIChwcm9wcy5yb3V0ZXJJbnB1dE5hbWUgIT0gbnVsbCAmJiBwcm9wcy5yb3V0ZXJJbnB1dE5hbWUgIT09ICcnICYmICFUb2tlbi5pc1VucmVzb2x2ZWQocHJvcHMucm91dGVySW5wdXROYW1lKSkge1xuICAgICAgaWYgKHByb3BzLnJvdXRlcklucHV0TmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVySW5wdXROYW1lTGVuZ3RoYCwgYFJvdXRlciBpbnB1dCBuYW1lIG11c3QgYmUgYmV0d2VlbiAxIGFuZCAxMjggY2hhcmFjdGVycywgZ290ICR7cHJvcHMucm91dGVySW5wdXROYW1lLmxlbmd0aH1gLCB0aGlzKTtcbiAgICAgIH1cbiAgICAgIGlmICghL15bYS16QS1aMC05LV0rJC8udGVzdChwcm9wcy5yb3V0ZXJJbnB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IobGl0YFJvdXRlcklucHV0TmFtZUZvcm1hdGAsIGBSb3V0ZXIgaW5wdXQgbmFtZSBtdXN0IGNvbnRhaW4gb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgaHlwaGVucywgZ290ICcke3Byb3BzLnJvdXRlcklucHV0TmFtZX0nYCwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbWF4aW11bSBiaXRyYXRlXG4gICAgaWYgKCFwcm9wcy5tYXhpbXVtQml0cmF0ZS5pc1VucmVzb2x2ZWQoKSAmJiBwcm9wcy5tYXhpbXVtQml0cmF0ZS50b0JwcygpIDwgMTAwMDAwMCkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVySW5wdXRNaW5CaXRyYXRlYCwgYE1heGltdW0gYml0cmF0ZSBtdXN0IGJlIGF0IGxlYXN0IDEsMDAwLDAwMCBiaXRzL3MgKDEgTWJwcyksIGdvdCAke3Byb3BzLm1heGltdW1CaXRyYXRlLnRvQnBzKCl9YCwgdGhpcyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYml0cmF0ZSBkb2VzIG5vdCBleGNlZWQgdGllciBsaW1pdFxuICAgIGNvbnN0IHJlc29sdmVkVGllciA9IHByb3BzLnRpZXIgPz8gUm91dGVySW5wdXRUaWVyLklOUFVUXzIwO1xuICAgIGNvbnN0IHRpZXJNYnBzID0gUm91dGVySW5wdXQudGllckxpbWl0TWJwcyhyZXNvbHZlZFRpZXIpO1xuICAgIGlmIChleGNlZWRzUm91dGVyVGllckJpdHJhdGUodGllck1icHMsIHByb3BzLm1heGltdW1CaXRyYXRlKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVySW5wdXRCaXRyYXRlRXhjZWVkc1RpZXJgLCBgTWF4aW11bSBiaXRyYXRlICR7cHJvcHMubWF4aW11bUJpdHJhdGUudG9CcHMoKSAvIDFfMDAwXzAwMH0gTWJwcyBleGNlZWRzIHRoZSAke3Jlc29sdmVkVGllci52YWx1ZX0gdGllciBsaW1pdCBvZiAke3RpZXJNYnBzfSBNYnBzYCwgdGhpcyk7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbWFpbnRlbmFuY2UgdGltZSBmb3JtYXRcbiAgICBpZiAocHJvcHMubWFpbnRlbmFuY2VDb25maWd1cmF0aW9uKSB7XG4gICAgICB2YWxpZGF0ZU1haW50ZW5hbmNlVGltZShwcm9wcy5tYWludGVuYW5jZUNvbmZpZ3VyYXRpb24udGltZSk7XG4gICAgfVxuXG4gICAgLy8gRW5oYW5jZWQgQ0RLIEFuYWx5dGljcyBUZWxlbWV0cnlcbiAgICBhZGRDb25zdHJ1Y3RNZXRhZGF0YSh0aGlzLCBwcm9wcyk7XG5cbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHRoaXMpO1xuICAgIGNvbnN0IHRhcmdldFJlZ2lvbiA9IHByb3BzLnJlZ2lvbk5hbWUgPz8gc3RhY2sucmVnaW9uO1xuXG4gICAgLy8gV2lsZGNhcmQgdGhlIGlkIOKAlCBwaW5uaW5nIHRoZSBsaXZlIEFSTiAoYXR0ckFybikgd291bGQgY3JlYXRlIGEgcm9sZSDihpIgcm91dGVyLWlucHV0IOKGkiByb2xlIGN5Y2xlLlxuICAgIGNvbnN0IHJvdXRlcklucHV0QXJuID0gc3RhY2suZm9ybWF0QXJuKHtcbiAgICAgIHNlcnZpY2U6ICdtZWRpYWNvbm5lY3QnLFxuICAgICAgcmVnaW9uOiB0YXJnZXRSZWdpb24sXG4gICAgICByZXNvdXJjZTogJ3JvdXRlcklucHV0JyxcbiAgICAgIHJlc291cmNlTmFtZTogJyonLFxuICAgICAgYXJuRm9ybWF0OiBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGNvbmZpZ0JpbmQgPSBwcm9wcy5jb25maWd1cmF0aW9uLl9iaW5kKHRoaXMsIHJvdXRlcklucHV0QXJuKTtcblxuICAgIC8vIFZhbGlkYXRlIEFaIG1hdGNoZXMgcmVnaW9uIGlmIHByb3ZpZGVkXG4gICAgaWYgKGNvbmZpZ0JpbmQuYXZhaWxhYmlsaXR5Wm9uZSAmJiAhY29uZmlnQmluZC5hdmFpbGFiaWxpdHlab25lLnN0YXJ0c1dpdGgodGFyZ2V0UmVnaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVySW5wdXRBelJlZ2lvbk1pc21hdGNoYCwgYEF2YWlsYWJpbGl0eSB6b25lICcke2NvbmZpZ0JpbmQuYXZhaWxhYmlsaXR5Wm9uZX0nIG11c3QgYmUgd2l0aGluIHJlZ2lvbiAnJHt0YXJnZXRSZWdpb259J2AsIHRoaXMpO1xuICAgIH1cblxuICAgIGNvbnN0IHRyYW5zaXQgPSByZXNvbHZlVHJhbnNpdEVuY3J5cHRpb24odGhpcywgJ1RyYW5zaXRFbmNyeXB0aW9uUm9sZScsIHByb3BzLnRyYW5zaXRFbmNyeXB0aW9uLCByb3V0ZXJJbnB1dEFybik7XG5cbiAgICBjb25zdCByb3V0ZXJpbnB1dCA9IG5ldyBDZm5Sb3V0ZXJJbnB1dCh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBuYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIG1heGltdW1CaXRyYXRlOiBwcm9wcy5tYXhpbXVtQml0cmF0ZS50b0JwcygpLFxuICAgICAgdGllcjogKHByb3BzLnRpZXIgPz8gUm91dGVySW5wdXRUaWVyLklOUFVUXzIwKS52YWx1ZSxcbiAgICAgIHJvdXRpbmdTY29wZTogcHJvcHMucm91dGluZ1Njb3BlLnZhbHVlLFxuICAgICAgbWFpbnRlbmFuY2VDb25maWd1cmF0aW9uOiBwcm9wcy5tYWludGVuYW5jZUNvbmZpZ3VyYXRpb24gPyB7XG4gICAgICAgIHByZWZlcnJlZERheVRpbWU6IHByb3BzLm1haW50ZW5hbmNlQ29uZmlndXJhdGlvbixcbiAgICAgIH0gOiB7XG4gICAgICAgIGRlZmF1bHQ6IHt9LFxuICAgICAgfSxcbiAgICAgIGNvbmZpZ3VyYXRpb246IGNvbmZpZ0JpbmQuY29uZmlnLFxuICAgICAgdHJhbnNpdEVuY3J5cHRpb246IHRyYW5zaXQuY29uZmlnLFxuICAgICAgcmVnaW9uTmFtZTogdGFyZ2V0UmVnaW9uLFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogY29uZmlnQmluZC5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgdGFnczogcHJvcHMudGFncyA/IHJlbmRlclRhZ3MocHJvcHMudGFncykgOiB1bmRlZmluZWQsXG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlcklucHV0QXJuID0gcm91dGVyaW5wdXQuYXR0ckFybjtcbiAgICB0aGlzLnJvdXRlcklucHV0SWQgPSByb3V0ZXJpbnB1dC5hdHRySWQ7XG4gICAgdGhpcy5pcEFkZHJlc3MgPSByb3V0ZXJpbnB1dC5hdHRySXBBZGRyZXNzO1xuICAgIHRoaXMuY3JlYXRlZEF0ID0gcm91dGVyaW5wdXQuYXR0ckNyZWF0ZWRBdDtcbiAgICB0aGlzLnVwZGF0ZWRBdCA9IHJvdXRlcmlucHV0LmF0dHJVcGRhdGVkQXQ7XG5cbiAgICAvLyBXaXRob3V0IHRoaXMgdGhlIHJvdXRlciBpbnB1dCBjYW4gYmUgY3JlYXRlZCBiZWZvcmUgdGhlXG4gICAgLy8gcG9saWN5IGlzIGF0dGFjaGVkIChcImFjY2VzcyBkZW5pZWRcIiBhdCBjcmVhdGUgdGltZSkuIE9yZGVyaW5nIHRoZSBncmFudCBiZWZvcmUgdGhlXG4gICAgLy8gcm91dGVyIGlucHV0IHB1bGxzIHRoZSBwb2xpY3kgaW4gYXMgYSBkZXBlbmRlbmN5LlxuICAgIHRyYW5zaXQuZ3JhbnQ/LmFwcGx5QmVmb3JlKHJvdXRlcmlucHV0KTtcblxuICAgIC8vIENvbXB1dGUgaW5nZXN0IGVuZHBvaW50cyBmb3IgcHJvdG9jb2wtYmFzZWQgdmFyaWFudHNcbiAgICB0aGlzLl9lbmRwb2ludHMgPSBwcm9wcy5jb25maWd1cmF0aW9uLl9lbmRwb2ludHMocm91dGVyaW5wdXQuYXR0cklwQWRkcmVzcyk7XG5cbiAgICAvLyBTdG9yZSB0aGUgdHJhbnNpdCBlbmNyeXB0aW9uIHNlY3JldCBpZiBleHBsaWNpdGx5IHByb3ZpZGVkXG4gICAgdGhpcy50cmFuc2l0RW5jcnlwdGlvblNlY3JldCA9IHByb3BzLnRyYW5zaXRFbmNyeXB0aW9uPy5zZWNyZXQ7XG4gICAgdGhpcy5ncmFudHMgPSBSb3V0ZXJJbnB1dEdyYW50cy5mcm9tUm91dGVySW5wdXQodGhpcyk7XG4gIH1cbn1cblxuIl19