@aws-cdk/aws-kinesisanalytics-flink-alpha
Version:
A CDK Construct Library for Kinesis Analytics Flink applications
647 lines • 83.8 kB
JavaScript
"use strict";
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
var _, done = false;
for (var i = decorators.length - 1; i >= 0; i--) {
var context = {};
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
if (kind === "accessor") {
if (result === void 0) continue;
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
if (_ = accept(result.get)) descriptor.get = _;
if (_ = accept(result.set)) descriptor.set = _;
if (_ = accept(result.init)) initializers.unshift(_);
}
else if (_ = accept(result)) {
if (kind === "field") initializers.unshift(_);
else descriptor[key] = _;
}
}
if (target) Object.defineProperty(target, contextIn.name, descriptor);
done = true;
};
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
var useValue = arguments.length > 2;
for (var i = 0; i < initializers.length; i++) {
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
}
return useValue ? value : void 0;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Application = void 0;
const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
const ec2 = require("aws-cdk-lib/aws-ec2");
const iam = require("aws-cdk-lib/aws-iam");
const aws_kinesisanalytics_1 = require("aws-cdk-lib/aws-kinesisanalytics");
const logs = require("aws-cdk-lib/aws-logs");
const core = require("aws-cdk-lib/core");
const environment_properties_1 = require("./private/environment-properties");
const flink_application_configuration_1 = require("./private/flink-application-configuration");
const validation_1 = require("./private/validation");
const metadata_resource_1 = require("aws-cdk-lib/core/lib/metadata-resource");
const prop_injectable_1 = require("aws-cdk-lib/core/lib/prop-injectable");
/**
* Implements the functionality shared between CDK created and imported
* IApplications.
*/
class ApplicationBase extends core.Resource {
/**
* The underlying connections object for the connections getter.
*
* @internal
*/
_connections;
/** Implement the convenience `IApplication.addToPrincipalPolicy` method. */
addToRolePolicy(policyStatement) {
if (this.role) {
this.role.addToPrincipalPolicy(policyStatement);
return true;
}
return false;
}
get connections() {
if (!this._connections) {
throw new Error('This Application isn\'t associated with a VPC. Provide a "vpc" prop when creating the Application or "securityGroups" when importing it.');
}
return this._connections;
}
/**
* Return a CloudWatch metric associated with this Flink application.
*
* @param metricName The name of the metric
* @param props Customization properties
*/
metric(metricName, props) {
return new cloudwatch.Metric({
namespace: 'AWS/KinesisAnalytics',
metricName,
dimensionsMap: { Application: this.applicationName },
...props,
}).attachTo(this);
}
/**
* The number of Kinesis Processing Units that are used to run your stream
* processing application. The average number of KPUs used each hour
* determines the billing for your application.
*
* Units: Count
*
* Reporting Level: Application
*
* @default - average over 5 minutes
*/
metricKpus(props) {
return this.metric('KPUs', { statistic: 'Average', ...props });
}
/**
* The time elapsed during an outage for failing/recovering jobs.
*
* Units: Milliseconds
*
* Reporting Level: Application
*
* @default - average over 5 minutes
*/
metricDowntime(props) {
return this.metric('downtime', { statistic: 'Average', ...props });
}
/**
* The time that the job has been running without interruption.
*
* Units: Milliseconds
*
* Reporting Level: Application
*
* @default - average over 5 minutes
*/
metricUptime(props) {
return this.metric('uptime', { statistic: 'Average', ...props });
}
/**
* The total number of times this job has fully restarted since it was
* submitted. This metric does not measure fine-grained restarts.
*
* Units: Count
*
* Reporting Level: Application
*
* @default - sum over 5 minutes
*/
metricFullRestarts(props) {
return this.metric('fullRestarts', { statistic: 'Sum', ...props });
}
/**
* The number of times checkpointing has failed.
*
* Units: Count
*
* Reporting Level: Application
*
* @default - sum over 5 minutes
*/
metricNumberOfFailedCheckpoints(props) {
return this.metric('numberOfFailedCheckpoints', { statistic: 'Sum', ...props });
}
/**
* The time it took to complete the last checkpoint.
*
* Units: Milliseconds
*
* Reporting Level: Application
*
* @default - maximum over 5 minutes
*/
metricLastCheckpointDuration(props) {
return this.metric('lastCheckpointDuration', { statistic: 'Maximum', ...props });
}
/**
* The total size of the last checkpoint.
*
* Units: Bytes
*
* Reporting Level: Application
*
* @default - maximum over 5 minutes
*/
metricLastCheckpointSize(props) {
return this.metric('lastCheckpointSize', { statistic: 'Maximum', ...props });
}
/**
* The overall percentage of CPU utilization across task managers. For
* example, if there are five task managers, Kinesis Data Analytics publishes
* five samples of this metric per reporting interval.
*
* Units: Percentage
*
* Reporting Level: Application
*
* @default - average over 5 minutes
*/
metricCpuUtilization(props) {
return this.metric('cpuUtilization', { statistic: 'Average', ...props });
}
/**
* Overall heap memory utilization across task managers. For example, if there
* are five task managers, Kinesis Data Analytics publishes five samples of
* this metric per reporting interval.
*
* Units: Percentage
*
* Reporting Level: Application
*
* @default - average over 5 minutes
*/
metricHeapMemoryUtilization(props) {
return this.metric('heapMemoryUtilization', { statistic: 'Average', ...props });
}
/**
* The total time spent performing old garbage collection operations.
*
* Units: Milliseconds
*
* Reporting Level: Application
*
* @default - sum over 5 minutes
*/
metricOldGenerationGCTime(props) {
return this.metric('oldGenerationGCTime', { statistic: 'Sum', ...props });
}
/**
* The total number of old garbage collection operations that have occurred
* across all task managers.
*
* Units: Count
*
* Reporting Level: Application
*
* @default - sum over 5 minutes
*/
metricOldGenerationGCCount(props) {
return this.metric('oldGenerationGCCount', { statistic: 'Sum', ...props });
}
/**
* The total number of live threads used by the application.
*
* Units: Count
*
* Reporting Level: Application
*
* @default - average over 5 minutes
*/
metricThreadsCount(props) {
return this.metric('threadsCount', { statistic: 'Average', ...props });
}
/**
* The total number of records this application, operator, or task has
* received.
*
* Units: Count
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricNumRecordsIn(props) {
return this.metric('numRecordsIn', { statistic: 'Average', ...props });
}
/**
* The total number of records this application, operator or task has received
* per second.
*
* Units: Count/Second
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricNumRecordsInPerSecond(props) {
return this.metric('numRecordsInPerSecond', { statistic: 'Average', ...props });
}
/**
* The total number of records this application, operator or task has emitted.
*
* Units: Count
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricNumRecordsOut(props) {
return this.metric('numRecordsOut', { statistic: 'Average', ...props });
}
/**
* The total number of records this application, operator or task has emitted
* per second.
*
* Units: Count/Second
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricNumRecordsOutPerSecond(props) {
return this.metric('numRecordsOutPerSecond', { statistic: 'Average', ...props });
}
/**
* The number of records this operator or task has dropped due to arriving
* late.
*
* Units: Count
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - sum over 5 minutes
*/
metricNumLateRecordsDropped(props) {
return this.metric('numLateRecordsDropped', { statistic: 'Sum', ...props });
}
/**
* The last watermark this application/operator/task/thread has received.
*
* Units: Milliseconds
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - maximum over 5 minutes
*/
metricCurrentInputWatermark(props) {
return this.metric('currentInputWatermark', { statistic: 'Maximum', ...props });
}
/**
* The last watermark this application/operator/task/thread has received.
*
* Units: Milliseconds
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - maximum over 5 minutes
*/
metricCurrentOutputWatermark(props) {
return this.metric('currentOutputWatermark', { statistic: 'Maximum', ...props });
}
/**
* The amount of managed memory currently used.
*
* Units: Bytes
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricManagedMemoryUsed(props) {
return this.metric('managedMemoryUsed', { statistic: 'Average', ...props });
}
/**
* The total amount of managed memory.
*
* Units: Bytes
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricManagedMemoryTotal(props) {
return this.metric('managedMemoryTotal', { statistic: 'Average', ...props });
}
/**
* Derived from managedMemoryUsed/managedMemoryTotal.
*
* Units: Percentage
*
* Reporting Level: Application, Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricManagedMemoryUtilization(props) {
return this.metric('managedMemoryUtilization', { statistic: 'Average', ...props });
}
/**
* The time (in milliseconds) this task or operator is idle (has no data to
* process) per second. Idle time excludes back pressured time, so if the task
* is back pressured it is not idle.
*
* Units: Milliseconds
*
* Reporting Level: Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricIdleTimeMsPerSecond(props) {
return this.metric('idleTimeMsPerSecond', { statistic: 'Average', ...props });
}
/**
* The time (in milliseconds) this task or operator is back pressured per
* second.
*
* Units: Milliseconds
*
* Reporting Level: Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricBackPressuredTimeMsPerSecond(props) {
return this.metric('backPressuredTimeMsPerSecond', { statistic: 'Average', ...props });
}
/**
* The time (in milliseconds) this task or operator is busy (neither idle nor
* back pressured) per second. Can be NaN, if the value could not be
* calculated.
*
* Units: Milliseconds
*
* Reporting Level: Operator, Task, Parallelism
*
* @default - average over 5 minutes
*/
metricBusyTimePerMsPerSecond(props) {
return this.metric('busyTimePerMsPerSecond', { statistic: 'Average', ...props });
}
}
/**
* An imported Flink application.
*/
let Import = (() => {
let _classDecorators = [prop_injectable_1.propertyInjectable];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = ApplicationBase;
var Import = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Import = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
}
/** Uniquely identifies this class. */
static PROPERTY_INJECTION_ID = '@aws-cdk.aws-kinesisanalytics-flink-alpha.Import';
grantPrincipal;
role;
applicationName;
applicationArn;
constructor(scope, id, attrs) {
super(scope, id);
// Enhanced CDK Analytics Telemetry
(0, metadata_resource_1.addConstructMetadata)(this, attrs);
// Imported applications have no associated role or grantPrincipal
this.grantPrincipal = new iam.UnknownPrincipal({ resource: this });
this.role = undefined;
this.applicationArn = attrs.applicationArn;
const applicationName = core.Stack.of(scope).splitArn(attrs.applicationArn, core.ArnFormat.SLASH_RESOURCE_NAME).resourceName;
if (!applicationName) {
throw new Error(`applicationArn for fromApplicationArn (${attrs.applicationArn}) must include resource name`);
}
this.applicationName = applicationName;
const securityGroups = attrs.securityGroups ?? [];
if (securityGroups.length > 0) {
this._connections = new ec2.Connections({ securityGroups });
}
}
static {
__runInitializers(_classThis, _classExtraInitializers);
}
};
return Import = _classThis;
})();
/**
* The L2 construct for Flink Kinesis Data Applications.
*
* @resource AWS::KinesisAnalyticsV2::Application
*
*/
let Application = (() => {
let _classDecorators = [prop_injectable_1.propertyInjectable];
let _classDescriptor;
let _classExtraInitializers = [];
let _classThis;
let _classSuper = ApplicationBase;
var Application = class extends _classSuper {
static { _classThis = this; }
static {
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
Application = _classThis = _classDescriptor.value;
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
}
static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-kinesisanalytics-flink-alpha.Application", version: "2.222.0-alpha.0" };
/** Uniquely identifies this class. */
static PROPERTY_INJECTION_ID = '@aws-cdk.aws-kinesisanalytics-flink-alpha.Application';
/**
* Import an existing Flink application defined outside of CDK code by
* applicationName.
*/
static fromApplicationName(scope, id, applicationName) {
const applicationArn = core.Stack.of(scope).formatArn(applicationArnComponents(applicationName));
return new Import(scope, id, { applicationArn });
}
/**
* Import an existing application defined outside of CDK code by
* applicationArn.
*/
static fromApplicationArn(scope, id, applicationArn) {
return new Import(scope, id, { applicationArn });
}
/**
* Import an existing application defined outside of CDK code.
*/
static fromApplicationAttributes(scope, id, attrs) {
try {
jsiiDeprecationWarnings._aws_cdk_aws_kinesisanalytics_flink_alpha_ApplicationAttributes(attrs);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, this.fromApplicationAttributes);
}
throw error;
}
return new Import(scope, id, {
applicationArn: attrs.applicationArn,
securityGroups: attrs.securityGroups,
});
}
applicationArn;
applicationName;
// Role must be optional for JSII compatibility
role;
grantPrincipal;
constructor(scope, id, props) {
super(scope, id, { physicalName: props.applicationName });
try {
jsiiDeprecationWarnings._aws_cdk_aws_kinesisanalytics_flink_alpha_ApplicationProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, Application);
}
throw error;
}
// Enhanced CDK Analytics Telemetry
(0, metadata_resource_1.addConstructMetadata)(this, props);
(0, validation_1.validateFlinkApplicationProps)(props);
this.role = props.role ?? new iam.Role(this, 'Role', {
assumedBy: new iam.ServicePrincipal('kinesisanalytics.amazonaws.com'),
});
this.grantPrincipal = this.role;
// Permit metric publishing to CloudWatch
this.role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['cloudwatch:PutMetricData'],
resources: ['*'],
}));
const code = props.code.bind(this);
code.bucket.grantRead(this);
let vpcConfigurations;
if (props.vpc) {
const securityGroups = props.securityGroups ?? [
new ec2.SecurityGroup(this, 'SecurityGroup', {
vpc: props.vpc,
}),
];
this._connections = new ec2.Connections({ securityGroups });
const subnetSelection = props.vpcSubnets ?? {
subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
};
vpcConfigurations = [{
securityGroupIds: securityGroups.map(sg => sg.securityGroupId),
subnetIds: props.vpc.selectSubnets(subnetSelection).subnetIds,
}];
}
const resource = new aws_kinesisanalytics_1.CfnApplicationV2(this, 'Resource', {
applicationName: props.applicationName,
runtimeEnvironment: props.runtime.value,
serviceExecutionRole: this.role.roleArn,
applicationConfiguration: {
...code.applicationCodeConfigurationProperty,
environmentProperties: (0, environment_properties_1.environmentProperties)(props.propertyGroups),
flinkApplicationConfiguration: (0, flink_application_configuration_1.flinkApplicationConfiguration)({
checkpointingEnabled: props.checkpointingEnabled,
checkpointInterval: props.checkpointInterval,
minPauseBetweenCheckpoints: props.minPauseBetweenCheckpoints,
logLevel: props.logLevel,
metricsLevel: props.metricsLevel,
autoScalingEnabled: props.autoScalingEnabled,
parallelism: props.parallelism,
parallelismPerKpu: props.parallelismPerKpu,
}),
applicationSnapshotConfiguration: {
snapshotsEnabled: props.snapshotsEnabled ?? true,
},
vpcConfigurations,
},
});
resource.node.addDependency(this.role);
const logGroup = props.logGroup ?? new logs.LogGroup(this, 'LogGroup');
const logStream = new logs.LogStream(this, 'LogStream', { logGroup });
/* Permit logging */
this.role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['logs:DescribeLogGroups'],
resources: [
core.Stack.of(this).formatArn({
service: 'logs',
resource: 'log-group',
arnFormat: core.ArnFormat.COLON_RESOURCE_NAME,
resourceName: '*',
}),
],
}));
this.role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['logs:DescribeLogStreams'],
resources: [logGroup.logGroupArn],
}));
const logStreamArn = `arn:${core.Aws.PARTITION}:logs:${core.Aws.REGION}:${core.Aws.ACCOUNT_ID}:log-group:${logGroup.logGroupName}:log-stream:${logStream.logStreamName}`;
this.role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['logs:PutLogEvents'],
resources: [logStreamArn],
}));
new aws_kinesisanalytics_1.CfnApplicationCloudWatchLoggingOptionV2(this, 'LoggingOption', {
applicationName: resource.ref,
cloudWatchLoggingOption: {
logStreamArn,
},
});
// Permissions required for VPC usage per:
// https://docs.aws.amazon.com/kinesisanalytics/latest/java/vpc-permissions.html
if (props.vpc) {
this.role.addToPrincipalPolicy(new iam.PolicyStatement({
actions: [
'ec2:DescribeVpcs',
'ec2:DescribeSubnets',
'ec2:DescribeSecurityGroups',
'ec2:DescribeDhcpOptions',
'ec2:CreateNetworkInterface',
'ec2:CreateNetworkInterfacePermission',
'ec2:DescribeNetworkInterfaces',
'ec2:DeleteNetworkInterface',
],
resources: ['*'],
}));
}
this.applicationName = this.getResourceNameAttribute(resource.ref);
this.applicationArn = this.getResourceArnAttribute(core.Stack.of(this).formatArn(applicationArnComponents(resource.ref)), applicationArnComponents(this.physicalName));
resource.applyRemovalPolicy(props.removalPolicy, {
default: core.RemovalPolicy.DESTROY,
});
}
static {
__runInitializers(_classThis, _classExtraInitializers);
}
};
return Application = _classThis;
})();
exports.Application = Application;
function applicationArnComponents(resourceName) {
return {
service: 'kinesisanalytics',
resource: 'application',
resourceName,
};
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhcHBsaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx5REFBeUQ7QUFDekQsMkNBQTJDO0FBQzNDLDJDQUEyQztBQUMzQywyRUFBNkc7QUFDN0csNkNBQTZDO0FBQzdDLHlDQUF5QztBQUd6Qyw2RUFBeUU7QUFDekUsK0ZBQTBGO0FBQzFGLHFEQUFpRztBQUVqRyw4RUFBOEU7QUFDOUUsMEVBQTBFO0FBMlUxRTs7O0dBR0c7QUFDSCxNQUFlLGVBQWdCLFNBQVEsSUFBSSxDQUFDLFFBQVE7SUFRbEQ7Ozs7T0FJRztJQUNPLFlBQVksQ0FBbUI7SUFFekMsNEVBQTRFO0lBQ3JFLGVBQWUsQ0FBQyxlQUFvQztRQUN6RCxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDaEQsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUVELElBQVcsV0FBVztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsMElBQTBJLENBQUMsQ0FBQztRQUM5SixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0tBQzFCO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsVUFBa0IsRUFBRSxLQUFnQztRQUN6RCxPQUFPLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUMzQixTQUFTLEVBQUUsc0JBQXNCO1lBQ2pDLFVBQVU7WUFDVixhQUFhLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUNwRCxHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUMsUUFBUSxDQUFDLElB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QUFDLENBQUMsU0FBUyxDQUFDLHdCQUF3QixDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUNyRSx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQzVDLENBQUM7WUFFRixRQUFRLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTtnQkFDL0MsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTzthQUNwQyxDQUFDLENBQUM7U0FDSjs7WUFwS1UsdURBQVc7Ozs7O0FBQVgsa0NBQVc7QUF1S3hCLFNBQVMsd0JBQXdCLENBQUMsWUFBb0I7SUFDcEQsT0FBTztRQUNMLE9BQU8sRUFBRSxrQkFBa0I7UUFDM0IsUUFBUSxFQUFFLGFBQWE7UUFDdkIsWUFBWTtLQUNiLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2xvdWR3YXRjaCBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgKiBhcyBlYzIgZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBDZm5BcHBsaWNhdGlvbkNsb3VkV2F0Y2hMb2dnaW5nT3B0aW9uVjIsIENmbkFwcGxpY2F0aW9uVjIgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mta2luZXNpc2FuYWx5dGljcyc7XG5pbXBvcnQgKiBhcyBsb2dzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sb2dzJztcbmltcG9ydCAqIGFzIGNvcmUgZnJvbSAnYXdzLWNkay1saWIvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IEFwcGxpY2F0aW9uQ29kZSB9IGZyb20gJy4vYXBwbGljYXRpb24tY29kZSc7XG5pbXBvcnQgeyBlbnZpcm9ubWVudFByb3BlcnRpZXMgfSBmcm9tICcuL3ByaXZhdGUvZW52aXJvbm1lbnQtcHJvcGVydGllcyc7XG5pbXBvcnQgeyBmbGlua0FwcGxpY2F0aW9uQ29uZmlndXJhdGlvbiB9IGZyb20gJy4vcHJpdmF0ZS9mbGluay1hcHBsaWNhdGlvbi1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7IHZhbGlkYXRlRmxpbmtBcHBsaWNhdGlvblByb3BzIGFzIHZhbGlkYXRlQXBwbGljYXRpb25Qcm9wcyB9IGZyb20gJy4vcHJpdmF0ZS92YWxpZGF0aW9uJztcbmltcG9ydCB7IExvZ0xldmVsLCBNZXRyaWNzTGV2ZWwsIFJ1bnRpbWUgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGFkZENvbnN0cnVjdE1ldGFkYXRhIH0gZnJvbSAnYXdzLWNkay1saWIvY29yZS9saWIvbWV0YWRhdGEtcmVzb3VyY2UnO1xuaW1wb3J0IHsgcHJvcGVydHlJbmplY3RhYmxlIH0gZnJvbSAnYXdzLWNkay1saWIvY29yZS9saWIvcHJvcC1pbmplY3RhYmxlJztcblxuLyoqXG4gKiBBbiBpbnRlcmZhY2UgZXhwcmVzc2luZyB0aGUgcHVibGljIHByb3BlcnRpZXMgb24gYm90aCBhbiBpbXBvcnRlZCBhbmRcbiAqIENESy1jcmVhdGVkIEZsaW5rIGFwcGxpY2F0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElBcHBsaWNhdGlvbiBleHRlbmRzIGNvcmUuSVJlc291cmNlLCBlYzIuSUNvbm5lY3RhYmxlLCBpYW0uSUdyYW50YWJsZSB7XG4gIC8qKlxuICAgKiBUaGUgYXBwbGljYXRpb24gQVJOLlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBhcHBsaWNhdGlvbkFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgRmxpbmsgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGFwcGxpY2F0aW9uTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgYXBwbGljYXRpb24gSUFNIHJvbGUuXG4gICAqL1xuICByZWFkb25seSByb2xlPzogaWFtLklSb2xlO1xuXG4gIC8qKlxuICAgKiBDb252ZW5pZW5jZSBtZXRob2QgZm9yIGFkZGluZyBhIHBvbGljeSBzdGF0ZW1lbnQgdG8gdGhlIGFwcGxpY2F0aW9uIHJvbGUuXG4gICAqL1xuICBhZGRUb1JvbGVQb2xpY3kocG9saWN5U3RhdGVtZW50OiBpYW0uUG9saWN5U3RhdGVtZW50KTogYm9vbGVhbjtcblxuICAvKipcbiAgICogUmV0dXJuIGEgQ2xvdWRXYXRjaCBtZXRyaWMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRmxpbmsgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBtZXRyaWNOYW1lIFRoZSBuYW1lIG9mIHRoZSBtZXRyaWNcbiAgICogQHBhcmFtIHByb3BzIEN1c3RvbWl6YXRpb24gcHJvcGVydGllc1xuICAgKi9cbiAgbWV0cmljKG1ldHJpY05hbWU6IHN0cmluZywgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBLaW5lc2lzIFByb2Nlc3NpbmcgVW5pdHMgdGhhdCBhcmUgdXNlZCB0byBydW4geW91ciBzdHJlYW1cbiAgICogcHJvY2Vzc2luZyBhcHBsaWNhdGlvbi4gVGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIEtQVXMgdXNlZCBlYWNoIGhvdXJcbiAgICogZGV0ZXJtaW5lcyB0aGUgYmlsbGluZyBmb3IgeW91ciBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogVW5pdHM6IENvdW50XG4gICAqXG4gICAqIFJlcG9ydGluZyBMZXZlbDogQXBwbGljYXRpb25cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBtZXRyaWNLcHVzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lIGVsYXBzZWQgZHVyaW5nIGFuIG91dGFnZSBmb3IgZmFpbGluZy9yZWNvdmVyaW5nIGpvYnMuXG4gICAqXG4gICAqIFVuaXRzOiBNaWxsaXNlY29uZHNcbiAgICpcbiAgICogUmVwb3J0aW5nIExldmVsOiBBcHBsaWNhdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY0Rvd250aW1lKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lIHRoYXQgdGhlIGpvYiBoYXMgYmVlbiBydW5uaW5nIHdpdGhvdXQgaW50ZXJydXB0aW9uLlxuICAgKlxuICAgKiBVbml0czogTWlsbGlzZWNvbmRzXG4gICAqXG4gICAqIFJlcG9ydGluZyBMZXZlbDogQXBwbGljYXRpb25cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzYW1wbGUgY291bnQgb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY1VwdGltZShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIHRpbWVzIHRoaXMgam9iIGhhcyBmdWxseSByZXN0YXJ0ZWQgc2luY2UgaXQgd2FzXG4gICAqIHN1Ym1pdHRlZC4gVGhpcyBtZXRyaWMgZG9lcyBub3QgbWVhc3VyZSBmaW5lLWdyYWluZWQgcmVzdGFydHMuXG4gICAqXG4gICAqIFVuaXRzOiBDb3VudFxuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBtZXRyaWNGdWxsUmVzdGFydHMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB0aW1lcyBjaGVja3BvaW50aW5nIGhhcyBmYWlsZWQuXG4gICAqXG4gICAqIFVuaXRzOiBDb3VudFxuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBtZXRyaWNOdW1iZXJPZkZhaWxlZENoZWNrcG9pbnRzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lIGl0IHRvb2sgdG8gY29tcGxldGUgdGhlIGxhc3QgY2hlY2twb2ludC5cbiAgICpcbiAgICogVW5pdHM6IE1pbGxpc2Vjb25kc1xuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbWF4aW11bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgbWV0cmljTGFzdENoZWNrcG9pbnREdXJhdGlvbihwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgdG90YWwgc2l6ZSBvZiB0aGUgbGFzdCBjaGVja3BvaW50LlxuICAgKlxuICAgKiBVbml0czogQnl0ZXNcbiAgICpcbiAgICogUmVwb3J0aW5nIExldmVsOiBBcHBsaWNhdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG1heGltdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY0xhc3RDaGVja3BvaW50U2l6ZShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgb3ZlcmFsbCBwZXJjZW50YWdlIG9mIENQVSB1dGlsaXphdGlvbiBhY3Jvc3MgdGFzayBtYW5hZ2Vycy4gRm9yXG4gICAqIGV4YW1wbGUsIGlmIHRoZXJlIGFyZSBmaXZlIHRhc2sgbWFuYWdlcnMsIEtpbmVzaXMgRGF0YSBBbmFseXRpY3MgcHVibGlzaGVzXG4gICAqIGZpdmUgc2FtcGxlcyBvZiB0aGlzIG1ldHJpYyBwZXIgcmVwb3J0aW5nIGludGVydmFsLlxuICAgKlxuICAgKiBVbml0czogUGVyY2VudGFnZVxuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYXZlcmFnZSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgbWV0cmljQ3B1VXRpbGl6YXRpb24ocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogT3ZlcmFsbCBoZWFwIG1lbW9yeSB1dGlsaXphdGlvbiBhY3Jvc3MgdGFzayBtYW5hZ2Vycy4gRm9yIGV4YW1wbGUsIGlmIHRoZXJlXG4gICAqIGFyZSBmaXZlIHRhc2sgbWFuYWdlcnMsIEtpbmVzaXMgRGF0YSBBbmFseXRpY3MgcHVibGlzaGVzIGZpdmUgc2FtcGxlcyBvZlxuICAgKiB0aGlzIG1ldHJpYyBwZXIgcmVwb3J0aW5nIGludGVydmFsLlxuICAgKlxuICAgKiBVbml0czogUGVyY2VudGFnZVxuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYXZlcmFnZSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgbWV0cmljSGVhcE1lbW9yeVV0aWxpemF0aW9uKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCB0aW1lIHNwZW50IHBlcmZvcm1pbmcgb2xkIGdhcmJhZ2UgY29sbGVjdGlvbiBvcGVyYXRpb25zLlxuICAgKlxuICAgKiBVbml0czogTWlsbGlzZWNvbmRzXG4gICAqXG4gICAqIFJlcG9ydGluZyBMZXZlbDogQXBwbGljYXRpb25cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY09sZEdlbmVyYXRpb25HQ1RpbWUocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIHRvdGFsIG51bWJlciBvZiBvbGQgZ2FyYmFnZSBjb2xsZWN0aW9uIG9wZXJhdGlvbnMgdGhhdCBoYXZlIG9jY3VycmVkXG4gICAqIGFjcm9zcyBhbGwgdGFzayBtYW5hZ2Vycy5cbiAgICpcbiAgICogVW5pdHM6IENvdW50XG4gICAqXG4gICAqIFJlcG9ydGluZyBMZXZlbDogQXBwbGljYXRpb25cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY09sZEdlbmVyYXRpb25HQ0NvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBudW1iZXIgb2YgbGl2ZSB0aHJlYWRzIHVzZWQgYnkgdGhlIGFwcGxpY2F0aW9uLlxuICAgKlxuICAgKiBVbml0czogQ291bnRcbiAgICpcbiAgICogUmVwb3J0aW5nIExldmVsOiBBcHBsaWNhdGlvblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY1RocmVhZHNDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIHJlY29yZHMgdGhpcyBhcHBsaWNhdGlvbiwgb3BlcmF0b3IsIG9yIHRhc2sgaGFzXG4gICAqIHJlY2VpdmVkLlxuICAgKlxuICAgKiBVbml0czogQ291bnRcbiAgICpcbiAgICogUmVwb3J0aW5nIExldmVsOiBBcHBsaWNhdGlvbiwgT3BlcmF0b3IsIFRhc2ssIFBhcmFsbGVsaXNtXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYXZlcmFnZSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgbWV0cmljTnVtUmVjb3Jkc0luKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBudW1iZXIgb2YgcmVjb3JkcyB0aGlzIGFwcGxpY2F0aW9uLCBvcGVyYXRvciBvciB0YXNrIGhhc1xuICAgKiByZWNlaXZlZCBwZXIgc2Vjb25kLlxuICAgKlxuICAgKiBVbml0czogQ291bnQvU2Vjb25kXG4gICAqXG4gICAqIFJlcG9ydGluZyBMZXZlbDogQXBwbGljYXRpb24sIE9wZXJhdG9yLCBUYXNrLCBQYXJhbGxlbGlzbVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY051bVJlY29yZHNJblBlclNlY29uZChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIHJlY29yZHMgdGhpcyBhcHBsaWNhdGlvbiwgb3BlcmF0b3Igb3IgdGFzayBoYXMgZW1pdHRlZC5cbiAgICpcbiAgICogVW5pdHM6IENvdW50XG4gICAqXG4gICAqIFJlcG9ydGluZyBMZXZlbDogQXBwbGljYXRpb24sIE9wZXJhdG9yLCBUYXNrLCBQYXJhbGxlbGlzbVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY051bVJlY29yZHNPdXQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIHRvdGFsIG51bWJlciBvZiByZWNvcmRzIHRoaXMgYXBwbGljYXRpb24sIG9wZXJhdG9yIG9yIHRhc2sgaGFzIGVtaXR0ZWRcbiAgICogcGVyIHNlY29uZC5cbiAgICpcbiAgICogVW5pdHM6IENvdW50L1NlY29uZFxuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uLCBPcGVyYXRvciwgVGFzaywgUGFyYWxsZWxpc21cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBtZXRyaWNOdW1SZWNvcmRzT3V0UGVyU2Vjb25kKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcmVjb3JkcyB0aGlzIG9wZXJhdG9yIG9yIHRhc2sgaGFzIGRyb3BwZWQgZHVlIHRvIGFycml2aW5nIGxhdGUuXG4gICAqXG4gICAqIFVuaXRzOiBDb3VudFxuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uLCBPcGVyYXRvciwgVGFzaywgUGFyYWxsZWxpc21cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG1ldHJpY051bUxhdGVSZWNvcmRzRHJvcHBlZChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgbGFzdCB3YXRlcm1hcmsgdGhpcyBhcHBsaWNhdGlvbi9vcGVyYXRvci90YXNrL3RocmVhZCBoYXMgcmVjZWl2ZWQuXG4gICAqXG4gICAqIFVuaXRzOiBNaWxsaXNlY29uZHNcbiAgICpcbiAgICogUmVwb3J0aW5nIExldmVsOiBBcHBsaWNhdGlvbiwgT3BlcmF0b3IsIFRhc2ssIFBhcmFsbGVsaXNtXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbWF4aW11bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgbWV0cmljQ3VycmVudElucHV0V2F0ZXJtYXJrKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBsYXN0IHdhdGVybWFyayB0aGlzIGFwcGxpY2F0aW9uL29wZXJhdG9yL3Rhc2svdGhyZWFkIGhhcyByZWNlaXZlZC5cbiAgICpcbiAgICogVW5pdHM6IE1pbGxpc2Vjb25kc1xuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uLCBPcGVyYXRvciwgVGFzaywgUGFyYWxsZWxpc21cbiAgICpcbiAgICogQGRlZmF1bHQgLSBtYXhpbXVtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBtZXRyaWNDdXJyZW50T3V0cHV0V2F0ZXJtYXJrKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBhbW91bnQgb2YgbWFuYWdlZCBtZW1vcnkgY3VycmVudGx5IHVzZWQuXG4gICAqXG4gICAqIFVuaXRzOiBCeXRlc1xuICAgKlxuICAgKiBSZXBvcnRpbmcgTGV2ZWw6IEFwcGxpY2F0aW9uLCBPcGVyYXRvciwgVGFzaywgUGFyYWxsZWxpc21cbiAgICpcbiAgICo