UNPKG

@pepperize/cdk-organizations

Version:

Manage AWS organizations, organizational units (OU), accounts and service control policies (SCP).

202 lines • 38.7 kB
"use strict"; var _a, _b; Object.defineProperty(exports, "__esModule", { value: true }); exports.Root = exports.Organization = exports.FeatureSet = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const aws_iam = require("aws-cdk-lib/aws-iam"); const custom_resources = require("aws-cdk-lib/custom-resources"); const constructs_1 = require("constructs"); const pascal_case_1 = require("pascal-case"); const dependency_chain_1 = require("./dependency-chain"); const enable_aws_service_access_1 = require("./enable-aws-service-access"); const enable_policy_type_1 = require("./enable-policy-type"); const organization_provider_1 = require("./organization-provider"); const policy_attachment_1 = require("./policy-attachment"); const tag_resource_1 = require("./tag-resource"); /** * Specifies the feature set supported by the new organization. Each feature set supports different levels of functionality. * * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html#feature-set */ var FeatureSet; (function (FeatureSet) { /** * All member accounts have their bills consolidated to and paid by the management account. For more information, see [Consolidated billing](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html#feature-set-cb-only) in the AWS Organizations User Guide. The consolidated billing feature subset isn’t available for organizations in the AWS GovCloud (US) Region. */ FeatureSet["CONSOLIDATED_BILLING"] = "CONSOLIDATED_BILLING"; /** * In addition to all the features supported by the consolidated billing feature set, the management account can also apply any policy type to any member account in the organization. For more information, see [All features](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html#feature-set-all) in the AWS Organizations User Guide. */ FeatureSet["ALL"] = "ALL"; })(FeatureSet || (exports.FeatureSet = FeatureSet = {})); class Organization extends constructs_1.Construct { /** * Describe the organization that the current account belongs to. * * @see https://docs.aws.amazon.com/organizations/latest/APIReference/API_DescribeOrganization.html */ static of(scope, id) { class Import extends constructs_1.Construct { constructor() { super(scope, id); const organizationsRegion = process.env.CDK_AWS_PARTITION === "aws-cn" ? "cn-northwest-1" : "us-east-1"; const resource = new custom_resources.AwsCustomResource(scope, "CustomResource", { resourceType: "Custom::Organizations_ImportOrganization", onCreate: { service: "Organizations", action: "describeOrganization", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#describeOrganization-property region: organizationsRegion, parameters: {}, physicalResourceId: custom_resources.PhysicalResourceId.fromResponse("Organization.Id"), }, onUpdate: { service: "Organizations", action: "describeOrganization", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#describeOrganization-property region: organizationsRegion, parameters: {}, physicalResourceId: custom_resources.PhysicalResourceId.fromResponse("Organization.Id"), }, installLatestAwsSdk: false, policy: custom_resources.AwsCustomResourcePolicy.fromSdkCalls({ resources: custom_resources.AwsCustomResourcePolicy.ANY_RESOURCE, }), }); this.featureSet = resource.getResponseField("Organization.FeatureSet"); this.managementAccountArn = resource.getResponseField("Organization.MasterAccountArn"); this.managementAccountEmail = resource.getResponseField("Organization.MasterAccountEmail"); this.managementAccountId = resource.getResponseField("Organization.MasterAccountId"); this.organizationArn = resource.getResponseField("Organization.Arn"); this.organizationId = resource.getResponseField("Organization.Id"); this.principal = new aws_iam.OrganizationPrincipal(this.organizationId); } } return new Import(); } constructor(scope, id, props = {}) { super(scope, id); const featureSet = props.featureSet || FeatureSet.ALL; const organizationProvider = organization_provider_1.OrganizationProvider.getOrCreate(this); this.resource = new aws_cdk_lib_1.CustomResource(this, "Organization", { serviceToken: organizationProvider.provider.serviceToken, resourceType: "Custom::Organizations_Organization", properties: { FeatureSet: featureSet, }, }); this.organizationId = this.resource.getAtt("Id").toString(); this.organizationArn = this.resource.getAtt("Arn").toString(); this.featureSet = this.resource.getAtt("FeatureSet").toString(); this.managementAccountArn = this.resource.getAtt("MasterAccountArn").toString(); this.managementAccountId = this.resource.getAtt("MasterAccountId").toString(); this.managementAccountEmail = this.resource.getAtt("MasterAccountEmail").toString(); this.principal = new aws_iam.OrganizationPrincipal(this.organizationId); this.root = new Root(this, "Root"); this.root.node.addDependency(this.resource); } /** * Enables trusted access for a supported AWS service (trusted service), which performs tasks in your organization and its accounts on your behalf. * @param servicePrincipal The supported AWS service that you specify * * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_integrate_services_list.html */ enableAwsServiceAccess(servicePrincipal) { const enableAwsServiceAccess = new enable_aws_service_access_1.EnableAwsServiceAccess(this, `Enable${(0, pascal_case_1.pascalCase)(servicePrincipal)}`, { servicePrincipal: servicePrincipal, }); enableAwsServiceAccess.node.addDependency(this.resource); } /** * Enables policy types in the following two broad categories: Authorization policies and Management policies. * @param policyType: the type of the policy that you specify * * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies.html#orgs-policy-types */ enablePolicyType(policyType) { this.root.enablePolicyType(policyType); } /** * Attach a policy. Before you can attach the policy, you must enable that policy type for use. You can use policies when you have all features enabled. * * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies.html */ attachPolicy(policy) { this.root.attachPolicy(policy); } } exports.Organization = Organization; _a = JSII_RTTI_SYMBOL_1; Organization[_a] = { fqn: "@pepperize/cdk-organizations.Organization", version: "0.7.988" }; /** * The parent container for all the accounts for your organization. If you apply a policy to the root, it applies to all organizational units (OUs) and accounts in the organization. * <strong>Currently, you can have only one root. AWS Organizations automatically creates it for you when you create an organization.</strong> * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html */ class Root extends constructs_1.Construct { constructor(scope, id) { super(scope, id); this.tags = new aws_cdk_lib_1.TagManager(aws_cdk_lib_1.TagType.KEY_VALUE, "Custom::Organizations_Root"); this.scope = scope; const organizationsRegion = process.env.CDK_AWS_PARTITION === "aws-cn" ? "cn-northwest-1" : "us-east-1"; this.resource = new custom_resources.AwsCustomResource(this, "RootCustomResource", { resourceType: "Custom::Organizations_Root", onCreate: { service: "Organizations", action: "listRoots", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#listRoots-property region: organizationsRegion, physicalResourceId: custom_resources.PhysicalResourceId.fromResponse("Roots.0.Id"), }, onUpdate: { service: "Organizations", action: "listRoots", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#listRoots-property region: organizationsRegion, physicalResourceId: custom_resources.PhysicalResourceId.fromResponse("Roots.0.Id"), }, onDelete: { service: "Organizations", action: "listRoots", // https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Organizations.html#listRoots-property region: organizationsRegion, }, installLatestAwsSdk: false, policy: custom_resources.AwsCustomResourcePolicy.fromSdkCalls({ resources: custom_resources.AwsCustomResourcePolicy.ANY_RESOURCE, }), }); this.rootId = this.resource.getResponseField("Roots.0.Id"); // Returns first root id. It seems AWS Organizations doesn't contain multiple roots. const stack = aws_cdk_lib_1.Stack.of(this); aws_cdk_lib_1.Aspects.of(stack).add(new dependency_chain_1.DependencyChain()); // sequentially chain organization resources which can't be deployed in parallel const tagResource = new tag_resource_1.TagResource(this, "Tags", { resourceId: this.rootId, tags: this.tags.renderedTags }); tagResource.node.addDependency(this.resource); } identifier() { return this.rootId; } /** * Attach a policy. Before you can attach the policy, you must enable that policy type for use. You can use policies when you have all features enabled. * * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies.html */ attachPolicy(policy) { const policyAttachment = new policy_attachment_1.PolicyAttachment(this.scope, `PolicyAttachment-${aws_cdk_lib_1.Names.nodeUniqueId(this.node)}-${aws_cdk_lib_1.Names.nodeUniqueId(policy.node)}`, { target: this, policy: policy, }); policyAttachment.node.addDependency(this.resource, policy); } /** * Enables and disables Enables a policy type. After you enable a policy type in a root, you can attach policies of that type to the root, any organizational unit (OU), or account in that root. * * @see https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_enable-disable.html */ enablePolicyType(policyType) { const enablePolicyType = new enable_policy_type_1.EnablePolicyType(this.scope, `Enable${(0, pascal_case_1.pascalCase)(policyType)}`, { root: this, policyType: policyType, }); enablePolicyType.node.addDependency(this.resource); } } exports.Root = Root; _b = JSII_RTTI_SYMBOL_1; Root[_b] = { fqn: "@pepperize/cdk-organizations.Root", version: "0.7.988" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnYW5pemF0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL29yZ2FuaXphdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUF5RjtBQUN6RiwrQ0FBK0M7QUFDL0MsaUVBQWlFO0FBQ2pFLDJDQUFtRDtBQUNuRCw2Q0FBeUM7QUFDekMseURBQXFEO0FBQ3JELDJFQUFxRTtBQUNyRSw2REFBd0Q7QUFDeEQsbUVBQStEO0FBRy9ELDJEQUFnRjtBQUNoRixpREFBZ0U7QUFFaEU7Ozs7R0FJRztBQUNILElBQVksVUFTWDtBQVRELFdBQVksVUFBVTtJQUNwQjs7T0FFRztJQUNILDJEQUE2QyxDQUFBO0lBQzdDOztPQUVHO0lBQ0gseUJBQVcsQ0FBQTtBQUNiLENBQUMsRUFUVyxVQUFVLDBCQUFWLFVBQVUsUUFTckI7QUFxREQsTUFBYSxZQUFhLFNBQVEsc0JBQVM7SUFDekM7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBZ0IsRUFBRSxFQUFVO1FBQzNDLE1BQU0sTUFBTyxTQUFRLHNCQUFTO1lBUzVCO2dCQUNFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBRWpCLE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7Z0JBRXhHLE1BQU0sUUFBUSxHQUFHLElBQUksZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsS0FBSyxFQUFFLGdCQUFnQixFQUFFO29CQUMvRSxZQUFZLEVBQUUsMENBQTBDO29CQUN4RCxRQUFRLEVBQUU7d0JBQ1IsT0FBTyxFQUFFLGVBQWU7d0JBQ3hCLE1BQU0sRUFBRSxzQkFBc0IsRUFBRSwyR0FBMkc7d0JBQzNJLE1BQU0sRUFBRSxtQkFBbUI7d0JBQzNCLFVBQVUsRUFBRSxFQUFFO3dCQUNkLGtCQUFrQixFQUFFLGdC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LEVBQUUsSUFBSTtZQUNWLFVBQVUsRUFBRSxVQUFVO1NBQ3ZCLENBQUMsQ0FBQztRQUNILGdCQUFnQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JELENBQUM7O0FBcEZILG9CQXFGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzcGVjdHMsIEN1c3RvbVJlc291cmNlLCBOYW1lcywgU3RhY2ssIFRhZ01hbmFnZXIsIFRhZ1R5cGUgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCAqIGFzIGF3c19pYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIjtcbmltcG9ydCAqIGFzIGN1c3RvbV9yZXNvdXJjZXMgZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIjtcbmltcG9ydCB7IENvbnN0cnVjdCwgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBwYXNjYWxDYXNlIH0gZnJvbSBcInBhc2NhbC1jYXNlXCI7XG5pbXBvcnQgeyBEZXBlbmRlbmN5Q2hhaW4gfSBmcm9tIFwiLi9kZXBlbmRlbmN5LWNoYWluXCI7XG5pbXBvcnQgeyBFbmFibGVBd3NTZXJ2aWNlQWNjZXNzIH0gZnJvbSBcIi4vZW5hYmxlLWF3cy1zZXJ2aWNlLWFjY2Vzc1wiO1xuaW1wb3J0IHsgRW5hYmxlUG9saWN5VHlwZSB9IGZyb20gXCIuL2VuYWJsZS1wb2xpY3ktdHlwZVwiO1xuaW1wb3J0IHsgT3JnYW5pemF0aW9uUHJvdmlkZXIgfSBmcm9tIFwiLi9vcmdhbml6YXRpb24tcHJvdmlkZXJcIjtcbmltcG9ydCB7IElQYXJlbnQgfSBmcm9tIFwiLi9wYXJlbnRcIjtcbmltcG9ydCB7IElQb2xpY3ksIFBvbGljeVR5cGUgfSBmcm9tIFwiLi9wb2xpY3lcIjtcbmltcG9ydCB7IElQb2xpY3lBdHRhY2htZW50VGFyZ2V0LCBQb2xpY3lBdHRhY2htZW50IH0gZnJvbSBcIi4vcG9saWN5LWF0dGFjaG1lbnRcIjtcbmltcG9ydCB7IElUYWdnYWJsZVJlc291cmNlLCBUYWdSZXNvdXJjZSB9IGZyb20gXCIuL3RhZy1yZXNvdXJjZVwiO1xuXG4vKipcbiAqIFNwZWNpZmllcyB0aGUgZmVhdHVyZSBzZXQgc3VwcG9ydGVkIGJ5IHRoZSBuZXcgb3JnYW5pemF0aW9uLiBFYWNoIGZlYXR1cmUgc2V0IHN1cHBvcnRzIGRpZmZlcmVudCBsZXZlbHMgb2YgZnVuY3Rpb25hbGl0eS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcmdhbml6YXRpb25zL2xhdGVzdC91c2VyZ3VpZGUvb3Jnc19nZXR0aW5nLXN0YXJ0ZWRfY29uY2VwdHMuaHRtbCNmZWF0dXJlLXNldFxuICovXG5leHBvcnQgZW51bSBGZWF0dXJlU2V0IHtcbiAgLyoqXG4gICAqIEFsbCBtZW1iZXIgYWNjb3VudHMgaGF2ZSB0aGVpciBiaWxscyBjb25zb2xpZGF0ZWQgdG8gYW5kIHBhaWQgYnkgdGhlIG1hbmFnZW1lbnQgYWNjb3VudC4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZSBbQ29uc29saWRhdGVkIGJpbGxpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcmdhbml6YXRpb25zL2xhdGVzdC91c2VyZ3VpZGUvb3Jnc19nZXR0aW5nLXN0YXJ0ZWRfY29uY2VwdHMuaHRtbCNmZWF0dXJlLXNldC1jYi1vbmx5KSBpbiB0aGUgQVdTIE9yZ2FuaXphdGlvbnMgVXNlciBHdWlkZS4gVGhlIGNvbnNvbGlkYXRlZCBiaWxsaW5nIGZlYXR1cmUgc3Vic2V0IGlzbuKAmXQgYXZhaWxhYmxlIGZvciBvcmdhbml6YXRpb25zIGluIHRoZSBBV1MgR292Q2xvdWQgKFVTKSBSZWdpb24uXG4gICAqL1xuICBDT05TT0xJREFURURfQklMTElORyA9IFwiQ09OU09MSURBVEVEX0JJTExJTkdcIixcbiAgLyoqXG4gICAqIEluIGFkZGl0aW9uIHRvIGFsbCB0aGUgZmVhdHVyZXMgc3VwcG9ydGVkIGJ5IHRoZSBjb25zb2xpZGF0ZWQgYmlsbGluZyBmZWF0dXJlIHNldCwgdGhlIG1hbmFnZW1lbnQgYWNjb3VudCBjYW4gYWxzbyBhcHBseSBhbnkgcG9saWN5IHR5cGUgdG8gYW55IG1lbWJlciBhY2NvdW50IGluIHRoZSBvcmdhbml6YXRpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgW0FsbCBmZWF0dXJlc10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29yZ2FuaXphdGlvbnMvbGF0ZXN0L3VzZXJndWlkZS9vcmdzX2dldHRpbmctc3RhcnRlZF9jb25jZXB0cy5odG1sI2ZlYXR1cmUtc2V0LWFsbCkgaW4gdGhlIEFXUyBPcmdhbml6YXRpb25zIFVzZXIgR3VpZGUuXG4gICAqL1xuICBBTEwgPSBcIkFMTFwiLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9yZ2FuaXphdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIEVuYWJsaW5nIGZlYXR1cmVzIGluIHlvdXIgb3JnYW5pemF0aW9uLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcmdhbml6YXRpb25zL2xhdGVzdC91c2VyZ3VpZGUvb3Jnc19tYW5hZ2Vfb3JnX3N1cHBvcnQtYWxsLWZlYXR1cmVzLmh0bWxcbiAgICpcbiAgICogQGRlZmF1bHQgQUxMXG4gICAqL1xuICByZWFkb25seSBmZWF0dXJlU2V0PzogRmVhdHVyZVNldDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIG9yZ2FuaXphdGlvbiB0byBjb25zb2xpZGF0ZSB5b3VyIEFXUyBhY2NvdW50cyBzbyB0aGF0IHlvdSBjYW4gYWRtaW5pc3RlciB0aGVtIGFzIGEgc2luZ2xlIHVuaXQuIEFuIG9yZ2FuaXphdGlvbiBoYXMgb25lIG1hbmFnZW1lbnQgYWNjb3VudCBhbG9uZyB3aXRoIHplcm8gb3IgbW9yZSBtZW1iZXIgYWNjb3VudHMuIFlvdSBjYW4gb3JnYW5pemUgdGhlIGFjY291bnRzIGluIGEgaGllcmFyY2hpY2FsLCB0cmVlLWxpa2Ugc3RydWN0dXJlIHdpdGggYSByb290IGF0IHRoZSB0b3AgYW5kIG9yZ2FuaXphdGlvbmFsIHVuaXRzIG5lc3RlZCB1bmRlciB0aGUgcm9vdC4gRWFjaCBhY2NvdW50IGNhbiBiZSBkaXJlY3RseSBpbiB0aGUgcm9vdCwgb3IgcGxhY2VkIGluIG9uZSBvZiB0aGUgT1VzIGluIHRoZSBoaWVyYXJjaHkuIEFuIG9yZ2FuaXphdGlvbiBoYXMgdGhlIGZ1bmN0aW9uYWxpdHkgdGhhdCBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBmZWF0dXJlIHNldCB0aGF0IHlvdSBlbmFibGUuXG4gKlxuICogPHN0cm9uZz5UaGUgYWNjb3VudCB3aG9zZSB1c2VyIGlzIGNhbGxpbmcgdGhlIENyZWF0ZU9yZ2FuaXphdGlvbiBvcGVyYXRpb24gYXV0b21hdGljYWxseSBiZWNvbWVzIHRoZSBtYW5hZ2VtZW50IGFjY291bnQgb2YgdGhlIG5ldyBvcmdhbml6YXRpb24uPC9zdHJvbmc+XG4gKlxuICogPHN0cm9uZz5Gb3IgZGVsZXRpb24gb2YgYW4gb3JnYW5pemF0aW9uIHlvdSBtdXN0IHByZXZpb3VzbHkgcmVtb3ZlIGFsbCB0aGUgbWVtYmVyIGFjY291bnRzLCBPVXMsIGFuZCBwb2xpY2llcyBmcm9tIHRoZSBvcmdhbml6YXRpb24hPC9zdHJvbmc+XG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3JnYW5pemF0aW9ucy9sYXRlc3QvdXNlcmd1aWRlL29yZ3NfbWFuYWdlX29yZ19jcmVhdGUuaHRtbCNjcmVhdGUtb3JnXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSU9yZ2FuaXphdGlvbiBleHRlbmRzIElDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChJRCkgb2YgYW4gb3JnYW5pemF0aW9uLiBUaGUgcmVnZXggcGF0dGVybiBmb3IgYW4gb3JnYW5pemF0aW9uIElEIHN0cmluZyByZXF1aXJlcyBcIm8tXCIgZm9sbG93ZWQgYnkgZnJvbSAxMCB0byAzMiBsb3dlcmNhc2UgbGV0dGVycyBvciBkaWdpdHMuXG4gICAqL1xuICByZWFkb25seSBvcmdhbml6YXRpb25JZDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIEFtYXpvbiBSZXNvdXJjZSBOYW1lIChBUk4pIG9mIGFuIG9yZ2FuaXphdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IG9yZ2FuaXphdGlvbkFybjogc3RyaW5nO1xuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBmdW5jdGlvbmFsaXR5IHRoYXQgY3VycmVudGx5IGlzIGF2YWlsYWJsZSB0byB0aGUgb3JnYW5pemF0aW9uLiBJZiBzZXQgdG8gXCJBTExcIiwgdGhlbiBhbGwgZmVhdHVyZXMgYXJlIGVuYWJsZWQgYW5kIHBvbGljaWVzIGNhbiBiZSBhcHBsaWVkIHRvIGFjY291bnRzIGluIHRoZSBvcmdhbml6YXRpb24uIElmIHNldCB0byBcIkNPTlNPTElEQVRFRF9CSUxMSU5HXCIsIHRoZW4gb25seSBjb25zb2xpZGF0ZWQgYmlsbGluZyBmdW5jdGlvbmFsaXR5IGlzIGF2YWlsYWJsZS5cbiAgICovXG4gIHJlYWRvbmx5IGZlYXR1cmVTZXQ6IEZlYXR1cmVTZXQ7XG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIGFjY291bnQgdGhhdCBpcyBkZXNpZ25hdGVkIGFzIHRoZSBtYW5hZ2VtZW50IGFjY291bnQgZm9yIHRoZSBvcmdhbml6YXRpb24uXG4gICAqL1xuICByZWFkb25seSBtYW5hZ2VtZW50QWNjb3VudEFybjogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChJRCkgb2YgdGhlIG1hbmFnZW1lbnQgYWNjb3VudCBvZiBhbiBvcmdhbml6YXRpb24uXG4gICAqL1xuICByZWFkb25seSBtYW5hZ2VtZW50QWNjb3VudElkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZW1haWwgYWRkcmVzcyB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgQVdTIGFjY291bnQgdGhhdCBpcyBkZXNpZ25hdGVkIGFzIHRoZSBtYW5hZ2VtZW50IGFjY291bnQgZm9yIHRoZSBvcmdhbml6YXRpb24uXG4gICAqL1xuICByZWFkb25seSBtYW5hZ2VtZW50QWNjb3VudEVtYWlsOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgcHJpbmNpcGFsIHRoYXQgcmVwcmVzZW50cyB0aGlzIEFXUyBPcmdhbml6YXRpb25cbiAgICovXG4gIHJlYWRvbmx5IHByaW5jaXBhbDogYXdzX2lhbS5JUHJpbmNpcGFsO1xufVxuXG5leHBvcnQgY2xhc3MgT3JnYW5pemF0aW9uIGV4dGVuZHMgQ29uc3RydWN0IGltcGxlbWVudHMgSU9yZ2FuaXphdGlvbiB7XG4gIC8qKlxuICAgKiBEZXNjcmliZSB0aGUgb3JnYW5pemF0aW9uIHRoYXQgdGhlIGN1cnJlbnQgYWNjb3VudCBiZWxvbmdzIHRvLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcmdhbml6YXRpb25zL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0Rlc2NyaWJlT3JnYW5pemF0aW9uLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgb2Yoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZyk6IElPcmdhbml6YXRpb24ge1xuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIENvbnN0cnVjdCBpbXBsZW1lbnRzIElPcmdhbml6YXRpb24ge1xuICAgICAgcmVhZG9ubHkgZmVhdHVyZVNldDogRmVhdHVyZVNldDtcbiAgICAgIHJlYWRvbmx5IG1hbmFnZW1lbnRBY2NvdW50QXJuOiBzdHJpbmc7XG4gICAgICByZWFkb25seSBtYW5hZ2VtZW50QWNjb3VudEVtYWlsOiBzdHJpbmc7XG4gICAgICByZWFkb25seSBtYW5hZ2VtZW50QWNjb3VudElkOiBzdHJpbmc7XG4gICAgICByZWFkb25seSBvcmdhbml6YXRpb25Bcm46IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IG9yZ2FuaXphdGlvbklkOiBzdHJpbmc7XG4gICAgICByZWFkb25seSBwcmluY2lwYWw6IGF3c19pYW0uSVByaW5jaXBhbDtcblxuICAgICAgcHVibGljIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgICAgIGNvbnN0IG9yZ2FuaXphdGlvbnNSZWdpb24gPSBwcm9jZXNzLmVudi5DREtfQVdTX1BBUlRJVElPTiA9PT0gXCJhd3MtY25cIiA/IFwiY24tbm9ydGh3ZXN0LTFcIiA6IFwidXMtZWFzdC0xXCI7XG5cbiAgICAgICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgY3VzdG9tX3Jlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZShzY29wZSwgXCJDdXN0b21SZXNvdXJjZVwiLCB7XG4gICAgICAgICAgcmVzb3VyY2VUeXBlOiBcIkN1c3RvbTo6T3JnYW5pemF0aW9uc19JbXBvcnRPcmdhbml6YXRpb25cIixcbiAgICAgICAgICBvbkNyZWF0ZToge1xuICAgICAgICAgICAgc2VydmljZTogXCJPcmdhbml6YXRpb25zXCIsXG4gICAgICAgICAgICBhY3Rpb246IFwiZGVzY3JpYmVPcmdhbml6YXRpb25cIiwgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvbGF0ZXN0L0FXUy9Pcmdhbml6YXRpb25zLmh0bWwjZGVzY3JpYmVPcmdhbml6YXRpb24tcHJvcGVydHlcbiAgICAgICAgICAgIHJlZ2lvbjogb3JnYW5pemF0aW9uc1JlZ2lvbixcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHt9LFxuICAgICAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBjdXN0b21fcmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5mcm9tUmVzcG9uc2UoXCJPcmdhbml6YXRpb24uSWRcIiksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvblVwZGF0ZToge1xuICAgICAgICAgICAgc2VydmljZTogXCJPcmdhbml6YXRpb25zXCIsXG4gICAgICAgICAgICBhY3Rpb246IFwiZGVzY3JpYmVPcmdhbml6YXRpb25cIiwgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvbGF0ZXN0L0FXUy9Pcmdhbml6YXRpb25zLmh0bWwjZGVzY3JpYmVPcmdhbml6YXRpb24tcHJvcGVydHlcbiAgICAgICAgICAgIHJlZ2lvbjogb3JnYW5pemF0aW9uc1JlZ2lvbixcbiAgICAgICAgICAgIHBhcmFtZXRlcnM6IHt9LFxuICAgICAgICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiBjdXN0b21fcmVzb3VyY2VzLlBoeXNpY2FsUmVzb3VyY2VJZC5mcm9tUmVzcG9uc2UoXCJPcmdhbml6YXRpb24uSWRcIiksXG4gICAgICAgICAgfSxcbiAgICAgICAgICBpbnN0YWxsTGF0ZXN0QXdzU2RrOiBmYWxzZSxcbiAgICAgICAgICBwb2xpY3k6IGN1c3RvbV9yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuZnJvbVNka0NhbGxzKHtcbiAgICAgICAgICAgIHJlc291cmNlczogY3VzdG9tX3Jlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5BTllfUkVTT1VSQ0UsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZmVhdHVyZVNldCA9IHJlc291cmNlLmdldFJlc3BvbnNlRmllbGQoXCJPcmdhbml6YXRpb24uRmVhdHVyZVNldFwiKSBhcyBGZWF0dXJlU2V0O1xuICAgICAgICB0aGlzLm1hbmFnZW1lbnRBY2NvdW50QXJuID0gcmVzb3VyY2UuZ2V0UmVzcG9uc2VGaWVsZChcIk9yZ2FuaXphdGlvbi5NYXN0ZXJBY2NvdW50QXJuXCIpO1xuICAgICAgICB0aGlzLm1hbmFnZW1lbnRBY2NvdW50RW1haWwgPSByZXNvdXJjZS5nZXRSZXNwb25zZUZpZWxkKFwiT3JnYW5pemF0aW9uLk1hc3RlckFjY291bnRFbWFpbFwiKTtcbiAgICAgICAgdGhpcy5tYW5hZ2VtZW50QWNjb3VudElkID0gcmVzb3VyY2UuZ2V0UmVzcG9uc2VGaWVsZChcIk9yZ2FuaXphdGlvbi5NYXN0ZXJBY2NvdW50SWRcIik7XG4gICAgICAgIHRoaXMub3JnYW5pemF0aW9uQXJuID0gcmVzb3VyY2UuZ2V0UmVzcG9uc2VGaWVsZChcIk9yZ2FuaXphdGlvbi5Bcm5cIik7XG4gICAgICAgIHRoaXMub3JnYW5pemF0aW9uSWQgPSByZXNvdXJjZS5nZXRSZXNwb25zZUZpZWxkKFwiT3JnYW5pemF0aW9uLklkXCIpO1xuICAgICAgICB0aGlzLnByaW5jaXBhbCA9IG5ldyBhd3NfaWFtLk9yZ2FuaXphdGlvblByaW5jaXBhbCh0aGlzLm9yZ2FuaXphdGlvbklkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltcG9ydCgpO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IG9yZ2FuaXphdGlvbklkOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBvcmdhbml6YXRpb25Bcm46IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGZlYXR1cmVTZXQ6IEZlYXR1cmVTZXQ7XG4gIHB1YmxpYyByZWFkb25seSBtYW5hZ2VtZW50QWNjb3VudEFybjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgbWFuYWdlbWVudEFjY291bnRJZDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgbWFuYWdlbWVudEFjY291bnRFbWFpbDogc3RyaW5nO1xuICByZWFkb25seSBwcmluY2lwYWw6IGF3c19pYW0uSVByaW5jaXBhbDtcbiAgLyoqXG4gICAqIFRoZSByb290IG9mIHRoZSBjdXJyZW50IG9yZ2FuaXphdGlvbiwgd2hpY2ggaXMgYXV0b21hdGljYWxseSBjcmVhdGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgcm9vdDogUm9vdDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlOiBDdXN0b21SZXNvdXJjZTtcblxuICBwdWJsaWMgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE9yZ2FuaXphdGlvblByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgZmVhdHVyZVNldCA9IHByb3BzLmZlYXR1cmVTZXQgfHwgRmVhdHVyZVNldC5BTEw7XG5cbiAgICBjb25zdCBvcmdhbml6YXRpb25Qcm92aWRlciA9IE9yZ2FuaXphdGlvblByb3ZpZGVyLmdldE9yQ3JlYXRlKHRoaXMpO1xuICAgIHRoaXMucmVzb3VyY2UgPSBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJPcmdhbml6YXRpb25cIiwge1xuICAgICAgc2VydmljZVRva2VuOiBvcmdhbml6YXRpb25Qcm92aWRlci5wcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpPcmdhbml6YXRpb25zX09yZ2FuaXphdGlvblwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBGZWF0dXJlU2V0OiBmZWF0dXJlU2V0LFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMub3JnYW5pemF0aW9uSWQgPSB0aGlzLnJlc291cmNlLmdldEF0dChcIklkXCIpLnRvU3RyaW5nKCk7XG4gICAgdGhpcy5vcmdhbml6YXRpb25Bcm4gPSB0aGlzLnJlc291cmNlLmdldEF0dChcIkFyblwiKS50b1N0cmluZygpO1xuICAgIHRoaXMuZmVhdHVyZVNldCA9IHRoaXMucmVzb3VyY2UuZ2V0QXR0KFwiRmVhdHVyZVNldFwiKS50b1N0cmluZygpIGFzIEZlYXR1cmVTZXQ7XG4gICAgdGhpcy5tYW5hZ2VtZW50QWNjb3VudEFybiA9IHRoaXMucmVzb3VyY2UuZ2V0QXR0KFwiTWFzdGVyQWNjb3VudEFyblwiKS50b1N0cmluZygpO1xuICAgIHRoaXMubWFuYWdlbWVudEFjY291bnRJZCA9IHRoaXMucmVzb3VyY2UuZ2V0QXR0KFwiTWFzdGVyQWNjb3VudElkXCIpLnRvU3RyaW5nKCk7XG4gICAgdGhpcy5tYW5hZ2VtZW50QWNjb3VudEVtYWlsID0gdGhpcy5yZXNvdXJjZS5nZXRBdHQoXCJNYXN0ZXJBY2NvdW50RW1haWxcIikudG9TdHJpbmcoKTtcbiAgICB0aGlzLnByaW5jaXBhbCA9IG5ldyBhd3NfaWFtLk9yZ2FuaXphdGlvblByaW5jaXBhbCh0aGlzLm9yZ2FuaXphdGlvbklkKTtcblxuICAgIHRoaXMucm9vdCA9IG5ldyBSb290KHRoaXMsIFwiUm9vdFwiKTtcbiAgICB0aGlzLnJvb3Qubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMucmVzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgdHJ1c3RlZCBhY2Nlc3MgZm9yIGEgc3VwcG9ydGVkIEFXUyBzZXJ2aWNlICh0cnVzdGVkIHNlcnZpY2UpLCB3aGljaCBwZXJmb3JtcyB0YXNrcyBpbiB5b3VyIG9yZ2FuaXphdGlvbiBhbmQgaXRzIGFjY291bnRzIG9uIHlvdXIgYmVoYWxmLlxuICAgKiBAcGFyYW0gc2VydmljZVByaW5jaXBhbCBUaGUgc3VwcG9ydGVkIEFXUyBzZXJ2aWNlIHRoYXQgeW91IHNwZWNpZnlcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3JnYW5pemF0aW9ucy9sYXRlc3QvdXNlcmd1aWRlL29yZ3NfaW50ZWdyYXRlX3NlcnZpY2VzX2xpc3QuaHRtbFxuICAgKi9cbiAgcHVibGljIGVuYWJsZUF3c1NlcnZpY2VBY2Nlc3Moc2VydmljZVByaW5jaXBhbDogc3RyaW5nKSB7XG4gICAgY29uc3QgZW5hYmxlQXdzU2VydmljZUFjY2VzcyA9IG5ldyBFbmFibGVBd3NTZXJ2aWNlQWNjZXNzKHRoaXMsIGBFbmFibGUke3Bhc2NhbENhc2Uoc2VydmljZVByaW5jaXBhbCl9YCwge1xuICAgICAgc2VydmljZVByaW5jaXBhbDogc2VydmljZVByaW5jaXBhbCxcbiAgICB9KTtcbiAgICBlbmFibGVBd3NTZXJ2aWNlQWNjZXNzLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLnJlc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGVzIHBvbGljeSB0eXBlcyBpbiB0aGUgZm9sbG93aW5nIHR3byBicm9hZCBjYXRlZ29yaWVzOiBBdXRob3JpemF0aW9uIHBvbGljaWVzIGFuZCBNYW5hZ2VtZW50IHBvbGljaWVzLlxuICAgKiBAcGFyYW0gcG9saWN5VHlwZTogdGhlIHR5cGUgb2YgdGhlIHBvbGljeSB0aGF0IHlvdSBzcGVjaWZ5XG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29yZ2FuaXphdGlvbnMvbGF0ZXN0L3VzZXJndWlkZS9vcmdzX21hbmFnZV9wb2xpY2llcy5odG1sI29yZ3MtcG9saWN5LXR5cGVzXG4gICAqL1xuICBwdWJsaWMgZW5hYmxlUG9saWN5VHlwZShwb2xpY3lUeXBlOiBQb2xpY3lUeXBlKSB7XG4gICAgdGhpcy5yb290LmVuYWJsZVBvbGljeVR5cGUocG9saWN5VHlwZSk7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoIGEgcG9saWN5LiBCZWZvcmUgeW91IGNhbiBhdHRhY2ggdGhlIHBvbGljeSwgeW91IG11c3QgZW5hYmxlIHRoYXQgcG9saWN5IHR5cGUgZm9yIHVzZS4gWW91IGNhbiB1c2UgcG9saWNpZXMgd2hlbiB5b3UgaGF2ZSBhbGwgZmVhdHVyZXMgZW5hYmxlZC5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3JnYW5pemF0aW9ucy9sYXRlc3QvdXNlcmd1aWRlL29yZ3NfbWFuYWdlX3BvbGljaWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBhdHRhY2hQb2xpY3kocG9saWN5OiBJUG9saWN5KSB7XG4gICAgdGhpcy5yb290LmF0dGFjaFBvbGljeShwb2xpY3kpO1xuICB9XG59XG5cbi8qKlxuICogVGhlIHBhcmVudCBjb250YWluZXIgZm9yIGFsbCB0aGUgYWNjb3VudHMgZm9yIHlvdXIgb3JnYW5pemF0aW9uLiBJZiB5b3UgYXBwbHkgYSBwb2xpY3kgdG8gdGhlIHJvb3QsIGl0IGFwcGxpZXMgdG8gYWxsIG9yZ2FuaXphdGlvbmFsIHVuaXRzIChPVXMpIGFuZCBhY2NvdW50cyBpbiB0aGUgb3JnYW5pemF0aW9uLlxuICogPHN0cm9uZz5DdXJyZW50bHksIHlvdSBjYW4gaGF2ZSBvbmx5IG9uZSByb290LiBBV1MgT3JnYW5pemF0aW9ucyBhdXRvbWF0aWNhbGx5IGNyZWF0ZXMgaXQgZm9yIHlvdSB3aGVuIHlvdSBjcmVhdGUgYW4gb3JnYW5pemF0aW9uLjwvc3Ryb25nPlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vb3JnYW5pemF0aW9ucy9sYXRlc3QvdXNlcmd1aWRlL29yZ3NfZ2V0dGluZy1zdGFydGVkX2NvbmNlcHRzLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIFJvb3QgZXh0ZW5kcyBDb25zdHJ1Y3QgaW1wbGVtZW50cyBJUGFyZW50LCBJUG9saWN5QXR0YWNobWVudFRhcmdldCwgSVRhZ2dhYmxlUmVzb3VyY2Uge1xuICAvKipcbiAgICogVGhlIHVuaXF1ZSBpZGVudGlmaWVyIChJRCkgZm9yIHRoZSByb290LiBUaGUgcmVnZXggcGF0dGVybiBmb3IgYSByb290IElEIHN0cmluZyByZXF1aXJlcyBcInItXCIgZm9sbG93ZWQgYnkgZnJvbSA0IHRvIDMyIGxvd2VyY2FzZSBsZXR0ZXJzIG9yIGRpZ2l0cy5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSByb290SWQ6IHN0cmluZztcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVzb3VyY2U6IGN1c3RvbV9yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzY29wZTogQ29uc3RydWN0O1xuXG4gIHJlYWRvbmx5IHRhZ3MgPSBuZXcgVGFnTWFuYWdlcihUYWdUeXBlLktFWV9WQUxVRSwgXCJDdXN0b206Ok9yZ2FuaXphdGlvbnNfUm9vdFwiKTtcblxuICBwdWJsaWMgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuXG4gICAgY29uc3Qgb3JnYW5pemF0aW9uc1JlZ2lvbiA9IHByb2Nlc3MuZW52LkNES19BV1NfUEFSVElUSU9OID09PSBcImF3cy1jblwiID8gXCJjbi1ub3J0aHdlc3QtMVwiIDogXCJ1cy1lYXN0LTFcIjtcblxuICAgIHRoaXMucmVzb3VyY2UgPSBuZXcgY3VzdG9tX3Jlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZSh0aGlzLCBcIlJvb3RDdXN0b21SZXNvdXJjZVwiLCB7XG4gICAgICByZXNvdXJjZVR5cGU6IFwiQ3VzdG9tOjpPcmdhbml6YXRpb25zX1Jvb3RcIixcbiAgICAgIG9uQ3JlYXRlOiB7XG4gICAgICAgIHNlcnZpY2U6IFwiT3JnYW5pemF0aW9uc1wiLFxuICAgICAgICBhY3Rpb246IFwibGlzdFJvb3RzXCIsIC8vIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NKYXZhU2NyaXB0U0RLL2xhdGVzdC9BV1MvT3JnYW5pemF0aW9ucy5odG1sI2xpc3RSb290cy1wcm9wZXJ0eVxuICAgICAgICByZWdpb246IG9yZ2FuaXphdGlvbnNSZWdpb24sXG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogY3VzdG9tX3Jlc291cmNlcy5QaHlzaWNhbFJlc291cmNlSWQuZnJvbVJlc3BvbnNlKFwiUm9vdHMuMC5JZFwiKSxcbiAgICAgIH0sXG4gICAgICBvblVwZGF0ZToge1xuICAgICAgICBzZXJ2aWNlOiBcIk9yZ2FuaXphdGlvbnNcIixcbiAgICAgICAgYWN0aW9uOiBcImxpc3RSb290c1wiLCAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTSmF2YVNjcmlwdFNESy9sYXRlc3QvQVdTL09yZ2FuaXphdGlvbnMuaHRtbCNsaXN0Um9vdHMtcHJvcGVydHlcbiAgICAgICAgcmVnaW9uOiBvcmdhbml6YXRpb25zUmVnaW9uLFxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IGN1c3RvbV9yZXNvdXJjZXMuUGh5c2ljYWxSZXNvdXJjZUlkLmZyb21SZXNwb25zZShcIlJvb3RzLjAuSWRcIiksXG4gICAgICB9LFxuICAgICAgb25EZWxldGU6IHtcbiAgICAgICAgc2VydmljZTogXCJPcmdhbml6YXRpb25zXCIsXG4gICAgICAgIGFjdGlvbjogXCJsaXN0Um9vdHNcIiwgLy8gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0phdmFTY3JpcHRTREsvbGF0ZXN0L0FXUy9Pcmdhbml6YXRpb25zLmh0bWwjbGlzdFJvb3RzLXByb3BlcnR5XG4gICAgICAgIHJlZ2lvbjogb3JnYW5pemF0aW9uc1JlZ2lvbixcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsTGF0ZXN0QXdzU2RrOiBmYWxzZSxcbiAgICAgIHBvbGljeTogY3VzdG9tX3Jlc291cmNlcy5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5mcm9tU2RrQ2FsbHMoe1xuICAgICAgICByZXNvdXJjZXM6IGN1c3RvbV9yZXNvdXJjZXMuQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3kuQU5ZX1JFU09VUkNFLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICB0aGlzLnJvb3RJZCA9IHRoaXMucmVzb3VyY2UuZ2V0UmVzcG9uc2VGaWVsZChcIlJvb3RzLjAuSWRcIik7IC8vIFJldHVybnMgZmlyc3Qgcm9vdCBpZC4gSXQgc2VlbXMgQVdTIE9yZ2FuaXphdGlvbnMgZG9lc24ndCBjb250YWluIG11bHRpcGxlIHJvb3RzLlxuXG4gICAgY29uc3Qgc3RhY2sgPSBTdGFjay5vZih0aGlzKTtcbiAgICBBc3BlY3RzLm9mKHN0YWNrKS5hZGQobmV3IERlcGVuZGVuY3lDaGFpbigpKTsgLy8gc2VxdWVudGlhbGx5IGNoYWluIG9yZ2FuaXphdGlvbiByZXNvdXJjZXMgd2hpY2ggY2FuJ3QgYmUgZGVwbG95ZWQgaW4gcGFyYWxsZWxcblxuICAgIGNvbnN0IHRhZ1Jlc291cmNlID0gbmV3IFRhZ1Jlc291cmNlKHRoaXMsIFwiVGFnc1wiLCB7IHJlc291cmNlSWQ6IHRoaXMucm9vdElkLCB0YWdzOiB0aGlzLnRhZ3MucmVuZGVyZWRUYWdzIH0pO1xuICAgIHRhZ1Jlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLnJlc291cmNlKTtcbiAgfVxuXG4gIHB1YmxpYyBpZGVudGlmaWVyKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucm9vdElkO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaCBhIHBvbGljeS4gQmVmb3JlIHlvdSBjYW4gYXR0YWNoIHRoZSBwb2xpY3ksIHlvdSBtdXN0IGVuYWJsZSB0aGF0IHBvbGljeSB0eXBlIGZvciB1c2UuIFlvdSBjYW4gdXNlIHBvbGljaWVzIHdoZW4geW91IGhhdmUgYWxsIGZlYXR1cmVzIGVuYWJsZWQuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL29yZ2FuaXphdGlvbnMvbGF0ZXN0L3VzZXJndWlkZS9vcmdzX21hbmFnZV9wb2xpY2llcy5odG1sXG4gICAqL1xuICBwdWJsaWMgYXR0YWNoUG9saWN5KHBvbGljeTogSVBvbGljeSkge1xuICAgIGNvbnN0IHBvbGljeUF0dGFjaG1lbnQgPSBuZXcgUG9saWN5QXR0YWNobWVudChcbiAgICAgIHRoaXMuc2NvcGUsXG4gICAgICBgUG9saWN5QXR0YWNobWVudC0ke05hbWVzLm5vZGVVbmlxdWVJZCh0aGlzLm5vZGUpfS0ke05hbWVzLm5vZGVVbmlxdWVJZChwb2xpY3kubm9kZSl9YCxcbiAgICAgIHtcbiAgICAgICAgdGFyZ2V0OiB0aGlzLFxuICAgICAgICBwb2xpY3k6IHBvbGljeSxcbiAgICAgIH1cbiAgICApO1xuICAgIHBvbGljeUF0dGFjaG1lbnQubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMucmVzb3VyY2UsIHBvbGljeSk7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyBhbmQgZGlzYWJsZXMgRW5hYmxlcyBhIHBvbGljeSB0eXBlLiBBZnRlciB5b3UgZW5hYmxlIGEgcG9saWN5IHR5cGUgaW4gYSByb290LCB5b3UgY2FuIGF0dGFjaCBwb2xpY2llcyBvZiB0aGF0IHR5cGUgdG8gdGhlIHJvb3QsIGFueSBvcmdhbml6YXRpb25hbCB1bml0IChPVSksIG9yIGFjY291bnQgaW4gdGhhdCByb290LlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9vcmdhbml6YXRpb25zL2xhdGVzdC91c2VyZ3VpZGUvb3Jnc19tYW5hZ2VfcG9saWNpZXNfZW5hYmxlLWRpc2FibGUuaHRtbFxuICAgKi9cbiAgcHVibGljIGVuYWJsZVBvbGljeVR5cGUocG9saWN5VHlwZTogUG9saWN5VHlwZSkge1xuICAgIGNvbnN0IGVuYWJsZVBvbGljeVR5cGUgPSBuZXcgRW5hYmxlUG9saWN5VHlwZSh0aGlzLnNjb3BlLCBgRW5hYmxlJHtwYXNjYWxDYXNlKHBvbGljeVR5cGUpfWAsIHtcbiAgICAgIHJvb3Q6IHRoaXMsXG4gICAgICBwb2xpY3lUeXBlOiBwb2xpY3lUeXBlLFxuICAgIH0pO1xuICAgIGVuYWJsZVBvbGljeVR5cGUubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMucmVzb3VyY2UpO1xuICB9XG59XG4iXX0=