@aws-cdk/aws-ec2-alpha 2.244.0-alpha.0 → 2.246.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.
package/.jsii CHANGED
@@ -8,7 +8,7 @@
8
8
  "url": "https://aws.amazon.com"
9
9
  },
10
10
  "dependencies": {
11
- "aws-cdk-lib": "^2.244.0",
11
+ "aws-cdk-lib": "^2.246.0",
12
12
  "constructs": "^10.5.0"
13
13
  },
14
14
  "dependencyClosure": {
@@ -1598,6 +1598,19 @@
1598
1598
  }
1599
1599
  }
1600
1600
  },
1601
+ "aws-cdk-lib.aws_elementalinference": {
1602
+ "targets": {
1603
+ "dotnet": {
1604
+ "namespace": "Amazon.CDK.AWS.ElementalInference"
1605
+ },
1606
+ "java": {
1607
+ "package": "software.amazon.awscdk.services.elementalinference"
1608
+ },
1609
+ "python": {
1610
+ "module": "aws_cdk.aws_elementalinference"
1611
+ }
1612
+ }
1613
+ },
1601
1614
  "aws-cdk-lib.aws_emr": {
1602
1615
  "targets": {
1603
1616
  "dotnet": {
@@ -3288,6 +3301,19 @@
3288
3301
  }
3289
3302
  }
3290
3303
  },
3304
+ "aws-cdk-lib.aws_route53globalresolver": {
3305
+ "targets": {
3306
+ "dotnet": {
3307
+ "namespace": "Amazon.CDK.AWS.Route53GlobalResolver"
3308
+ },
3309
+ "java": {
3310
+ "package": "software.amazon.awscdk.services.route53globalresolver"
3311
+ },
3312
+ "python": {
3313
+ "module": "aws_cdk.aws_route53globalresolver"
3314
+ }
3315
+ }
3316
+ },
3291
3317
  "aws-cdk-lib.aws_route53profiles": {
3292
3318
  "targets": {
3293
3319
  "dotnet": {
@@ -5724,6 +5750,22 @@
5724
5750
  }
5725
5751
  }
5726
5752
  },
5753
+ "aws-cdk-lib.interfaces.aws_elementalinference": {
5754
+ "targets": {
5755
+ "dotnet": {
5756
+ "namespace": "Amazon.CDK.Interfaces.ElementalInference"
5757
+ },
5758
+ "go": {
5759
+ "packageName": "interfacesawselementalinference"
5760
+ },
5761
+ "java": {
5762
+ "package": "software.amazon.awscdk.interfaces.elementalinference"
5763
+ },
5764
+ "python": {
5765
+ "module": "aws_cdk.interfaces.aws_elementalinference"
5766
+ }
5767
+ }
5768
+ },
5727
5769
  "aws-cdk-lib.interfaces.aws_emr": {
5728
5770
  "targets": {
5729
5771
  "dotnet": {
@@ -7676,6 +7718,22 @@
7676
7718
  }
7677
7719
  }
7678
7720
  },
7721
+ "aws-cdk-lib.interfaces.aws_route53globalresolver": {
7722
+ "targets": {
7723
+ "dotnet": {
7724
+ "namespace": "Amazon.CDK.Interfaces.Route53GlobalResolver"
7725
+ },
7726
+ "go": {
7727
+ "packageName": "interfacesawsroute53globalresolver"
7728
+ },
7729
+ "java": {
7730
+ "package": "software.amazon.awscdk.interfaces.route53globalresolver"
7731
+ },
7732
+ "python": {
7733
+ "module": "aws_cdk.interfaces.aws_route53globalresolver"
7734
+ }
7735
+ }
7736
+ },
7679
7737
  "aws-cdk-lib.interfaces.aws_route53profiles": {
7680
7738
  "targets": {
7681
7739
  "dotnet": {
@@ -8669,7 +8727,7 @@
8669
8727
  },
8670
8728
  "name": "@aws-cdk/aws-ec2-alpha",
8671
8729
  "readme": {
8672
- "markdown": "# Amazon VpcV2 Construct Library\n<!--BEGIN STABILITY BANNER-->\n\n---\n\n![cdk-constructs: Developer Preview](https://img.shields.io/badge/cdk--constructs-developer--preview-informational.svg?style=for-the-badge)\n\n> The APIs of higher level constructs in this module are in **developer preview** before they\n> become stable. We will only make breaking changes to address unforeseen API issues. Therefore,\n> these APIs are not subject to [Semantic Versioning](https://semver.org/), and breaking changes\n> will be announced in release notes. This means that while you may use them, you may need to\n> update your source code when upgrading to a newer version of this package.\n\n---\n\n<!--END STABILITY BANNER-->\n\n## VpcV2\n\n`VpcV2` is a re-write of the [`ec2.Vpc`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html) construct. This new construct enables higher level of customization\non the VPC being created. `VpcV2` implements the existing [`IVpc`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.IVpc.html), therefore,\n`VpcV2` is compatible with other constructs that accepts `IVpc` (e.g. [`ApplicationLoadBalancer`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer.html#construct-props)).\n\n`VpcV2` supports the addition of both primary and secondary addresses. The primary address must be an IPv4 address, which can be specified as a CIDR string or assigned from an IPAM pool. Secondary addresses can be either IPv4 or IPv6.\nBy default, `VpcV2` assigns `10.0.0.0/16` as the primary CIDR if no other CIDR is specified.\n\nBelow is an example of creating a VPC with both IPv4 and IPv6 support:\n\n```ts\nconst stack = new Stack();\nnew VpcV2(this, 'Vpc', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/24'),\n secondaryAddressBlocks: [\n IpAddresses.amazonProvidedIpv6({cidrBlockName: 'AmazonProvidedIpv6'}),\n ],\n});\n```\n\n`VpcV2` does not automatically create subnets or allocate IP addresses, which is different from the `Vpc` construct.\n\n## SubnetV2\n\n`SubnetV2` is a re-write of the [`ec2.Subnet`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Subnet.html) construct.\nThis new construct can be used to add subnets to a `VpcV2` instance:\nNote: When defining a subnet with `SubnetV2`, CDK automatically creates a new route table, unless a route table is explicitly provided as an input to the construct.\nTo enable the `mapPublicIpOnLaunch` feature (which is `false` by default), set the property to `true` when creating the subnet.\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc', {\n secondaryAddressBlocks: [\n IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonProvidedIp'}),\n ],\n});\n\nnew SubnetV2(this, 'subnetA', {\n vpc: myVpc,\n availabilityZone: 'us-east-1a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n ipv6CidrBlock: new IpCidr('2a05:d02c:25:4000::/60'),\n subnetType: SubnetType.PUBLIC,\n mapPublicIpOnLaunch: true,\n})\n```\n\nSince `VpcV2` does not create subnets automatically, users have full control over IP addresses allocation across subnets.\n\n## IP Addresses Management\n\nAdditional CIDRs can be added to the VPC via the `secondaryAddressBlocks` property.\nThe following example illustrates the options of defining these secondary address blocks using `IPAM`:\n\nNote: There’s currently an issue with IPAM pool deletion that may affect the `cdk --destroy` command. This is because IPAM takes time to detect when the IP address pool has been deallocated after the VPC is deleted. The current workaround is to wait until the IP address is fully deallocated from the pool before retrying the deletion. Below command can be used to check allocations for a pool using CLI\n\n```shell\naws ec2 get-ipam-pool-allocations --ipam-pool-id <ipam-pool-id>\n```\n\nRef: https://docs.aws.amazon.com/cli/latest/reference/ec2/get-ipam-pool-allocations.html\n\n```ts\nconst stack = new Stack();\nconst ipam = new Ipam(this, 'Ipam', {\n operatingRegions: ['us-west-1']\n});\nconst ipamPublicPool = ipam.publicScope.addPool('PublicPoolA', {\n addressFamily: AddressFamily.IP_V6,\n awsService: AwsServiceName.EC2,\n locale: 'us-west-1',\n publicIpSource: IpamPoolPublicIpSource.AMAZON,\n});\nipamPublicPool.provisionCidr('PublicPoolACidrA', { netmaskLength: 52 } );\n\nconst ipamPrivatePool = ipam.privateScope.addPool('PrivatePoolA', {\n addressFamily: AddressFamily.IP_V4,\n});\nipamPrivatePool.provisionCidr('PrivatePoolACidrA', { netmaskLength: 8 } );\n\nnew VpcV2(this, 'Vpc', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/24'),\n secondaryAddressBlocks: [\n IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonIpv6' }),\n IpAddresses.ipv6Ipam({\n ipamPool: ipamPublicPool,\n netmaskLength: 52,\n cidrBlockName: 'ipv6Ipam',\n }),\n IpAddresses.ipv4Ipam({\n ipamPool: ipamPrivatePool,\n netmaskLength: 8,\n cidrBlockName: 'ipv4Ipam',\n }),\n ],\n});\n```\n\n### Bring your own IPv6 addresses (BYOIP)\n\nIf you have your own IP address that you would like to use with EC2, you can set up an IPv6 pool via the AWS CLI, and use that pool ID in your application.\n\nOnce you have certified your IP address block with an ROA and have obtained an X-509 certificate, you can run the following command to provision your CIDR block in your AWS account:\n\n```shell\naws ec2 provision-byoip-cidr --region <region> --cidr <your CIDR block> --cidr-authorization-context Message=\"1|aws|<account>|<your CIDR block>|<expiration date>|SHA256\".Signature=\"<signature>\"\n```\n\nWhen your BYOIP CIDR is provisioned, you can run the following command to retrieve your IPv6 pool ID, which will be used in your VPC declaration:\n\n```shell\naws ec2 describe-byoip-cidr --region <region>\n```\n\nFor more help on setting up your IPv6 address, please review the [EC2 Documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html).\n\nOnce you have provisioned your address block, you can use the IPv6 in your VPC as follows:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n secondaryAddressBlocks: [IpAddresses.ipv6ByoipPool({\n cidrBlockName: 'MyByoipCidrBlock',\n ipv6PoolId: 'ipv6pool-ec2-someHashValue',\n ipv6CidrBlock: '2001:db8::/32'\n })],\n enableDnsHostnames: true,\n enableDnsSupport: true,\n});\n```\n\n## Routing\n\n`RouteTable` is a new construct that allows for route tables to be customized in a variety of ways. Using this construct, a customized route table can be added to the subnets defined using `SubnetV2`.\nFor instance, the following example shows how a custom route table can be created and appended to a `SubnetV2`:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n routeTable,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE_ISOLATED,\n});\n```\n\n`Routes` can be created to link subnets to various different AWS services via gateways and endpoints. Each unique route target has its own dedicated construct that can be routed to a given subnet via the `Route` construct. An example using the `InternetGateway` construct can be seen below:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE_ISOLATED });\n\nconst igw = new InternetGateway(this, 'IGW', {\n vpc: myVpc,\n});\nnew Route(this, 'IgwRoute', {\n routeTable,\n destination: '0.0.0.0/0',\n target: { gateway: igw },\n});\n```\n\nAlternatively, `Routes` can also be created via method `addRoute` in the `RouteTable` class. An example using the `EgressOnlyInternetGateway` construct can be seen below:\nNote: `EgressOnlyInternetGateway` can only be used to set up outbound IPv6 routing.\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc',{\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n secondaryAddressBlocks: [IpAddresses.amazonProvidedIpv6({\n cidrBlockName: 'AmazonProvided',\n })]\n });\n\nconst eigw = new EgressOnlyInternetGateway(this, 'EIGW', {\n vpc: myVpc,\n});\n\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\n\nrouteTable.addRoute('EIGW', '::/0', { gateway: eigw });\n```\n\nOther route targets may require a deeper set of parameters to set up properly. For instance, the example below illustrates how to set up a `NatGateway`:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE_ISOLATED });\n\nconst natgw = new NatGateway(this, 'NatGW', {\n subnet: subnet,\n vpc: myVpc,\n connectivityType: NatConnectivityType.PRIVATE,\n privateIpAddress: '10.0.0.42',\n});\nnew Route(this, 'NatGwRoute', {\n routeTable,\n destination: '0.0.0.0/0',\n target: { gateway: natgw },\n});\n```\n\nIt is also possible to set up endpoints connecting other AWS services. For instance, the example below illustrates the linking of a Dynamo DB endpoint via the existing `ec2.GatewayVpcEndpoint` construct as a route target:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE });\n\nconst dynamoEndpoint = new ec2.GatewayVpcEndpoint(this, 'DynamoEndpoint', {\n service: ec2.GatewayVpcEndpointAwsService.DYNAMODB,\n vpc: myVpc,\n subnets: [subnet],\n});\nnew Route(this, 'DynamoDBRoute', {\n routeTable,\n destination: '0.0.0.0/0',\n target: { endpoint: dynamoEndpoint },\n});\n```\n\n## VPC Peering Connection\n\nVPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module.\n\nPeering Connection cannot be established between two VPCs with overlapping CIDR ranges. Please make sure the two VPC CIDRs do not overlap with each other else it will throw an error.\n\nFor more information, see [What is VPC peering?](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html).\n\nThe following show examples of how to create a peering connection between two VPCs for all possible combinations of same-account or cross-account, and same-region or cross-region configurations.\n\nNote: You cannot create a VPC peering connection between VPCs that have matching or overlapping CIDR blocks\n\n**Case 1: Same Account and Same Region Peering Connection**\n\n```ts\nconst stack = new Stack();\n\nconst vpcA = new VpcV2(this, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nconst vpcB = new VpcV2(this, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst peeringConnection = vpcA.createPeeringConnection('sameAccountSameRegionPeering', {\n acceptorVpc: vpcB,\n});\n```\n\n**Case 2: Same Account and Cross Region Peering Connection**\n\nThere is no difference from Case 1 when calling `createPeeringConnection`. The only change is that one of the VPCs are created in another stack with a different region. To establish cross region VPC peering connection, acceptorVpc needs to be imported to the requestor VPC stack using `fromVpcV2Attributes` method.\n\n```ts\nconst app = new App();\n\nconst stackA = new Stack(app, 'VpcStackA', { env: { account: '000000000000', region: 'us-east-1' } });\nconst stackB = new Stack(app, 'VpcStackB', { env: { account: '000000000000', region: 'us-west-2' } });\n\nconst vpcA = new VpcV2(stackA, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nnew VpcV2(stackB, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst vpcB = VpcV2.fromVpcV2Attributes(stackA, 'ImportedVpcB', {\n vpcId: 'MockVpcBid',\n vpcCidrBlock: '10.1.0.0/16',\n region: 'us-west-2',\n ownerAccountId: '000000000000',\n });\n\n\nconst peeringConnection = vpcA.createPeeringConnection('sameAccountCrossRegionPeering', {\n acceptorVpc: vpcB,\n});\n```\n\n**Case 3: Cross Account Peering Connection**\n\nFor cross-account connections, the acceptor account needs an IAM role that grants the requestor account permission to initiate the connection. Create a new IAM role in the acceptor account using method `createAcceptorVpcRole` to provide the necessary permissions.\n\nOnce role is created in account, provide role arn for field `peerRoleArn` under method `createPeeringConnection`\n\n```ts\nconst stack = new Stack();\n\nconst acceptorVpc = new VpcV2(this, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nconst acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('000000000000'); // Requestor account ID\n```\n\nAfter creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. Import acceptorVpc to the stack using `fromVpcV2Attributes` method, it is recommended to specify owner account id of the acceptor VPC in case of cross account peering connection, if acceptor VPC is hosted in different region provide region value for import as well.\nThe following code snippet demonstrates how to set up VPC peering between two VPCs in different AWS accounts using CDK:\n\n```ts\nconst stack = new Stack();\n\nconst acceptorVpc = VpcV2.fromVpcV2Attributes(this, 'acceptorVpc', {\n vpcId: 'vpc-XXXX',\n vpcCidrBlock: '10.0.0.0/16',\n region: 'us-east-2',\n ownerAccountId: '111111111111',\n });\n\nconst acceptorRoleArn = 'arn:aws:iam::111111111111:role/VpcPeeringRole';\n\nconst requestorVpc = new VpcV2(this, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst peeringConnection = requestorVpc.createPeeringConnection('crossAccountCrossRegionPeering', {\n acceptorVpc: acceptorVpc,\n peerRoleArn: acceptorRoleArn,\n});\n```\n\n### Route Table Configuration\n\nAfter establishing the VPC peering connection, routes must be added to the respective route tables in the VPCs to enable traffic flow. If a route is added to the requestor stack, information will be able to flow from the requestor VPC to the acceptor VPC, but not in the reverse direction. For bi-directional communication, routes need to be added in both VPCs from their respective stacks.\n\nFor more information, see [Update your route tables for a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-routing.html).\n\n```ts\nconst stack = new Stack();\n\nconst acceptorVpc = new VpcV2(this, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nconst requestorVpc = new VpcV2(this, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst peeringConnection = requestorVpc.createPeeringConnection('peeringConnection', {\n acceptorVpc: acceptorVpc,\n});\n\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: requestorVpc,\n});\n\nrouteTable.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection });\n```\n\nThis can also be done using AWS CLI. For more information, see [create-route](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route.html).\n\n```bash\n# Add a route to the requestor VPC route table\naws ec2 create-route --route-table-id rtb-requestor --destination-cidr-block 10.0.0.0/16 --vpc-peering-connection-id pcx-xxxxxxxx\n\n# For bi-directional add a route in the acceptor vpc account as well\naws ec2 create-route --route-table-id rtb-acceptor --destination-cidr-block 10.1.0.0/16 --vpc-peering-connection-id pcx-xxxxxxxx\n```\n\n### Deleting the Peering Connection\n\nTo delete a VPC peering connection, use the following command:\n\n```bash\naws ec2 delete-vpc-peering-connection --vpc-peering-connection-id pcx-xxxxxxxx\n```\n\nFor more information, see [Delete a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html#delete-vpc-peering-connection).\n\n## Adding Egress-Only Internet Gateway to VPC\n\nAn egress-only internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows outbound communication over IPv6 from instances in your VPC to the internet, and prevents the internet from initiating an IPv6 connection with your instances.\n\nFor more information see [Enable outbound IPv6 traffic using an egress-only internet gateway](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html).\n\nVpcV2 supports adding an egress only internet gateway to VPC using the `addEgressOnlyInternetGateway` method.\n\nBy default, this method sets up a route to all outbound IPv6 address ranges, unless a specific destination is provided by the user. It can only be configured for IPv6-enabled VPCs.\nThe `Subnets` parameter accepts a `SubnetFilter`, which can be based on a `SubnetType` in VpcV2. A new route will be added to the route tables of all subnets that match this filter.\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc',{\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n secondaryAddressBlocks: [IpAddresses.amazonProvidedIpv6({\n cidrBlockName: 'AmazonProvided',\n })]\n });\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n ipv6CidrBlock: new IpCidr('2001:db8:1::/64'),\n subnetType: SubnetType.PRIVATE });\n\nmyVpc.addEgressOnlyInternetGateway({\n subnets: [{subnetType: SubnetType.PRIVATE}],\n destination: '::/60',\n})\n```\n\n## Adding NATGateway to the VPC\n\nA NAT gateway is a Network Address Translation (NAT) service.You can use a NAT gateway so that instances in a private subnet can connect to services outside your VPC but external services cannot initiate a connection with those instances.\n\nFor more information, see [NAT gateway basics](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html).\n\nWhen you create a NAT gateway, you specify one of the following connectivity types:\n\n**Public – (Default)**: Instances in private subnets can connect to the internet through a public NAT gateway, but cannot receive unsolicited inbound connections from the internet\n\n**Private**: Instances in private subnets can connect to other VPCs or your on-premises network through a private NAT gateway.\n\nTo define the NAT gateway connectivity type as `ConnectivityType.Public`, you need to ensure that there is an IGW(Internet Gateway) attached to the subnet's VPC.\nSince a NATGW is associated with a particular subnet, providing `subnet` field in the input props is mandatory.\n\nAdditionally, you can set up a route in any route table with the target set to the NAT Gateway. The function `addNatGateway` returns a `NATGateway` object that you can reference later.\n\nThe code example below provides the definition for adding a NAT gateway to your subnet:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC });\n\nmyVpc.addInternetGateway();\nmyVpc.addNatGateway({\n subnet: subnet,\n connectivityType: NatConnectivityType.PUBLIC,\n});\n```\n\n## Enable VPNGateway for the VPC\n\nA virtual private gateway is the endpoint on the VPC side of your VPN connection.\n\nFor more information, see [What is AWS Site-to-Site VPN?](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html).\n\nVPN route propagation is a feature in Amazon Web Services (AWS) that automatically updates route tables in your Virtual Private Cloud (VPC) with routes learned from a VPN connection.\n\nTo enable VPN route propagation, use the `vpnRoutePropagation` property to specify the subnets as an input to the function. VPN route propagation will then be enabled for each subnet with the corresponding route table IDs.\n\nAdditionally, you can set up a route in any route table with the target set to the VPN Gateway. The function `enableVpnGatewayV2` returns a `VPNGatewayV2` object that you can reference later.\n\nThe code example below provides the definition for setting up a VPN gateway with `vpnRoutePropagation` enabled:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst vpnGateway = myVpc.enableVpnGatewayV2({\n vpnRoutePropagation: [{ subnetType: SubnetType.PUBLIC }],\n type: VpnConnectionType.IPSEC_1,\n});\n\nconst routeTable = new RouteTable(stack, 'routeTable', {\n vpc: myVpc\n } );\n\nnew Route(stack, 'route', {\n destination: '172.31.0.0/24',\n target: { gateway: vpnGateway },\n routeTable: routeTable,\n});\n```\n\n## Adding InternetGateway to the VPC\n\nAn internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows communication between your VPC and the internet. It supports both IPv4 and IPv6 traffic.\n\nFor more information, see [Enable VPC internet access using internet gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-igw-internet-access.html).\n\nYou can add an internet gateway to a VPC using `addInternetGateway` method. By default, this method creates a route in all Public Subnets with outbound destination set to `0.0.0.0` for IPv4 and `::0` for IPv6 enabled VPC.\nInstead of using the default settings, you can configure a custom destination range by providing an optional input `destination` to the method.\nIn addition to the custom IP range, you can also choose to filter subnets where default routes should be created.\n\nThe code example below shows how to add an internet gateway with a custom outbound destination IP range:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\n\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC });\n\nmyVpc.addInternetGateway({\n ipv4Destination: '192.168.0.0/16',\n});\n```\n\nThe following code examples demonstrates how to add an internet gateway with a custom outbound destination IP range for specific subnets:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\n\nconst mySubnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC });\n\nmyVpc.addInternetGateway({\n ipv4Destination: '192.168.0.0/16',\n subnets: [mySubnet],\n});\n```\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\n\nmyVpc.addInternetGateway({\n ipv4Destination: '192.168.0.0/16',\n subnets: [{subnetType: SubnetType.PRIVATE_WITH_EGRESS}],\n});\n```\n\n## Importing an existing VPC\n\nYou can import an existing VPC and its subnets using the `VpcV2.fromVpcV2Attributes()` method or an individual subnet using `SubnetV2.fromSubnetV2Attributes()` method.\n\n### Importing a VPC\n\nTo import an existing VPC, use the `VpcV2.fromVpcV2Attributes()` method. You'll need to provide the VPC ID, primary CIDR block, and information about the subnets. You can import secondary address as well created through IPAM, BYOIP(IPv4) or enabled through Amazon Provided IPv6. You must provide VPC Id and its primary CIDR block for importing it.\n\nIf you wish to add a new subnet to imported VPC, new subnet's IP range(IPv4) will be validated against provided secondary and primary address block to confirm that it is within the the range of VPC.\n\nHere's an example of importing a VPC with only the required parameters\n\n``` ts\nconst stack = new Stack();\n\nconst importedVpc = VpcV2.fromVpcV2Attributes(stack, 'ImportedVpc', {\n vpcId: 'mockVpcID',\n vpcCidrBlock: '10.0.0.0/16',\n});\n```\n\nIn case of cross account or cross region VPC, its recommended to provide region and ownerAccountId so that these values for the VPC can be used to populate correct arn value for the VPC. If a VPC region and account ID is not provided, then region and account configured in the stack will be used. Furthermore, these fields will be referenced later while setting up VPC peering connection, so its necessary to set these fields to a correct value.\n\nBelow is an example of importing a cross region and cross account VPC, VPC arn for this case would be 'arn:aws:ec2:us-west-2:123456789012:vpc/mockVpcID'\n\n``` ts\nconst stack = new Stack();\n\n//Importing a cross account or cross region VPC\nconst importedVpc = VpcV2.fromVpcV2Attributes(stack, 'ImportedVpc', {\n vpcId: 'mockVpcID',\n vpcCidrBlock: '10.0.0.0/16',\n ownerAccountId: '123456789012',\n region: 'us-west-2',\n});\n```\n\nHere's an example of how to import a VPC with multiple CIDR blocks, IPv6 support, and different subnet types:\n\nIn this example, we're importing a VPC with:\n\n - A primary CIDR block (10.1.0.0/16)\n - One secondary IPv4 CIDR block (10.2.0.0/16)\n - Two secondary address using IPAM pool (IPv4 and IPv6)\n - VPC has Amazon-provided IPv6 CIDR enabled\n - An isolated subnet in us-west-2a\n - A public subnet in us-west-2b\n\n```ts\nconst stack = new Stack();\n\nconst importedVpc = VpcV2.fromVpcV2Attributes(this, 'ImportedVPC', {\n vpcId: 'vpc-XXX',\n vpcCidrBlock: '10.1.0.0/16',\n secondaryCidrBlocks: [\n {\n cidrBlock: '10.2.0.0/16',\n cidrBlockName: 'ImportedBlock1',\n },\n {\n ipv6IpamPoolId: 'ipam-pool-XXX',\n ipv6NetmaskLength: 52,\n cidrBlockName: 'ImportedIpamIpv6',\n },\n {\n ipv4IpamPoolId: 'ipam-pool-XXX',\n ipv4IpamProvisionedCidrs: ['10.2.0.0/16'],\n cidrBlockName: 'ImportedIpamIpv4',\n },\n {\n amazonProvidedIpv6CidrBlock: true,\n }\n ],\n subnets: [{\n subnetName: 'IsolatedSubnet2',\n subnetId: 'subnet-03cd773c0fe08ed26',\n subnetType: SubnetType.PRIVATE_ISOLATED,\n availabilityZone: 'us-west-2a',\n ipv4CidrBlock: '10.2.0.0/24',\n routeTableId: 'rtb-0871c310f98da2cbb',\n },\n {\n subnetId: 'subnet-0fa477e01db27d820',\n subnetType: SubnetType.PUBLIC,\n availabilityZone: 'us-west-2b',\n ipv4CidrBlock: '10.3.0.0/24',\n routeTableId: 'rtb-014f3043098fe4b96',\n }],\n});\n\n// You can now use the imported VPC in your stack\n\n// Adding a new subnet to the imported VPC\nconst importedSubnet = new SubnetV2(this, 'NewSubnet', {\n availabilityZone: 'us-west-2a',\n ipv4CidrBlock: new IpCidr('10.2.2.0/24'),\n vpc: importedVpc,\n subnetType: SubnetType.PUBLIC,\n});\n\n// Adding gateways to the imported VPC\nimportedVpc.addInternetGateway();\nimportedVpc.addNatGateway({ subnet: importedSubnet });\nimportedVpc.addEgressOnlyInternetGateway();\n```\n\nYou can add more subnets as needed by including additional entries in the `isolatedSubnets`, `publicSubnets`, or other subnet type arrays (e.g., `privateSubnets`).\n\n### Importing Subnets\n\nYou can also import individual subnets using the `SubnetV2.fromSubnetV2Attributes()` method. This is useful when you need to work with specific subnets independently of a VPC.\n\nHere's an example of how to import a subnet:\n\n```ts\nSubnetV2.fromSubnetV2Attributes(this, 'ImportedSubnet', {\n subnetId: 'subnet-0123456789abcdef0',\n availabilityZone: 'us-west-2a',\n ipv4CidrBlock: '10.2.0.0/24',\n routeTableId: 'rtb-0871c310f98da2cbb',\n subnetType: SubnetType.PRIVATE_ISOLATED,\n});\n```\n\nBy importing existing VPCs and subnets, you can easily integrate your existing AWS infrastructure with new resources created through CDK. This is particularly useful when you need to work with pre-existing network configurations or when you're migrating existing infrastructure to CDK.\n\n### Tagging VPC and its components\n\nBy default, when a resource name is given to the construct, it automatically adds a tag with the key `Name` and the value set to the provided resource name. To add additional custom tags, use the Tag Manager, like this: `Tags.of(myConstruct).add('key', 'value');`.\n\nFor example, if the `vpcName` is set to `TestVpc`, the following code will add a tag to the VPC with `key: Name` and `value: TestVpc`.\n\n```ts\nconst vpc = new VpcV2(this, 'VPC-integ-test-tag', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n enableDnsHostnames: true,\n enableDnsSupport: true,\n vpcName: 'CDKintegTestVPC',\n});\n\n// Add custom tags if needed\nTags.of(vpc).add('Environment', 'Production');\n```\n\n## Transit Gateway\n\nThe AWS Transit Gateway construct library allows you to create and configure Transit Gateway resources using AWS CDK.\n\nSee [AWS Transit Gateway Docs](docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) for more info.\n\n### Overview\n\nThe Transit Gateway construct (`TransitGateway`) is the main entry point for creating and managing your Transit Gateway infrastructure. It provides methods to create route tables, attach VPCs, and configure cross-account access.\n\nThe Transit Gateway construct library provides four main constructs:\n\n- `TransitGateway`: The central hub for your network connections\n- `TransitGatewayRouteTable`: Manages routing between attached networks\n- `TransitGatewayVpcAttachment`: Connects VPCs to the Transit Gateway\n- `TransitGatewayRoute`: Defines routing rules within your Transit Gateway\n\n### Basic Usage\n\nTo create a minimal deployable `TransitGateway`:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\n```\n\n### Default Transit Gateway Route Table\n\nBy default, `TransitGateway` is created with a default `TransitGatewayRouteTable`, for which automatic Associations and automatic Propagations are enabled.\n\n> Note: When you create a default Transit Gateway in AWS Console, a default Transit Gateway Route Table is automatically created by AWS. However, when using the CDK Transit Gateway L2 construct, the underlying L1 construct is configured with `defaultRouteTableAssociation` and `defaultRouteTablePropagation` explicitly disabled. This ensures that AWS does not create the default route table, allowing the CDK to define a custom default route table instead.\n>\n> As a result, in the AWS Console, the **Default association route table** and **Default propagation route table** settings will appear as disabled. Despite this, the CDK still provides automatic association and propagation functionality through its internal implementation, which can be controlled using the `defaultRouteTableAssociation` and `defaultRouteTablePropagation` properties within the CDK.\n\n\nYou can disable the automatic Association/Propagation on the default `TransitGatewayRouteTable` via the `TransitGateway` properties. This will still create a default route table for you:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway', {\n defaultRouteTableAssociation: false,\n defaultRouteTablePropagation: false,\n});\n```\n\n### Transit Gateway Route Table Management\n\nAdd additional Transit Gateway Route Tables using the `addRouteTable()` method:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\n\nconst routeTable = transitGateway.addRouteTable('CustomRouteTable');\n```\n\n### Attaching VPCs to the Transit Gateway\n\nCurrently only VPC to Transit Gateway attachments are supported.\n\nCreate an attachment from a VPC to the Transit Gateway using the `attachVpc()` method:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet1 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst subnet2 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.1.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\n\n// Create a basic attachment\nconst attachment = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet1, subnet2]\n});\n\n// Create an attachment with optional parameters\nconst attachmentWithOptions = transitGateway.attachVpc('VpcAttachmentWithOptions', {\n vpc: myVpc,\n subnets: [subnet1],\n vpcAttachmentOptions: {\n dnsSupport: true,\n applianceModeSupport: true,\n ipv6Support: true,\n securityGroupReferencingSupport: true,\n }\n});\n```\n\nIf you want to automatically associate and propagate routes with transit gateway route tables, you can pass the `associationRouteTable` and `propagationRouteTables` parameters. This will automatically create the necessary associations and propagations based on the provided route tables.\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet1 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst subnet2 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.1.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\nconst associationRouteTable = transitGateway.addRouteTable('AssociationRouteTable');\nconst propagationRouteTable1 = transitGateway.addRouteTable('PropagationRouteTable1');\nconst propagationRouteTable2 = transitGateway.addRouteTable('PropagationRouteTable2');\n\n// Create an attachment with automatically created association + propagations\nconst attachmentWithRoutes = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet1, subnet2],\n associationRouteTable: associationRouteTable,\n propagationRouteTables: [propagationRouteTable1, propagationRouteTable2],\n});\n```\n\nIn this example, the `associationRouteTable` is set to `associationRouteTable`, and `propagationRouteTables` is set to an array containing `propagationRouteTable1` and `propagationRouteTable2`. This triggers the automatic creation of route table associations and route propagations between the Transit Gateway and the specified route tables.\n\n### Adding static routes to the route table\n\nAdd static routes using either the `addRoute()` method to add an active route or `addBlackholeRoute()` to add a blackhole route:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\nconst routeTable = transitGateway.addRouteTable('CustomRouteTable');\n\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst attachment = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet]\n});\n\n// Add a static route to direct traffic\nrouteTable.addRoute('StaticRoute', attachment, '10.0.0.0/16');\n\n// Block unwanted traffic with a blackhole route\nrouteTable.addBlackholeRoute('BlackholeRoute', '172.16.0.0/16');\n```\n\n### Route Table Associations and Propagations\n\nConfigure route table associations and enable route propagation:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\nconst routeTable = transitGateway.addRouteTable('CustomRouteTable');\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\nconst attachment = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet]\n});\n\n// Associate an attachment with a route table\nrouteTable.addAssociation('Association', attachment);\n\n// Enable route propagation for an attachment\nrouteTable.enablePropagation('Propagation', attachment);\n```\n\n**Associations** — The linking of a Transit Gateway attachment to a specific route table, which determines which routes that attachment will use for routing decisions.\n\n**Propagation** — The automatic advertisement of routes from an attachment to a route table, allowing the route table to learn about available network destinations.\n"
8730
+ "markdown": "# Amazon VpcV2 Construct Library\n<!--BEGIN STABILITY BANNER-->\n\n---\n\n![cdk-constructs: Developer Preview](https://img.shields.io/badge/cdk--constructs-developer--preview-informational.svg?style=for-the-badge)\n\n> The APIs of higher level constructs in this module are in **developer preview** before they\n> become stable. We will only make breaking changes to address unforeseen API issues. Therefore,\n> these APIs are not subject to [Semantic Versioning](https://semver.org/), and breaking changes\n> will be announced in release notes. This means that while you may use them, you may need to\n> update your source code when upgrading to a newer version of this package.\n\n---\n\n<!--END STABILITY BANNER-->\n\n## VpcV2\n\n`VpcV2` is a re-write of the [`ec2.Vpc`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html) construct. This new construct enables higher level of customization\non the VPC being created. `VpcV2` implements the existing [`IVpc`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.IVpc.html), therefore,\n`VpcV2` is compatible with other constructs that accepts `IVpc` (e.g. [`ApplicationLoadBalancer`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer.html#construct-props)).\n\n`VpcV2` supports the addition of both primary and secondary addresses. The primary address must be an IPv4 address, which can be specified as a CIDR string or assigned from an IPAM pool. Secondary addresses can be either IPv4 or IPv6.\nBy default, `VpcV2` assigns `10.0.0.0/16` as the primary CIDR if no other CIDR is specified.\n\nBelow is an example of creating a VPC with both IPv4 and IPv6 support:\n\n```ts\nconst stack = new Stack();\nnew VpcV2(this, 'Vpc', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/24'),\n secondaryAddressBlocks: [\n IpAddresses.amazonProvidedIpv6({cidrBlockName: 'AmazonProvidedIpv6'}),\n ],\n});\n```\n\n`VpcV2` does not automatically create subnets or allocate IP addresses, which is different from the `Vpc` construct.\n\n## SubnetV2\n\n`SubnetV2` is a re-write of the [`ec2.Subnet`](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Subnet.html) construct.\nThis new construct can be used to add subnets to a `VpcV2` instance:\nNote: When defining a subnet with `SubnetV2`, CDK automatically creates a new route table, unless a route table is explicitly provided as an input to the construct.\nTo enable the `mapPublicIpOnLaunch` feature (which is `false` by default), set the property to `true` when creating the subnet.\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc', {\n secondaryAddressBlocks: [\n IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonProvidedIp'}),\n ],\n});\n\nnew SubnetV2(this, 'subnetA', {\n vpc: myVpc,\n availabilityZone: 'us-east-1a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n ipv6CidrBlock: new IpCidr('2a05:d02c:25:4000::/60'),\n subnetType: SubnetType.PUBLIC,\n mapPublicIpOnLaunch: true,\n})\n```\n\nSince `VpcV2` does not create subnets automatically, users have full control over IP addresses allocation across subnets.\n\n## IP Addresses Management\n\nAdditional CIDRs can be added to the VPC via the `secondaryAddressBlocks` property.\nThe following example illustrates the options of defining these secondary address blocks using `IPAM`:\n\nNote: There’s currently an issue with IPAM pool deletion that may affect the `cdk --destroy` command. This is because IPAM takes time to detect when the IP address pool has been deallocated after the VPC is deleted. The current workaround is to wait until the IP address is fully deallocated from the pool before retrying the deletion. Below command can be used to check allocations for a pool using CLI\n\n```shell\naws ec2 get-ipam-pool-allocations --ipam-pool-id <ipam-pool-id>\n```\n\nRef: https://docs.aws.amazon.com/cli/latest/reference/ec2/get-ipam-pool-allocations.html\n\n```ts\nconst stack = new Stack();\nconst ipam = new Ipam(this, 'Ipam', {\n operatingRegions: ['us-west-1']\n});\nconst ipamPublicPool = ipam.publicScope.addPool('PublicPoolA', {\n addressFamily: AddressFamily.IP_V6,\n awsService: AwsServiceName.EC2,\n locale: 'us-west-1',\n publicIpSource: IpamPoolPublicIpSource.AMAZON,\n});\nipamPublicPool.provisionCidr('PublicPoolACidrA', { netmaskLength: 52 } );\n\nconst ipamPrivatePool = ipam.privateScope.addPool('PrivatePoolA', {\n addressFamily: AddressFamily.IP_V4,\n});\nipamPrivatePool.provisionCidr('PrivatePoolACidrA', { netmaskLength: 8 } );\n\nnew VpcV2(this, 'Vpc', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/24'),\n secondaryAddressBlocks: [\n IpAddresses.amazonProvidedIpv6({ cidrBlockName: 'AmazonIpv6' }),\n IpAddresses.ipv6Ipam({\n ipamPool: ipamPublicPool,\n netmaskLength: 52,\n cidrBlockName: 'ipv6Ipam',\n }),\n IpAddresses.ipv4Ipam({\n ipamPool: ipamPrivatePool,\n netmaskLength: 8,\n cidrBlockName: 'ipv4Ipam',\n }),\n ],\n});\n```\n\n### Bring your own IPv6 addresses (BYOIP)\n\nIf you have your own IP address that you would like to use with EC2, you can set up an IPv6 pool via the AWS CLI, and use that pool ID in your application.\n\nOnce you have certified your IP address block with an ROA and have obtained an X-509 certificate, you can run the following command to provision your CIDR block in your AWS account:\n\n```shell\naws ec2 provision-byoip-cidr --region <region> --cidr <your CIDR block> --cidr-authorization-context Message=\"1|aws|<account>|<your CIDR block>|<expiration date>|SHA256\".Signature=\"<signature>\"\n```\n\nWhen your BYOIP CIDR is provisioned, you can run the following command to retrieve your IPv6 pool ID, which will be used in your VPC declaration:\n\n```shell\naws ec2 describe-byoip-cidr --region <region>\n```\n\nFor more help on setting up your IPv6 address, please review the [EC2 Documentation](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-byoip.html).\n\nOnce you have provisioned your address block, you can use the IPv6 in your VPC as follows:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n secondaryAddressBlocks: [IpAddresses.ipv6ByoipPool({\n cidrBlockName: 'MyByoipCidrBlock',\n ipv6PoolId: 'ipv6pool-ec2-someHashValue',\n ipv6CidrBlock: '2001:db8::/32'\n })],\n enableDnsHostnames: true,\n enableDnsSupport: true,\n});\n```\n\n## Routing\n\n`RouteTable` is a new construct that allows for route tables to be customized in a variety of ways. Using this construct, a customized route table can be added to the subnets defined using `SubnetV2`.\nFor instance, the following example shows how a custom route table can be created and appended to a `SubnetV2`:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n routeTable,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE_ISOLATED,\n});\n```\n\n`Routes` can be created to link subnets to various different AWS services via gateways and endpoints. Each unique route target has its own dedicated construct that can be routed to a given subnet via the `Route` construct. An example using the `InternetGateway` construct can be seen below:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE_ISOLATED });\n\nconst igw = new InternetGateway(this, 'IGW', {\n vpc: myVpc,\n});\nnew Route(this, 'IgwRoute', {\n routeTable,\n destination: '0.0.0.0/0',\n target: { gateway: igw },\n});\n```\n\nAlternatively, `Routes` can also be created via method `addRoute` in the `RouteTable` class. An example using the `EgressOnlyInternetGateway` construct can be seen below:\nNote: `EgressOnlyInternetGateway` can only be used to set up outbound IPv6 routing.\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc',{\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n secondaryAddressBlocks: [IpAddresses.amazonProvidedIpv6({\n cidrBlockName: 'AmazonProvided',\n })]\n });\n\nconst eigw = new EgressOnlyInternetGateway(this, 'EIGW', {\n vpc: myVpc,\n});\n\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\n\nrouteTable.addRoute('EIGW', '::/0', { gateway: eigw });\n```\n\nOther route targets may require a deeper set of parameters to set up properly. For instance, the example below illustrates how to set up a `NatGateway`:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE_ISOLATED });\n\nconst natgw = new NatGateway(this, 'NatGW', {\n subnet: subnet,\n vpc: myVpc,\n connectivityType: NatConnectivityType.PRIVATE,\n privateIpAddress: '10.0.0.42',\n});\nnew Route(this, 'NatGwRoute', {\n routeTable,\n destination: '0.0.0.0/0',\n target: { gateway: natgw },\n});\n```\n\nIt is also possible to set up endpoints connecting other AWS services. For instance, the example below illustrates the linking of a Dynamo DB endpoint via the existing `ec2.GatewayVpcEndpoint` construct as a route target:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PRIVATE });\n\nconst dynamoEndpoint = new ec2.GatewayVpcEndpoint(this, 'DynamoEndpoint', {\n service: ec2.GatewayVpcEndpointAwsService.DYNAMODB,\n vpc: myVpc,\n subnets: [subnet],\n});\nnew Route(this, 'DynamoDBRoute', {\n routeTable,\n destination: '0.0.0.0/0',\n target: { endpoint: dynamoEndpoint },\n});\n```\n\n## VPC Peering Connection\n\nVPC peering connection allows you to connect two VPCs and route traffic between them using private IP addresses. The VpcV2 construct supports creating VPC peering connections through the `VPCPeeringConnection` construct from the `route` module.\n\nPeering Connection cannot be established between two VPCs with overlapping CIDR ranges. Please make sure the two VPC CIDRs do not overlap with each other else it will throw an error.\n\nFor more information, see [What is VPC peering?](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html).\n\nThe following show examples of how to create a peering connection between two VPCs for all possible combinations of same-account or cross-account, and same-region or cross-region configurations.\n\nNote: You cannot create a VPC peering connection between VPCs that have matching or overlapping CIDR blocks\n\n**Case 1: Same Account and Same Region Peering Connection**\n\n```ts\nconst stack = new Stack();\n\nconst vpcA = new VpcV2(this, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nconst vpcB = new VpcV2(this, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst peeringConnection = vpcA.createPeeringConnection('sameAccountSameRegionPeering', {\n acceptorVpc: vpcB,\n});\n```\n\n**Case 2: Same Account and Cross Region Peering Connection**\n\nThere is no difference from Case 1 when calling `createPeeringConnection`. The only change is that one of the VPCs are created in another stack with a different region. To establish cross region VPC peering connection, acceptorVpc needs to be imported to the requestor VPC stack using `fromVpcV2Attributes` method.\n\n```ts\nconst app = new App();\n\nconst stackA = new Stack(app, 'VpcStackA', { env: { account: '000000000000', region: 'us-east-1' } });\nconst stackB = new Stack(app, 'VpcStackB', { env: { account: '000000000000', region: 'us-west-2' } });\n\nconst vpcA = new VpcV2(stackA, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nnew VpcV2(stackB, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst vpcB = VpcV2.fromVpcV2Attributes(stackA, 'ImportedVpcB', {\n vpcId: 'MockVpcBid',\n vpcCidrBlock: '10.1.0.0/16',\n region: 'us-west-2',\n ownerAccountId: '000000000000',\n });\n\n\nconst peeringConnection = vpcA.createPeeringConnection('sameAccountCrossRegionPeering', {\n acceptorVpc: vpcB,\n});\n```\n\n**Case 3: Cross Account Peering Connection**\n\nFor cross-account connections, the acceptor account needs an IAM role that grants the requestor account permission to initiate the connection. Create a new IAM role in the acceptor account using method `createAcceptorVpcRole` to provide the necessary permissions.\n\nOnce role is created in account, provide role arn for field `peerRoleArn` under method `createPeeringConnection`\n\n```ts\nconst stack = new Stack();\n\nconst acceptorVpc = new VpcV2(this, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nconst acceptorRoleArn = acceptorVpc.createAcceptorVpcRole('000000000000'); // Requestor account ID\n```\n\nAfter creating an IAM role in the acceptor account, we can initiate the peering connection request from the requestor VPC. Import acceptorVpc to the stack using `fromVpcV2Attributes` method, it is recommended to specify owner account id of the acceptor VPC in case of cross account peering connection, if acceptor VPC is hosted in different region provide region value for import as well.\nThe following code snippet demonstrates how to set up VPC peering between two VPCs in different AWS accounts using CDK:\n\n```ts\nconst stack = new Stack();\n\nconst acceptorVpc = VpcV2.fromVpcV2Attributes(this, 'acceptorVpc', {\n vpcId: 'vpc-XXXX',\n vpcCidrBlock: '10.0.0.0/16',\n region: 'us-east-2',\n ownerAccountId: '111111111111',\n });\n\nconst acceptorRoleArn = 'arn:aws:iam::111111111111:role/VpcPeeringRole';\n\nconst requestorVpc = new VpcV2(this, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst peeringConnection = requestorVpc.createPeeringConnection('crossAccountCrossRegionPeering', {\n acceptorVpc: acceptorVpc,\n peerRoleArn: acceptorRoleArn,\n});\n```\n\n### Route Table Configuration\n\nAfter establishing the VPC peering connection, routes must be added to the respective route tables in the VPCs to enable traffic flow. If a route is added to the requestor stack, information will be able to flow from the requestor VPC to the acceptor VPC, but not in the reverse direction. For bi-directional communication, routes need to be added in both VPCs from their respective stacks.\n\nFor more information, see [Update your route tables for a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-routing.html).\n\n```ts\nconst stack = new Stack();\n\nconst acceptorVpc = new VpcV2(this, 'VpcA', {\n primaryAddressBlock: IpAddresses.ipv4('10.0.0.0/16'),\n});\n\nconst requestorVpc = new VpcV2(this, 'VpcB', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n});\n\nconst peeringConnection = requestorVpc.createPeeringConnection('peeringConnection', {\n acceptorVpc: acceptorVpc,\n});\n\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: requestorVpc,\n});\n\nrouteTable.addRoute('vpcPeeringRoute', '10.0.0.0/16', { gateway: peeringConnection });\n```\n\nThis can also be done using AWS CLI. For more information, see [create-route](https://docs.aws.amazon.com/cli/latest/reference/ec2/create-route.html).\n\n```bash\n# Add a route to the requestor VPC route table\naws ec2 create-route --route-table-id rtb-requestor --destination-cidr-block 10.0.0.0/16 --vpc-peering-connection-id pcx-xxxxxxxx\n\n# For bi-directional add a route in the acceptor vpc account as well\naws ec2 create-route --route-table-id rtb-acceptor --destination-cidr-block 10.1.0.0/16 --vpc-peering-connection-id pcx-xxxxxxxx\n```\n\n### Deleting the Peering Connection\n\nTo delete a VPC peering connection, use the following command:\n\n```bash\naws ec2 delete-vpc-peering-connection --vpc-peering-connection-id pcx-xxxxxxxx\n```\n\nFor more information, see [Delete a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/create-vpc-peering-connection.html#delete-vpc-peering-connection).\n\n## Adding Egress-Only Internet Gateway to VPC\n\nAn egress-only internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows outbound communication over IPv6 from instances in your VPC to the internet, and prevents the internet from initiating an IPv6 connection with your instances.\n\nFor more information see [Enable outbound IPv6 traffic using an egress-only internet gateway](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html).\n\nVpcV2 supports adding an egress only internet gateway to VPC using the `addEgressOnlyInternetGateway` method.\n\nBy default, this method sets up a route to all outbound IPv6 address ranges, unless a specific destination is provided by the user. It can only be configured for IPv6-enabled VPCs.\nThe `Subnets` parameter accepts a `SubnetFilter`, which can be based on a `SubnetType` in VpcV2. A new route will be added to the route tables of all subnets that match this filter.\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc',{\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n secondaryAddressBlocks: [IpAddresses.amazonProvidedIpv6({\n cidrBlockName: 'AmazonProvided',\n })]\n });\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n ipv6CidrBlock: new IpCidr('2001:db8:1::/64'),\n subnetType: SubnetType.PRIVATE });\n\nmyVpc.addEgressOnlyInternetGateway({\n subnets: [{subnetType: SubnetType.PRIVATE}],\n destination: '::/60',\n})\n```\n\n## Adding NATGateway to the VPC\n\nA NAT gateway is a Network Address Translation (NAT) service.You can use a NAT gateway so that instances in a private subnet can connect to services outside your VPC but external services cannot initiate a connection with those instances.\n\nFor more information, see [NAT gateway basics](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html).\n\nWhen you create a NAT gateway, you specify one of the following connectivity types:\n\n**Public – (Default)**: Instances in private subnets can connect to the internet through a public NAT gateway, but cannot receive unsolicited inbound connections from the internet\n\n**Private**: Instances in private subnets can connect to other VPCs or your on-premises network through a private NAT gateway.\n\nTo define the NAT gateway connectivity type as `ConnectivityType.Public`, you need to ensure that there is an IGW(Internet Gateway) attached to the subnet's VPC.\nSince a NATGW is associated with a particular subnet, providing `subnet` field in the input props is mandatory.\n\nAdditionally, you can set up a route in any route table with the target set to the NAT Gateway. The function `addNatGateway` returns a `NATGateway` object that you can reference later.\n\nThe code example below provides the definition for adding a NAT gateway to your subnet:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst routeTable = new RouteTable(this, 'RouteTable', {\n vpc: myVpc,\n});\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC });\n\nmyVpc.addInternetGateway();\nmyVpc.addNatGateway({\n subnet: subnet,\n connectivityType: NatConnectivityType.PUBLIC,\n});\n```\n\n## Enable VPNGateway for the VPC\n\nA virtual private gateway is the endpoint on the VPC side of your VPN connection.\n\nFor more information, see [What is AWS Site-to-Site VPN?](https://docs.aws.amazon.com/vpn/latest/s2svpn/VPC_VPN.html).\n\nVPN route propagation is a feature in Amazon Web Services (AWS) that automatically updates route tables in your Virtual Private Cloud (VPC) with routes learned from a VPN connection.\n\nTo enable VPN route propagation, use the `vpnRoutePropagation` property to specify the subnets as an input to the function. VPN route propagation will then be enabled for each subnet with the corresponding route table IDs.\n\nAdditionally, you can set up a route in any route table with the target set to the VPN Gateway. The function `enableVpnGatewayV2` returns a `VPNGatewayV2` object that you can reference later.\n\nThe code example below provides the definition for setting up a VPN gateway with `vpnRoutePropagation` enabled:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\nconst vpnGateway = myVpc.enableVpnGatewayV2({\n vpnRoutePropagation: [{ subnetType: SubnetType.PUBLIC }],\n type: VpnConnectionType.IPSEC_1,\n});\n\nconst routeTable = new RouteTable(stack, 'routeTable', {\n vpc: myVpc\n } );\n\nnew Route(stack, 'route', {\n destination: '172.31.0.0/24',\n target: { gateway: vpnGateway },\n routeTable: routeTable,\n});\n```\n\n## Adding InternetGateway to the VPC\n\nAn internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows communication between your VPC and the internet. It supports both IPv4 and IPv6 traffic.\n\nFor more information, see [Enable VPC internet access using internet gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-igw-internet-access.html).\n\nYou can add an internet gateway to a VPC using `addInternetGateway` method. By default, this method creates a route in all Public Subnets with outbound destination set to `0.0.0.0` for IPv4 and `::0` for IPv6 enabled VPC.\nInstead of using the default settings, you can configure a custom destination range by providing an optional input `destination` to the method.\nIn addition to the custom IP range, you can also choose to filter subnets where default routes should be created.\n\nThe code example below shows how to add an internet gateway with a custom outbound destination IP range:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\n\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC });\n\nmyVpc.addInternetGateway({\n ipv4Destination: '192.168.0.0/16',\n});\n```\n\nThe following code examples demonstrates how to add an internet gateway with a custom outbound destination IP range for specific subnets:\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\n\nconst mySubnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC });\n\nmyVpc.addInternetGateway({\n ipv4Destination: '192.168.0.0/16',\n subnets: [mySubnet],\n});\n```\n\n```ts\nconst stack = new Stack();\nconst myVpc = new VpcV2(this, 'Vpc');\n\nmyVpc.addInternetGateway({\n ipv4Destination: '192.168.0.0/16',\n subnets: [{subnetType: SubnetType.PRIVATE_WITH_EGRESS}],\n});\n```\n\n## Importing an existing VPC\n\nYou can import an existing VPC and its subnets using the `VpcV2.fromVpcV2Attributes()` method or an individual subnet using `SubnetV2.fromSubnetV2Attributes()` method.\n\n### Importing a VPC\n\nTo import an existing VPC, use the `VpcV2.fromVpcV2Attributes()` method. You'll need to provide the VPC ID, primary CIDR block, and information about the subnets. You can import secondary address as well created through IPAM, BYOIP(IPv4) or enabled through Amazon Provided IPv6. You must provide VPC Id and its primary CIDR block for importing it.\n\nIf you wish to add a new subnet to imported VPC, new subnet's IP range(IPv4) will be validated against provided secondary and primary address block to confirm that it is within the range of VPC.\n\nHere's an example of importing a VPC with only the required parameters\n\n``` ts\nconst stack = new Stack();\n\nconst importedVpc = VpcV2.fromVpcV2Attributes(stack, 'ImportedVpc', {\n vpcId: 'mockVpcID',\n vpcCidrBlock: '10.0.0.0/16',\n});\n```\n\nIn case of cross account or cross region VPC, its recommended to provide region and ownerAccountId so that these values for the VPC can be used to populate correct arn value for the VPC. If a VPC region and account ID is not provided, then region and account configured in the stack will be used. Furthermore, these fields will be referenced later while setting up VPC peering connection, so its necessary to set these fields to a correct value.\n\nBelow is an example of importing a cross region and cross account VPC, VPC arn for this case would be 'arn:aws:ec2:us-west-2:123456789012:vpc/mockVpcID'\n\n``` ts\nconst stack = new Stack();\n\n//Importing a cross account or cross region VPC\nconst importedVpc = VpcV2.fromVpcV2Attributes(stack, 'ImportedVpc', {\n vpcId: 'mockVpcID',\n vpcCidrBlock: '10.0.0.0/16',\n ownerAccountId: '123456789012',\n region: 'us-west-2',\n});\n```\n\nHere's an example of how to import a VPC with multiple CIDR blocks, IPv6 support, and different subnet types:\n\nIn this example, we're importing a VPC with:\n\n - A primary CIDR block (10.1.0.0/16)\n - One secondary IPv4 CIDR block (10.2.0.0/16)\n - Two secondary address using IPAM pool (IPv4 and IPv6)\n - VPC has Amazon-provided IPv6 CIDR enabled\n - An isolated subnet in us-west-2a\n - A public subnet in us-west-2b\n\n```ts\nconst stack = new Stack();\n\nconst importedVpc = VpcV2.fromVpcV2Attributes(this, 'ImportedVPC', {\n vpcId: 'vpc-XXX',\n vpcCidrBlock: '10.1.0.0/16',\n secondaryCidrBlocks: [\n {\n cidrBlock: '10.2.0.0/16',\n cidrBlockName: 'ImportedBlock1',\n },\n {\n ipv6IpamPoolId: 'ipam-pool-XXX',\n ipv6NetmaskLength: 52,\n cidrBlockName: 'ImportedIpamIpv6',\n },\n {\n ipv4IpamPoolId: 'ipam-pool-XXX',\n ipv4IpamProvisionedCidrs: ['10.2.0.0/16'],\n cidrBlockName: 'ImportedIpamIpv4',\n },\n {\n amazonProvidedIpv6CidrBlock: true,\n }\n ],\n subnets: [{\n subnetName: 'IsolatedSubnet2',\n subnetId: 'subnet-03cd773c0fe08ed26',\n subnetType: SubnetType.PRIVATE_ISOLATED,\n availabilityZone: 'us-west-2a',\n ipv4CidrBlock: '10.2.0.0/24',\n routeTableId: 'rtb-0871c310f98da2cbb',\n },\n {\n subnetId: 'subnet-0fa477e01db27d820',\n subnetType: SubnetType.PUBLIC,\n availabilityZone: 'us-west-2b',\n ipv4CidrBlock: '10.3.0.0/24',\n routeTableId: 'rtb-014f3043098fe4b96',\n }],\n});\n\n// You can now use the imported VPC in your stack\n\n// Adding a new subnet to the imported VPC\nconst importedSubnet = new SubnetV2(this, 'NewSubnet', {\n availabilityZone: 'us-west-2a',\n ipv4CidrBlock: new IpCidr('10.2.2.0/24'),\n vpc: importedVpc,\n subnetType: SubnetType.PUBLIC,\n});\n\n// Adding gateways to the imported VPC\nimportedVpc.addInternetGateway();\nimportedVpc.addNatGateway({ subnet: importedSubnet });\nimportedVpc.addEgressOnlyInternetGateway();\n```\n\nYou can add more subnets as needed by including additional entries in the `isolatedSubnets`, `publicSubnets`, or other subnet type arrays (e.g., `privateSubnets`).\n\n### Importing Subnets\n\nYou can also import individual subnets using the `SubnetV2.fromSubnetV2Attributes()` method. This is useful when you need to work with specific subnets independently of a VPC.\n\nHere's an example of how to import a subnet:\n\n```ts\nSubnetV2.fromSubnetV2Attributes(this, 'ImportedSubnet', {\n subnetId: 'subnet-0123456789abcdef0',\n availabilityZone: 'us-west-2a',\n ipv4CidrBlock: '10.2.0.0/24',\n routeTableId: 'rtb-0871c310f98da2cbb',\n subnetType: SubnetType.PRIVATE_ISOLATED,\n});\n```\n\nBy importing existing VPCs and subnets, you can easily integrate your existing AWS infrastructure with new resources created through CDK. This is particularly useful when you need to work with pre-existing network configurations or when you're migrating existing infrastructure to CDK.\n\n### Tagging VPC and its components\n\nBy default, when a resource name is given to the construct, it automatically adds a tag with the key `Name` and the value set to the provided resource name. To add additional custom tags, use the Tag Manager, like this: `Tags.of(myConstruct).add('key', 'value');`.\n\nFor example, if the `vpcName` is set to `TestVpc`, the following code will add a tag to the VPC with `key: Name` and `value: TestVpc`.\n\n```ts\nconst vpc = new VpcV2(this, 'VPC-integ-test-tag', {\n primaryAddressBlock: IpAddresses.ipv4('10.1.0.0/16'),\n enableDnsHostnames: true,\n enableDnsSupport: true,\n vpcName: 'CDKintegTestVPC',\n});\n\n// Add custom tags if needed\nTags.of(vpc).add('Environment', 'Production');\n```\n\n## Transit Gateway\n\nThe AWS Transit Gateway construct library allows you to create and configure Transit Gateway resources using AWS CDK.\n\nSee [AWS Transit Gateway Docs](docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) for more info.\n\n### Overview\n\nThe Transit Gateway construct (`TransitGateway`) is the main entry point for creating and managing your Transit Gateway infrastructure. It provides methods to create route tables, attach VPCs, and configure cross-account access.\n\nThe Transit Gateway construct library provides four main constructs:\n\n- `TransitGateway`: The central hub for your network connections\n- `TransitGatewayRouteTable`: Manages routing between attached networks\n- `TransitGatewayVpcAttachment`: Connects VPCs to the Transit Gateway\n- `TransitGatewayRoute`: Defines routing rules within your Transit Gateway\n\n### Basic Usage\n\nTo create a minimal deployable `TransitGateway`:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\n```\n\n### Default Transit Gateway Route Table\n\nBy default, `TransitGateway` is created with a default `TransitGatewayRouteTable`, for which automatic Associations and automatic Propagations are enabled.\n\n> Note: When you create a default Transit Gateway in AWS Console, a default Transit Gateway Route Table is automatically created by AWS. However, when using the CDK Transit Gateway L2 construct, the underlying L1 construct is configured with `defaultRouteTableAssociation` and `defaultRouteTablePropagation` explicitly disabled. This ensures that AWS does not create the default route table, allowing the CDK to define a custom default route table instead.\n>\n> As a result, in the AWS Console, the **Default association route table** and **Default propagation route table** settings will appear as disabled. Despite this, the CDK still provides automatic association and propagation functionality through its internal implementation, which can be controlled using the `defaultRouteTableAssociation` and `defaultRouteTablePropagation` properties within the CDK.\n\n\nYou can disable the automatic Association/Propagation on the default `TransitGatewayRouteTable` via the `TransitGateway` properties. This will still create a default route table for you:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway', {\n defaultRouteTableAssociation: false,\n defaultRouteTablePropagation: false,\n});\n```\n\n### Transit Gateway Route Table Management\n\nAdd additional Transit Gateway Route Tables using the `addRouteTable()` method:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\n\nconst routeTable = transitGateway.addRouteTable('CustomRouteTable');\n```\n\n### Attaching VPCs to the Transit Gateway\n\nCurrently only VPC to Transit Gateway attachments are supported.\n\nCreate an attachment from a VPC to the Transit Gateway using the `attachVpc()` method:\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet1 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst subnet2 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.1.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\n\n// Create a basic attachment\nconst attachment = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet1, subnet2]\n});\n\n// Create an attachment with optional parameters\nconst attachmentWithOptions = transitGateway.attachVpc('VpcAttachmentWithOptions', {\n vpc: myVpc,\n subnets: [subnet1],\n vpcAttachmentOptions: {\n dnsSupport: true,\n applianceModeSupport: true,\n ipv6Support: true,\n securityGroupReferencingSupport: true,\n }\n});\n```\n\nIf you want to automatically associate and propagate routes with transit gateway route tables, you can pass the `associationRouteTable` and `propagationRouteTables` parameters. This will automatically create the necessary associations and propagations based on the provided route tables.\n\n```ts\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet1 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst subnet2 = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.1.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\nconst associationRouteTable = transitGateway.addRouteTable('AssociationRouteTable');\nconst propagationRouteTable1 = transitGateway.addRouteTable('PropagationRouteTable1');\nconst propagationRouteTable2 = transitGateway.addRouteTable('PropagationRouteTable2');\n\n// Create an attachment with automatically created association + propagations\nconst attachmentWithRoutes = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet1, subnet2],\n associationRouteTable: associationRouteTable,\n propagationRouteTables: [propagationRouteTable1, propagationRouteTable2],\n});\n```\n\nIn this example, the `associationRouteTable` is set to `associationRouteTable`, and `propagationRouteTables` is set to an array containing `propagationRouteTable1` and `propagationRouteTable2`. This triggers the automatic creation of route table associations and route propagations between the Transit Gateway and the specified route tables.\n\n### Adding static routes to the route table\n\nAdd static routes using either the `addRoute()` method to add an active route or `addBlackholeRoute()` to add a blackhole route:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\nconst routeTable = transitGateway.addRouteTable('CustomRouteTable');\n\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\n\nconst attachment = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet]\n});\n\n// Add a static route to direct traffic\nrouteTable.addRoute('StaticRoute', attachment, '10.0.0.0/16');\n\n// Block unwanted traffic with a blackhole route\nrouteTable.addBlackholeRoute('BlackholeRoute', '172.16.0.0/16');\n```\n\n### Route Table Associations and Propagations\n\nConfigure route table associations and enable route propagation:\n\n```ts\nconst transitGateway = new TransitGateway(this, 'MyTransitGateway');\nconst routeTable = transitGateway.addRouteTable('CustomRouteTable');\nconst myVpc = new VpcV2(this, 'Vpc');\nconst subnet = new SubnetV2(this, 'Subnet', {\n vpc: myVpc,\n availabilityZone: 'eu-west-2a',\n ipv4CidrBlock: new IpCidr('10.0.0.0/24'),\n subnetType: SubnetType.PUBLIC\n});\nconst attachment = transitGateway.attachVpc('VpcAttachment', {\n vpc: myVpc,\n subnets: [subnet]\n});\n\n// Associate an attachment with a route table\nrouteTable.addAssociation('Association', attachment);\n\n// Enable route propagation for an attachment\nrouteTable.enablePropagation('Propagation', attachment);\n```\n\n**Associations** — The linking of a Transit Gateway attachment to a specific route table, which determines which routes that attachment will use for routing decisions.\n\n**Propagation** — The automatic advertisement of routes from an attachment to a route table, allowing the route table to learn about available network destinations.\n"
8673
8731
  },
8674
8732
  "repository": {
8675
8733
  "directory": "packages/@aws-cdk/aws-ec2-alpha",
@@ -10588,10 +10646,10 @@
10588
10646
  {
10589
10647
  "abstract": true,
10590
10648
  "docs": {
10591
- "default": "- no route propogation",
10649
+ "default": "- no route propagation",
10592
10650
  "remarks": "For more information, see the {@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpngateway.html}.",
10593
10651
  "stability": "experimental",
10594
- "summary": "Adds VPN Gateway to VPC and set route propogation."
10652
+ "summary": "Adds VPN Gateway to VPC and set route propagation."
10595
10653
  },
10596
10654
  "locationInModule": {
10597
10655
  "filename": "lib/vpc-v2-base.ts",
@@ -11670,7 +11728,7 @@
11670
11728
  "docs": {
11671
11729
  "default": "- Stack.region if defined in the stack",
11672
11730
  "remarks": "Operating Regions are AWS Regions where the IPAM is allowed to manage IP address CIDRs\nFor more information about operating Regions, see [Create an IPAM](https://docs.aws.amazon.com//vpc/latest/ipam/create-ipam.html) in the *Amazon VPC IPAM User Guide* .",
11673
- "see": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipam.html#cfn-ec2-ipam-operatingregions",
11731
+ "see": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipam.html#cfn-ec2-ipam-operatingregions",
11674
11732
  "stability": "experimental",
11675
11733
  "summary": "The operating Regions for an IPAM."
11676
11734
  },
@@ -12330,7 +12388,7 @@
12330
12388
  "docs": {
12331
12389
  "default": "- required in case of an IPv6, throws an error if not provided.",
12332
12390
  "remarks": "\"ec2\", for example, allows users to use space for Elastic IP addresses and VPCs.",
12333
- "see": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-awsservice",
12391
+ "see": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-awsservice",
12334
12392
  "stability": "experimental",
12335
12393
  "summary": "Limits which service in AWS that the pool can be used in."
12336
12394
  },
@@ -12391,7 +12449,7 @@
12391
12449
  "docs": {
12392
12450
  "default": "- Current operating region of IPAM",
12393
12451
  "remarks": "Should be one of the IPAM operating region.\n Only resources in the same Region as the locale of the pool can get IP address allocations from the pool.\nYou can only allocate a CIDR for a VPC, for example, from an IPAM pool that shares a locale with the VPC’s Region.\nNote that once you choose a Locale for a pool, you cannot modify it. If you choose an AWS Region for locale that has not been configured as an operating Region for the IPAM, you'll get an error.",
12394
- "see": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-locale",
12452
+ "see": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-locale",
12395
12453
  "stability": "experimental",
12396
12454
  "summary": "The locale (AWS Region) of the pool."
12397
12455
  },
@@ -15925,7 +15983,7 @@
15925
15983
  {
15926
15984
  "abstract": true,
15927
15985
  "docs": {
15928
- "see": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpngateway.html#cfn-ec2-vpngateway-type",
15986
+ "see": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpngateway.html#cfn-ec2-vpngateway-type",
15929
15987
  "stability": "experimental",
15930
15988
  "summary": "The type of VPN connection the virtual private gateway supports."
15931
15989
  },
@@ -15978,7 +16036,7 @@
15978
16036
  {
15979
16037
  "abstract": true,
15980
16038
  "docs": {
15981
- "default": "- no propogation for routes",
16039
+ "default": "- no propagation for routes",
15982
16040
  "stability": "experimental",
15983
16041
  "summary": "Subnets where the route propagation should be added."
15984
16042
  },
@@ -17818,6 +17876,6 @@
17818
17876
  "symbolId": "lib/vpc-v2:VpcV2Props"
17819
17877
  }
17820
17878
  },
17821
- "version": "2.244.0-alpha.0",
17879
+ "version": "2.246.0-alpha.0",
17822
17880
  "fingerprint": "**********"
17823
17881
  }
Binary file
package/README.md CHANGED
@@ -584,7 +584,7 @@ You can import an existing VPC and its subnets using the `VpcV2.fromVpcV2Attribu
584
584
 
585
585
  To import an existing VPC, use the `VpcV2.fromVpcV2Attributes()` method. You'll need to provide the VPC ID, primary CIDR block, and information about the subnets. You can import secondary address as well created through IPAM, BYOIP(IPv4) or enabled through Amazon Provided IPv6. You must provide VPC Id and its primary CIDR block for importing it.
586
586
 
587
- If you wish to add a new subnet to imported VPC, new subnet's IP range(IPv4) will be validated against provided secondary and primary address block to confirm that it is within the the range of VPC.
587
+ If you wish to add a new subnet to imported VPC, new subnet's IP range(IPv4) will be validated against provided secondary and primary address block to confirm that it is within the range of VPC.
588
588
 
589
589
  Here's an example of importing a VPC with only the required parameters
590
590
 
package/lib/ipam.d.ts CHANGED
@@ -51,7 +51,7 @@ export interface IpamProps {
51
51
  * The operating Regions for an IPAM.
52
52
  * Operating Regions are AWS Regions where the IPAM is allowed to manage IP address CIDRs
53
53
  * For more information about operating Regions, see [Create an IPAM](https://docs.aws.amazon.com//vpc/latest/ipam/create-ipam.html) in the *Amazon VPC IPAM User Guide* .
54
- * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipam.html#cfn-ec2-ipam-operatingregions
54
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipam.html#cfn-ec2-ipam-operatingregions
55
55
  *
56
56
  * @default - Stack.region if defined in the stack
57
57
  */
@@ -97,7 +97,7 @@ export interface PoolOptions {
97
97
  * Only resources in the same Region as the locale of the pool can get IP address allocations from the pool.
98
98
  * You can only allocate a CIDR for a VPC, for example, from an IPAM pool that shares a locale with the VPC’s Region.
99
99
  * Note that once you choose a Locale for a pool, you cannot modify it. If you choose an AWS Region for locale that has not been configured as an operating Region for the IPAM, you'll get an error.
100
- * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-locale
100
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-locale
101
101
  *
102
102
  * @default - Current operating region of IPAM
103
103
  */
@@ -115,7 +115,7 @@ export interface PoolOptions {
115
115
  *
116
116
  * "ec2", for example, allows users to use space for Elastic IP addresses and VPCs.
117
117
  *
118
- * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-awsservice
118
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-ipampool.html#cfn-ec2-ipampool-awsservice
119
119
  *
120
120
  * @default - required in case of an IPv6, throws an error if not provided.
121
121
  */
package/lib/ipam.js CHANGED
@@ -315,7 +315,7 @@ let Ipam = (() => {
315
315
  Ipam = _classThis = _classDescriptor.value;
316
316
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
317
317
  }
318
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-ec2-alpha.Ipam", version: "2.244.0-alpha.0" };
318
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-ec2-alpha.Ipam", version: "2.246.0-alpha.0" };
319
319
  /** Uniquely identifies this class. */
320
320
  static PROPERTY_INJECTION_ID = '@aws-cdk.aws-ec2-alpha.Ipam';
321
321
  /**
@@ -444,4 +444,4 @@ function createIpamPool(scope, id, scopeOptions, poolOptions, scopeId) {
444
444
  awsService: poolOptions.awsService,
445
445
  });
446
446
  }
447
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImlwYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQWlFO0FBQ2pFLGlEQUEwRjtBQUMxRiw4RUFBOEY7QUFDOUYsMEVBQTBFO0FBRzFFOzs7OztHQUtHO0FBQ0gsSUFBWSxhQVlYO0FBWkQsV0FBWSxhQUFhO0lBQ3ZCOzs7T0FHRztJQUNILCtCQUFjLENBQUE7SUFFZDs7O09BR0c7SUFDSCwrQkFBYyxDQUFBO0FBQ2hCLENBQUMsRUFaVyxhQUFhLDZCQUFiLGFBQWEsUUFZeEI7QUFFRDs7OztHQUlHO0FBQ0gsSUFBWSxzQkFVWDtBQVZELFdBQVksc0JBQXNCO0lBQ2hDOztPQUVHO0lBQ0gseUNBQWUsQ0FBQTtJQUVmOztPQUVHO0lBQ0gsMkNBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQVZXLHNCQUFzQixzQ0FBdEIsc0JBQXNCLFFBVWpDO0FBRUQ7O0dBRUc7QUFDSCxJQUFZLGNBS1g7QUFMRCxXQUFZLGNBQWM7SUFDeEI7O09BRUc7SUFDSCw2QkFBVyxDQUFBO0FBQ2IsQ0FBQyxFQUxXLGNBQWMsOEJBQWQsY0FBYyxRQUt6QjtBQXlCRDs7R0FFRztBQUNILElBQVksYUFVWDtBQVZELFdBQVksYUFBYTtJQUN2Qjs7T0FFRztJQUNILG9DQUFtQixDQUFBO0lBRW5COztPQUVHO0lBQ0gsa0NBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQVZXLGFBQWEsNkJBQWIsYUFBYSxRQVV4QjtBQTRERCxNQUFNLFFBQVEsR0FBVyxNQUFNLENBQUM7QUE4SmhDOzs7Ozs7R0FNRztJQUVHLFFBQVE7NEJBRGIsb0NBQWtCOzs7O3NCQUNJLHNCQUFROzs7d0JBQWhCLFNBQVEsV0FBUTs7Ozt5Q0FnRTVCLElBQUEsa0NBQWMsR0FBRTtZQUNqQiwwTEFBTyxhQUFhLDZEQU9uQjtZQXhFSCw2S0F5RUM7Ozs7UUF4RUMsc0NBQXNDO1FBQy9C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QWMsQ0FDckIsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLFlBQTRCLEVBQzVCLFdBQXdCLEVBQ3hCLE9BQWU7SUFFZixrRUFBa0U7SUFDbEUsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdkIsTUFBTSwwQkFBMEIsR0FBRyxZQUFZLENBQUMsb0JBQW9CO1lBQ2xFLENBQUMsQ0FBQyxZQUFZLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUN4RSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxLQUFLLFdBQVcsQ0FBQyxNQUFNLENBQUM7WUFDM0QsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUVWLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLFdBQVcsQ0FBQyxNQUFNLHNDQUFzQyxZQUFZLENBQUMsb0JBQW9CLEtBQUs7Z0JBQ3BJLDhFQUE4RSxDQUFDLENBQUM7UUFDcEYsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7UUFDN0IsWUFBWSxFQUFFLFdBQVcsQ0FBQyxZQUFZO1FBQ3RDLGFBQWEsRUFBRSxXQUFXLENBQUMsYUFBYTtRQUN4QyxvQkFBb0IsRUFBRSxXQUFXLENBQUMsb0JBQW9CO1FBQ3RELFdBQVcsRUFBRSxPQUFPO1FBQ3BCLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTTtRQUMxQixjQUFjLEVBQUUsV0FBVyxDQUFDLGNBQWM7UUFDMUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxVQUFVO0tBQ25DLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMYXp5LCBOYW1lcywgUmVzb3VyY2UsIFN0YWNrLCBUYWdzIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ2ZuSVBBTSwgQ2ZuSVBBTVBvb2wsIENmbklQQU1Qb29sQ2lkciwgQ2ZuSVBBTVNjb3BlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgeyBhZGRDb25zdHJ1Y3RNZXRhZGF0YSwgTWV0aG9kTWV0YWRhdGEgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9tZXRhZGF0YS1yZXNvdXJjZSc7XG5pbXBvcnQgeyBwcm9wZXJ0eUluamVjdGFibGUgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9wcm9wLWluamVjdGFibGUnO1xuaW1wb3J0IHR5cGUgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBhZGRyZXNzIGZhbWlseSBmb3IgSVAgYWRkcmVzc2VzIGluIGFuIElQQU0gcG9vbC5cbiAqIElQX1Y0IC0gUmVwcmVzZW50cyB0aGUgSVB2NCBhZGRyZXNzIGZhbWlseS5cbiAqIElQX1Y2IC0gUmVwcmVzZW50cyB0aGUgSVB2NiBhZGRyZXNzIGZhbWlseS5cbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sI2Nmbi1lYzItaXBhbXBvb2wtYWRkcmVzc2ZhbWlseVxuICovXG5leHBvcnQgZW51bSBBZGRyZXNzRmFtaWx5IHtcbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIElQdjQgYWRkcmVzcyBmYW1pbHkuXG4gICAqIEFsbG93ZWQgdW5kZXIgcHVibGljIGFuZCBwcml2YXRlIHBvb2wuXG4gICAqL1xuICBJUF9WNCA9ICdpcHY0JyxcblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgSVB2NiBhZGRyZXNzIGZhbWlseS5cbiAgICogT25seSBhbGxvd2VkIHVuZGVyIHB1YmxpYyBwb29sLlxuICAgKi9cbiAgSVBfVjYgPSAnaXB2NicsXG59XG5cbi8qKlxuICogVGhlIElQIGFkZHJlc3Mgc291cmNlIGZvciBwb29scyBpbiB0aGUgcHVibGljIHNjb3BlLlxuICogT25seSB1c2VkIGZvciBwcm92aXNpb25pbmcgSVAgYWRkcmVzcyBDSURScyB0byBwb29scyBpbiB0aGUgcHVibGljIHNjb3BlLlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sLmh0bWwjY2ZuLWVjMi1pcGFtcG9vbC1wdWJsaWNpcHNvdXJjZVxuICovXG5leHBvcnQgZW51bSBJcGFtUG9vbFB1YmxpY0lwU291cmNlIHtcbiAgLyoqXG4gICAqIEJZT0lQIElwdjYgdG8gYmUgcmVnaXN0ZXJlZCB1bmRlciBJUEFNXG4gICAqL1xuICBCWU9JUCA9ICdieW9pcCcsXG5cbiAgLyoqXG4gICAqIEFtYXpvbiBQcm92aWRlZCBJcHY2IHJhbmdlXG4gICAqL1xuICBBTUFaT04gPSAnYW1hem9uJyxcbn1cblxuLyoqXG4gKiBMaW1pdHMgd2hpY2ggc2VydmljZSBpbiBBV1MgdGhhdCB0aGUgcG9vbCBjYW4gYmUgdXNlZCBpblxuICovXG5leHBvcnQgZW51bSBBd3NTZXJ2aWNlTmFtZSB7XG4gIC8qKlxuICAgKiAgQWxsb3dzIHVzZXJzIHRvIHVzZSBzcGFjZSBmb3IgRWxhc3RpYyBJUCBhZGRyZXNzZXMgYW5kIFZQQ3NcbiAgICovXG4gIEVDMiA9ICdlYzInLFxufVxuXG4vKipcbiAqIE9wdGlvbnMgdG8gY3JlYXRlIGEgbmV3IElwYW0gaW4gdGhlIGFjY291bnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJcGFtUHJvcHMge1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlcmF0aW5nIFJlZ2lvbnMgZm9yIGFuIElQQU0uXG4gICAqIE9wZXJhdGluZyBSZWdpb25zIGFyZSBBV1MgUmVnaW9ucyB3aGVyZSB0aGUgSVBBTSBpcyBhbGxvd2VkIHRvIG1hbmFnZSBJUCBhZGRyZXNzIENJRFJzXG4gICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG9wZXJhdGluZyBSZWdpb25zLCBzZWUgW0NyZWF0ZSBhbiBJUEFNXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vL3ZwYy9sYXRlc3QvaXBhbS9jcmVhdGUtaXBhbS5odG1sKSBpbiB0aGUgKkFtYXpvbiBWUEMgSVBBTSBVc2VyIEd1aWRlKiAuXG4gICAqIEBzZWUgaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW0uaHRtbCNjZm4tZWMyLWlwYW0tb3BlcmF0aW5ncmVnaW9uc1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIFN0YWNrLnJlZ2lvbiBpZiBkZWZpbmVkIGluIHRoZSBzdGFja1xuICAgKi9cbiAgcmVhZG9ubHkgb3BlcmF0aW5nUmVnaW9ucz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIElQQU0gdGhhdCBjYW4gYmUgdXNlZCBmb3IgdGFnZ2luZyByZXNvdXJjZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIElmIG5vIG5hbWUgcHJvdmlkZWQsIG5vIHRhZ3Mgd2lsbCBiZSBhZGRlZCB0byB0aGUgSVBBTVxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbU5hbWU/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVmZXJzIHRvIHR3byBwb3NzaWJsZSBzY29wZSB0eXBlcyB1bmRlciBJUEFNXG4gKi9cbmV4cG9ydCBlbnVtIElwYW1TY29wZVR5cGUge1xuICAvKipcbiAgICogRGVmYXVsdCBzY29wZXMgY3JlYXRlZCBieSBJUEFNXG4gICAqL1xuICBERUZBVUxUID0gJ2RlZmF1bHQnLFxuXG4gIC8qKlxuICAgKiBDdXN0b20gc2NvcGUgY3JlYXRlZCB1c2luZyBtZXRob2RcbiAgICovXG4gIENVU1RPTSA9ICdjdXN0b20nLFxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNvbmZpZ3VyaW5nIGFuIElQQU0gcG9vbC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lYzItaXBhbXBvb2wuaHRtbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvb2xPcHRpb25zIHtcblxuICAvKipcbiAgICogYWRkcmVzc0ZhbWlseSAtIFRoZSBhZGRyZXNzIGZhbWlseSBvZiB0aGUgcG9vbCAoaXB2NCBvciBpcHY2KS5cbiAgICovXG4gIHJlYWRvbmx5IGFkZHJlc3NGYW1pbHk6IEFkZHJlc3NGYW1pbHk7XG5cbiAgLyoqXG4gICAqIEluZm9ybWF0aW9uIGFib3V0IHRoZSBDSURScyBwcm92aXNpb25lZCB0byB0aGUgcG9vbC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBDSURScyBhcmUgcHJvdmlzaW9uZWRcbiAgICovXG4gIHJlYWRvbmx5IGlwdjRQcm92aXNpb25lZENpZHJzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoZSBsb2NhbGUgKEFXUyBSZWdpb24pIG9mIHRoZSBwb29sLiBTaG91bGQgYmUgb25lIG9mIHRoZSBJUEFNIG9wZXJhdGluZyByZWdpb24uXG4gICAqICBPbmx5IHJlc291cmNlcyBpbiB0aGUgc2FtZSBSZWdpb24gYXMgdGhlIGxvY2FsZSBvZiB0aGUgcG9vbCBjYW4gZ2V0IElQIGFkZHJlc3MgYWxsb2NhdGlvbnMgZnJvbSB0aGUgcG9vbC5cbiAgICogWW91IGNhbiBvbmx5IGFsbG9jYXRlIGEgQ0lEUiBmb3IgYSBWUEMsIGZvciBleGFtcGxlLCBmcm9tIGFuIElQQU0gcG9vbCB0aGF0IHNoYXJlcyBhIGxvY2FsZSB3aXRoIHRoZSBWUEPigJlzIFJlZ2lvbi5cbiAgICogTm90ZSB0aGF0IG9uY2UgeW91IGNob29zZSBhIExvY2FsZSBmb3IgYSBwb29sLCB5b3UgY2Fubm90IG1vZGlmeSBpdC4gSWYgeW91IGNob29zZSBhbiBBV1MgUmVnaW9uIGZvciBsb2NhbGUgdGhhdCBoYXMgbm90IGJlZW4gY29uZmlndXJlZCBhcyBhbiBvcGVyYXRpbmcgUmVnaW9uIGZvciB0aGUgSVBBTSwgeW91J2xsIGdldCBhbiBlcnJvci5cbiAgICogQHNlZSBodHRwOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lYzItaXBhbXBvb2wuaHRtbCNjZm4tZWMyLWlwYW1wb29sLWxvY2FsZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEN1cnJlbnQgb3BlcmF0aW5nIHJlZ2lvbiBvZiBJUEFNXG4gICAqL1xuICByZWFkb25seSBsb2NhbGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBJUCBhZGRyZXNzIHNvdXJjZSBmb3IgcG9vbHMgaW4gdGhlIHB1YmxpYyBzY29wZS5cbiAgICogT25seSB1c2VkIGZvciBJUHY2IGFkZHJlc3NcbiAgICogT25seSBhbGxvd2VkIHZhbHVlcyB0byB0aGlzIGFyZSAnYnlvaXAnIG9yICdhbWF6b24nXG4gICAqXG4gICAqIEBkZWZhdWx0IGFtYXpvblxuICAgKi9cbiAgcmVhZG9ubHkgcHVibGljSXBTb3VyY2U/OiBJcGFtUG9vbFB1YmxpY0lwU291cmNlO1xuXG4gIC8qKlxuICAgKiBMaW1pdHMgd2hpY2ggc2VydmljZSBpbiBBV1MgdGhhdCB0aGUgcG9vbCBjYW4gYmUgdXNlZCBpbi5cbiAgICpcbiAgICogXCJlYzJcIiwgZm9yIGV4YW1wbGUsIGFsbG93cyB1c2VycyB0byB1c2Ugc3BhY2UgZm9yIEVsYXN0aWMgSVAgYWRkcmVzc2VzIGFuZCBWUENzLlxuICAgKlxuICAgKiBAc2VlIGh0dHA6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sI2Nmbi1lYzItaXBhbXBvb2wtYXdzc2VydmljZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHJlcXVpcmVkIGluIGNhc2Ugb2YgYW4gSVB2NiwgdGhyb3dzIGFuIGVycm9yIGlmIG5vdCBwcm92aWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGF3c1NlcnZpY2U/OiBBd3NTZXJ2aWNlTmFtZTtcblxuICAvKipcbiAgICogSVBBTSBQb29sIHJlc291cmNlIG5hbWUgdG8gYmUgdXNlZCBmb3IgdGFnZ2luZ1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF1dG9nZW5lcmF0ZWQgYnkgQ0RLIGlmIG5vdCBwcm92aWRlZFxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbVBvb2xOYW1lPzogc3RyaW5nO1xufVxuXG5jb25zdCBOQU1FX1RBRzogc3RyaW5nID0gJ05hbWUnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGFuIElQQU0gcG9vbC5cbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sXG4gKi9cbmludGVyZmFjZSBJcGFtUG9vbFByb3BzIGV4dGVuZHMgUG9vbE9wdGlvbnMge1xuICAvKipcbiAgICogU2NvcGUgaWQgd2hlcmUgcG9vbCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAqL1xuICByZWFkb25seSBpcGFtU2NvcGVJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgdG8gcHJvdmlzaW9uIENJRFJzIHRvIGFuIElQQU0gcG9vbC5cbiAqIFVzZWQgdG8gY3JlYXRlIGEgbmV3IElwYW1Qb29sQ2lkclxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sY2lkci5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSXBhbVBvb2xDaWRyUHJvdmlzaW9uaW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJcHY2IE5ldG1hc2sgbGVuZ3RoIGZvciB0aGUgQ0lEUlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHBvb2wgcHJvdmlzaW9uZWQgd2l0aG91dCBuZXRtYXNrIGxlbmd0aCwgbmVlZCBjaWRyIHJhbmdlIGluIHRoaXMgY2FzZVxuICAgKi9cbiAgcmVhZG9ubHkgbmV0bWFza0xlbmd0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogSXB2NiBDSURSIGJsb2NrIGZvciB0aGUgSVBBTSBwb29sXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcG9vbCBwcm92aXNpb25lZCB3aXRob3V0IG5ldG1hc2sgbGVuZ3RoLCBuZWVkIG5ldG1hc2sgbGVuZ3RoIGluIHRoaXMgY2FzZVxuICAgKi9cbiAgcmVhZG9ubHkgY2lkcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZWZpbml0aW9uIHVzZWQgdG8gYWRkIG9yIGNyZWF0ZSBhIG5ldyBJUEFNIHBvb2xcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSXBhbVBvb2wge1xuICAvKipcbiAgICogUG9vbCBJRCB0byBiZSBwYXNzZWQgdG8gdGhlIFZQQyBjb25zdHJ1Y3RcbiAgICogQGF0dHJpYnV0ZSBJcGFtUG9vbElkXG4gICAqL1xuICByZWFkb25seSBpcGFtUG9vbElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFBvb2wgQ0lEUiBmb3IgSVB2NiB0byBiZSBwcm92aXNpb25lZCB3aXRoIFB1YmxpYyBJUCBzb3VyY2Ugc2V0IHRvICdBbWF6b24nXG4gICAqL1xuICByZWFkb25seSBpcGFtQ2lkcnM6IENmbklQQU1Qb29sQ2lkcltdO1xuXG4gIC8qKlxuICAgKiBQb29sIENJRFIgZm9yIElQdjQgdG8gYmUgcHJvdmlzaW9uZWQgdXNpbmcgSVBBTVxuICAgKiBSZXF1aXJlZCB0byBjaGVjayBmb3Igc3VibmV0IElQIHJhbmdlIGlzIHdpdGhpbiB0aGUgVlBDIHJhbmdlXG4gICAqL1xuICByZWFkb25seSBpcGFtSXB2NENpZHJzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBhIElQdjYgYWRkcmVzcyB3aXRoIElQQU0gcG9vbFxuICAgKi9cbiAgcHJvdmlzaW9uQ2lkcihpZDogc3RyaW5nLCBvcHRpb25zOiBJcGFtUG9vbENpZHJQcm92aXNpb25pbmdPcHRpb25zKTogQ2ZuSVBBTVBvb2xDaWRyO1xuXG59XG5cbi8qKlxuICogSVBBTSBzY29wZSBpcyB0aGUgaGlnaGVzdC1sZXZlbCBjb250YWluZXIgd2l0aGluIElQQU0uIEFuIElQQU0gY29udGFpbnMgdHdvIGRlZmF1bHQgc2NvcGVzLlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1zY29wZS5odG1sXG4gKi9cbmludGVyZmFjZSBJcGFtU2NvcGVQcm9wcyBleHRlbmRzIElwYW1TY29wZU9wdGlvbnMge1xuICAvKipcbiAgICogSVBBTSBpZCB0byB3aGljaCBzY29wZSBuZWVkcyB0byBiZSBhZGRlZFxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE9wZXJhdGluZyByZWdpb25zIGZvciB0aGUgSXBhbVxuICAgKiBSZXF1aXJlZCBpbiBvcmRlciB0byB2YWxpZGF0ZSB0aGUgbG9jYWxlIGJlaW5nIHNldCBvbiBwb29sXG4gICAqL1xuICByZWFkb25seSBpcGFtT3BlcmF0aW5nUmVnaW9uczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBpcGFtIHNjb3BlIGlkIHRvIGFkZCBhIHBvb2wgaW4gb3JkZXIgdG8gc3VwcG9ydCBkZWZhdWx0IHNjb3Blc1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRocm93cyBhbiBlcnJvciBpZiBubyBzY29wZSBpZCBpcyBwcm92aWRlZFxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbVNjb3BlSWQ/OiBzdHJpbmc7XG5cbn1cblxuLyoqXG4gKiBCZWluZyB1c2VkIGluIElQQU0gY2xhc3MgdG8gYWRkIHBvb2xzIHRvIGRlZmF1bHQgc2NvcGUgY3JlYXRlZCBieSBJUEFNLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElwYW1TY29wZU9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBJUEFNIHNjb3BlIG5hbWUgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHRhZ2dpbmdcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyB0YWdzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHNjb3BlXG4gICAqL1xuICByZWFkb25seSBpcGFtU2NvcGVOYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNvbmZpZ3VyaW5nIGFuIElQIEFkZHJlc3MgTWFuYWdlciAoSVBBTSkuXG4gKlxuICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSB0aGUge0BsaW5rIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lYzItaXBhbS5odG1sfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJcGFtT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIENJRFIgTWFzayBmb3IgVnBjXG4gICAqIE9ubHkgcmVxdWlyZWQgd2hlbiB1c2luZyBBV1MgSXBhbVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIG5ldG1hc2sgbGVuZ3RoIGZvciBJUEFNIGF0dGFjaGVkIHRvIFZQQyBzZWNvbmRhcnkgYWRkcmVzc1xuICAgKi9cbiAgcmVhZG9ubHkgbmV0bWFza0xlbmd0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogSXB2NCBvciBhbiBJcHY2IElQQU0gcG9vbFxuICAgKiBPbmx5IHJlcXVpcmVkIHdoZW4gdXNpbmcgQVdTIElwYW1cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBwb29sIGF0dGFjaGVkIHRvIFZQQyBzZWNvbmRhcnkgYWRkcmVzc1xuICAgKi9cbiAgcmVhZG9ubHkgaXBhbVBvb2w/OiBJSXBhbVBvb2w7XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVkIHRvIHNldCBTZWNvbmRhcnkgY2lkciBibG9jayByZXNvdXJjZSBuYW1lXG4gICAqIGluIG9yZGVyIHRvIGdlbmVyYXRlIHVuaXF1ZSBsb2dpY2FsIGlkIGZvciB0aGUgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBjaWRyQmxvY2tOYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBJcGFtU2NvcGUgQ2xhc3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSXBhbVNjb3BlQmFzZSB7XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBzY29wZSBvZiBzdGFjayB0byBiZSBwYXNzZWQgaW4gb3JkZXIgdG8gY3JlYXRlXG4gICAqIGEgbmV3IElQQU0gcG9vbFxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdDtcblxuICAvKipcbiAgICogRGVmYXVsdCBTY29wZSBpZHMgY3JlYXRlZCBieSB0aGUgSVBBTSBvciBhIG5ldyBSZXNvdXJjZSBpZFxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGVJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIHNjb3BlIHR5cGUgY2FuIGJlIGVpdGhlciBkZWZhdWx0IG9yIGN1c3RvbVxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGVUeXBlPzogSXBhbVNjb3BlVHlwZTtcblxuICAvKipcbiAgICogRnVuY3Rpb24gdG8gYWRkIGEgbmV3IHBvb2wgdG8gYW4gSVBBTSBzY29wZVxuICAgKi9cbiAgYWRkUG9vbChpZDogc3RyaW5nLCBvcHRpb25zOiBQb29sT3B0aW9ucyk6IElJcGFtUG9vbDtcblxufVxuXG4vKipcbiAqIENyZWF0ZXMgbmV3IElQQU0gUG9vbFxuICogUG9vbHMgZW5hYmxlIHlvdSB0byBvcmdhbml6ZSB5b3VyIElQIGFkZHJlc3NlcyBhY2NvcmRpbmcgdG8geW91ciByb3V0aW5nIGFuZCBzZWN1cml0eSBuZWVkc1xuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sLmh0bWxcbiAqIEByZXNvdXJjZSBBV1M6OkVDMjo6SVBBTVBvb2xcbiAqIEBpbnRlcm5hbFxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5jbGFzcyBJcGFtUG9vbCBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSUlwYW1Qb29sIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWMyLWFscGhhLklwYW1Qb29sJztcbiAgLyoqXG4gICAqIFBvb2wgSUQgdG8gYmUgcGFzc2VkIHRvIHRoZSBWUEMgY29uc3RydWN0XG4gICAqIEBhdHRyaWJ1dGUgSXBhbVBvb2xJZFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlwYW1Qb29sSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogUG9vbCBDSURSIGZvciBJUHY2IHRvIGJlIHByb3Zpc2lvbmVkIHdpdGggUHVibGljIElQIHNvdXJjZSBzZXQgdG8gJ0FtYXpvbidcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpcGFtQ2lkcnM6IENmbklQQU1Qb29sQ2lkcltdID0gW107XG5cbiAgLyoqXG4gICAqIFBvb2wgQ0lEUiBmb3IgSVB2NCB0byBiZSBwcm92aXNpb25lZCB1c2luZyBJUEFNXG4gICAqIFJlcXVpcmVkIHRvIGNoZWNrIGZvciBzdWJuZXQgSVAgcmFuZ2UgaXMgd2l0aGluIHRoZSBWUEMgcmFuZ2VcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpcGFtSXB2NENpZHJzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgdG8gaXBhbVBvb2wgcmVzb3VyY2UgY3JlYXRlZCBpbiB0aGlzIGNsYXNzXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9pcGFtUG9vbDogQ2ZuSVBBTVBvb2w7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElwYW1Qb29sUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMuaXBhbVBvb2xOYW1lID8/IExhenkuc3RyaW5nKHtcbiAgICAgICAgcHJvZHVjZTogKCkgPT4gTmFtZXMudW5pcXVlUmVzb3VyY2VOYW1lKHRoaXMsIHsgbWF4TGVuZ3RoOiAxMjgsIGFsbG93ZWRTcGVjaWFsQ2hhcmFjdGVyczogJ18nIH0pLFxuICAgICAgfSksXG4gICAgfSk7XG4gICAgLy8gRW5oYW5jZWQgQ0RLIEFuYWx5dGljcyBUZWxlbWV0cnlcbiAgICBhZGRDb25zdHJ1Y3RNZXRhZGF0YSh0aGlzLCBwcm9wcyk7XG5cbiAgICBpZiAocHJvcHMuYWRkcmVzc0ZhbWlseSA9PT0gQWRkcmVzc0ZhbWlseS5JUF9WNiAmJiAhcHJvcHMuYXdzU2VydmljZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhd3NTZXJ2aWNlIGlzIHJlcXVpcmVkIHdoZW4gYWRkcmVzc0ZhbWlseSBpcyBzZXQgdG8gaXB2NicpO1xuICAgIH1cblxuICAgIC8vIEFkZCB0YWdzIHRvIHRoZSBJUEFNIFBvb2wgaWYgbmFtZSBpcyBwcm92aWRlZFxuICAgIGlmIChwcm9wcy5pcGFtUG9vbE5hbWUpIHtcbiAgICAgIFRhZ3Mub2YodGhpcykuYWRkKE5BTUVfVEFHLCBwcm9wcy5pcGFtUG9vbE5hbWUpO1xuICAgIH1cblxuICAgIHRoaXMuX2lwYW1Qb29sID0gbmV3IENmbklQQU1Qb29sKHRoaXMsIGlkLCB7XG4gICAgICBhZGRyZXNzRmFtaWx5OiBwcm9wcy5hZGRyZXNzRmFtaWx5LFxuICAgICAgcHJvdmlzaW9uZWRDaWRyczogcHJvcHMuaXB2NFByb3Zpc2lvbmVkQ2lkcnM/Lm1hcChjaWRyID0+ICh7IGNpZHIgfSkpLFxuICAgICAgbG9jYWxlOiBwcm9wcy5sb2NhbGUsXG4gICAgICBpcGFtU2NvcGVJZDogcHJvcHMuaXBhbVNjb3BlSWQsXG4gICAgICBwdWJsaWNJcFNvdXJjZTogcHJvcHMucHVibGljSXBTb3VyY2UsXG4gICAgICBhd3NTZXJ2aWNlOiBwcm9wcy5hd3NTZXJ2aWNlLFxuICAgIH0pO1xuICAgIHRoaXMuaXBhbVBvb2xJZCA9IHRoaXMuX2lwYW1Qb29sLmF0dHJJcGFtUG9vbElkO1xuXG4gICAgLy8gUG9wdWxhdGluZyB0byBjaGVjayBmb3Igc3VibmV0IHJhbmdlIGFnYWluc3QgYWxsIElQdjQgcmFuZ2VzIGFzc2lnbmVkIHRvIFZQQyBpbmNsdWRpbmcgSVBBTVxuICAgIHByb3BzLmlwdjRQcm92aXNpb25lZENpZHJzPy5tYXAoY2lkciA9PiAodGhpcy5pcGFtSXB2NENpZHJzLnB1c2goY2lkcikpKTtcbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5faXBhbVBvb2w7XG4gIH1cblxuICAvKipcbiAgICogQSBDSURSIHByb3Zpc2lvbmVkIHRvIGFuIElQQU0gcG9vbC5cbiAgICogQHBhcmFtIGlkIE5hbWUgb2YgUmVzb3VyY2VcbiAgICogQHBhcmFtIG9wdGlvbnMgRWl0aGVyIGEgQ0lEUiBvciBuZXRtYXNrIGxlbmd0aCBtdXN0IGJlIHByb3ZpZGVkXG4gICAqIEByZXR1cm5zIEFXUzo6RUMyOjpJUEFNUG9vbENpZHJcbiAgICovXG4gIEBNZXRob2RNZXRhZGF0YSgpXG4gIHB1YmxpYyBwcm92aXNpb25DaWRyKGlkOiBzdHJpbmcsIG9wdGlvbnM6IElwYW1Qb29sQ2lkclByb3Zpc2lvbmluZ09wdGlvbnMpOiBDZm5JUEFNUG9vbENpZHIge1xuICAgIGNvbnN0IGNpZHIgPSBuZXcgQ2ZuSVBBTVBvb2xDaWRyKHRoaXMsIGlkLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgaXBhbVBvb2xJZDogdGhpcy5pcGFtUG9vbElkLFxuICAgIH0pO1xuICAgIHRoaXMuaXBhbUNpZHJzLnB1c2goY2lkcik7XG4gICAgcmV0dXJuIGNpZHI7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGN1c3RvbSBJcGFtIFNjb3BlLCBjdXN0b20gSVBBTSBzY29wZXMgY2FuIG9ubHkgYmUgcHJpdmF0ZVxuICogKGNhbiBiZSB1c2VkIGZvciBhZGRpbmcgY3VzdG9tIHNjb3BlcyB0byBhbiBleGlzdGluZyBJUEFNKVxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1zY29wZS5odG1sXG4gKiBAcmVzb3VyY2UgQVdTOjpFQzI6OklQQU1TY29wZVxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5jbGFzcyBJcGFtU2NvcGUgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElJcGFtU2NvcGVCYXNlIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWMyLWFscGhhLklwYW1TY29wZSc7XG4gIC8qKlxuICAgKiBTdG9yZXMgdGhlIHJlZmVyZW5jZSB0byBuZXdseSBjcmVhdGVkIFJlc291cmNlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9pcGFtU2NvcGU6IENmbklQQU1TY29wZTtcblxuICAvKipcbiAgICogSUQgZm9yIFJlc291cmNlIElwYW1TY29wZVxuICAgKiBAYXR0cmlidXRlIElwYW1TY29wZUlkXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2NvcGVJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIHRvIGNvbmZpZ3VyZSBpcGFtIHNjb3BlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBJcGFtU2NvcGVQcm9wcztcblxuICAvKipcbiAgICogUmVmZXJlbmNlIHRvIHN0YWNrIHNjb3BlIHRvIGJlIHBhc3NlZCB0aHJvdWdoIGFkZFBvb2wgbWV0aG9kIGlub3JkZXIgdG8gY3JlYXRlIGEgbmV3IElwYW1Qb29sXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdDtcblxuICAvKipcbiAgICogRGVmaW5lcyBzY29wZSB0eXBlIGNhbiBiZSBlaXRoZXIgZGVmYXVsdCBvciBjdXN0b21cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzY29wZVR5cGU6IElwYW1TY29wZVR5cGU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElwYW1TY29wZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICAvLyBFbmhhbmNlZCBDREsgQW5hbHl0aWNzIFRlbGVtZXRyeVxuICAgIGFkZENvbnN0cnVjdE1ldGFkYXRhKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLl9pcGFtU2NvcGUgPSBuZXcgQ2ZuSVBBTVNjb3BlKHNjb3BlLCAnSXBhbVNjb3BlJywge1xuICAgICAgaXBhbUlkOiBwcm9wcy5pcGFtSWQsXG4gICAgfSk7XG4gICAgVGFncy5vZih0aGlzLl9pcGFtU2NvcGUpLmFkZChOQU1FX1RBRywgcHJvcHMuaXBhbVNjb3BlTmFtZSA/PyAnQ3VzdG9tSXBhbVNjb3BlJyk7XG4gICAgdGhpcy5zY29wZUlkID0gdGhpcy5faXBhbVNjb3BlLmF0dHJJcGFtU2NvcGVJZDtcbiAgICB0aGlzLnNjb3BlVHlwZSA9IElwYW1TY29wZVR5cGUuQ1VTVE9NO1xuICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBvb2wgdG8gdGhlIElQQU0gc2NvcGUuXG4gICAqIEBleHRlcm5hbFxuICAgKi9cbiAgYWRkUG9vbChpZDogc3RyaW5nLCBvcHRpb25zOiBQb29sT3B0aW9ucyk6IElJcGFtUG9vbCB7XG4gICAgcmV0dXJuIGNyZWF0ZUlwYW1Qb29sKHRoaXMuc2NvcGUsIGlkLCB0aGlzLnByb3BzLCBvcHRpb25zLCB0aGlzLnNjb3BlSWQpO1xuICB9XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgSVBBTSBkZWZhdWx0IHNjb3Blcy5cbiAqL1xuY2xhc3MgSXBhbVNjb3BlQmFzZSBpbXBsZW1lbnRzIElJcGFtU2NvcGVCYXNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdCxcbiAgICByZWFkb25seSBzY29wZUlkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogSXBhbVNjb3BlUHJvcHMsXG4gICAgcmVhZG9ubHkgc2NvcGVUeXBlPzogSXBhbVNjb3BlVHlwZSxcbiAgKSB7XG4gICAgdGhpcy5zY29wZVR5cGUgPSBJcGFtU2NvcGVUeXBlLkRFRkFVTFQ7XG4gICAgaWYgKCFwcm9wcy5pcGFtU2NvcGVJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpcGFtU2NvcGVJZCBpcyByZXF1aXJlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjb3BlSWQgPSBwcm9wcy5pcGFtU2NvcGVJZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBvb2wgdG8gdGhlIElQQU0gc2NvcGUuXG4gICAqIEBleHRlcm5hbFxuICAgKi9cbiAgYWRkUG9vbChpZDogc3RyaW5nLCBvcHRpb25zOiBQb29sT3B0aW9ucyk6IElJcGFtUG9vbCB7XG4gICAgcmV0dXJuIGNyZWF0ZUlwYW1Qb29sKHRoaXMuc2NvcGUsIGlkLCB0aGlzLnByb3BzLCBvcHRpb25zLCB0aGlzLnNjb3BlSWQpO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBuZXcgSVBBTSB3aXRoIGRlZmF1bHQgcHVibGljIGFuZCBwcml2YXRlIHNjb3BlXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lYzItaXBhbXNjb3BlLmh0bWxcbiAqIEByZXNvdXJjZSBBV1M6OkVDMjo6SVBBTVxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5leHBvcnQgY2xhc3MgSXBhbSBleHRlbmRzIFJlc291cmNlIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWMyLWFscGhhLklwYW0nO1xuICAvKipcbiAgICogUHJvdmlkZXMgYWNjZXNzIHRvIGRlZmF1bHQgcHVibGljIElQQU0gc2NvcGUgdGhyb3VnaCBhZGQgcG9vbCBtZXRob2QuXG4gICAqIFVzYWdlOiBUbyBhZGQgYW4gSXBhbSBQb29sIHRvIGEgZGVmYXVsdCBwdWJsaWMgc2NvcGVcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1zY29wZS5odG1sXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHVibGljU2NvcGU6IElJcGFtU2NvcGVCYXNlO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBhY2Nlc3MgdG8gZGVmYXVsdCBwcml2YXRlIElQQU0gc2NvcGUgdGhyb3VnaCBhZGQgcG9vbCBtZXRob2QuXG4gICAqIFVzYWdlOiBUbyBhZGQgYW4gSXBhbSBQb29sIHRvIGEgZGVmYXVsdCBwcml2YXRlIHNjb3BlXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtc2NvcGUuaHRtbFxuICAgKiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHJpdmF0ZVNjb3BlOiBJSXBhbVNjb3BlQmFzZTtcblxuICAvLyBSZXNvdXJjZSBJUEFNXG4gIHByaXZhdGUgcmVhZG9ubHkgX2lwYW06IENmbklQQU07XG4gIC8qKlxuICAgKiBBY2Nlc3MgdG8gSXBhbSByZXNvdXJjZSBpZCB0aGF0IGNhbiBiZSB1c2VkIGxhdGVyIHRvIGFkZCBhIGN1c3RvbSBwcml2YXRlIHNjb3BlIHRvIHRoaXMgSVBBTVxuICAgKiBAYXR0cmlidXRlIElwYW1JZFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlwYW1JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIG9wZXJhdGluZyByZWdpb25zIGZvciBJUEFNXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgb3BlcmF0aW5nUmVnaW9uczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIExpc3Qgb2Ygc2NvcGVzIGNyZWF0ZWQgdW5kZXIgdGhpcyBJUEFNXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2NvcGVzOiBJSXBhbVNjb3BlQmFzZVtdID0gW107XG5cbiAgLyoqXG4gICAqIElQQU0gbmFtZSB0byBiZSB1c2VkIGZvciB0YWdnaW5nXG4gICAqIEBkZWZhdWx0IC0gbm8gdGFnIHNwZWNpZmllZFxuICAgKiBAYXR0cmlidXRlIElwYW1OYW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXBhbU5hbWU/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBJcGFtUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIC8vIEVuaGFuY2VkIENESyBBbmFseXRpY3MgVGVsZW1ldHJ5XG4gICAgYWRkQ29uc3RydWN0TWV0YWRhdGEodGhpcywgcHJvcHMpO1xuICAgIGlmIChwcm9wcz8uaXBhbU5hbWUpIHtcbiAgICAgIFRhZ3Mub2YodGhpcykuYWRkKE5BTUVfVEFHLCBwcm9wcy5pcGFtTmFtZSk7XG4gICAgfVxuICAgIGlmIChwcm9wcz8ub3BlcmF0aW5nUmVnaW9ucyAmJiAocHJvcHMub3BlcmF0aW5nUmVnaW9ucy5sZW5ndGggPT09IDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGF0IGxlYXN0IG9uZSBvcGVyYXRpbmcgcmVnaW9uJyk7XG4gICAgfVxuXG4gICAgdGhpcy5vcGVyYXRpbmdSZWdpb25zID0gcHJvcHM/Lm9wZXJhdGluZ1JlZ2lvbnMgPz8gW1N0YWNrLm9mKHRoaXMpLnJlZ2lvbl07XG4gICAgdGhpcy5pcGFtTmFtZSA9IHByb3BzPy5pcGFtTmFtZTtcblxuICAgIHRoaXMuX2lwYW0gPSBuZXcgQ2ZuSVBBTSh0aGlzLCAnSXBhbScsIHtcbiAgICAgIG9wZXJhdGluZ1JlZ2lvbnM6IHRoaXMub3BlcmF0aW5nUmVnaW9ucyA/IHRoaXMub3BlcmF0aW5nUmVnaW9ucy5tYXAocmVnaW9uID0+ICh7IHJlZ2lvbk5hbWU6IHJlZ2lvbiB9KSkgOiBbXSxcbiAgICB9KTtcbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5faXBhbTtcblxuICAgIHRoaXMuaXBhbUlkID0gdGhpcy5faXBhbS5hdHRySXBhbUlkO1xuICAgIHRoaXMucHVibGljU2NvcGUgPSBuZXcgSXBhbVNjb3BlQmFzZSh0aGlzLCAnRGVmYXVsdFB1YmxpY1Njb3BlJywge1xuICAgICAgaXBhbU9wZXJhdGluZ1JlZ2lvbnM6IHRoaXMub3BlcmF0aW5nUmVnaW9ucyxcbiAgICAgIGlwYW1JZDogdGhpcy5faXBhbS5hdHRySXBhbUlkLFxuICAgICAgaXBhbVNjb3BlSWQ6IHRoaXMuX2lwYW0uYXR0clB1YmxpY0RlZmF1bHRTY29wZUlkLFxuICAgIH0pO1xuICAgIHRoaXMucHJpdmF0ZVNjb3BlID0gbmV3IElwYW1TY29wZUJhc2UodGhpcywgJ0RlZmF1bHRQcml2YXRlU2NvcGUnLCB7XG4gICAgICBpcGFtT3BlcmF0aW5nUmVnaW9uczogdGhpcy5vcGVyYXRpbmdSZWdpb25zLFxuICAgICAgaXBhbUlkOiB0aGlzLl9pcGFtLmF0dHJJcGFtSWQsXG4gICAgICBpcGFtU2NvcGVJZDogdGhpcy5faXBhbS5hdHRyUHJpdmF0ZURlZmF1bHRTY29wZUlkLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zY29wZXMucHVzaCh0aGlzLnB1YmxpY1Njb3BlLCB0aGlzLnByaXZhdGVTY29wZSk7XG4gIH1cblxuICAvKipcbiAgICogRnVuY3Rpb24gdG8gYWRkIGN1c3RvbSBzY29wZSB0byBhbiBleGlzdGluZyBJUEFNXG4gICAqIEN1c3RvbSBzY29wZXMgY2FuIG9ubHkgYmUgcHJpdmF0ZVxuICAgKi9cbiAgQE1ldGhvZE1ldGFkYXRhKClcbiAgcHVibGljIGFkZFNjb3BlKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIG9wdGlvbnM6IElwYW1TY29wZU9wdGlvbnMpOiBJSXBhbVNjb3BlQmFzZSB7XG4gICAgY29uc3QgaXBhbVNjb3BlID0gbmV3IElwYW1TY29wZShzY29wZSwgaWQsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBpcGFtSWQ6IHRoaXMuaXBhbUlkLFxuICAgICAgaXBhbU9wZXJhdGluZ1JlZ2lvbnM6IHRoaXMub3BlcmF0aW5nUmVnaW9ucyxcbiAgICB9KTtcbiAgICB0aGlzLnNjb3Blcy5wdXNoKGlwYW1TY29wZSk7XG4gICAgcmV0dXJuIGlwYW1TY29wZTtcbiAgfVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uIHRvIGNyZWF0ZSBJcGFtUG9vbCB1bmRlciBzY29wZVxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlwYW1Qb29sKFxuICBzY29wZTogQ29uc3RydWN0LFxuICBpZDogc3RyaW5nLFxuICBzY29wZU9wdGlvbnM6IElwYW1TY29wZVByb3BzLFxuICBwb29sT3B0aW9uczogUG9vbE9wdGlvbnMsXG4gIHNjb3BlSWQ6IHN0cmluZyxcbik6IElwYW1Qb29sIHtcbiAgLy8gT25seSBjaGVjayBsb2NhbGUgaWYgaXQncyBwcm92aWRlZCBzaW5jZSBpdCdzIGFuIG9wdGlvbmFsIGZpZWxkXG4gIGlmIChwb29sT3B0aW9ucy5sb2NhbGUpIHtcbiAgICBjb25zdCBpc0xvY2FsZUluT3BlcmF0aW5nUmVnaW9ucyA9IHNjb3BlT3B0aW9ucy5pcGFtT3BlcmF0aW5nUmVnaW9uc1xuICAgICAgPyBzY29wZU9wdGlvbnMuaXBhbU9wZXJhdGluZ1JlZ2lvbnMubWFwKHJlZ2lvbiA9PiAoeyByZWdpb25OYW1lOiByZWdpb24gfSkpXG4gICAgICAgIC5zb21lKHJlZ2lvbiA9PiByZWdpb24ucmVnaW9uTmFtZSA9PT0gcG9vbE9wdGlvbnMubG9jYWxlKVxuICAgICAgOiBmYWxzZTtcblxuICAgIGlmICghaXNMb2NhbGVJbk9wZXJhdGluZ1JlZ2lvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHByb3ZpZGVkIGxvY2FsZSAnJHtwb29sT3B0aW9ucy5sb2NhbGV9JyBpcyBub3QgaW4gdGhlIG9wZXJhdGluZyByZWdpb25zICgke3Njb3BlT3B0aW9ucy5pcGFtT3BlcmF0aW5nUmVnaW9uc30pLiBgICtcbiAgICAgICAgJ0lmIHNwZWNpZmllZCwgbG9jYWxlIG11c3QgYmUgY29uZmlndXJlZCBhcyBhbiBvcGVyYXRpbmcgcmVnaW9uIGZvciB0aGUgSVBBTS4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IElwYW1Qb29sKHNjb3BlLCBpZCwge1xuICAgIGlwYW1Qb29sTmFtZTogcG9vbE9wdGlvbnMuaXBhbVBvb2xOYW1lLFxuICAgIGFkZHJlc3NGYW1pbHk6IHBvb2xPcHRpb25zLmFkZHJlc3NGYW1pbHksXG4gICAgaXB2NFByb3Zpc2lvbmVkQ2lkcnM6IHBvb2xPcHRpb25zLmlwdjRQcm92aXNpb25lZENpZHJzLFxuICAgIGlwYW1TY29wZUlkOiBzY29wZUlkLFxuICAgIGxvY2FsZTogcG9vbE9wdGlvbnMubG9jYWxlLFxuICAgIHB1YmxpY0lwU291cmNlOiBwb29sT3B0aW9ucy5wdWJsaWNJcFNvdXJjZSxcbiAgICBhd3NTZXJ2aWNlOiBwb29sT3B0aW9ucy5hd3NTZXJ2aWNlLFxuICB9KTtcbn1cbiJdfQ==
447
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImlwYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkNBQWlFO0FBQ2pFLGlEQUEwRjtBQUMxRiw4RUFBOEY7QUFDOUYsMEVBQTBFO0FBRzFFOzs7OztHQUtHO0FBQ0gsSUFBWSxhQVlYO0FBWkQsV0FBWSxhQUFhO0lBQ3ZCOzs7T0FHRztJQUNILCtCQUFjLENBQUE7SUFFZDs7O09BR0c7SUFDSCwrQkFBYyxDQUFBO0FBQ2hCLENBQUMsRUFaVyxhQUFhLDZCQUFiLGFBQWEsUUFZeEI7QUFFRDs7OztHQUlHO0FBQ0gsSUFBWSxzQkFVWDtBQVZELFdBQVksc0JBQXNCO0lBQ2hDOztPQUVHO0lBQ0gseUNBQWUsQ0FBQTtJQUVmOztPQUVHO0lBQ0gsMkNBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQVZXLHNCQUFzQixzQ0FBdEIsc0JBQXNCLFFBVWpDO0FBRUQ7O0dBRUc7QUFDSCxJQUFZLGNBS1g7QUFMRCxXQUFZLGNBQWM7SUFDeEI7O09BRUc7SUFDSCw2QkFBVyxDQUFBO0FBQ2IsQ0FBQyxFQUxXLGNBQWMsOEJBQWQsY0FBYyxRQUt6QjtBQXlCRDs7R0FFRztBQUNILElBQVksYUFVWDtBQVZELFdBQVksYUFBYTtJQUN2Qjs7T0FFRztJQUNILG9DQUFtQixDQUFBO0lBRW5COztPQUVHO0lBQ0gsa0NBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQVZXLGFBQWEsNkJBQWIsYUFBYSxRQVV4QjtBQTRERCxNQUFNLFFBQVEsR0FBVyxNQUFNLENBQUM7QUE4SmhDOzs7Ozs7R0FNRztJQUVHLFFBQVE7NEJBRGIsb0NBQWtCOzs7O3NCQUNJLHNCQUFROzs7d0JBQWhCLFNBQVEsV0FBUTs7Ozt5Q0FnRTVCLElBQUEsa0NBQWMsR0FBRTtZQUNqQiwwTEFBTyxhQUFhLDZEQU9uQjtZQXhFSCw2S0F5RUM7Ozs7UUF4RUMsc0NBQXNDO1FBQy9C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QWMsQ0FDckIsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLFlBQTRCLEVBQzVCLFdBQXdCLEVBQ3hCLE9BQWU7SUFFZixrRUFBa0U7SUFDbEUsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdkIsTUFBTSwwQkFBMEIsR0FBRyxZQUFZLENBQUMsb0JBQW9CO1lBQ2xFLENBQUMsQ0FBQyxZQUFZLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO2lCQUN4RSxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxLQUFLLFdBQVcsQ0FBQyxNQUFNLENBQUM7WUFDM0QsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUVWLElBQUksQ0FBQywwQkFBMEIsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLFdBQVcsQ0FBQyxNQUFNLHNDQUFzQyxZQUFZLENBQUMsb0JBQW9CLEtBQUs7Z0JBQ3BJLDhFQUE4RSxDQUFDLENBQUM7UUFDcEYsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7UUFDN0IsWUFBWSxFQUFFLFdBQVcsQ0FBQyxZQUFZO1FBQ3RDLGFBQWEsRUFBRSxXQUFXLENBQUMsYUFBYTtRQUN4QyxvQkFBb0IsRUFBRSxXQUFXLENBQUMsb0JBQW9CO1FBQ3RELFdBQVcsRUFBRSxPQUFPO1FBQ3BCLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTTtRQUMxQixjQUFjLEVBQUUsV0FBVyxDQUFDLGNBQWM7UUFDMUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxVQUFVO0tBQ25DLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBMYXp5LCBOYW1lcywgUmVzb3VyY2UsIFN0YWNrLCBUYWdzIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ2ZuSVBBTSwgQ2ZuSVBBTVBvb2wsIENmbklQQU1Qb29sQ2lkciwgQ2ZuSVBBTVNjb3BlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWVjMic7XG5pbXBvcnQgeyBhZGRDb25zdHJ1Y3RNZXRhZGF0YSwgTWV0aG9kTWV0YWRhdGEgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9tZXRhZGF0YS1yZXNvdXJjZSc7XG5pbXBvcnQgeyBwcm9wZXJ0eUluamVjdGFibGUgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9wcm9wLWluamVjdGFibGUnO1xuaW1wb3J0IHR5cGUgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBhZGRyZXNzIGZhbWlseSBmb3IgSVAgYWRkcmVzc2VzIGluIGFuIElQQU0gcG9vbC5cbiAqIElQX1Y0IC0gUmVwcmVzZW50cyB0aGUgSVB2NCBhZGRyZXNzIGZhbWlseS5cbiAqIElQX1Y2IC0gUmVwcmVzZW50cyB0aGUgSVB2NiBhZGRyZXNzIGZhbWlseS5cbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sI2Nmbi1lYzItaXBhbXBvb2wtYWRkcmVzc2ZhbWlseVxuICovXG5leHBvcnQgZW51bSBBZGRyZXNzRmFtaWx5IHtcbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIElQdjQgYWRkcmVzcyBmYW1pbHkuXG4gICAqIEFsbG93ZWQgdW5kZXIgcHVibGljIGFuZCBwcml2YXRlIHBvb2wuXG4gICAqL1xuICBJUF9WNCA9ICdpcHY0JyxcblxuICAvKipcbiAgICogUmVwcmVzZW50cyB0aGUgSVB2NiBhZGRyZXNzIGZhbWlseS5cbiAgICogT25seSBhbGxvd2VkIHVuZGVyIHB1YmxpYyBwb29sLlxuICAgKi9cbiAgSVBfVjYgPSAnaXB2NicsXG59XG5cbi8qKlxuICogVGhlIElQIGFkZHJlc3Mgc291cmNlIGZvciBwb29scyBpbiB0aGUgcHVibGljIHNjb3BlLlxuICogT25seSB1c2VkIGZvciBwcm92aXNpb25pbmcgSVAgYWRkcmVzcyBDSURScyB0byBwb29scyBpbiB0aGUgcHVibGljIHNjb3BlLlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sLmh0bWwjY2ZuLWVjMi1pcGFtcG9vbC1wdWJsaWNpcHNvdXJjZVxuICovXG5leHBvcnQgZW51bSBJcGFtUG9vbFB1YmxpY0lwU291cmNlIHtcbiAgLyoqXG4gICAqIEJZT0lQIElwdjYgdG8gYmUgcmVnaXN0ZXJlZCB1bmRlciBJUEFNXG4gICAqL1xuICBCWU9JUCA9ICdieW9pcCcsXG5cbiAgLyoqXG4gICAqIEFtYXpvbiBQcm92aWRlZCBJcHY2IHJhbmdlXG4gICAqL1xuICBBTUFaT04gPSAnYW1hem9uJyxcbn1cblxuLyoqXG4gKiBMaW1pdHMgd2hpY2ggc2VydmljZSBpbiBBV1MgdGhhdCB0aGUgcG9vbCBjYW4gYmUgdXNlZCBpblxuICovXG5leHBvcnQgZW51bSBBd3NTZXJ2aWNlTmFtZSB7XG4gIC8qKlxuICAgKiAgQWxsb3dzIHVzZXJzIHRvIHVzZSBzcGFjZSBmb3IgRWxhc3RpYyBJUCBhZGRyZXNzZXMgYW5kIFZQQ3NcbiAgICovXG4gIEVDMiA9ICdlYzInLFxufVxuXG4vKipcbiAqIE9wdGlvbnMgdG8gY3JlYXRlIGEgbmV3IElwYW0gaW4gdGhlIGFjY291bnRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJcGFtUHJvcHMge1xuXG4gIC8qKlxuICAgKiBUaGUgb3BlcmF0aW5nIFJlZ2lvbnMgZm9yIGFuIElQQU0uXG4gICAqIE9wZXJhdGluZyBSZWdpb25zIGFyZSBBV1MgUmVnaW9ucyB3aGVyZSB0aGUgSVBBTSBpcyBhbGxvd2VkIHRvIG1hbmFnZSBJUCBhZGRyZXNzIENJRFJzXG4gICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG9wZXJhdGluZyBSZWdpb25zLCBzZWUgW0NyZWF0ZSBhbiBJUEFNXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vL3ZwYy9sYXRlc3QvaXBhbS9jcmVhdGUtaXBhbS5odG1sKSBpbiB0aGUgKkFtYXpvbiBWUEMgSVBBTSBVc2VyIEd1aWRlKiAuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtLmh0bWwjY2ZuLWVjMi1pcGFtLW9wZXJhdGluZ3JlZ2lvbnNcbiAgICpcbiAgICogQGRlZmF1bHQgLSBTdGFjay5yZWdpb24gaWYgZGVmaW5lZCBpbiB0aGUgc3RhY2tcbiAgICovXG4gIHJlYWRvbmx5IG9wZXJhdGluZ1JlZ2lvbnM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogTmFtZSBvZiBJUEFNIHRoYXQgY2FuIGJlIHVzZWQgZm9yIHRhZ2dpbmcgcmVzb3VyY2VcbiAgICpcbiAgICogQGRlZmF1bHQgLSBJZiBubyBuYW1lIHByb3ZpZGVkLCBubyB0YWdzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIElQQU1cbiAgICovXG4gIHJlYWRvbmx5IGlwYW1OYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlZmVycyB0byB0d28gcG9zc2libGUgc2NvcGUgdHlwZXMgdW5kZXIgSVBBTVxuICovXG5leHBvcnQgZW51bSBJcGFtU2NvcGVUeXBlIHtcbiAgLyoqXG4gICAqIERlZmF1bHQgc2NvcGVzIGNyZWF0ZWQgYnkgSVBBTVxuICAgKi9cbiAgREVGQVVMVCA9ICdkZWZhdWx0JyxcblxuICAvKipcbiAgICogQ3VzdG9tIHNjb3BlIGNyZWF0ZWQgdXNpbmcgbWV0aG9kXG4gICAqL1xuICBDVVNUT00gPSAnY3VzdG9tJyxcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBjb25maWd1cmluZyBhbiBJUEFNIHBvb2wuXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sLmh0bWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb29sT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIGFkZHJlc3NGYW1pbHkgLSBUaGUgYWRkcmVzcyBmYW1pbHkgb2YgdGhlIHBvb2wgKGlwdjQgb3IgaXB2NikuXG4gICAqL1xuICByZWFkb25seSBhZGRyZXNzRmFtaWx5OiBBZGRyZXNzRmFtaWx5O1xuXG4gIC8qKlxuICAgKiBJbmZvcm1hdGlvbiBhYm91dCB0aGUgQ0lEUnMgcHJvdmlzaW9uZWQgdG8gdGhlIHBvb2wuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gQ0lEUnMgYXJlIHByb3Zpc2lvbmVkXG4gICAqL1xuICByZWFkb25seSBpcHY0UHJvdmlzaW9uZWRDaWRycz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaGUgbG9jYWxlIChBV1MgUmVnaW9uKSBvZiB0aGUgcG9vbC4gU2hvdWxkIGJlIG9uZSBvZiB0aGUgSVBBTSBvcGVyYXRpbmcgcmVnaW9uLlxuICAgKiAgT25seSByZXNvdXJjZXMgaW4gdGhlIHNhbWUgUmVnaW9uIGFzIHRoZSBsb2NhbGUgb2YgdGhlIHBvb2wgY2FuIGdldCBJUCBhZGRyZXNzIGFsbG9jYXRpb25zIGZyb20gdGhlIHBvb2wuXG4gICAqIFlvdSBjYW4gb25seSBhbGxvY2F0ZSBhIENJRFIgZm9yIGEgVlBDLCBmb3IgZXhhbXBsZSwgZnJvbSBhbiBJUEFNIHBvb2wgdGhhdCBzaGFyZXMgYSBsb2NhbGUgd2l0aCB0aGUgVlBD4oCZcyBSZWdpb24uXG4gICAqIE5vdGUgdGhhdCBvbmNlIHlvdSBjaG9vc2UgYSBMb2NhbGUgZm9yIGEgcG9vbCwgeW91IGNhbm5vdCBtb2RpZnkgaXQuIElmIHlvdSBjaG9vc2UgYW4gQVdTIFJlZ2lvbiBmb3IgbG9jYWxlIHRoYXQgaGFzIG5vdCBiZWVuIGNvbmZpZ3VyZWQgYXMgYW4gb3BlcmF0aW5nIFJlZ2lvbiBmb3IgdGhlIElQQU0sIHlvdSdsbCBnZXQgYW4gZXJyb3IuXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sI2Nmbi1lYzItaXBhbXBvb2wtbG9jYWxlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQ3VycmVudCBvcGVyYXRpbmcgcmVnaW9uIG9mIElQQU1cbiAgICovXG4gIHJlYWRvbmx5IGxvY2FsZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQIGFkZHJlc3Mgc291cmNlIGZvciBwb29scyBpbiB0aGUgcHVibGljIHNjb3BlLlxuICAgKiBPbmx5IHVzZWQgZm9yIElQdjYgYWRkcmVzc1xuICAgKiBPbmx5IGFsbG93ZWQgdmFsdWVzIHRvIHRoaXMgYXJlICdieW9pcCcgb3IgJ2FtYXpvbidcbiAgICpcbiAgICogQGRlZmF1bHQgYW1hem9uXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNJcFNvdXJjZT86IElwYW1Qb29sUHVibGljSXBTb3VyY2U7XG5cbiAgLyoqXG4gICAqIExpbWl0cyB3aGljaCBzZXJ2aWNlIGluIEFXUyB0aGF0IHRoZSBwb29sIGNhbiBiZSB1c2VkIGluLlxuICAgKlxuICAgKiBcImVjMlwiLCBmb3IgZXhhbXBsZSwgYWxsb3dzIHVzZXJzIHRvIHVzZSBzcGFjZSBmb3IgRWxhc3RpYyBJUCBhZGRyZXNzZXMgYW5kIFZQQ3MuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sI2Nmbi1lYzItaXBhbXBvb2wtYXdzc2VydmljZVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHJlcXVpcmVkIGluIGNhc2Ugb2YgYW4gSVB2NiwgdGhyb3dzIGFuIGVycm9yIGlmIG5vdCBwcm92aWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGF3c1NlcnZpY2U/OiBBd3NTZXJ2aWNlTmFtZTtcblxuICAvKipcbiAgICogSVBBTSBQb29sIHJlc291cmNlIG5hbWUgdG8gYmUgdXNlZCBmb3IgdGFnZ2luZ1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIGF1dG9nZW5lcmF0ZWQgYnkgQ0RLIGlmIG5vdCBwcm92aWRlZFxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbVBvb2xOYW1lPzogc3RyaW5nO1xufVxuXG5jb25zdCBOQU1FX1RBRzogc3RyaW5nID0gJ05hbWUnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGFuIElQQU0gcG9vbC5cbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtcG9vbC5odG1sXG4gKi9cbmludGVyZmFjZSBJcGFtUG9vbFByb3BzIGV4dGVuZHMgUG9vbE9wdGlvbnMge1xuICAvKipcbiAgICogU2NvcGUgaWQgd2hlcmUgcG9vbCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAqL1xuICByZWFkb25seSBpcGFtU2NvcGVJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgdG8gcHJvdmlzaW9uIENJRFJzIHRvIGFuIElQQU0gcG9vbC5cbiAqIFVzZWQgdG8gY3JlYXRlIGEgbmV3IElwYW1Qb29sQ2lkclxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sY2lkci5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSXBhbVBvb2xDaWRyUHJvdmlzaW9uaW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJcHY2IE5ldG1hc2sgbGVuZ3RoIGZvciB0aGUgQ0lEUlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHBvb2wgcHJvdmlzaW9uZWQgd2l0aG91dCBuZXRtYXNrIGxlbmd0aCwgbmVlZCBjaWRyIHJhbmdlIGluIHRoaXMgY2FzZVxuICAgKi9cbiAgcmVhZG9ubHkgbmV0bWFza0xlbmd0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogSXB2NiBDSURSIGJsb2NrIGZvciB0aGUgSVBBTSBwb29sXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcG9vbCBwcm92aXNpb25lZCB3aXRob3V0IG5ldG1hc2sgbGVuZ3RoLCBuZWVkIG5ldG1hc2sgbGVuZ3RoIGluIHRoaXMgY2FzZVxuICAgKi9cbiAgcmVhZG9ubHkgY2lkcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZWZpbml0aW9uIHVzZWQgdG8gYWRkIG9yIGNyZWF0ZSBhIG5ldyBJUEFNIHBvb2xcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSXBhbVBvb2wge1xuICAvKipcbiAgICogUG9vbCBJRCB0byBiZSBwYXNzZWQgdG8gdGhlIFZQQyBjb25zdHJ1Y3RcbiAgICogQGF0dHJpYnV0ZSBJcGFtUG9vbElkXG4gICAqL1xuICByZWFkb25seSBpcGFtUG9vbElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFBvb2wgQ0lEUiBmb3IgSVB2NiB0byBiZSBwcm92aXNpb25lZCB3aXRoIFB1YmxpYyBJUCBzb3VyY2Ugc2V0IHRvICdBbWF6b24nXG4gICAqL1xuICByZWFkb25seSBpcGFtQ2lkcnM6IENmbklQQU1Qb29sQ2lkcltdO1xuXG4gIC8qKlxuICAgKiBQb29sIENJRFIgZm9yIElQdjQgdG8gYmUgcHJvdmlzaW9uZWQgdXNpbmcgSVBBTVxuICAgKiBSZXF1aXJlZCB0byBjaGVjayBmb3Igc3VibmV0IElQIHJhbmdlIGlzIHdpdGhpbiB0aGUgVlBDIHJhbmdlXG4gICAqL1xuICByZWFkb25seSBpcGFtSXB2NENpZHJzPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBhIElQdjYgYWRkcmVzcyB3aXRoIElQQU0gcG9vbFxuICAgKi9cbiAgcHJvdmlzaW9uQ2lkcihpZDogc3RyaW5nLCBvcHRpb25zOiBJcGFtUG9vbENpZHJQcm92aXNpb25pbmdPcHRpb25zKTogQ2ZuSVBBTVBvb2xDaWRyO1xuXG59XG5cbi8qKlxuICogSVBBTSBzY29wZSBpcyB0aGUgaGlnaGVzdC1sZXZlbCBjb250YWluZXIgd2l0aGluIElQQU0uIEFuIElQQU0gY29udGFpbnMgdHdvIGRlZmF1bHQgc2NvcGVzLlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1zY29wZS5odG1sXG4gKi9cbmludGVyZmFjZSBJcGFtU2NvcGVQcm9wcyBleHRlbmRzIElwYW1TY29wZU9wdGlvbnMge1xuICAvKipcbiAgICogSVBBTSBpZCB0byB3aGljaCBzY29wZSBuZWVkcyB0byBiZSBhZGRlZFxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE9wZXJhdGluZyByZWdpb25zIGZvciB0aGUgSXBhbVxuICAgKiBSZXF1aXJlZCBpbiBvcmRlciB0byB2YWxpZGF0ZSB0aGUgbG9jYWxlIGJlaW5nIHNldCBvbiBwb29sXG4gICAqL1xuICByZWFkb25seSBpcGFtT3BlcmF0aW5nUmVnaW9uczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIEN1c3RvbSBpcGFtIHNjb3BlIGlkIHRvIGFkZCBhIHBvb2wgaW4gb3JkZXIgdG8gc3VwcG9ydCBkZWZhdWx0IHNjb3Blc1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRocm93cyBhbiBlcnJvciBpZiBubyBzY29wZSBpZCBpcyBwcm92aWRlZFxuICAgKi9cbiAgcmVhZG9ubHkgaXBhbVNjb3BlSWQ/OiBzdHJpbmc7XG5cbn1cblxuLyoqXG4gKiBCZWluZyB1c2VkIGluIElQQU0gY2xhc3MgdG8gYWRkIHBvb2xzIHRvIGRlZmF1bHQgc2NvcGUgY3JlYXRlZCBieSBJUEFNLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElwYW1TY29wZU9wdGlvbnMge1xuXG4gIC8qKlxuICAgKiBJUEFNIHNjb3BlIG5hbWUgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHRhZ2dpbmdcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyB0YWdzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHNjb3BlXG4gICAqL1xuICByZWFkb25seSBpcGFtU2NvcGVOYW1lPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNvbmZpZ3VyaW5nIGFuIElQIEFkZHJlc3MgTWFuYWdlciAoSVBBTSkuXG4gKlxuICogRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSB0aGUge0BsaW5rIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lYzItaXBhbS5odG1sfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJcGFtT3B0aW9ucyB7XG5cbiAgLyoqXG4gICAqIENJRFIgTWFzayBmb3IgVnBjXG4gICAqIE9ubHkgcmVxdWlyZWQgd2hlbiB1c2luZyBBV1MgSXBhbVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIG5ldG1hc2sgbGVuZ3RoIGZvciBJUEFNIGF0dGFjaGVkIHRvIFZQQyBzZWNvbmRhcnkgYWRkcmVzc1xuICAgKi9cbiAgcmVhZG9ubHkgbmV0bWFza0xlbmd0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogSXB2NCBvciBhbiBJcHY2IElQQU0gcG9vbFxuICAgKiBPbmx5IHJlcXVpcmVkIHdoZW4gdXNpbmcgQVdTIElwYW1cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBwb29sIGF0dGFjaGVkIHRvIFZQQyBzZWNvbmRhcnkgYWRkcmVzc1xuICAgKi9cbiAgcmVhZG9ubHkgaXBhbVBvb2w/OiBJSXBhbVBvb2w7XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVkIHRvIHNldCBTZWNvbmRhcnkgY2lkciBibG9jayByZXNvdXJjZSBuYW1lXG4gICAqIGluIG9yZGVyIHRvIGdlbmVyYXRlIHVuaXF1ZSBsb2dpY2FsIGlkIGZvciB0aGUgcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBjaWRyQmxvY2tOYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBJcGFtU2NvcGUgQ2xhc3NcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJSXBhbVNjb3BlQmFzZSB7XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgY3VycmVudCBzY29wZSBvZiBzdGFjayB0byBiZSBwYXNzZWQgaW4gb3JkZXIgdG8gY3JlYXRlXG4gICAqIGEgbmV3IElQQU0gcG9vbFxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdDtcblxuICAvKipcbiAgICogRGVmYXVsdCBTY29wZSBpZHMgY3JlYXRlZCBieSB0aGUgSVBBTSBvciBhIG5ldyBSZXNvdXJjZSBpZFxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGVJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBEZWZpbmVzIHNjb3BlIHR5cGUgY2FuIGJlIGVpdGhlciBkZWZhdWx0IG9yIGN1c3RvbVxuICAgKi9cbiAgcmVhZG9ubHkgc2NvcGVUeXBlPzogSXBhbVNjb3BlVHlwZTtcblxuICAvKipcbiAgICogRnVuY3Rpb24gdG8gYWRkIGEgbmV3IHBvb2wgdG8gYW4gSVBBTSBzY29wZVxuICAgKi9cbiAgYWRkUG9vbChpZDogc3RyaW5nLCBvcHRpb25zOiBQb29sT3B0aW9ucyk6IElJcGFtUG9vbDtcblxufVxuXG4vKipcbiAqIENyZWF0ZXMgbmV3IElQQU0gUG9vbFxuICogUG9vbHMgZW5hYmxlIHlvdSB0byBvcmdhbml6ZSB5b3VyIElQIGFkZHJlc3NlcyBhY2NvcmRpbmcgdG8geW91ciByb3V0aW5nIGFuZCBzZWN1cml0eSBuZWVkc1xuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1wb29sLmh0bWxcbiAqIEByZXNvdXJjZSBBV1M6OkVDMjo6SVBBTVBvb2xcbiAqIEBpbnRlcm5hbFxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5jbGFzcyBJcGFtUG9vbCBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSUlwYW1Qb29sIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWMyLWFscGhhLklwYW1Qb29sJztcbiAgLyoqXG4gICAqIFBvb2wgSUQgdG8gYmUgcGFzc2VkIHRvIHRoZSBWUEMgY29uc3RydWN0XG4gICAqIEBhdHRyaWJ1dGUgSXBhbVBvb2xJZFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlwYW1Qb29sSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogUG9vbCBDSURSIGZvciBJUHY2IHRvIGJlIHByb3Zpc2lvbmVkIHdpdGggUHVibGljIElQIHNvdXJjZSBzZXQgdG8gJ0FtYXpvbidcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpcGFtQ2lkcnM6IENmbklQQU1Qb29sQ2lkcltdID0gW107XG5cbiAgLyoqXG4gICAqIFBvb2wgQ0lEUiBmb3IgSVB2NCB0byBiZSBwcm92aXNpb25lZCB1c2luZyBJUEFNXG4gICAqIFJlcXVpcmVkIHRvIGNoZWNrIGZvciBzdWJuZXQgSVAgcmFuZ2UgaXMgd2l0aGluIHRoZSBWUEMgcmFuZ2VcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBpcGFtSXB2NENpZHJzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgdG8gaXBhbVBvb2wgcmVzb3VyY2UgY3JlYXRlZCBpbiB0aGlzIGNsYXNzXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9pcGFtUG9vbDogQ2ZuSVBBTVBvb2w7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElwYW1Qb29sUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMuaXBhbVBvb2xOYW1lID8/IExhenkuc3RyaW5nKHtcbiAgICAgICAgcHJvZHVjZTogKCkgPT4gTmFtZXMudW5pcXVlUmVzb3VyY2VOYW1lKHRoaXMsIHsgbWF4TGVuZ3RoOiAxMjgsIGFsbG93ZWRTcGVjaWFsQ2hhcmFjdGVyczogJ18nIH0pLFxuICAgICAgfSksXG4gICAgfSk7XG4gICAgLy8gRW5oYW5jZWQgQ0RLIEFuYWx5dGljcyBUZWxlbWV0cnlcbiAgICBhZGRDb25zdHJ1Y3RNZXRhZGF0YSh0aGlzLCBwcm9wcyk7XG5cbiAgICBpZiAocHJvcHMuYWRkcmVzc0ZhbWlseSA9PT0gQWRkcmVzc0ZhbWlseS5JUF9WNiAmJiAhcHJvcHMuYXdzU2VydmljZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhd3NTZXJ2aWNlIGlzIHJlcXVpcmVkIHdoZW4gYWRkcmVzc0ZhbWlseSBpcyBzZXQgdG8gaXB2NicpO1xuICAgIH1cblxuICAgIC8vIEFkZCB0YWdzIHRvIHRoZSBJUEFNIFBvb2wgaWYgbmFtZSBpcyBwcm92aWRlZFxuICAgIGlmIChwcm9wcy5pcGFtUG9vbE5hbWUpIHtcbiAgICAgIFRhZ3Mub2YodGhpcykuYWRkKE5BTUVfVEFHLCBwcm9wcy5pcGFtUG9vbE5hbWUpO1xuICAgIH1cblxuICAgIHRoaXMuX2lwYW1Qb29sID0gbmV3IENmbklQQU1Qb29sKHRoaXMsIGlkLCB7XG4gICAgICBhZGRyZXNzRmFtaWx5OiBwcm9wcy5hZGRyZXNzRmFtaWx5LFxuICAgICAgcHJvdmlzaW9uZWRDaWRyczogcHJvcHMuaXB2NFByb3Zpc2lvbmVkQ2lkcnM/Lm1hcChjaWRyID0+ICh7IGNpZHIgfSkpLFxuICAgICAgbG9jYWxlOiBwcm9wcy5sb2NhbGUsXG4gICAgICBpcGFtU2NvcGVJZDogcHJvcHMuaXBhbVNjb3BlSWQsXG4gICAgICBwdWJsaWNJcFNvdXJjZTogcHJvcHMucHVibGljSXBTb3VyY2UsXG4gICAgICBhd3NTZXJ2aWNlOiBwcm9wcy5hd3NTZXJ2aWNlLFxuICAgIH0pO1xuICAgIHRoaXMuaXBhbVBvb2xJZCA9IHRoaXMuX2lwYW1Qb29sLmF0dHJJcGFtUG9vbElkO1xuXG4gICAgLy8gUG9wdWxhdGluZyB0byBjaGVjayBmb3Igc3VibmV0IHJhbmdlIGFnYWluc3QgYWxsIElQdjQgcmFuZ2VzIGFzc2lnbmVkIHRvIFZQQyBpbmNsdWRpbmcgSVBBTVxuICAgIHByb3BzLmlwdjRQcm92aXNpb25lZENpZHJzPy5tYXAoY2lkciA9PiAodGhpcy5pcGFtSXB2NENpZHJzLnB1c2goY2lkcikpKTtcbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5faXBhbVBvb2w7XG4gIH1cblxuICAvKipcbiAgICogQSBDSURSIHByb3Zpc2lvbmVkIHRvIGFuIElQQU0gcG9vbC5cbiAgICogQHBhcmFtIGlkIE5hbWUgb2YgUmVzb3VyY2VcbiAgICogQHBhcmFtIG9wdGlvbnMgRWl0aGVyIGEgQ0lEUiBvciBuZXRtYXNrIGxlbmd0aCBtdXN0IGJlIHByb3ZpZGVkXG4gICAqIEByZXR1cm5zIEFXUzo6RUMyOjpJUEFNUG9vbENpZHJcbiAgICovXG4gIEBNZXRob2RNZXRhZGF0YSgpXG4gIHB1YmxpYyBwcm92aXNpb25DaWRyKGlkOiBzdHJpbmcsIG9wdGlvbnM6IElwYW1Qb29sQ2lkclByb3Zpc2lvbmluZ09wdGlvbnMpOiBDZm5JUEFNUG9vbENpZHIge1xuICAgIGNvbnN0IGNpZHIgPSBuZXcgQ2ZuSVBBTVBvb2xDaWRyKHRoaXMsIGlkLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgaXBhbVBvb2xJZDogdGhpcy5pcGFtUG9vbElkLFxuICAgIH0pO1xuICAgIHRoaXMuaXBhbUNpZHJzLnB1c2goY2lkcik7XG4gICAgcmV0dXJuIGNpZHI7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGN1c3RvbSBJcGFtIFNjb3BlLCBjdXN0b20gSVBBTSBzY29wZXMgY2FuIG9ubHkgYmUgcHJpdmF0ZVxuICogKGNhbiBiZSB1c2VkIGZvciBhZGRpbmcgY3VzdG9tIHNjb3BlcyB0byBhbiBleGlzdGluZyBJUEFNKVxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1zY29wZS5odG1sXG4gKiBAcmVzb3VyY2UgQVdTOjpFQzI6OklQQU1TY29wZVxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5jbGFzcyBJcGFtU2NvcGUgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElJcGFtU2NvcGVCYXNlIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWMyLWFscGhhLklwYW1TY29wZSc7XG4gIC8qKlxuICAgKiBTdG9yZXMgdGhlIHJlZmVyZW5jZSB0byBuZXdseSBjcmVhdGVkIFJlc291cmNlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9pcGFtU2NvcGU6IENmbklQQU1TY29wZTtcblxuICAvKipcbiAgICogSUQgZm9yIFJlc291cmNlIElwYW1TY29wZVxuICAgKiBAYXR0cmlidXRlIElwYW1TY29wZUlkXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2NvcGVJZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIHRvIGNvbmZpZ3VyZSBpcGFtIHNjb3BlXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHByb3BzOiBJcGFtU2NvcGVQcm9wcztcblxuICAvKipcbiAgICogUmVmZXJlbmNlIHRvIHN0YWNrIHNjb3BlIHRvIGJlIHBhc3NlZCB0aHJvdWdoIGFkZFBvb2wgbWV0aG9kIGlub3JkZXIgdG8gY3JlYXRlIGEgbmV3IElwYW1Qb29sXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdDtcblxuICAvKipcbiAgICogRGVmaW5lcyBzY29wZSB0eXBlIGNhbiBiZSBlaXRoZXIgZGVmYXVsdCBvciBjdXN0b21cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzY29wZVR5cGU6IElwYW1TY29wZVR5cGU7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IElwYW1TY29wZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICAvLyBFbmhhbmNlZCBDREsgQW5hbHl0aWNzIFRlbGVtZXRyeVxuICAgIGFkZENvbnN0cnVjdE1ldGFkYXRhKHRoaXMsIHByb3BzKTtcbiAgICB0aGlzLl9pcGFtU2NvcGUgPSBuZXcgQ2ZuSVBBTVNjb3BlKHNjb3BlLCAnSXBhbVNjb3BlJywge1xuICAgICAgaXBhbUlkOiBwcm9wcy5pcGFtSWQsXG4gICAgfSk7XG4gICAgVGFncy5vZih0aGlzLl9pcGFtU2NvcGUpLmFkZChOQU1FX1RBRywgcHJvcHMuaXBhbVNjb3BlTmFtZSA/PyAnQ3VzdG9tSXBhbVNjb3BlJyk7XG4gICAgdGhpcy5zY29wZUlkID0gdGhpcy5faXBhbVNjb3BlLmF0dHJJcGFtU2NvcGVJZDtcbiAgICB0aGlzLnNjb3BlVHlwZSA9IElwYW1TY29wZVR5cGUuQ1VTVE9NO1xuICAgIHRoaXMuc2NvcGUgPSBzY29wZTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBvb2wgdG8gdGhlIElQQU0gc2NvcGUuXG4gICAqIEBleHRlcm5hbFxuICAgKi9cbiAgYWRkUG9vbChpZDogc3RyaW5nLCBvcHRpb25zOiBQb29sT3B0aW9ucyk6IElJcGFtUG9vbCB7XG4gICAgcmV0dXJuIGNyZWF0ZUlwYW1Qb29sKHRoaXMuc2NvcGUsIGlkLCB0aGlzLnByb3BzLCBvcHRpb25zLCB0aGlzLnNjb3BlSWQpO1xuICB9XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgSVBBTSBkZWZhdWx0IHNjb3Blcy5cbiAqL1xuY2xhc3MgSXBhbVNjb3BlQmFzZSBpbXBsZW1lbnRzIElJcGFtU2NvcGVCYXNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdCxcbiAgICByZWFkb25seSBzY29wZUlkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogSXBhbVNjb3BlUHJvcHMsXG4gICAgcmVhZG9ubHkgc2NvcGVUeXBlPzogSXBhbVNjb3BlVHlwZSxcbiAgKSB7XG4gICAgdGhpcy5zY29wZVR5cGUgPSBJcGFtU2NvcGVUeXBlLkRFRkFVTFQ7XG4gICAgaWYgKCFwcm9wcy5pcGFtU2NvcGVJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpcGFtU2NvcGVJZCBpcyByZXF1aXJlZCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjb3BlSWQgPSBwcm9wcy5pcGFtU2NvcGVJZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHBvb2wgdG8gdGhlIElQQU0gc2NvcGUuXG4gICAqIEBleHRlcm5hbFxuICAgKi9cbiAgYWRkUG9vbChpZDogc3RyaW5nLCBvcHRpb25zOiBQb29sT3B0aW9ucyk6IElJcGFtUG9vbCB7XG4gICAgcmV0dXJuIGNyZWF0ZUlwYW1Qb29sKHRoaXMuc2NvcGUsIGlkLCB0aGlzLnByb3BzLCBvcHRpb25zLCB0aGlzLnNjb3BlSWQpO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBuZXcgSVBBTSB3aXRoIGRlZmF1bHQgcHVibGljIGFuZCBwcml2YXRlIHNjb3BlXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NDbG91ZEZvcm1hdGlvbi9sYXRlc3QvVXNlckd1aWRlL2F3cy1yZXNvdXJjZS1lYzItaXBhbXNjb3BlLmh0bWxcbiAqIEByZXNvdXJjZSBBV1M6OkVDMjo6SVBBTVxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5leHBvcnQgY2xhc3MgSXBhbSBleHRlbmRzIFJlc291cmNlIHtcbiAgLyoqIFVuaXF1ZWx5IGlkZW50aWZpZXMgdGhpcyBjbGFzcy4gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9QRVJUWV9JTkpFQ1RJT05fSUQ6IHN0cmluZyA9ICdAYXdzLWNkay5hd3MtZWMyLWFscGhhLklwYW0nO1xuICAvKipcbiAgICogUHJvdmlkZXMgYWNjZXNzIHRvIGRlZmF1bHQgcHVibGljIElQQU0gc2NvcGUgdGhyb3VnaCBhZGQgcG9vbCBtZXRob2QuXG4gICAqIFVzYWdlOiBUbyBhZGQgYW4gSXBhbSBQb29sIHRvIGEgZGVmYXVsdCBwdWJsaWMgc2NvcGVcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTQ2xvdWRGb3JtYXRpb24vbGF0ZXN0L1VzZXJHdWlkZS9hd3MtcmVzb3VyY2UtZWMyLWlwYW1zY29wZS5odG1sXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHVibGljU2NvcGU6IElJcGFtU2NvcGVCYXNlO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBhY2Nlc3MgdG8gZGVmYXVsdCBwcml2YXRlIElQQU0gc2NvcGUgdGhyb3VnaCBhZGQgcG9vbCBtZXRob2QuXG4gICAqIFVzYWdlOiBUbyBhZGQgYW4gSXBhbSBQb29sIHRvIGEgZGVmYXVsdCBwcml2YXRlIHNjb3BlXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjMi1pcGFtc2NvcGUuaHRtbFxuICAgKiAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHJpdmF0ZVNjb3BlOiBJSXBhbVNjb3BlQmFzZTtcblxuICAvLyBSZXNvdXJjZSBJUEFNXG4gIHByaXZhdGUgcmVhZG9ubHkgX2lwYW06IENmbklQQU07XG4gIC8qKlxuICAgKiBBY2Nlc3MgdG8gSXBhbSByZXNvdXJjZSBpZCB0aGF0IGNhbiBiZSB1c2VkIGxhdGVyIHRvIGFkZCBhIGN1c3RvbSBwcml2YXRlIHNjb3BlIHRvIHRoaXMgSVBBTVxuICAgKiBAYXR0cmlidXRlIElwYW1JZFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlwYW1JZDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIG9wZXJhdGluZyByZWdpb25zIGZvciBJUEFNXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgb3BlcmF0aW5nUmVnaW9uczogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIExpc3Qgb2Ygc2NvcGVzIGNyZWF0ZWQgdW5kZXIgdGhpcyBJUEFNXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc2NvcGVzOiBJSXBhbVNjb3BlQmFzZVtdID0gW107XG5cbiAgLyoqXG4gICAqIElQQU0gbmFtZSB0byBiZSB1c2VkIGZvciB0YWdnaW5nXG4gICAqIEBkZWZhdWx0IC0gbm8gdGFnIHNwZWNpZmllZFxuICAgKiBAYXR0cmlidXRlIElwYW1OYW1lXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXBhbU5hbWU/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM/OiBJcGFtUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIC8vIEVuaGFuY2VkIENESyBBbmFseXRpY3MgVGVsZW1ldHJ5XG4gICAgYWRkQ29uc3RydWN0TWV0YWRhdGEodGhpcywgcHJvcHMpO1xuICAgIGlmIChwcm9wcz8uaXBhbU5hbWUpIHtcbiAgICAgIFRhZ3Mub2YodGhpcykuYWRkKE5BTUVfVEFHLCBwcm9wcy5pcGFtTmFtZSk7XG4gICAgfVxuICAgIGlmIChwcm9wcz8ub3BlcmF0aW5nUmVnaW9ucyAmJiAocHJvcHMub3BlcmF0aW5nUmVnaW9ucy5sZW5ndGggPT09IDApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBwcm92aWRlIGF0IGxlYXN0IG9uZSBvcGVyYXRpbmcgcmVnaW9uJyk7XG4gICAgfVxuXG4gICAgdGhpcy5vcGVyYXRpbmdSZWdpb25zID0gcHJvcHM/Lm9wZXJhdGluZ1JlZ2lvbnMgPz8gW1N0YWNrLm9mKHRoaXMpLnJlZ2lvbl07XG4gICAgdGhpcy5pcGFtTmFtZSA9IHByb3BzPy5pcGFtTmFtZTtcblxuICAgIHRoaXMuX2lwYW0gPSBuZXcgQ2ZuSVBBTSh0aGlzLCAnSXBhbScsIHtcbiAgICAgIG9wZXJhdGluZ1JlZ2lvbnM6IHRoaXMub3BlcmF0aW5nUmVnaW9ucyA/IHRoaXMub3BlcmF0aW5nUmVnaW9ucy5tYXAocmVnaW9uID0+ICh7IHJlZ2lvbk5hbWU6IHJlZ2lvbiB9KSkgOiBbXSxcbiAgICB9KTtcbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5faXBhbTtcblxuICAgIHRoaXMuaXBhbUlkID0gdGhpcy5faXBhbS5hdHRySXBhbUlkO1xuICAgIHRoaXMucHVibGljU2NvcGUgPSBuZXcgSXBhbVNjb3BlQmFzZSh0aGlzLCAnRGVmYXVsdFB1YmxpY1Njb3BlJywge1xuICAgICAgaXBhbU9wZXJhdGluZ1JlZ2lvbnM6IHRoaXMub3BlcmF0aW5nUmVnaW9ucyxcbiAgICAgIGlwYW1JZDogdGhpcy5faXBhbS5hdHRySXBhbUlkLFxuICAgICAgaXBhbVNjb3BlSWQ6IHRoaXMuX2lwYW0uYXR0clB1YmxpY0RlZmF1bHRTY29wZUlkLFxuICAgIH0pO1xuICAgIHRoaXMucHJpdmF0ZVNjb3BlID0gbmV3IElwYW1TY29wZUJhc2UodGhpcywgJ0RlZmF1bHRQcml2YXRlU2NvcGUnLCB7XG4gICAgICBpcGFtT3BlcmF0aW5nUmVnaW9uczogdGhpcy5vcGVyYXRpbmdSZWdpb25zLFxuICAgICAgaXBhbUlkOiB0aGlzLl9pcGFtLmF0dHJJcGFtSWQsXG4gICAgICBpcGFtU2NvcGVJZDogdGhpcy5faXBhbS5hdHRyUHJpdmF0ZURlZmF1bHRTY29wZUlkLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zY29wZXMucHVzaCh0aGlzLnB1YmxpY1Njb3BlLCB0aGlzLnByaXZhdGVTY29wZSk7XG4gIH1cblxuICAvKipcbiAgICogRnVuY3Rpb24gdG8gYWRkIGN1c3RvbSBzY29wZSB0byBhbiBleGlzdGluZyBJUEFNXG4gICAqIEN1c3RvbSBzY29wZXMgY2FuIG9ubHkgYmUgcHJpdmF0ZVxuICAgKi9cbiAgQE1ldGhvZE1ldGFkYXRhKClcbiAgcHVibGljIGFkZFNjb3BlKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIG9wdGlvbnM6IElwYW1TY29wZU9wdGlvbnMpOiBJSXBhbVNjb3BlQmFzZSB7XG4gICAgY29uc3QgaXBhbVNjb3BlID0gbmV3IElwYW1TY29wZShzY29wZSwgaWQsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBpcGFtSWQ6IHRoaXMuaXBhbUlkLFxuICAgICAgaXBhbU9wZXJhdGluZ1JlZ2lvbnM6IHRoaXMub3BlcmF0aW5nUmVnaW9ucyxcbiAgICB9KTtcbiAgICB0aGlzLnNjb3Blcy5wdXNoKGlwYW1TY29wZSk7XG4gICAgcmV0dXJuIGlwYW1TY29wZTtcbiAgfVxufVxuXG4vKipcbiAqIEZ1bmN0aW9uIHRvIGNyZWF0ZSBJcGFtUG9vbCB1bmRlciBzY29wZVxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUlwYW1Qb29sKFxuICBzY29wZTogQ29uc3RydWN0LFxuICBpZDogc3RyaW5nLFxuICBzY29wZU9wdGlvbnM6IElwYW1TY29wZVByb3BzLFxuICBwb29sT3B0aW9uczogUG9vbE9wdGlvbnMsXG4gIHNjb3BlSWQ6IHN0cmluZyxcbik6IElwYW1Qb29sIHtcbiAgLy8gT25seSBjaGVjayBsb2NhbGUgaWYgaXQncyBwcm92aWRlZCBzaW5jZSBpdCdzIGFuIG9wdGlvbmFsIGZpZWxkXG4gIGlmIChwb29sT3B0aW9ucy5sb2NhbGUpIHtcbiAgICBjb25zdCBpc0xvY2FsZUluT3BlcmF0aW5nUmVnaW9ucyA9IHNjb3BlT3B0aW9ucy5pcGFtT3BlcmF0aW5nUmVnaW9uc1xuICAgICAgPyBzY29wZU9wdGlvbnMuaXBhbU9wZXJhdGluZ1JlZ2lvbnMubWFwKHJlZ2lvbiA9PiAoeyByZWdpb25OYW1lOiByZWdpb24gfSkpXG4gICAgICAgIC5zb21lKHJlZ2lvbiA9PiByZWdpb24ucmVnaW9uTmFtZSA9PT0gcG9vbE9wdGlvbnMubG9jYWxlKVxuICAgICAgOiBmYWxzZTtcblxuICAgIGlmICghaXNMb2NhbGVJbk9wZXJhdGluZ1JlZ2lvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHByb3ZpZGVkIGxvY2FsZSAnJHtwb29sT3B0aW9ucy5sb2NhbGV9JyBpcyBub3QgaW4gdGhlIG9wZXJhdGluZyByZWdpb25zICgke3Njb3BlT3B0aW9ucy5pcGFtT3BlcmF0aW5nUmVnaW9uc30pLiBgICtcbiAgICAgICAgJ0lmIHNwZWNpZmllZCwgbG9jYWxlIG11c3QgYmUgY29uZmlndXJlZCBhcyBhbiBvcGVyYXRpbmcgcmVnaW9uIGZvciB0aGUgSVBBTS4nKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IElwYW1Qb29sKHNjb3BlLCBpZCwge1xuICAgIGlwYW1Qb29sTmFtZTogcG9vbE9wdGlvbnMuaXBhbVBvb2xOYW1lLFxuICAgIGFkZHJlc3NGYW1pbHk6IHBvb2xPcHRpb25zLmFkZHJlc3NGYW1pbHksXG4gICAgaXB2NFByb3Zpc2lvbmVkQ2lkcnM6IHBvb2xPcHRpb25zLmlwdjRQcm92aXNpb25lZENpZHJzLFxuICAgIGlwYW1TY29wZUlkOiBzY29wZUlkLFxuICAgIGxvY2FsZTogcG9vbE9wdGlvbnMubG9jYWxlLFxuICAgIHB1YmxpY0lwU291cmNlOiBwb29sT3B0aW9ucy5wdWJsaWNJcFNvdXJjZSxcbiAgICBhd3NTZXJ2aWNlOiBwb29sT3B0aW9ucy5hd3NTZXJ2aWNlLFxuICB9KTtcbn1cbiJdfQ==