1 | ;
|
2 | var _a;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.EdgeFunction = void 0;
|
5 | const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const path = require("path");
|
8 | const iam = require("@aws-cdk/aws-iam");
|
9 | const lambda = require("@aws-cdk/aws-lambda");
|
10 | const ssm = require("@aws-cdk/aws-ssm");
|
11 | const core_1 = require("@aws-cdk/core");
|
12 | /**
|
13 | * A Lambda@Edge function.
|
14 | *
|
15 | * Convenience resource for requesting a Lambda function in the 'us-east-1' region for use with Lambda@Edge.
|
16 | * Implements several restrictions enforced by Lambda@Edge.
|
17 | *
|
18 | * Note that this construct requires that the 'us-east-1' region has been bootstrapped.
|
19 | * See https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html or 'cdk bootstrap --help' for options.
|
20 | *
|
21 | * @resource AWS::Lambda::Function
|
22 | */
|
23 | class EdgeFunction extends core_1.Resource {
|
24 | constructor(scope, id, props) {
|
25 | super(scope, id);
|
26 | this.isBoundToVpc = false;
|
27 | try {
|
28 | jsiiDeprecationWarnings._aws_cdk_aws_cloudfront_experimental_EdgeFunctionProps(props);
|
29 | }
|
30 | catch (error) {
|
31 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
32 | Error.captureStackTrace(error, this.constructor);
|
33 | }
|
34 | throw error;
|
35 | }
|
36 | // Create a simple Function if we're already in us-east-1; otherwise create a cross-region stack.
|
37 | const regionIsUsEast1 = !core_1.Token.isUnresolved(this.env.region) && this.env.region === 'us-east-1';
|
38 | const { edgeFunction, edgeArn } = regionIsUsEast1
|
39 | ? this.createInRegionFunction(props)
|
40 | : this.createCrossRegionFunction(id, props);
|
41 | this.edgeArn = edgeArn;
|
42 | this.functionArn = edgeArn;
|
43 | this._edgeFunction = edgeFunction;
|
44 | this.functionName = this._edgeFunction.functionName;
|
45 | this.grantPrincipal = this._edgeFunction.role;
|
46 | this.permissionsNode = this._edgeFunction.permissionsNode;
|
47 | this.version = lambda.extractQualifierFromArn(this.functionArn);
|
48 | this.architecture = this._edgeFunction.architecture;
|
49 | this.resourceArnsForGrantInvoke = this._edgeFunction.resourceArnsForGrantInvoke;
|
50 | this.node.defaultChild = this._edgeFunction;
|
51 | }
|
52 | get lambda() {
|
53 | return this._edgeFunction;
|
54 | }
|
55 | /**
|
56 | * Convenience method to make `EdgeFunction` conform to the same interface as `Function`.
|
57 | */
|
58 | get currentVersion() {
|
59 | return this;
|
60 | }
|
61 | addAlias(aliasName, options = {}) {
|
62 | return new lambda.Alias(this._edgeFunction, `Alias${aliasName}`, {
|
63 | aliasName,
|
64 | version: this._edgeFunction.currentVersion,
|
65 | ...options,
|
66 | });
|
67 | }
|
68 | /**
|
69 | * Not supported. Connections are only applicable to VPC-enabled functions.
|
70 | */
|
71 | get connections() {
|
72 | throw new Error('Lambda@Edge does not support connections');
|
73 | }
|
74 | get latestVersion() {
|
75 | throw new Error('$LATEST function version cannot be used for Lambda@Edge');
|
76 | }
|
77 | addEventSourceMapping(id, options) {
|
78 | return this.lambda.addEventSourceMapping(id, options);
|
79 | }
|
80 | addPermission(id, permission) {
|
81 | return this.lambda.addPermission(id, permission);
|
82 | }
|
83 | addToRolePolicy(statement) {
|
84 | return this.lambda.addToRolePolicy(statement);
|
85 | }
|
86 | grantInvoke(identity) {
|
87 | return this.lambda.grantInvoke(identity);
|
88 | }
|
89 | grantInvokeUrl(identity) {
|
90 | return this.lambda.grantInvokeUrl(identity);
|
91 | }
|
92 | metric(metricName, props) {
|
93 | return this.lambda.metric(metricName, { ...props, region: EdgeFunction.EDGE_REGION });
|
94 | }
|
95 | metricDuration(props) {
|
96 | return this.lambda.metricDuration({ ...props, region: EdgeFunction.EDGE_REGION });
|
97 | }
|
98 | metricErrors(props) {
|
99 | return this.lambda.metricErrors({ ...props, region: EdgeFunction.EDGE_REGION });
|
100 | }
|
101 | metricInvocations(props) {
|
102 | return this.lambda.metricInvocations({ ...props, region: EdgeFunction.EDGE_REGION });
|
103 | }
|
104 | metricThrottles(props) {
|
105 | return this.lambda.metricThrottles({ ...props, region: EdgeFunction.EDGE_REGION });
|
106 | }
|
107 | /** Adds an event source to this function. */
|
108 | addEventSource(source) {
|
109 | return this.lambda.addEventSource(source);
|
110 | }
|
111 | configureAsyncInvoke(options) {
|
112 | return this.lambda.configureAsyncInvoke(options);
|
113 | }
|
114 | addFunctionUrl(options) {
|
115 | return this.lambda.addFunctionUrl(options);
|
116 | }
|
117 | /** Create a function in-region */
|
118 | createInRegionFunction(props) {
|
119 | const edgeFunction = new lambda.Function(this, 'Fn', props);
|
120 | addEdgeLambdaToRoleTrustStatement(edgeFunction.role);
|
121 | return { edgeFunction, edgeArn: edgeFunction.currentVersion.edgeArn };
|
122 | }
|
123 | /** Create a support stack and function in us-east-1, and a SSM reader in-region */
|
124 | createCrossRegionFunction(id, props) {
|
125 | const parameterNamePrefix = 'cdk/EdgeFunctionArn';
|
126 | if (core_1.Token.isUnresolved(this.env.region)) {
|
127 | throw new Error('stacks which use EdgeFunctions must have an explicitly set region');
|
128 | }
|
129 | // SSM parameter names must only contain letters, numbers, ., _, -, or /.
|
130 | const sanitizedPath = this.node.path.replace(/[^\/\w.-]/g, '_');
|
131 | const parameterName = `/${parameterNamePrefix}/${this.env.region}/${sanitizedPath}`;
|
132 | const functionStack = this.edgeStack(props.stackId);
|
133 | const edgeFunction = new lambda.Function(functionStack, id, props);
|
134 | addEdgeLambdaToRoleTrustStatement(edgeFunction.role);
|
135 | // Store the current version's ARN to be retrieved by the cross region reader below.
|
136 | const version = edgeFunction.currentVersion;
|
137 | new ssm.StringParameter(edgeFunction, 'Parameter', {
|
138 | parameterName,
|
139 | stringValue: version.edgeArn,
|
140 | });
|
141 | const edgeArn = this.createCrossRegionArnReader(parameterNamePrefix, parameterName, version);
|
142 | return { edgeFunction, edgeArn };
|
143 | }
|
144 | createCrossRegionArnReader(parameterNamePrefix, parameterName, version) {
|
145 | // Prefix of the parameter ARN that applies to all EdgeFunctions.
|
146 | // This is necessary because the `CustomResourceProvider` is a singleton, and the `policyStatement`
|
147 | // must work for multiple EdgeFunctions.
|
148 | const parameterArnPrefix = this.stack.formatArn({
|
149 | service: 'ssm',
|
150 | region: EdgeFunction.EDGE_REGION,
|
151 | resource: 'parameter',
|
152 | resourceName: parameterNamePrefix + '/*',
|
153 | });
|
154 | const resourceType = 'Custom::CrossRegionStringParameterReader';
|
155 | const serviceToken = core_1.CustomResourceProvider.getOrCreate(this, resourceType, {
|
156 | codeDirectory: path.join(__dirname, 'edge-function'),
|
157 | runtime: core_1.CustomResourceProviderRuntime.NODEJS_12_X,
|
158 | policyStatements: [{
|
159 | Effect: 'Allow',
|
160 | Resource: parameterArnPrefix,
|
161 | Action: ['ssm:GetParameter'],
|
162 | }],
|
163 | });
|
164 | const resource = new core_1.CustomResource(this, 'ArnReader', {
|
165 | resourceType: resourceType,
|
166 | serviceToken,
|
167 | properties: {
|
168 | Region: EdgeFunction.EDGE_REGION,
|
169 | ParameterName: parameterName,
|
170 | // This is used to determine when the function has changed, to refresh the ARN from the custom resource.
|
171 | //
|
172 | // Use the logical id of the function version. Whenever a function version changes, the logical id must be
|
173 | // changed for it to take effect - a good candidate for RefreshToken.
|
174 | RefreshToken: core_1.Lazy.uncachedString({
|
175 | produce: () => {
|
176 | const cfn = version.node.defaultChild;
|
177 | return this.stack.resolve(cfn.logicalId);
|
178 | },
|
179 | }),
|
180 | },
|
181 | });
|
182 | return resource.getAttString('FunctionArn');
|
183 | }
|
184 | edgeStack(stackId) {
|
185 | const stage = core_1.Stage.of(this);
|
186 | if (!stage) {
|
187 | throw new Error('stacks which use EdgeFunctions must be part of a CDK app or stage');
|
188 | }
|
189 | const edgeStackId = stackId !== null && stackId !== void 0 ? stackId : `edge-lambda-stack-${this.stack.node.addr}`;
|
190 | let edgeStack = stage.node.tryFindChild(edgeStackId);
|
191 | if (!edgeStack) {
|
192 | edgeStack = new core_1.Stack(stage, edgeStackId, {
|
193 | env: {
|
194 | region: EdgeFunction.EDGE_REGION,
|
195 | account: core_1.Stack.of(this).account,
|
196 | },
|
197 | });
|
198 | }
|
199 | this.stack.addDependency(edgeStack);
|
200 | return edgeStack;
|
201 | }
|
202 | }
|
203 | exports.EdgeFunction = EdgeFunction;
|
204 | _a = JSII_RTTI_SYMBOL_1;
|
205 | EdgeFunction[_a] = { fqn: "@aws-cdk/aws-cloudfront.experimental.EdgeFunction", version: "1.157.0" };
|
206 | EdgeFunction.EDGE_REGION = 'us-east-1';
|
207 | function addEdgeLambdaToRoleTrustStatement(role) {
|
208 | if (role instanceof iam.Role && role.assumeRolePolicy) {
|
209 | const statement = new iam.PolicyStatement();
|
210 | const edgeLambdaServicePrincipal = new iam.ServicePrincipal('edgelambda.amazonaws.com');
|
211 | statement.addPrincipals(edgeLambdaServicePrincipal);
|
212 | statement.addActions(edgeLambdaServicePrincipal.assumeRoleAction);
|
213 | role.assumeRolePolicy.addStatements(statement);
|
214 | }
|
215 | }
|
216 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRnZS1mdW5jdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImVkZ2UtZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsNkJBQTZCO0FBRzdCLHdDQUF3QztBQUN4Qyw4Q0FBOEM7QUFDOUMsd0NBQXdDO0FBQ3hDLHdDQUl1QjtBQWV2Qjs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBYSxZQUFhLFNBQVEsZUFBUTtJQWlCeEMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUNoRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBVkgsaUJBQVksR0FBRyxLQUFLLENBQUM7Ozs7Ozs7Ozs7UUFZbkMsaUdBQWlHO1FBQ2pHLE1BQU0sZUFBZSxHQUFHLENBQUMsWUFBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQztRQUNoRyxNQUFNLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxHQUFHLGVBQWU7WUFDL0MsQ0FBQyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUM7WUFDcEMsQ0FBQyxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFOUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFFdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxZQUFZLENBQUM7UUFDbEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQztRQUNwRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSyxDQUFDO1FBQy9DLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUM7UUFDMUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUM7UUFDcEQsSUFBSSxDQUFDLDBCQUEwQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsMEJBQTBCLENBQUM7UUFFaEYsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztLQUM3QztJQUVELElBQVcsTUFBTTtRQUNmLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztLQUMzQjtJQUVEOztPQUVHO0lBQ0gsSUFBVyxjQUFjO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFTSxRQUFRLENBQUMsU0FBaUIsRUFBRSxVQUErQixFQUFFO1FBQ2xFLE9BQU8sSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsUUFBUSxTQUFTLEVBQUUsRUFBRTtZQUMvRCxTQUFTO1lBQ1QsT0FBTyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYztZQUMxQyxHQUFHLE9BQU87U0FDWCxDQUFDLENBQUM7S0FDSjtJQUVEOztPQUVHO0lBQ0gsSUFBVyxXQUFXO1FBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztLQUM3RDtJQUNELElBQVcsYUFBYTtRQUN0QixNQUFNLElBQUksS0FBSyxDQUFDLHlEQUF5RCxDQUFDLENBQUM7S0FDNUU7SUFFTSxxQkFBcUIsQ0FBQyxFQUFVLEVBQUUsT0FBeUM7UUFDaEYsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQztLQUN2RDtJQUNNLGFBQWEsQ0FBQyxFQUFVLEVBQUUsVUFBNkI7UUFDNUQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7S0FDbEQ7SUFDTSxlQUFlLENBQUMsU0FBOEI7UUFDbkQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztLQUMvQztJQUNNLFdBQVcsQ0FBQyxRQUF3QjtRQUN6QyxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0tBQzFDO0lBQ00sY0FBYyxDQUFDLFFBQXdCO1FBQzVDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7S0FDN0M7SUFDTSxNQUFNLENBQUMsVUFBa0IsRUFBRSxLQUFnQztRQUNoRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxFQUFFLEdBQUcsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztLQUN2RjtJQUNNLGNBQWMsQ0FBQyxLQUFnQztRQUNwRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0tBQ25GO0lBQ00sWUFBWSxDQUFDLEtBQWdDO1FBQ2xELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7S0FDakY7SUFDTSxpQkFBaUIsQ0FBQyxLQUFnQztRQUN2RCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7S0FDdEY7SUFDTSxlQUFlLENBQUMsS0FBZ0M7UUFDckQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztLQUNwRjtJQUNELDZDQUE2QztJQUN0QyxjQUFjLENBQUMsTUFBMkI7UUFDL0MsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztLQUMzQztJQUNNLG9CQUFvQixDQUFDLE9BQXdDO1FBQ2xFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztLQUNsRDtJQUNNLGNBQWMsQ0FBQyxPQUFtQztRQUN2RCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQzVDO0lBRUQsa0NBQWtDO0lBQzFCLHNCQUFzQixDQUFDLEtBQTJCO1FBQ3hELE1BQU0sWUFBWSxHQUFHLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzVELGlDQUFpQyxDQUFDLFlBQVksQ0FBQyxJQUFLLENBQUMsQ0FBQztRQUV0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxZQUFZLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO0tBQ3ZFO0lBRUQsbUZBQW1GO0lBQzNFLHlCQUF5QixDQUFDLEVBQVUsRUFBRSxLQUF3QjtRQUNwRSxNQUFNLG1CQUFtQixHQUFHLHFCQUFxQixDQUFDO1FBQ2xELElBQUksWUFBSyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQUMsbUVBQW1FLENBQUMsQ0FBQztTQUN0RjtRQUNELHlFQUF5RTtRQUN6RSxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hFLE1BQU0sYUFBYSxHQUFHLElBQUksbUJBQW1CLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLENBQUM7UUFDcEYsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbkUsaUNBQWlDLENBQUMsWUFBWSxDQUFDLElBQUssQ0FBQyxDQUFDO1FBRXRELG9GQUFvRjtRQUNwRixNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsY0FBYyxDQUFDO1FBQzVDLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFO1lBQ2pELGFBQWE7WUFDYixXQUFXLEVBQUUsT0FBTyxDQUFDLE9BQU87U0FDN0IsQ0FBQyxDQUFDO1FBRUgsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLDBCQUEwQixDQUFDLG1CQUFtQixFQUFFLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUU3RixPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxDQUFDO0tBQ2xDO0lBRU8sMEJBQTBCLENBQUMsbUJBQTJCLEVBQUUsYUFBcUIsRUFBRSxPQUF1QjtRQUM1RyxpRUFBaUU7UUFDakUsbUdBQW1HO1FBQ25HLHdDQUF3QztRQUN4QyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1lBQzlDLE9BQU8sRUFBRSxLQUFLO1lBQ2QsTUFBTSxFQUFFLFlBQVksQ0FBQyxXQUFXO1lBQ2hDLFFBQVEsRUFBRSxXQUFXO1lBQ3JCLFlBQVksRUFBRSxtQkFBbUIsR0FBRyxJQUFJO1NBQ3pDLENBQUMsQ0FBQztRQUVILE1BQU0sWUFBWSxHQUFHLDBDQUEwQyxDQUFDO1FBQ2hFLE1BQU0sWUFBWSxHQUFHLDZCQUFzQixDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFO1lBQzFFLGFBQWEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxlQUFlLENBQUM7WUFDcEQsT0FBTyxFQUFFLG9DQUE2QixDQUFDLFdBQVc7WUFDbEQsZ0JBQWdCLEVBQUUsQ0FBQztvQkFDakIsTUFBTSxFQUFFLE9BQU87b0JBQ2YsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsTUFBTSxFQUFFLENBQUMsa0JBQWtCLENBQUM7aUJBQzdCLENBQUM7U0FDSCxDQUFDLENBQUM7UUFDSCxNQUFNLFFBQVEsR0FBRyxJQUFJLHFCQUFjLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRTtZQUNyRCxZQUFZLEVBQUUsWUFBWTtZQUMxQixZQUFZO1lBQ1osVUFBVSxFQUFFO2dCQUNWLE1BQU0sRUFBRSxZQUFZLENBQUMsV0FBVztnQkFDaEMsYUFBYSxFQUFFLGFBQWE7Z0JBQzVCLHdHQUF3RztnQkFDeEcsRUFBRTtnQkFDRiwwR0FBMEc7Z0JBQzFHLHFFQUFxRTtnQkFDckUsWUFBWSxFQUFFLFdBQUksQ0FBQyxjQUFjLENBQUM7b0JBQ2hDLE9BQU8sRUFBRSxHQUFHLEVBQUU7d0JBQ1osTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUEyQixDQUFDO3dCQUNyRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDM0MsQ0FBQztpQkFDRixDQUFDO2FBQ0g7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPLFFBQVEsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7S0FDN0M7SUFFTyxTQUFTLENBQUMsT0FBZ0I7UUFDaEMsTUFBTSxLQUFLLEdBQUcsWUFBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxtRUFBbUUsQ0FBQyxDQUFDO1NBQ3RGO1FBRUQsTUFBTSxXQUFXLEdBQUcsT0FBTyxhQUFQLE9BQU8sY0FBUCxPQUFPLEdBQUkscUJBQXFCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNFLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBVSxDQUFDO1FBQzlELElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDZCxTQUFTLEdBQUcsSUFBSSxZQUFLLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtnQkFDeEMsR0FBRyxFQUFFO29CQUNILE1BQU0sRUFBRSxZQUFZLENBQUMsV0FBVztvQkFDaEMsT0FBTyxFQUFFLFlBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTztpQkFDaEM7YUFDRixDQUFDLENBQUM7U0FDSjtRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sU0FBUyxDQUFDO0tBQ2xCOztBQTdNSCxvQ0E4TUM7OztBQTVNeUIsd0JBQVcsR0FBVyxXQUFXLENBQUM7QUFvTjVELFNBQVMsaUNBQWlDLENBQUMsSUFBZTtJQUN4RCxJQUFJLElBQUksWUFBWSxHQUFHLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtRQUNyRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM1QyxNQUFNLDBCQUEwQixHQUFHLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDeEYsU0FBUyxDQUFDLGFBQWEsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ3BELFNBQVMsQ0FBQyxVQUFVLENBQUMsMEJBQTBCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0tBQ2hEO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyBjbG91ZHdhdGNoIGZyb20gJ0Bhd3MtY2RrL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCAqIGFzIGVjMiBmcm9tICdAYXdzLWNkay9hd3MtZWMyJztcbmltcG9ydCAqIGFzIGlhbSBmcm9tICdAYXdzLWNkay9hd3MtaWFtJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdAYXdzLWNkay9hd3MtbGFtYmRhJztcbmltcG9ydCAqIGFzIHNzbSBmcm9tICdAYXdzLWNkay9hd3Mtc3NtJztcbmltcG9ydCB7XG4gIENmblJlc291cmNlLCBDb25zdHJ1Y3ROb2RlLFxuICBDdXN0b21SZXNvdXJjZSwgQ3VzdG9tUmVzb3VyY2VQcm92aWRlciwgQ3VzdG9tUmVzb3VyY2VQcm92aWRlclJ1bnRpbWUsXG4gIExhenksIFJlc291cmNlLCBTdGFjaywgU3RhZ2UsIFRva2VuLFxufSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGNyZWF0aW5nIGEgTGFtYmRhQEVkZ2UgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFZGdlRnVuY3Rpb25Qcm9wcyBleHRlbmRzIGxhbWJkYS5GdW5jdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBzdGFjayBJRCBvZiBMYW1iZGFARWRnZSBmdW5jdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBgZWRnZS1sYW1iZGEtc3RhY2stJHtyZWdpb259YFxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tJZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIExhbWJkYUBFZGdlIGZ1bmN0aW9uLlxuICpcbiAqIENvbnZlbmllbmNlIHJlc291cmNlIGZvciByZXF1ZXN0aW5nIGEgTGFtYmRhIGZ1bmN0aW9uIGluIHRoZSAndXMtZWFzdC0xJyByZWdpb24gZm9yIHVzZSB3aXRoIExhbWJkYUBFZGdlLlxuICogSW1wbGVtZW50cyBzZXZlcmFsIHJlc3RyaWN0aW9ucyBlbmZvcmNlZCBieSBMYW1iZGFARWRnZS5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBjb25zdHJ1Y3QgcmVxdWlyZXMgdGhhdCB0aGUgJ3VzLWVhc3QtMScgcmVnaW9uIGhhcyBiZWVuIGJvb3RzdHJhcHBlZC5cbiAqIFNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2RrL2xhdGVzdC9ndWlkZS9ib290c3RyYXBwaW5nLmh0bWwgb3IgJ2NkayBib290c3RyYXAgLS1oZWxwJyBmb3Igb3B0aW9ucy5cbiAqXG4gKiBAcmVzb3VyY2UgQVdTOjpMYW1iZGE6OkZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBFZGdlRnVuY3Rpb24gZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIGxhbWJkYS5JVmVyc2lvbiB7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgRURHRV9SRUdJT046IHN0cmluZyA9ICd1cy1lYXN0LTEnO1xuXG4gIHB1YmxpYyByZWFkb25seSBlZGdlQXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbk5hbWU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGZ1bmN0aW9uQXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBncmFudFByaW5jaXBhbDogaWFtLklQcmluY2lwYWw7XG4gIHB1YmxpYyByZWFkb25seSBpc0JvdW5kVG9WcGMgPSBmYWxzZTtcbiAgcHVibGljIHJlYWRvbmx5IHBlcm1pc3Npb25zTm9kZTogQ29uc3RydWN0Tm9kZTtcbiAgcHVibGljIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG4gIHB1YmxpYyByZWFkb25seSB2ZXJzaW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBhcmNoaXRlY3R1cmU6IGxhbWJkYS5BcmNoaXRlY3R1cmU7XG4gIHB1YmxpYyByZWFkb25seSByZXNvdXJjZUFybnNGb3JHcmFudEludm9rZTogc3RyaW5nW107XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZWRnZUZ1bmN0aW9uOiBsYW1iZGEuRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEVkZ2VGdW5jdGlvblByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIC8vIENyZWF0ZSBhIHNpbXBsZSBGdW5jdGlvbiBpZiB3ZSdyZSBhbHJlYWR5IGluIHVzLWVhc3QtMTsgb3RoZXJ3aXNlIGNyZWF0ZSBhIGNyb3NzLXJlZ2lvbiBzdGFjay5cbiAgICBjb25zdCByZWdpb25Jc1VzRWFzdDEgPSAhVG9rZW4uaXNVbnJlc29sdmVkKHRoaXMuZW52LnJlZ2lvbikgJiYgdGhpcy5lbnYucmVnaW9uID09PSAndXMtZWFzdC0xJztcbiAgICBjb25zdCB7IGVkZ2VGdW5jdGlvbiwgZWRnZUFybiB9ID0gcmVnaW9uSXNVc0Vhc3QxXG4gICAgICA/IHRoaXMuY3JlYXRlSW5SZWdpb25GdW5jdGlvbihwcm9wcylcbiAgICAgIDogdGhpcy5jcmVhdGVDcm9zc1JlZ2lvbkZ1bmN0aW9uKGlkLCBwcm9wcyk7XG5cbiAgICB0aGlzLmVkZ2VBcm4gPSBlZGdlQXJuO1xuXG4gICAgdGhpcy5mdW5jdGlvbkFybiA9IGVkZ2VBcm47XG4gICAgdGhpcy5fZWRnZUZ1bmN0aW9uID0gZWRnZUZ1bmN0aW9uO1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lID0gdGhpcy5fZWRnZUZ1bmN0aW9uLmZ1bmN0aW9uTmFtZTtcbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gdGhpcy5fZWRnZUZ1bmN0aW9uLnJvbGUhO1xuICAgIHRoaXMucGVybWlzc2lvbnNOb2RlID0gdGhpcy5fZWRnZUZ1bmN0aW9uLnBlcm1pc3Npb25zTm9kZTtcbiAgICB0aGlzLnZlcnNpb24gPSBsYW1iZGEuZXh0cmFjdFF1YWxpZmllckZyb21Bcm4odGhpcy5mdW5jdGlvbkFybik7XG4gICAgdGhpcy5hcmNoaXRlY3R1cmUgPSB0aGlzLl9lZGdlRnVuY3Rpb24uYXJjaGl0ZWN0dXJlO1xuICAgIHRoaXMucmVzb3VyY2VBcm5zRm9yR3JhbnRJbnZva2UgPSB0aGlzLl9lZGdlRnVuY3Rpb24ucmVzb3VyY2VBcm5zRm9yR3JhbnRJbnZva2U7XG5cbiAgICB0aGlzLm5vZGUuZGVmYXVsdENoaWxkID0gdGhpcy5fZWRnZUZ1bmN0aW9uO1xuICB9XG5cbiAgcHVibGljIGdldCBsYW1iZGEoKTogbGFtYmRhLklGdW5jdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VkZ2VGdW5jdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdG8gbWFrZSBgRWRnZUZ1bmN0aW9uYCBjb25mb3JtIHRvIHRoZSBzYW1lIGludGVyZmFjZSBhcyBgRnVuY3Rpb25gLlxuICAgKi9cbiAgcHVibGljIGdldCBjdXJyZW50VmVyc2lvbigpOiBsYW1iZGEuSVZlcnNpb24ge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgcHVibGljIGFkZEFsaWFzKGFsaWFzTmFtZTogc3RyaW5nLCBvcHRpb25zOiBsYW1iZGEuQWxpYXNPcHRpb25zID0ge30pOiBsYW1iZGEuQWxpYXMge1xuICAgIHJldHVybiBuZXcgbGFtYmRhLkFsaWFzKHRoaXMuX2VkZ2VGdW5jdGlvbiwgYEFsaWFzJHthbGlhc05hbWV9YCwge1xuICAgICAgYWxpYXNOYW1lLFxuICAgICAgdmVyc2lvbjogdGhpcy5fZWRnZUZ1bmN0aW9uLmN1cnJlbnRWZXJzaW9uLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3Qgc3VwcG9ydGVkLiBDb25uZWN0aW9ucyBhcmUgb25seSBhcHBsaWNhYmxlIHRvIFZQQy1lbmFibGVkIGZ1bmN0aW9ucy5cbiAgICovXG4gIHB1YmxpYyBnZXQgY29ubmVjdGlvbnMoKTogZWMyLkNvbm5lY3Rpb25zIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xhbWJkYUBFZGdlIGRvZXMgbm90IHN1cHBvcnQgY29ubmVjdGlvbnMnKTtcbiAgfVxuICBwdWJsaWMgZ2V0IGxhdGVzdFZlcnNpb24oKTogbGFtYmRhLklWZXJzaW9uIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJyRMQVRFU1QgZnVuY3Rpb24gdmVyc2lvbiBjYW5ub3QgYmUgdXNlZCBmb3IgTGFtYmRhQEVkZ2UnKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRFdmVudFNvdXJjZU1hcHBpbmcoaWQ6IHN0cmluZywgb3B0aW9uczogbGFtYmRhLkV2ZW50U291cmNlTWFwcGluZ09wdGlvbnMpOiBsYW1iZGEuRXZlbnRTb3VyY2VNYXBwaW5nIHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGEuYWRkRXZlbnRTb3VyY2VNYXBwaW5nKGlkLCBvcHRpb25zKTtcbiAgfVxuICBwdWJsaWMgYWRkUGVybWlzc2lvbihpZDogc3RyaW5nLCBwZXJtaXNzaW9uOiBsYW1iZGEuUGVybWlzc2lvbik6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5hZGRQZXJtaXNzaW9uKGlkLCBwZXJtaXNzaW9uKTtcbiAgfVxuICBwdWJsaWMgYWRkVG9Sb2xlUG9saWN5KHN0YXRlbWVudDogaWFtLlBvbGljeVN0YXRlbWVudCk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5hZGRUb1JvbGVQb2xpY3koc3RhdGVtZW50KTtcbiAgfVxuICBwdWJsaWMgZ3JhbnRJbnZva2UoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlKTogaWFtLkdyYW50IHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGEuZ3JhbnRJbnZva2UoaWRlbnRpdHkpO1xuICB9XG4gIHB1YmxpYyBncmFudEludm9rZVVybChpZGVudGl0eTogaWFtLklHcmFudGFibGUpOiBpYW0uR3JhbnQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5ncmFudEludm9rZVVybChpZGVudGl0eSk7XG4gIH1cbiAgcHVibGljIG1ldHJpYyhtZXRyaWNOYW1lOiBzdHJpbmcsIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWMobWV0cmljTmFtZSwgeyAuLi5wcm9wcywgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04gfSk7XG4gIH1cbiAgcHVibGljIG1ldHJpY0R1cmF0aW9uKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNEdXJhdGlvbih7IC4uLnByb3BzLCByZWdpb246IEVkZ2VGdW5jdGlvbi5FREdFX1JFR0lPTiB9KTtcbiAgfVxuICBwdWJsaWMgbWV0cmljRXJyb3JzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNFcnJvcnMoeyAuLi5wcm9wcywgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04gfSk7XG4gIH1cbiAgcHVibGljIG1ldHJpY0ludm9jYXRpb25zKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNJbnZvY2F0aW9ucyh7IC4uLnByb3BzLCByZWdpb246IEVkZ2VGdW5jdGlvbi5FREdFX1JFR0lPTiB9KTtcbiAgfVxuICBwdWJsaWMgbWV0cmljVGhyb3R0bGVzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5tZXRyaWNUaHJvdHRsZXMoeyAuLi5wcm9wcywgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04gfSk7XG4gIH1cbiAgLyoqIEFkZHMgYW4gZXZlbnQgc291cmNlIHRvIHRoaXMgZnVuY3Rpb24uICovXG4gIHB1YmxpYyBhZGRFdmVudFNvdXJjZShzb3VyY2U6IGxhbWJkYS5JRXZlbnRTb3VyY2UpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGEuYWRkRXZlbnRTb3VyY2Uoc291cmNlKTtcbiAgfVxuICBwdWJsaWMgY29uZmlndXJlQXN5bmNJbnZva2Uob3B0aW9uczogbGFtYmRhLkV2ZW50SW52b2tlQ29uZmlnT3B0aW9ucyk6IHZvaWQge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5jb25maWd1cmVBc3luY0ludm9rZShvcHRpb25zKTtcbiAgfVxuICBwdWJsaWMgYWRkRnVuY3Rpb25Vcmwob3B0aW9ucz86IGxhbWJkYS5GdW5jdGlvblVybE9wdGlvbnMpOiBsYW1iZGEuRnVuY3Rpb25Vcmwge1xuICAgIHJldHVybiB0aGlzLmxhbWJkYS5hZGRGdW5jdGlvblVybChvcHRpb25zKTtcbiAgfVxuXG4gIC8qKiBDcmVhdGUgYSBmdW5jdGlvbiBpbi1yZWdpb24gKi9cbiAgcHJpdmF0ZSBjcmVhdGVJblJlZ2lvbkZ1bmN0aW9uKHByb3BzOiBsYW1iZGEuRnVuY3Rpb25Qcm9wcyk6IEZ1bmN0aW9uQ29uZmlnIHtcbiAgICBjb25zdCBlZGdlRnVuY3Rpb24gPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKHRoaXMsICdGbicsIHByb3BzKTtcbiAgICBhZGRFZGdlTGFtYmRhVG9Sb2xlVHJ1c3RTdGF0ZW1lbnQoZWRnZUZ1bmN0aW9uLnJvbGUhKTtcblxuICAgIHJldHVybiB7IGVkZ2VGdW5jdGlvbiwgZWRnZUFybjogZWRnZUZ1bmN0aW9uLmN1cnJlbnRWZXJzaW9uLmVkZ2VBcm4gfTtcbiAgfVxuXG4gIC8qKiBDcmVhdGUgYSBzdXBwb3J0IHN0YWNrIGFuZCBmdW5jdGlvbiBpbiB1cy1lYXN0LTEsIGFuZCBhIFNTTSByZWFkZXIgaW4tcmVnaW9uICovXG4gIHByaXZhdGUgY3JlYXRlQ3Jvc3NSZWdpb25GdW5jdGlvbihpZDogc3RyaW5nLCBwcm9wczogRWRnZUZ1bmN0aW9uUHJvcHMpOiBGdW5jdGlvbkNvbmZpZyB7XG4gICAgY29uc3QgcGFyYW1ldGVyTmFtZVByZWZpeCA9ICdjZGsvRWRnZUZ1bmN0aW9uQXJuJztcbiAgICBpZiAoVG9rZW4uaXNVbnJlc29sdmVkKHRoaXMuZW52LnJlZ2lvbikpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignc3RhY2tzIHdoaWNoIHVzZSBFZGdlRnVuY3Rpb25zIG11c3QgaGF2ZSBhbiBleHBsaWNpdGx5IHNldCByZWdpb24nKTtcbiAgICB9XG4gICAgLy8gU1NNIHBhcmFtZXRlciBuYW1lcyBtdXN0IG9ubHkgY29udGFpbiBsZXR0ZXJzLCBudW1iZXJzLCAuLCBfLCAtLCBvciAvLlxuICAgIGNvbnN0IHNhbml0aXplZFBhdGggPSB0aGlzLm5vZGUucGF0aC5yZXBsYWNlKC9bXlxcL1xcdy4tXS9nLCAnXycpO1xuICAgIGNvbnN0IHBhcmFtZXRlck5hbWUgPSBgLyR7cGFyYW1ldGVyTmFtZVByZWZpeH0vJHt0aGlzLmVudi5yZWdpb259LyR7c2FuaXRpemVkUGF0aH1gO1xuICAgIGNvbnN0IGZ1bmN0aW9uU3RhY2sgPSB0aGlzLmVkZ2VTdGFjayhwcm9wcy5zdGFja0lkKTtcblxuICAgIGNvbnN0IGVkZ2VGdW5jdGlvbiA9IG5ldyBsYW1iZGEuRnVuY3Rpb24oZnVuY3Rpb25TdGFjaywgaWQsIHByb3BzKTtcbiAgICBhZGRFZGdlTGFtYmRhVG9Sb2xlVHJ1c3RTdGF0ZW1lbnQoZWRnZUZ1bmN0aW9uLnJvbGUhKTtcblxuICAgIC8vIFN0b3JlIHRoZSBjdXJyZW50IHZlcnNpb24ncyBBUk4gdG8gYmUgcmV0cmlldmVkIGJ5IHRoZSBjcm9zcyByZWdpb24gcmVhZGVyIGJlbG93LlxuICAgIGNvbnN0IHZlcnNpb24gPSBlZGdlRnVuY3Rpb24uY3VycmVudFZlcnNpb247XG4gICAgbmV3IHNzbS5TdHJpbmdQYXJhbWV0ZXIoZWRnZUZ1bmN0aW9uLCAnUGFyYW1ldGVyJywge1xuICAgICAgcGFyYW1ldGVyTmFtZSxcbiAgICAgIHN0cmluZ1ZhbHVlOiB2ZXJzaW9uLmVkZ2VBcm4sXG4gICAgfSk7XG5cbiAgICBjb25zdCBlZGdlQXJuID0gdGhpcy5jcmVhdGVDcm9zc1JlZ2lvbkFyblJlYWRlcihwYXJhbWV0ZXJOYW1lUHJlZml4LCBwYXJhbWV0ZXJOYW1lLCB2ZXJzaW9uKTtcblxuICAgIHJldHVybiB7IGVkZ2VGdW5jdGlvbiwgZWRnZUFybiB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVDcm9zc1JlZ2lvbkFyblJlYWRlcihwYXJhbWV0ZXJOYW1lUHJlZml4OiBzdHJpbmcsIHBhcmFtZXRlck5hbWU6IHN0cmluZywgdmVyc2lvbjogbGFtYmRhLlZlcnNpb24pOiBzdHJpbmcge1xuICAgIC8vIFByZWZpeCBvZiB0aGUgcGFyYW1ldGVyIEFSTiB0aGF0IGFwcGxpZXMgdG8gYWxsIEVkZ2VGdW5jdGlvbnMuXG4gICAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGUgYEN1c3RvbVJlc291cmNlUHJvdmlkZXJgIGlzIGEgc2luZ2xldG9uLCBhbmQgdGhlIGBwb2xpY3lTdGF0ZW1lbnRgXG4gICAgLy8gbXVzdCB3b3JrIGZvciBtdWx0aXBsZSBFZGdlRnVuY3Rpb25zLlxuICAgIGNvbnN0IHBhcmFtZXRlckFyblByZWZpeCA9IHRoaXMuc3RhY2suZm9ybWF0QXJuKHtcbiAgICAgIHNlcnZpY2U6ICdzc20nLFxuICAgICAgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04sXG4gICAgICByZXNvdXJjZTogJ3BhcmFtZXRlcicsXG4gICAgICByZXNvdXJjZU5hbWU6IHBhcmFtZXRlck5hbWVQcmVmaXggKyAnLyonLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzb3VyY2VUeXBlID0gJ0N1c3RvbTo6Q3Jvc3NSZWdpb25TdHJpbmdQYXJhbWV0ZXJSZWFkZXInO1xuICAgIGNvbnN0IHNlcnZpY2VUb2tlbiA9IEN1c3RvbVJlc291cmNlUHJvdmlkZXIuZ2V0T3JDcmVhdGUodGhpcywgcmVzb3VyY2VUeXBlLCB7XG4gICAgICBjb2RlRGlyZWN0b3J5OiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnZWRnZS1mdW5jdGlvbicpLFxuICAgICAgcnVudGltZTogQ3VzdG9tUmVzb3VyY2VQcm92aWRlclJ1bnRpbWUuTk9ERUpTXzEyX1gsXG4gICAgICBwb2xpY3lTdGF0ZW1lbnRzOiBbe1xuICAgICAgICBFZmZlY3Q6ICdBbGxvdycsXG4gICAgICAgIFJlc291cmNlOiBwYXJhbWV0ZXJBcm5QcmVmaXgsXG4gICAgICAgIEFjdGlvbjogWydzc206R2V0UGFyYW1ldGVyJ10sXG4gICAgICB9XSxcbiAgICB9KTtcbiAgICBjb25zdCByZXNvdXJjZSA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCAnQXJuUmVhZGVyJywge1xuICAgICAgcmVzb3VyY2VUeXBlOiByZXNvdXJjZVR5cGUsXG4gICAgICBzZXJ2aWNlVG9rZW4sXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIFJlZ2lvbjogRWRnZUZ1bmN0aW9uLkVER0VfUkVHSU9OLFxuICAgICAgICBQYXJhbWV0ZXJOYW1lOiBwYXJhbWV0ZXJOYW1lLFxuICAgICAgICAvLyBUaGlzIGlzIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZW4gdGhlIGZ1bmN0aW9uIGhhcyBjaGFuZ2VkLCB0byByZWZyZXNoIHRoZSBBUk4gZnJvbSB0aGUgY3VzdG9tIHJlc291cmNlLlxuICAgICAgICAvL1xuICAgICAgICAvLyBVc2UgdGhlIGxvZ2ljYWwgaWQgb2YgdGhlIGZ1bmN0aW9uIHZlcnNpb24uIFdoZW5ldmVyIGEgZnVuY3Rpb24gdmVyc2lvbiBjaGFuZ2VzLCB0aGUgbG9naWNhbCBpZCBtdXN0IGJlXG4gICAgICAgIC8vIGNoYW5nZWQgZm9yIGl0IHRvIHRha2UgZWZmZWN0IC0gYSBnb29kIGNhbmRpZGF0ZSBmb3IgUmVmcmVzaFRva2VuLlxuICAgICAgICBSZWZyZXNoVG9rZW46IExhenkudW5jYWNoZWRTdHJpbmcoe1xuICAgICAgICAgIHByb2R1Y2U6ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNmbiA9IHZlcnNpb24ubm9kZS5kZWZhdWx0Q2hpbGQgYXMgQ2ZuUmVzb3VyY2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFjay5yZXNvbHZlKGNmbi5sb2dpY2FsSWQpO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHJldHVybiByZXNvdXJjZS5nZXRBdHRTdHJpbmcoJ0Z1bmN0aW9uQXJuJyk7XG4gIH1cblxuICBwcml2YXRlIGVkZ2VTdGFjayhzdGFja0lkPzogc3RyaW5nKTogU3RhY2sge1xuICAgIGNvbnN0IHN0YWdlID0gU3RhZ2Uub2YodGhpcyk7XG4gICAgaWYgKCFzdGFnZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdGFja3Mgd2hpY2ggdXNlIEVkZ2VGdW5jdGlvbnMgbXVzdCBiZSBwYXJ0IG9mIGEgQ0RLIGFwcCBvciBzdGFnZScpO1xuICAgIH1cblxuICAgIGNvbnN0IGVkZ2VTdGFja0lkID0gc3RhY2tJZCA/PyBgZWRnZS1sYW1iZGEtc3RhY2stJHt0aGlzLnN0YWNrLm5vZGUuYWRkcn1gO1xuICAgIGxldCBlZGdlU3RhY2sgPSBzdGFnZS5ub2RlLnRyeUZpbmRDaGlsZChlZGdlU3RhY2tJZCkgYXMgU3RhY2s7XG4gICAgaWYgKCFlZGdlU3RhY2spIHtcbiAgICAgIGVkZ2VTdGFjayA9IG5ldyBTdGFjayhzdGFnZSwgZWRnZVN0YWNrSWQsIHtcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgcmVnaW9uOiBFZGdlRnVuY3Rpb24uRURHRV9SRUdJT04sXG4gICAgICAgICAgYWNjb3VudDogU3RhY2sub2YodGhpcykuYWNjb3VudCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnN0YWNrLmFkZERlcGVuZGVuY3koZWRnZVN0YWNrKTtcbiAgICByZXR1cm4gZWRnZVN0YWNrO1xuICB9XG59XG5cbi8qKiBSZXN1bHQgb2YgY3JlYXRpbmcgYW4gaW4tcmVnaW9uIG9yIGNyb3NzLXJlZ2lvbiBmdW5jdGlvbiAqL1xuaW50ZXJmYWNlIEZ1bmN0aW9uQ29uZmlnIHtcbiAgcmVhZG9ubHkgZWRnZUZ1bmN0aW9uOiBsYW1iZGEuRnVuY3Rpb247XG4gIHJlYWRvbmx5IGVkZ2VBcm46IHN0cmluZztcbn1cblxuZnVuY3Rpb24gYWRkRWRnZUxhbWJkYVRvUm9sZVRydXN0U3RhdGVtZW50KHJvbGU6IGlhbS5JUm9sZSkge1xuICBpZiAocm9sZSBpbnN0YW5jZW9mIGlhbS5Sb2xlICYmIHJvbGUuYXNzdW1lUm9sZVBvbGljeSkge1xuICAgIGNvbnN0IHN0YXRlbWVudCA9IG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KCk7XG4gICAgY29uc3QgZWRnZUxhbWJkYVNlcnZpY2VQcmluY2lwYWwgPSBuZXcgaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2VkZ2VsYW1iZGEuYW1hem9uYXdzLmNvbScpO1xuICAgIHN0YXRlbWVudC5hZGRQcmluY2lwYWxzKGVkZ2VMYW1iZGFTZXJ2aWNlUHJpbmNpcGFsKTtcbiAgICBzdGF0ZW1lbnQuYWRkQWN0aW9ucyhlZGdlTGFtYmRhU2VydmljZVByaW5jaXBhbC5hc3N1bWVSb2xlQWN0aW9uKTtcbiAgICByb2xlLmFzc3VtZVJvbGVQb2xpY3kuYWRkU3RhdGVtZW50cyhzdGF0ZW1lbnQpO1xuICB9XG59XG4iXX0= |
\ | No newline at end of file |