@aws-cdk/aws-eks-v2-alpha
Version:
The CDK Construct Library for AWS::EKS
410 lines • 65.8 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nodegroup = exports.TaintEffect = exports.CapacityType = exports.NodegroupAmiType = void 0;
const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const constructs_1 = require("constructs");
const cluster_1 = require("./cluster");
const aws_eks_1 = require("aws-cdk-lib/aws-eks");
const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const core_1 = require("aws-cdk-lib/core");
const cxapi = require("aws-cdk-lib/cx-api");
const nodegroup_1 = require("./private/nodegroup");
const metadata_resource_1 = require("aws-cdk-lib/core/lib/metadata-resource");
const prop_injectable_1 = require("aws-cdk-lib/core/lib/prop-injectable");
/**
* The AMI type for your node group.
*
* GPU instance types should use the `AL2_x86_64_GPU` AMI type, which uses the
* Amazon EKS-optimized Linux AMI with GPU support or the `BOTTLEROCKET_ARM_64_NVIDIA` or `BOTTLEROCKET_X86_64_NVIDIA`
* AMI types, which uses the Amazon EKS-optimized Linux AMI with Nvidia-GPU support.
*
* Non-GPU instances should use the `AL2_x86_64` AMI type, which uses the Amazon EKS-optimized Linux AMI.
*/
var NodegroupAmiType;
(function (NodegroupAmiType) {
/**
* Amazon Linux 2 (x86-64)
*/
NodegroupAmiType["AL2_X86_64"] = "AL2_x86_64";
/**
* Amazon Linux 2 with GPU support
*/
NodegroupAmiType["AL2_X86_64_GPU"] = "AL2_x86_64_GPU";
/**
* Amazon Linux 2 (ARM-64)
*/
NodegroupAmiType["AL2_ARM_64"] = "AL2_ARM_64";
/**
* Bottlerocket Linux (ARM-64)
*/
NodegroupAmiType["BOTTLEROCKET_ARM_64"] = "BOTTLEROCKET_ARM_64";
/**
* Bottlerocket (x86-64)
*/
NodegroupAmiType["BOTTLEROCKET_X86_64"] = "BOTTLEROCKET_x86_64";
/**
* Bottlerocket Linux with Nvidia-GPU support (ARM-64)
*/
NodegroupAmiType["BOTTLEROCKET_ARM_64_NVIDIA"] = "BOTTLEROCKET_ARM_64_NVIDIA";
/**
* Bottlerocket with Nvidia-GPU support (x86-64)
*/
NodegroupAmiType["BOTTLEROCKET_X86_64_NVIDIA"] = "BOTTLEROCKET_x86_64_NVIDIA";
/**
* Bottlerocket Linux (ARM-64) with FIPS enabled
*/
NodegroupAmiType["BOTTLEROCKET_ARM_64_FIPS"] = "BOTTLEROCKET_ARM_64_FIPS";
/**
* Bottlerocket (x86-64) with FIPS enabled
*/
NodegroupAmiType["BOTTLEROCKET_X86_64_FIPS"] = "BOTTLEROCKET_x86_64_FIPS";
/**
* Windows Core 2019 (x86-64)
*/
NodegroupAmiType["WINDOWS_CORE_2019_X86_64"] = "WINDOWS_CORE_2019_x86_64";
/**
* Windows Core 2022 (x86-64)
*/
NodegroupAmiType["WINDOWS_CORE_2022_X86_64"] = "WINDOWS_CORE_2022_x86_64";
/**
* Windows Full 2019 (x86-64)
*/
NodegroupAmiType["WINDOWS_FULL_2019_X86_64"] = "WINDOWS_FULL_2019_x86_64";
/**
* Windows Full 2022 (x86-64)
*/
NodegroupAmiType["WINDOWS_FULL_2022_X86_64"] = "WINDOWS_FULL_2022_x86_64";
/**
* Amazon Linux 2023 (x86-64)
*/
NodegroupAmiType["AL2023_X86_64_STANDARD"] = "AL2023_x86_64_STANDARD";
/**
* Amazon Linux 2023 with AWS Neuron drivers (x86-64)
*/
NodegroupAmiType["AL2023_X86_64_NEURON"] = "AL2023_x86_64_NEURON";
/**
* Amazon Linux 2023 with NVIDIA drivers (x86-64)
*/
NodegroupAmiType["AL2023_X86_64_NVIDIA"] = "AL2023_x86_64_NVIDIA";
/**
* Amazon Linux 2023 (ARM-64)
*/
NodegroupAmiType["AL2023_ARM_64_STANDARD"] = "AL2023_ARM_64_STANDARD";
})(NodegroupAmiType || (exports.NodegroupAmiType = NodegroupAmiType = {}));
/**
* Capacity type of the managed node group
*/
var CapacityType;
(function (CapacityType) {
/**
* spot instances
*/
CapacityType["SPOT"] = "SPOT";
/**
* on-demand instances
*/
CapacityType["ON_DEMAND"] = "ON_DEMAND";
/**
* capacity block instances
*/
CapacityType["CAPACITY_BLOCK"] = "CAPACITY_BLOCK";
})(CapacityType || (exports.CapacityType = CapacityType = {}));
/**
* Effect types of kubernetes node taint.
*/
var TaintEffect;
(function (TaintEffect) {
/**
* NoSchedule
*/
TaintEffect["NO_SCHEDULE"] = "NO_SCHEDULE";
/**
* PreferNoSchedule
*/
TaintEffect["PREFER_NO_SCHEDULE"] = "PREFER_NO_SCHEDULE";
/**
* NoExecute
*/
TaintEffect["NO_EXECUTE"] = "NO_EXECUTE";
})(TaintEffect || (exports.TaintEffect = TaintEffect = {}));
/**
* The Nodegroup resource class
* @resource AWS::EKS::Nodegroup
*/
let Nodegroup = class Nodegroup extends core_1.Resource {
/**
* Import the Nodegroup from attributes
*/
static fromNodegroupName(scope, id, nodegroupName) {
class Import extends core_1.Resource {
constructor() {
super(...arguments);
this.nodegroupName = nodegroupName;
}
}
return new Import(scope, id);
}
constructor(scope, id, props) {
super(scope, id, {
physicalName: props.nodegroupName,
});
try {
jsiiDeprecationWarnings._aws_cdk_aws_eks_v2_alpha_NodegroupProps(props);
}
catch (error) {
if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
Error.captureStackTrace(error, Nodegroup);
}
throw error;
}
// Enhanced CDK Analytics Telemetry
(0, metadata_resource_1.addConstructMetadata)(this, props);
this.cluster = props.cluster;
this.desiredSize = props.desiredSize ?? props.minSize ?? 2;
this.maxSize = props.maxSize ?? this.desiredSize;
this.minSize = props.minSize ?? 1;
(0, core_1.withResolved)(this.desiredSize, this.maxSize, (desired, max) => {
if (desired === undefined) {
return;
}
if (desired > max) {
throw new Error(`Desired capacity ${desired} can't be greater than max size ${max}`);
}
});
(0, core_1.withResolved)(this.desiredSize, this.minSize, (desired, min) => {
if (desired === undefined) {
return;
}
if (desired < min) {
throw new Error(`Minimum capacity ${min} can't be greater than desired size ${desired}`);
}
});
if (props.launchTemplateSpec && props.diskSize) {
// see - https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html
// and https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-disksize
throw new Error('diskSize must be specified within the launch template');
}
if (props.instanceType && props.instanceTypes) {
throw new Error('"instanceType is deprecated, please use "instanceTypes" only.');
}
if (props.instanceType) {
core_1.Annotations.of(this).addWarningV2('@aws-cdk/aws-eks:managedNodeGroupDeprecatedInstanceType', '"instanceType" is deprecated and will be removed in the next major version. please use "instanceTypes" instead');
}
const instanceTypes = props.instanceTypes ?? (props.instanceType ? [props.instanceType] : undefined);
let possibleAmiTypes = [];
if (instanceTypes && instanceTypes.length > 0) {
/**
* if the user explicitly configured instance types, we can't caculate the expected ami type as we support
* Amazon Linux 2, Bottlerocket, and Windows now. However we can check:
*
* 1. instance types of different CPU architectures are not mixed(e.g. X86 with ARM).
* 2. user-specified amiType should be included in `possibleAmiTypes`.
*/
possibleAmiTypes = getPossibleAmiTypes(instanceTypes);
// if the user explicitly configured an ami type, make sure it's included in the possibleAmiTypes
if (props.amiType && !possibleAmiTypes.includes(props.amiType)) {
throw new Error(`The specified AMI does not match the instance types architecture, either specify one of ${possibleAmiTypes.join(', ').toUpperCase()} or don't specify any`);
}
// if the user explicitly configured a Windows ami type, make sure the instanceType is allowed
if (props.amiType && windowsAmiTypes.includes(props.amiType) &&
instanceTypes.filter(isWindowsSupportedInstanceType).length < instanceTypes.length) {
throw new Error('The specified instanceType does not support Windows workloads. '
+ 'Amazon EC2 instance types C3, C4, D2, I2, M4 (excluding m4.16xlarge), M6a.x, and '
+ 'R3 instances aren\'t supported for Windows workloads.');
}
}
if (!props.nodeRole) {
const ngRole = new aws_iam_1.Role(this, 'NodeGroupRole', {
assumedBy: new aws_iam_1.ServicePrincipal('ec2.amazonaws.com'),
});
ngRole.addManagedPolicy(aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName('AmazonEKSWorkerNodePolicy'));
ngRole.addManagedPolicy(aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName('AmazonEKS_CNI_Policy'));
ngRole.addManagedPolicy(aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName('AmazonEC2ContainerRegistryReadOnly'));
// Grant additional IPv6 networking permissions if running in IPv6
// https://docs.aws.amazon.com/eks/latest/userguide/cni-iam-role.html
if (props.cluster.ipFamily == cluster_1.IpFamily.IP_V6) {
ngRole.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
// eslint-disable-next-line @cdklabs/no-literal-partition
resources: ['arn:aws:ec2:*:*:network-interface/*'],
actions: [
'ec2:AssignIpv6Addresses',
'ec2:UnassignIpv6Addresses',
],
}));
}
this.role = ngRole;
}
else {
this.role = props.nodeRole;
}
this.validateUpdateConfig(props.maxUnavailable, props.maxUnavailablePercentage);
const resource = new aws_eks_1.CfnNodegroup(this, 'Resource', {
clusterName: this.cluster.clusterName,
nodegroupName: props.nodegroupName,
nodeRole: this.role.roleArn,
subnets: this.cluster.vpc.selectSubnets(props.subnets).subnetIds,
/**
* Case 1: If launchTemplate is explicitly specified with custom AMI, we cannot specify amiType, or the node group deployment will fail.
* As we don't know if the custom AMI is specified in the lauchTemplate, we just use props.amiType.
*
* Case 2: If launchTemplate is not specified, we try to determine amiType from the instanceTypes and it could be either AL2 or Bottlerocket.
* To avoid breaking changes, we use possibleAmiTypes[0] if amiType is undefined and make sure AL2 is always the first element in possibleAmiTypes
* as AL2 is previously the `expectedAmi` and this avoids breaking changes.
*
* That being said, users now either have to explicitly specify correct amiType or just leave it undefined.
*/
amiType: props.launchTemplateSpec ? props.amiType : (props.amiType ?? possibleAmiTypes[0]),
capacityType: props.capacityType ? props.capacityType.valueOf() : undefined,
diskSize: props.diskSize,
forceUpdateEnabled: props.forceUpdate ?? true,
// note that we don't check if a launch template is configured here (even though it might configure instance types as well)
// because this doesn't have a default value, meaning the user had to explicitly configure this.
instanceTypes: instanceTypes?.map(t => t.toString()),
labels: props.labels,
taints: props.taints,
launchTemplate: props.launchTemplateSpec,
releaseVersion: props.releaseVersion,
remoteAccess: props.remoteAccess ? {
ec2SshKey: props.remoteAccess.sshKeyName,
sourceSecurityGroups: props.remoteAccess.sourceSecurityGroups ?
props.remoteAccess.sourceSecurityGroups.map(m => m.securityGroupId) : undefined,
} : undefined,
scalingConfig: {
desiredSize: this.desiredSize,
maxSize: this.maxSize,
minSize: this.minSize,
},
tags: props.tags,
updateConfig: props.maxUnavailable || props.maxUnavailablePercentage ? {
maxUnavailable: props.maxUnavailable,
maxUnavailablePercentage: props.maxUnavailablePercentage,
} : undefined,
nodeRepairConfig: props.enableNodeAutoRepair ? {
enabled: props.enableNodeAutoRepair,
} : undefined,
});
if (this.cluster instanceof cluster_1.Cluster) {
// the controller runs on the worker nodes so they cannot
// be deleted before the controller.
if (this.cluster.albController) {
constructs_1.Node.of(this.cluster.albController).addDependency(this);
}
}
this.nodegroupArn = this.getResourceArnAttribute(resource.attrArn, {
service: 'eks',
resource: 'nodegroup',
resourceName: this.physicalName,
});
if (core_1.FeatureFlags.of(this).isEnabled(cxapi.EKS_NODEGROUP_NAME)) {
this.nodegroupName = this.getResourceNameAttribute(resource.attrNodegroupName);
}
else {
this.nodegroupName = this.getResourceNameAttribute(resource.ref);
}
}
validateUpdateConfig(maxUnavailable, maxUnavailablePercentage) {
if (!maxUnavailable && !maxUnavailablePercentage)
return;
if (maxUnavailable && maxUnavailablePercentage) {
throw new Error('maxUnavailable and maxUnavailablePercentage are not allowed to be defined together');
}
if (maxUnavailablePercentage && (maxUnavailablePercentage < 1 || maxUnavailablePercentage > 100)) {
throw new Error(`maxUnavailablePercentage must be between 1 and 100, got ${maxUnavailablePercentage}`);
}
if (maxUnavailable) {
if (maxUnavailable > this.maxSize) {
throw new Error(`maxUnavailable must be lower than maxSize (${this.maxSize}), got ${maxUnavailable}`);
}
if (maxUnavailable < 1 || maxUnavailable > 100) {
throw new Error(`maxUnavailable must be between 1 and 100, got ${maxUnavailable}`);
}
}
}
};
exports.Nodegroup = Nodegroup;
_a = JSII_RTTI_SYMBOL_1;
Nodegroup[_a] = { fqn: "@aws-cdk/aws-eks-v2-alpha.Nodegroup", version: "2.208.0-alpha.0" };
/** Uniquely identifies this class. */
Nodegroup.PROPERTY_INJECTION_ID = '@aws-cdk.aws-eks-v2-alpha.Nodegroup';
exports.Nodegroup = Nodegroup = __decorate([
prop_injectable_1.propertyInjectable
], Nodegroup);
/**
* AMI types of different architectures. Make sure AL2 is always the first element, which will be the default
* AmiType if amiType and launchTemplateSpec are both undefined.
*/
const arm64AmiTypes = [
NodegroupAmiType.AL2_ARM_64,
NodegroupAmiType.AL2023_ARM_64_STANDARD,
NodegroupAmiType.BOTTLEROCKET_ARM_64,
];
const x8664AmiTypes = [
NodegroupAmiType.AL2_X86_64,
NodegroupAmiType.AL2023_X86_64_STANDARD,
NodegroupAmiType.BOTTLEROCKET_X86_64,
NodegroupAmiType.WINDOWS_CORE_2019_X86_64,
NodegroupAmiType.WINDOWS_CORE_2022_X86_64,
NodegroupAmiType.WINDOWS_FULL_2019_X86_64,
NodegroupAmiType.WINDOWS_FULL_2022_X86_64,
];
const windowsAmiTypes = [
NodegroupAmiType.WINDOWS_CORE_2019_X86_64,
NodegroupAmiType.WINDOWS_CORE_2022_X86_64,
NodegroupAmiType.WINDOWS_FULL_2019_X86_64,
NodegroupAmiType.WINDOWS_FULL_2022_X86_64,
];
const gpuAmiTypes = [
NodegroupAmiType.AL2_X86_64_GPU,
NodegroupAmiType.AL2023_X86_64_NEURON,
NodegroupAmiType.AL2023_X86_64_NVIDIA,
NodegroupAmiType.BOTTLEROCKET_X86_64_NVIDIA,
NodegroupAmiType.BOTTLEROCKET_ARM_64_NVIDIA,
];
/**
* This function check if the instanceType is supported by Windows AMI.
* https://docs.aws.amazon.com/eks/latest/userguide/windows-support.html
* @param instanceType The EC2 instance type
*/
function isWindowsSupportedInstanceType(instanceType) {
// compare instanceType to forbidden InstanceTypes for Windows. Add exception for m6a.16xlarge.
// NOTE: i2 instance class is not present in the InstanceClass enum.
const forbiddenInstanceClasses = [aws_ec2_1.InstanceClass.C3, aws_ec2_1.InstanceClass.C4, aws_ec2_1.InstanceClass.D2, aws_ec2_1.InstanceClass.M4,
aws_ec2_1.InstanceClass.M6A, aws_ec2_1.InstanceClass.R3];
return instanceType.toString() === aws_ec2_1.InstanceType.of(aws_ec2_1.InstanceClass.M4, aws_ec2_1.InstanceSize.XLARGE16).toString() ||
forbiddenInstanceClasses.every((c) => !instanceType.sameInstanceClassAs(aws_ec2_1.InstanceType.of(c, aws_ec2_1.InstanceSize.LARGE)) && !instanceType.toString().match(/^i2/));
}
/**
* This function examines the CPU architecture of every instance type and determines
* what AMI types are compatible for all of them. it either throws or produces an array of possible AMI types because
* instance types of different CPU architectures are not supported.
* @param instanceTypes The instance types
* @returns NodegroupAmiType[]
*/
function getPossibleAmiTypes(instanceTypes) {
function typeToArch(instanceType) {
return (0, nodegroup_1.isGpuInstanceType)(instanceType) ? 'GPU' : instanceType.architecture;
}
const archAmiMap = new Map([
[aws_ec2_1.InstanceArchitecture.ARM_64, arm64AmiTypes],
[aws_ec2_1.InstanceArchitecture.X86_64, x8664AmiTypes],
['GPU', gpuAmiTypes],
]);
const architectures = new Set(instanceTypes.map(typeToArch));
if (architectures.size === 0) { // protective code, the current implementation will never result in this.
throw new Error(`Cannot determine any ami type compatible with instance types: ${instanceTypes.map(i => i.toString()).join(', ')}`);
}
if (architectures.size > 1) {
throw new Error('instanceTypes of different architectures is not allowed');
}
return archAmiMap.get(Array.from(architectures)[0]);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlZC1ub2RlZ3JvdXAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYW5hZ2VkLW5vZGVncm91cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkM7QUFDN0MsdUNBQXdEO0FBQ3hELGlEQUFtRDtBQUNuRCxpREFBdUk7QUFDdkksaURBQW9HO0FBQ3BHLDJDQUFnRztBQUNoRyw0Q0FBNEM7QUFDNUMsbURBQXdEO0FBQ3hELDhFQUE4RTtBQUM5RSwwRUFBMEU7QUFhMUU7Ozs7Ozs7O0dBUUc7QUFDSCxJQUFZLGdCQXFFWDtBQXJFRCxXQUFZLGdCQUFnQjtJQUMxQjs7T0FFRztJQUNILDZDQUF5QixDQUFBO0lBQ3pCOztPQUVHO0lBQ0gscURBQWlDLENBQUE7SUFDakM7O09BRUc7SUFDSCw2Q0FBeUIsQ0FBQTtJQUN6Qjs7T0FFRztJQUNILCtEQUEyQyxDQUFBO0lBQzNDOztPQUVHO0lBQ0gsK0RBQTJDLENBQUE7SUFDM0M7O09BRUc7SUFDSCw2RUFBeUQsQ0FBQTtJQUN6RDs7T0FFRztJQUNILDZFQUF5RCxDQUFBO0lBQ3pEOztPQUVHO0lBQ0gseUVBQXFELENBQUE7SUFDckQ7O09BRUc7SUFDSCx5RUFBcUQsQ0FBQTtJQUNyRDs7T0FFRztJQUNILHlFQUFxRCxDQUFBO0lBQ3JEOztPQUVHO0lBQ0gseUVBQXFELENBQUE7SUFDckQ7O09BRUc7SUFDSCx5RUFBcUQsQ0FBQTtJQUNyRDs7T0FFRztJQUNILHlFQUFxRCxDQUFBO0lBQ3JEOztPQUVHO0lBQ0gscUVBQWlELENBQUE7SUFDakQ7O09BRUc7SUFDSCxpRUFBNkMsQ0FBQTtJQUM3Qzs7T0FFRztJQUNILGlFQUE2QyxDQUFBO0lBQzdDOztPQUVHO0lBQ0gscUVBQWlELENBQUE7QUFDbkQsQ0FBQyxFQXJFVyxnQkFBZ0IsZ0NBQWhCLGdCQUFnQixRQXFFM0I7QUFFRDs7R0FFRztBQUNILElBQVksWUFhWDtBQWJELFdBQVksWUFBWTtJQUN0Qjs7T0FF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QUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN0SSxDQUFDO0lBRUQsSUFBSSxhQUFhLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsT0FBTyxVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUUsQ0FBQztBQUN2RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29uc3RydWN0LCBOb2RlIH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBDbHVzdGVyLCBJQ2x1c3RlciwgSXBGYW1pbHkgfSBmcm9tICcuL2NsdXN0ZXInO1xuaW1wb3J0IHsgQ2ZuTm9kZWdyb3VwIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVrcyc7XG5pbXBvcnQgeyBJbnN0YW5jZVR5cGUsIElTZWN1cml0eUdyb3VwLCBTdWJuZXRTZWxlY3Rpb24sIEluc3RhbmNlQXJjaGl0ZWN0dXJlLCBJbnN0YW5jZUNsYXNzLCBJbnN0YW5jZVNpemUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtZWMyJztcbmltcG9ydCB7IElSb2xlLCBNYW5hZ2VkUG9saWN5LCBQb2xpY3lTdGF0ZW1lbnQsIFJvbGUsIFNlcnZpY2VQcmluY2lwYWwgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IElSZXNvdXJjZSwgUmVzb3VyY2UsIEFubm90YXRpb25zLCB3aXRoUmVzb2x2ZWQsIEZlYXR1cmVGbGFncyB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUnO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnYXdzLWNkay1saWIvY3gtYXBpJztcbmltcG9ydCB7IGlzR3B1SW5zdGFuY2VUeXBlIH0gZnJvbSAnLi9wcml2YXRlL25vZGVncm91cCc7XG5pbXBvcnQgeyBhZGRDb25zdHJ1Y3RNZXRhZGF0YSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL21ldGFkYXRhLXJlc291cmNlJztcbmltcG9ydCB7IHByb3BlcnR5SW5qZWN0YWJsZSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL3Byb3AtaW5qZWN0YWJsZSc7XG5cbi8qKlxuICogTm9kZUdyb3VwIGludGVyZmFjZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIElOb2RlZ3JvdXAgZXh0ZW5kcyBJUmVzb3VyY2Uge1xuICAvKipcbiAgICogTmFtZSBvZiB0aGUgbm9kZWdyb3VwXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IG5vZGVncm91cE5hbWU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgQU1JIHR5cGUgZm9yIHlvdXIgbm9kZSBncm91cC5cbiAqXG4gKiBHUFUgaW5zdGFuY2UgdHlwZXMgc2hvdWxkIHVzZSB0aGUgYEFMMl94ODZfNjRfR1BVYCBBTUkgdHlwZSwgd2hpY2ggdXNlcyB0aGVcbiAqIEFtYXpvbiBFS1Mtb3B0aW1pemVkIExpbnV4IEFNSSB3aXRoIEdQVSBzdXBwb3J0IG9yIHRoZSBgQk9UVExFUk9DS0VUX0FSTV82NF9OVklESUFgIG9yIGBCT1RUTEVST0NLRVRfWDg2XzY0X05WSURJQWBcbiAqIEFNSSB0eXBlcywgd2hpY2ggdXNlcyB0aGUgQW1hem9uIEVLUy1vcHRpbWl6ZWQgTGludXggQU1JIHdpdGggTnZpZGlhLUdQVSBzdXBwb3J0LlxuICpcbiAqIE5vbi1HUFUgaW5zdGFuY2VzIHNob3VsZCB1c2UgdGhlIGBBTDJfeDg2XzY0YCBBTUkgdHlwZSwgd2hpY2ggdXNlcyB0aGUgQW1hem9uIEVLUy1vcHRpbWl6ZWQgTGludXggQU1JLlxuICovXG5leHBvcnQgZW51bSBOb2RlZ3JvdXBBbWlUeXBlIHtcbiAgLyoqXG4gICAqIEFtYXpvbiBMaW51eCAyICh4ODYtNjQpXG4gICAqL1xuICBBTDJfWDg2XzY0ID0gJ0FMMl94ODZfNjQnLFxuICAvKipcbiAgICogQW1hem9uIExpbnV4IDIgd2l0aCBHUFUgc3VwcG9ydFxuICAgKi9cbiAgQUwyX1g4Nl82NF9HUFUgPSAnQUwyX3g4Nl82NF9HUFUnLFxuICAvKipcbiAgICogQW1hem9uIExpbnV4IDIgKEFSTS02NClcbiAgICovXG4gIEFMMl9BUk1fNjQgPSAnQUwyX0FSTV82NCcsXG4gIC8qKlxuICAgKiAgQm90dGxlcm9ja2V0IExpbnV4IChBUk0tNjQpXG4gICAqL1xuICBCT1RUTEVST0NLRVRfQVJNXzY0ID0gJ0JPVFRMRVJPQ0tFVF9BUk1fNjQnLFxuICAvKipcbiAgICogQm90dGxlcm9ja2V0ICh4ODYtNjQpXG4gICAqL1xuICBCT1RUTEVST0NLRVRfWDg2XzY0ID0gJ0JPVFRMRVJPQ0tFVF94ODZfNjQnLFxuICAvKipcbiAgICogIEJvdHRsZXJvY2tldCBMaW51eCB3aXRoIE52aWRpYS1HUFUgc3VwcG9ydCAoQVJNLTY0KVxuICAgKi9cbiAgQk9UVExFUk9DS0VUX0FSTV82NF9OVklESUEgPSAnQk9UVExFUk9DS0VUX0FSTV82NF9OVklESUEnLFxuICAvKipcbiAgICogQm90dGxlcm9ja2V0IHdpdGggTnZpZGlhLUdQVSBzdXBwb3J0ICh4ODYtNjQpXG4gICAqL1xuICBCT1RUTEVST0NLRVRfWDg2XzY0X05WSURJQSA9ICdCT1RUTEVST0NLRVRfeDg2XzY0X05WSURJQScsXG4gIC8qKlxuICAgKiBCb3R0bGVyb2NrZXQgTGludXggKEFSTS02NCkgd2l0aCBGSVBTIGVuYWJsZWRcbiAgICovXG4gIEJPVFRMRVJPQ0tFVF9BUk1fNjRfRklQUyA9ICdCT1RUTEVST0NLRVRfQVJNXzY0X0ZJUFMnLFxuICAvKipcbiAgICogQm90dGxlcm9ja2V0ICh4ODYtNjQpIHdpdGggRklQUyBlbmFibGVkXG4gICAqL1xuICBCT1RUTEVST0NLRVRfWDg2XzY0X0ZJUFMgPSAnQk9UVExFUk9DS0VUX3g4Nl82NF9GSVBTJyxcbiAgLyoqXG4gICAqIFdpbmRvd3MgQ29yZSAyMDE5ICh4ODYtNjQpXG4gICAqL1xuICBXSU5ET1dTX0NPUkVfMjAxOV9YODZfNjQgPSAnV0lORE9XU19DT1JFXzIwMTlfeDg2XzY0JyxcbiAgLyoqXG4gICAqIFdpbmRvd3MgQ29yZSAyMDIyICh4ODYtNjQpXG4gICAqL1xuICBXSU5ET1dTX0NPUkVfMjAyMl9YODZfNjQgPSAnV0lORE9XU19DT1JFXzIwMjJfeDg2XzY0JyxcbiAgLyoqXG4gICAqIFdpbmRvd3MgRnVsbCAyMDE5ICh4ODYtNjQpXG4gICAqL1xuICBXSU5ET1dTX0ZVTExfMjAxOV9YODZfNjQgPSAnV0lORE9XU19GVUxMXzIwMTlfeDg2XzY0JyxcbiAgLyoqXG4gICAqIFdpbmRvd3MgRnVsbCAyMDIyICh4ODYtNjQpXG4gICAqL1xuICBXSU5ET1dTX0ZVTExfMjAyMl9YODZfNjQgPSAnV0lORE9XU19GVUxMXzIwMjJfeDg2XzY0JyxcbiAgLyoqXG4gICAqIEFtYXpvbiBMaW51eCAyMDIzICh4ODYtNjQpXG4gICAqL1xuICBBTDIwMjNfWDg2XzY0X1NUQU5EQVJEID0gJ0FMMjAyM194ODZfNjRfU1RBTkRBUkQnLFxuICAvKipcbiAgICogQW1hem9uIExpbnV4IDIwMjMgd2l0aCBBV1MgTmV1cm9uIGRyaXZlcnMgKHg4Ni02NClcbiAgICovXG4gIEFMMjAyM19YODZfNjRfTkVVUk9OID0gJ0FMMjAyM194ODZfNjRfTkVVUk9OJyxcbiAgLyoqXG4gICAqIEFtYXpvbiBMaW51eCAyMDIzIHdpdGggTlZJRElBIGRyaXZlcnMgKHg4Ni02NClcbiAgICovXG4gIEFMMjAyM19YODZfNjRfTlZJRElBID0gJ0FMMjAyM194ODZfNjRfTlZJRElBJyxcbiAgLyoqXG4gICAqIEFtYXpvbiBMaW51eCAyMDIzIChBUk0tNjQpXG4gICAqL1xuICBBTDIwMjNfQVJNXzY0X1NUQU5EQVJEID0gJ0FMMjAyM19BUk1fNjRfU1RBTkRBUkQnLFxufVxuXG4vKipcbiAqIENhcGFjaXR5IHR5cGUgb2YgdGhlIG1hbmFnZWQgbm9kZSBncm91cFxuICovXG5leHBvcnQgZW51bSBDYXBhY2l0eVR5cGUge1xuICAvKipcbiAgICogc3BvdCBpbnN0YW5jZXNcbiAgICovXG4gIFNQT1QgPSAnU1BPVCcsXG4gIC8qKlxuICAgKiBvbi1kZW1hbmQgaW5zdGFuY2VzXG4gICAqL1xuICBPTl9ERU1BTkQgPSAnT05fREVNQU5EJyxcbiAgLyoqXG4gICAqIGNhcGFjaXR5IGJsb2NrIGluc3RhbmNlc1xuICAgKi9cbiAgQ0FQQUNJVFlfQkxPQ0sgPSAnQ0FQQUNJVFlfQkxPQ0snLFxufVxuXG4vKipcbiAqIFRoZSByZW1vdGUgYWNjZXNzIChTU0gpIGNvbmZpZ3VyYXRpb24gdG8gdXNlIHdpdGggeW91ciBub2RlIGdyb3VwLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWtzLW5vZGVncm91cC1yZW1vdGVhY2Nlc3MuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5vZGVncm91cFJlbW90ZUFjY2VzcyB7XG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIEVDMiBTU0gga2V5IHRoYXQgcHJvdmlkZXMgYWNjZXNzIGZvciBTU0ggY29tbXVuaWNhdGlvbiB3aXRoIHRoZSB3b3JrZXIgbm9kZXMgaW4gdGhlIG1hbmFnZWQgbm9kZSBncm91cC5cbiAgICovXG4gIHJlYWRvbmx5IHNzaEtleU5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBzZWN1cml0eSBncm91cHMgdGhhdCBhcmUgYWxsb3dlZCBTU0ggYWNjZXNzIChwb3J0IDIyKSB0byB0aGUgd29ya2VyIG5vZGVzLiBJZiB5b3Ugc3BlY2lmeSBhbiBBbWF6b24gRUMyIFNTSFxuICAgKiBrZXkgYnV0IGRvIG5vdCBzcGVjaWZ5IGEgc291cmNlIHNlY3VyaXR5IGdyb3VwIHdoZW4geW91IGNyZWF0ZSBhIG1hbmFnZWQgbm9kZSBncm91cCwgdGhlbiBwb3J0IDIyIG9uIHRoZSB3b3JrZXJcbiAgICogbm9kZXMgaXMgb3BlbmVkIHRvIHRoZSBpbnRlcm5ldCAoMC4wLjAuMC8wKS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBwb3J0IDIyIG9uIHRoZSB3b3JrZXIgbm9kZXMgaXMgb3BlbmVkIHRvIHRoZSBpbnRlcm5ldCAoMC4wLjAuMC8wKVxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlU2VjdXJpdHlHcm91cHM/OiBJU2VjdXJpdHlHcm91cFtdO1xufVxuXG4vKipcbiAqIExhdW5jaCB0ZW1wbGF0ZSBwcm9wZXJ0eSBzcGVjaWZpY2F0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGF1bmNoVGVtcGxhdGVTcGVjIHtcbiAgLyoqXG4gICAqIFRoZSBMYXVuY2ggdGVtcGxhdGUgSURcbiAgICovXG4gIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgbGF1bmNoIHRlbXBsYXRlIHZlcnNpb24gdG8gYmUgdXNlZCAob3B0aW9uYWwpLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRoZSBkZWZhdWx0IHZlcnNpb24gb2YgdGhlIGxhdW5jaCB0ZW1wbGF0ZVxuICAgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBFZmZlY3QgdHlwZXMgb2Yga3ViZXJuZXRlcyBub2RlIHRhaW50LlxuICovXG5leHBvcnQgZW51bSBUYWludEVmZmVjdCB7XG4gIC8qKlxuICAgKiBOb1NjaGVkdWxlXG4gICAqL1xuICBOT19TQ0hFRFVMRSA9ICdOT19TQ0hFRFVMRScsXG4gIC8qKlxuICAgKiBQcmVmZXJOb1NjaGVkdWxlXG4gICAqL1xuICBQUkVGRVJfTk9fU0NIRURVTEUgPSAnUFJFRkVSX05PX1NDSEVEVUxFJyxcbiAgLyoqXG4gICAqIE5vRXhlY3V0ZVxuICAgKi9cbiAgTk9fRVhFQ1VURSA9ICdOT19FWEVDVVRFJyxcbn1cblxuLyoqXG4gKiBUYWludCBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUYWludFNwZWMge1xuICAvKipcbiAgICogRWZmZWN0IHR5cGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBOb25lXG4gICAqL1xuICByZWFkb25seSBlZmZlY3Q/OiBUYWludEVmZmVjdDtcbiAgLyoqXG4gICAqIFRhaW50IGtleVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IGtleT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRhaW50IHZhbHVlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhlIE5vZGVncm91cCBPcHRpb25zIGZvciBhZGROb2RlR3JvdXAoKSBtZXRob2RcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOb2RlZ3JvdXBPcHRpb25zIHtcbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIE5vZGVncm91cFxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHJlc291cmNlIElEXG4gICAqL1xuICByZWFkb25seSBub2RlZ3JvdXBOYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHN1Ym5ldHMgdG8gdXNlIGZvciB0aGUgQXV0byBTY2FsaW5nIGdyb3VwIHRoYXQgaXMgY3JlYXRlZCBmb3IgeW91ciBub2RlIGdyb3VwLiBCeSBzcGVjaWZ5aW5nIHRoZVxuICAgKiBTdWJuZXRTZWxlY3Rpb24sIHRoZSBzZWxlY3RlZCBzdWJuZXRzIHdpbGwgYXV0b21hdGljYWxseSBhcHBseSByZXF1aXJlZCB0YWdzIGkuZS5cbiAgICogYGt1YmVybmV0ZXMuaW8vY2x1c3Rlci9DTFVTVEVSX05BTUVgIHdpdGggYSB2YWx1ZSBvZiBgc2hhcmVkYCwgd2hlcmUgYENMVVNURVJfTkFNRWAgaXMgcmVwbGFjZWQgd2l0aFxuICAgKiB0aGUgbmFtZSBvZiB5b3VyIGNsdXN0ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcHJpdmF0ZSBzdWJuZXRzXG4gICAqL1xuICByZWFkb25seSBzdWJuZXRzPzogU3VibmV0U2VsZWN0aW9uO1xuICAvKipcbiAgICogVGhlIEFNSSB0eXBlIGZvciB5b3VyIG5vZGUgZ3JvdXAuIElmIHlvdSBleHBsaWNpdGx5IHNwZWNpZnkgdGhlIGxhdW5jaFRlbXBsYXRlIHdpdGggY3VzdG9tIEFNSSwgZG8gbm90IHNwZWNpZnkgdGhpcyBwcm9wZXJ0eSwgb3JcbiAgICogdGhlIG5vZGUgZ3JvdXAgZGVwbG95bWVudCB3aWxsIGZhaWwuIEluIG90aGVyIGNhc2VzLCB5b3Ugd2lsbCBuZWVkIHRvIHNwZWNpZnkgY29ycmVjdCBhbWlUeXBlIGZvciB0aGUgbm9kZWdyb3VwLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF1dG8tZGV0ZXJtaW5lZCBmcm9tIHRoZSBpbnN0YW5jZVR5cGVzIHByb3BlcnR5IHdoZW4gbGF1bmNoVGVtcGxhdGVTcGVjIHByb3BlcnR5IGlzIG5vdCBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IGFtaVR5cGU/OiBOb2RlZ3JvdXBBbWlUeXBlO1xuICAvKipcbiAgICogVGhlIHJvb3QgZGV2aWNlIGRpc2sgc2l6ZSAoaW4gR2lCKSBmb3IgeW91ciBub2RlIGdyb3VwIGluc3RhbmNlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgMjBcbiAgICovXG4gIHJlYWRvbmx5IGRpc2tTaXplPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGN1cnJlbnQgbnVtYmVyIG9mIHdvcmtlciBub2RlcyB0aGF0IHRoZSBtYW5hZ2VkIG5vZGUgZ3JvdXAgc2hvdWxkIG1haW50YWluLiBJZiBub3Qgc3BlY2lmaWVkLFxuICAgKiB0aGUgbm9kZXdncm91cCB3aWxsIGluaXRpYWxseSBjcmVhdGUgYG1pblNpemVgIGluc3RhbmNlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgMlxuICAgKi9cbiAgcmVhZG9ubHkgZGVzaXJlZFNpemU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2Ygd29ya2VyIG5vZGVzIHRoYXQgdGhlIG1hbmFnZWQgbm9kZSBncm91cCBjYW4gc2NhbGUgb3V0IHRvLiBNYW5hZ2VkIG5vZGUgZ3JvdXBzIGNhbiBzdXBwb3J0IHVwIHRvIDEwMCBub2RlcyBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlc2lyZWRTaXplXG4gICAqL1xuICByZWFkb25seSBtYXhTaXplPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIG1pbmltdW0gbnVtYmVyIG9mIHdvcmtlciBub2RlcyB0aGF0IHRoZSBtYW5hZ2VkIG5vZGUgZ3JvdXAgY2FuIHNjYWxlIGluIHRvLiBUaGlzIG51bWJlciBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB6ZXJvLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBtaW5TaXplPzogbnVtYmVyO1xuICAvKipcbiAgICogRm9yY2UgdGhlIHVwZGF0ZSBpZiB0aGUgZXhpc3Rpbmcgbm9kZSBncm91cCdzIHBvZHMgYXJlIHVuYWJsZSB0byBiZSBkcmFpbmVkIGR1ZSB0byBhIHBvZCBkaXNydXB0aW9uIGJ1ZGdldCBpc3N1ZS5cbiAgICogSWYgYW4gdXBkYXRlIGZhaWxzIGJlY2F1c2UgcG9kcyBjb3VsZCBub3QgYmUgZHJhaW5lZCwgeW91IGNhbiBmb3JjZSB0aGUgdXBkYXRlIGFmdGVyIGl0IGZhaWxzIHRvIHRlcm1pbmF0ZSB0aGUgb2xkXG4gICAqIG5vZGUgd2hldGhlciBvciBub3QgYW55IHBvZHMgYXJlXG4gICAqIHJ1bm5pbmcgb24gdGhlIG5vZGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGZvcmNlVXBkYXRlPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFRoZSBpbnN0YW5jZSB0eXBlIHRvIHVzZSBmb3IgeW91ciBub2RlIGdyb3VwLiBDdXJyZW50bHksIHlvdSBjYW4gc3BlY2lmeSBhIHNpbmdsZSBpbnN0YW5jZSB0eXBlIGZvciBhIG5vZGUgZ3JvdXAuXG4gICAqIFRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGlzIHBhcmFtZXRlciBpcyBgdDMubWVkaXVtYC4gSWYgeW91IGNob29zZSBhIEdQVSBpbnN0YW5jZSB0eXBlLCBiZSBzdXJlIHRvIHNwZWNpZnkgdGhlXG4gICAqIGBBTDJfeDg2XzY0X0dQVWAsIGBCT1RUTEVST0NLRVRfQVJNXzY0X05WSURJQWAsIG9yIGBCT1RUTEVST0NLRVRfeDg2XzY0X05WSURJQWAgd2l0aCB0aGUgYW1pVHlwZSBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IHQzLm1lZGl1bVxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGluc3RhbmNlVHlwZXNgIGluc3RlYWQuXG4gICAqL1xuICByZWFkb25seSBpbnN0YW5jZVR5cGU/OiBJbnN0YW5jZVR5cGU7XG4gIC8qKlxuICAgKiBUaGUgaW5zdGFuY2UgdHlwZXMgdG8gdXNlIGZvciB5b3VyIG5vZGUgZ3JvdXAuXG4gICAqIEBkZWZhdWx0IHQzLm1lZGl1bSB3aWxsIGJlIHVzZWQgYWNjb3JkaW5nIHRvIHRoZSBjbG91ZGZvcm1hdGlvbiBkb2N1bWVudC5cbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWtzLW5vZGVncm91cC5odG1sI2Nmbi1la3Mtbm9kZWdyb3VwLWluc3RhbmNldHlwZXNcbiAgICovXG4gIHJlYWRvbmx5IGluc3RhbmNlVHlwZXM/OiBJbnN0YW5jZVR5cGVbXTtcbiAgLyoqXG4gICAqIFRoZSBLdWJlcm5ldGVzIGxhYmVscyB0byBiZSBhcHBsaWVkIHRvIHRoZSBub2RlcyBpbiB0aGUgbm9kZSBncm91cCB3aGVuIHRoZXkgYXJlIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWxzPzogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIH07XG4gIC8qKlxuICAgKiBUaGUgS3ViZXJuZXRlcyB0YWludHMgdG8gYmUgYXBwbGllZCB0byB0aGUgbm9kZXMgaW4gdGhlIG5vZGUgZ3JvdXAgd2hlbiB0aGV5IGFyZSBjcmVhdGVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vbmVcbiAgICovXG4gIHJlYWRvbmx5IHRhaW50cz86IFRhaW50U3BlY1tdO1xuICAvKipcbiAgICogVGhlIElBTSByb2xlIHRvIGFzc29jaWF0ZSB3aXRoIHlvdXIgbm9kZSBncm91cC4gVGhlIEFtYXpvbiBFS1Mgd29ya2VyIG5vZGUga3ViZWxldCBkYWVtb25cbiAgICogbWFrZXMgY2FsbHMgdG8gQVdTIEFQSXMgb24geW91ciBiZWhhbGYuIFdvcmtlciBub2RlcyByZWNlaXZlIHBlcm1pc3Npb25zIGZvciB0aGVzZSBBUEkgY2FsbHMgdGhyb3VnaFxuICAgKiBhbiBJQU0gaW5zdGFuY2UgcHJvZmlsZSBhbmQgYXNzb2NpYXRlZCBwb2xpY2llcy4gQmVmb3JlIHlvdSBjYW4gbGF1bmNoIHdvcmtlciBub2RlcyBhbmQgcmVnaXN0ZXIgdGhlbVxuICAgKiBpbnRvIGEgY2x1c3RlciwgeW91IG11c3QgY3JlYXRlIGFuIElBTSByb2xlIGZvciB0aG9zZSB3b3JrZXIgbm9kZXMgdG8gdXNlIHdoZW4gdGhleSBhcmUgbGF1bmNoZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm9uZS4gQXV0by1nZW5lcmF0ZWQgaWYgbm90IHNwZWNpZmllZC5cbiAgICovXG4gIHJlYWRvbmx5IG5vZGVSb2xlPzogSVJvbGU7XG4gIC8qKlxuICAgKiBUaGUgQU1JIHZlcnNpb24gb2YgdGhlIEFtYXpvbiBFS1Mtb3B0aW1pemVkIEFNSSB0byB1c2Ugd2l0aCB5b3VyIG5vZGUgZ3JvdXAgKGZvciBleGFtcGxlLCBgMS4xNC43LVlZWVlNTUREYCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gVGhlIGxhdGVzdCBhdmFpbGFibGUgQU1JIHZlcnNpb24gZm9yIHRoZSBub2RlIGdyb3VwJ3MgY3VycmVudCBLdWJlcm5ldGVzIHZlcnNpb24gaXMgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IHJlbGVhc2VWZXJzaW9uPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHJlbW90ZSBhY2Nlc3MgKFNTSCkgY29uZmlndXJhdGlvbiB0byB1c2Ugd2l0aCB5b3VyIG5vZGUgZ3JvdXAuIERpc2FibGVkIGJ5IGRlZmF1bHQsIGhvd2V2ZXIsIGlmIHlvdVxuICAgKiBzcGVjaWZ5IGFuIEFtYXpvbiBFQzIgU1NIIGtleSBidXQgZG8gbm90IHNwZWNpZnkgYSBzb3VyY2Ugc2VjdXJpdHkgZ3JvdXAgd2hlbiB5b3UgY3JlYXRlIGEgbWFuYWdlZCBub2RlIGdyb3VwLFxuICAgKiB0aGVuIHBvcnQgMjIgb24gdGhlIHdvcmtlciBub2RlcyBpcyBvcGVuZWQgdG8gdGhlIGludGVybmV0ICgwLjAuMC4wLzApXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZGlzYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IHJlbW90ZUFjY2Vzcz86IE5vZGVncm91cFJlbW90ZUFjY2VzcztcbiAgLyoqXG4gICAqIFRoZSBtZXRhZGF0YSB0byBhcHBseSB0byB0aGUgbm9kZSBncm91cCB0byBhc3Npc3Qgd2l0aCBjYXRlZ29yaXphdGlvbiBhbmQgb3JnYW5pemF0aW9uLiBFYWNoIHRhZyBjb25zaXN0cyBvZlxuICAgKiBhIGtleSBhbmQgYW4gb3B0aW9uYWwgdmFsdWUsIGJvdGggb2Ygd2hpY2ggeW91IGRlZmluZS4gTm9kZSBncm91cCB0YWdzIGRvIG5vdCBwcm9wYWdhdGUgdG8gYW55IG90aGVyIHJlc291cmNlc1xuICAgKiBhc3NvY2lhdGVkIHdpdGggdGhlIG5vZGUgZ3JvdXAsIHN1Y2ggYXMgdGhlIEFtYXpvbiBFQzIgaW5zdGFuY2VzIG9yIHN1Ym5ldHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgdGFncz86IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9O1xuICAvKipcbiAgICogTGF1bmNoIHRlbXBsYXRlIHNwZWNpZmljYXRpb24gdXNlZCBmb3IgdGhlIG5vZGVncm91cFxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9la3MvbGF0ZXN0L3VzZXJndWlkZS9sYXVuY2gtdGVtcGxhdGVzLmh0bWxcbiAgICogQGRlZmF1bHQgLSBubyBsYXVuY2ggdGVtcGxhdGVcbiAgICovXG4gIHJlYWRvbmx5IGxhdW5jaFRlbXBsYXRlU3BlYz86IExhdW5jaFRlbXBsYXRlU3BlYztcbiAgLyoqXG4gICAqIFRoZSBjYXBhY2l0eSB0eXBlIG9mIHRoZSBub2RlZ3JvdXAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gT05fREVNQU5EXG4gICAqL1xuICByZWFkb25seSBjYXBhY2l0eVR5cGU/OiBDYXBhY2l0eVR5cGU7XG5cbiAgLyoqXG4gICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBub2RlcyB1bmF2YWlsYWJsZSBhdCBvbmNlIGR1cmluZyBhIHZlcnNpb24gdXBkYXRlLlxuICAgKiBOb2RlcyB3aWxsIGJlIHVwZGF0ZWQgaW4gcGFyYWxsZWwuIFRoZSBtYXhpbXVtIG51bWJlciBpcyAxMDAuXG4gICAqXG4gICAqIFRoaXMgdmFsdWUgb3IgYG1heFVuYXZhaWxhYmxlUGVyY2VudGFnZWAgaXMgcmVxdWlyZWQgdG8gaGF2ZSBhIHZhbHVlIGZvciBjdXN0b20gdXBkYXRlIGNvbmZpZ3VyYXRpb25zIHRvIGJlIGFwcGxpZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWtzLW5vZGVncm91cC11cGRhdGVjb25maWcuaHRtbCNjZm4tZWtzLW5vZGVncm91cC11cGRhdGVjb25maWctbWF4dW5hdmFpbGFibGVcbiAgICogQGRlZmF1bHQgMVxuICAgKi9cbiAgcmVhZG9ubHkgbWF4VW5hdmFpbGFibGU/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBtYXhpbXVtIHBlcmNlbnRhZ2Ugb2Ygbm9kZXMgdW5hdmFpbGFibGUgZHVyaW5nIGEgdmVyc2lvbiB1cGRhdGUuXG4gICAqIFRoaXMgcGVyY2VudGFnZSBvZiBub2RlcyB3aWxsIGJlIHVwZGF0ZWQgaW4gcGFyYWxsZWwsIHVwIHRvIDEwMCBub2RlcyBhdCBvbmNlLlxuICAgKlxuICAgKiBUaGlzIHZhbHVlIG9yIGBtYXhVbmF2YWlsYWJsZWAgaXMgcmVxdWlyZWQgdG8gaGF2ZSBhIHZhbHVlIGZvciBjdXN0b20gdXBkYXRlIGNvbmZpZ3VyYXRpb25zIHRvIGJlIGFwcGxpZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXByb3BlcnRpZXMtZWtzLW5vZGVncm91cC11cGRhdGVjb25maWcuaHRtbCNjZm4tZWtzLW5vZGVncm91cC11cGRhdGVjb25maWctbWF4dW5hdmFpbGFibGVwZXJjZW50YWdlXG4gICAqIEBkZWZhdWx0IHVuZGVmaW5lZCAtIG5vZGUgZ3JvdXBzIHdpbGwgdXBkYXRlIGluc3RhbmNlcyBvbmUgYXQgYSB0aW1lXG4gICAqL1xuICByZWFkb25seSBtYXhVbmF2YWlsYWJsZVBlcmNlbnRhZ2U/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIGVuYWJsZSBub2RlIGF1dG8gcmVwYWlyIGZvciB0aGUgbm9kZSBncm91cC4gTm9kZSBhdXRvIHJlcGFpciBpcyBkaXNhYmxlZCBieSBkZWZhdWx0LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9la3MvbGF0ZXN0L3VzZXJndWlkZS9ub2RlLWhlYWx0aC5odG1sI25vZGUtYXV0by1yZXBhaXJcbiAgICogQGRlZmF1bHQgLSBkaXNhYmxlZFxuICAgKi9cbiAgcmVhZG9ubHkgZW5hYmxlTm9kZUF1dG9SZXBhaXI/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIE5vZGVHcm91cCBwcm9wZXJ0aWVzIGludGVyZmFjZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIE5vZGVncm91cFByb3BzIGV4dGVuZHMgTm9kZWdyb3VwT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBDbHVzdGVyIHJlc291cmNlXG4gICAqL1xuICByZWFkb25seSBjbHVzdGVyOiBJQ2x1c3Rlcjtcbn1cblxuLyoqXG4gKiBUaGUgTm9kZWdyb3VwIHJlc291cmNlIGNsYXNzXG4gKiBAcmVzb3VyY2UgQVdTOjpFS1M6Ok5vZGVncm91cFxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5leHBvcnQgY2xhc3MgTm9kZWdyb3VwIGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJTm9kZWdyb3VwIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWtzLXYyLWFscGhhLk5vZGVncm91cCc7XG5cbiAgLyoqXG4gICAqIEltcG9ydCB0aGUgTm9kZWdyb3VwIGZyb20gYXR0cmlidXRlc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tTm9kZWdyb3VwTmFtZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBub2RlZ3JvdXBOYW1lOiBzdHJpbmcpOiBJTm9kZWdyb3VwIHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElOb2RlZ3JvdXAge1xuICAgICAgcHVibGljIHJlYWRvbmx5IG5vZGVncm91cE5hbWUgPSBub2RlZ3JvdXBOYW1lO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQpO1xuICB9XG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIG5vZGVncm91cFxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbm9kZWdyb3VwQXJuOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBOb2RlZ3JvdXAgbmFtZVxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbm9kZWdyb3VwTmFtZTogc3RyaW5nO1xuICAvKipcbiAgICogdGhlIEFtYXpvbiBFS1MgY2x1c3RlciByZXNvdXJjZVxuICAgKlxuICAgKiBAYXR0cmlidXRlIENsdXN0ZXJOYW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY2x1c3RlcjogSUNsdXN0ZXI7XG4gIC8qKlxuICAgKiBJQU0gcm9sZSBvZiB0aGUgaW5zdGFuY2UgcHJvZmlsZSBmb3IgdGhlIG5vZGVncm91cFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHJvbGU6IElSb2xlO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzaXJlZFNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhTaXplOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWluU2l6ZTogbnVtYmVyO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOb2RlZ3JvdXBQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgcGh5c2ljYWxOYW1lOiBwcm9wcy5ub2RlZ3JvdXBOYW1lLFxuICAgIH0pO1xuICAgIC8vIEVuaGFuY2VkIENESyBBbmFseXRpY3MgVGVsZW1ldHJ5XG4gICAgYWRkQ29uc3RydWN0TWV0YWRhdGEodGhpcywgcHJvcHMpO1xuXG4gICAgdGhpcy5jbHVzdGVyID0gcHJvcHMuY2x1c3RlcjtcblxuICAgIHRoaXMuZGVzaXJlZFNpemUgPSBwcm9wcy5kZXNpcmVkU2l6ZSA/PyBwcm9wcy5taW5TaXplID8/IDI