raindancers-cloudfront 0.0.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.
Files changed (103) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +176 -0
  3. package/lib/bicep/deploy/deploy.d.ts +46 -0
  4. package/lib/bicep/deploy/deploy.js +123 -0
  5. package/lib/bicep/deploy/index.d.ts +3 -0
  6. package/lib/bicep/deploy/index.js +20 -0
  7. package/lib/bicep/deploy/template.d.ts +75 -0
  8. package/lib/bicep/deploy/template.js +364 -0
  9. package/lib/bicep/deploy/templateBuilder.d.ts +16 -0
  10. package/lib/bicep/deploy/templateBuilder.js +35 -0
  11. package/lib/bicep/index.d.ts +3 -0
  12. package/lib/bicep/index.js +40 -0
  13. package/lib/bicep/patterns/azureAdApplicationFederated.d.ts +58 -0
  14. package/lib/bicep/patterns/azureAdApplicationFederated.js +317 -0
  15. package/lib/bicep/patterns/index.d.ts +1 -0
  16. package/lib/bicep/patterns/index.js +18 -0
  17. package/lib/bicep/resources/azure/appServicePlan.d.ts +11 -0
  18. package/lib/bicep/resources/azure/appServicePlan.js +24 -0
  19. package/lib/bicep/resources/azure/applicationInsights.d.ts +13 -0
  20. package/lib/bicep/resources/azure/applicationInsights.js +27 -0
  21. package/lib/bicep/resources/azure/deploymentScript.d.ts +16 -0
  22. package/lib/bicep/resources/azure/deploymentScript.js +43 -0
  23. package/lib/bicep/resources/azure/functionApp.d.ts +20 -0
  24. package/lib/bicep/resources/azure/functionApp.js +54 -0
  25. package/lib/bicep/resources/azure/index.d.ts +8 -0
  26. package/lib/bicep/resources/azure/index.js +25 -0
  27. package/lib/bicep/resources/azure/logAnalyticsWorkspace.d.ts +11 -0
  28. package/lib/bicep/resources/azure/logAnalyticsWorkspace.js +26 -0
  29. package/lib/bicep/resources/azure/managedIdentity.d.ts +13 -0
  30. package/lib/bicep/resources/azure/managedIdentity.js +24 -0
  31. package/lib/bicep/resources/azure/roleAssignment.d.ts +18 -0
  32. package/lib/bicep/resources/azure/roleAssignment.js +34 -0
  33. package/lib/bicep/resources/azure/storageAccount.d.ts +11 -0
  34. package/lib/bicep/resources/azure/storageAccount.js +28 -0
  35. package/lib/bicep/resources/graph/appRoleAssignment.d.ts +25 -0
  36. package/lib/bicep/resources/graph/appRoleAssignment.js +33 -0
  37. package/lib/bicep/resources/graph/application.d.ts +51 -0
  38. package/lib/bicep/resources/graph/application.js +88 -0
  39. package/lib/bicep/resources/graph/bicepConstruct.d.ts +14 -0
  40. package/lib/bicep/resources/graph/bicepConstruct.js +29 -0
  41. package/lib/bicep/resources/graph/existingServicePrincipal.d.ts +19 -0
  42. package/lib/bicep/resources/graph/existingServicePrincipal.js +26 -0
  43. package/lib/bicep/resources/graph/federatedIdentityCredential.d.ts +29 -0
  44. package/lib/bicep/resources/graph/federatedIdentityCredential.js +31 -0
  45. package/lib/bicep/resources/graph/group.d.ts +26 -0
  46. package/lib/bicep/resources/graph/group.js +31 -0
  47. package/lib/bicep/resources/graph/index.d.ts +8 -0
  48. package/lib/bicep/resources/graph/index.js +25 -0
  49. package/lib/bicep/resources/graph/servicePrincipal.d.ts +22 -0
  50. package/lib/bicep/resources/graph/servicePrincipal.js +27 -0
  51. package/lib/bicep/resources/graph/types/index.d.ts +1 -0
  52. package/lib/bicep/resources/graph/types/index.js +18 -0
  53. package/lib/bicep/resources/graph/types/permissions.d.ts +54 -0
  54. package/lib/bicep/resources/graph/types/permissions.js +73 -0
  55. package/lib/bicep/resources/index.d.ts +2 -0
  56. package/lib/bicep/resources/index.js +39 -0
  57. package/lib/cloudfront/auth/authLambdaFunctions.d.ts +20 -0
  58. package/lib/cloudfront/auth/authLambdaFunctions.js +159 -0
  59. package/lib/cloudfront/auth/authSecretManager.d.ts +19 -0
  60. package/lib/cloudfront/auth/authSecretManager.js +92 -0
  61. package/lib/cloudfront/auth/cognitoAuthSecretManager.d.ts +20 -0
  62. package/lib/cloudfront/auth/cognitoAuthSecretManager.js +93 -0
  63. package/lib/cloudfront/auth/index.d.ts +3 -0
  64. package/lib/cloudfront/auth/index.js +20 -0
  65. package/lib/cloudfront/authSecurityTable.d.ts +10 -0
  66. package/lib/cloudfront/authSecurityTable.js +78 -0
  67. package/lib/cloudfront/cloudfront-functions/function-composer.d.ts +21 -0
  68. package/lib/cloudfront/cloudfront-functions/function-composer.js +132 -0
  69. package/lib/cloudfront/cloudfrontCertificate.d.ts +40 -0
  70. package/lib/cloudfront/cloudfrontCertificate.js +116 -0
  71. package/lib/cloudfront/cloudfrontWebAcl.d.ts +72 -0
  72. package/lib/cloudfront/cloudfrontWebAcl.js +249 -0
  73. package/lib/cloudfront/countries.d.ts +260 -0
  74. package/lib/cloudfront/countries.js +263 -0
  75. package/lib/cloudfront/deployment/viteFrontendDeployment.d.ts +12 -0
  76. package/lib/cloudfront/deployment/viteFrontendDeployment.js +63 -0
  77. package/lib/cloudfront/index.d.ts +11 -0
  78. package/lib/cloudfront/index.js +28 -0
  79. package/lib/cloudfront/jwtDecoder.d.ts +5 -0
  80. package/lib/cloudfront/jwtDecoder.js +57 -0
  81. package/lib/cloudfront/logging/auditLogArchive.d.ts +18 -0
  82. package/lib/cloudfront/logging/auditLogArchive.js +205 -0
  83. package/lib/cloudfront/logging/index.d.ts +1 -0
  84. package/lib/cloudfront/logging/index.js +18 -0
  85. package/lib/cloudfront/oauthEdgeRole.d.ts +9 -0
  86. package/lib/cloudfront/oauthEdgeRole.js +56 -0
  87. package/lib/cloudfront/patterns/authInfrastructure.d.ts +34 -0
  88. package/lib/cloudfront/patterns/authInfrastructure.js +140 -0
  89. package/lib/cloudfront/patterns/cognito-secured-cloudfront.d.ts +36 -0
  90. package/lib/cloudfront/patterns/cognito-secured-cloudfront.js +285 -0
  91. package/lib/cloudfront/patterns/cognitoAuthInfrastructure.d.ts +28 -0
  92. package/lib/cloudfront/patterns/cognitoAuthInfrastructure.js +157 -0
  93. package/lib/cloudfront/patterns/index.d.ts +4 -0
  94. package/lib/cloudfront/patterns/index.js +21 -0
  95. package/lib/cloudfront/patterns/securedCloudFront.d.ts +73 -0
  96. package/lib/cloudfront/patterns/securedCloudFront.js +416 -0
  97. package/lib/cloudfront/ssmCrossRegionWriter.d.ts +9 -0
  98. package/lib/cloudfront/ssmCrossRegionWriter.js +65 -0
  99. package/lib/cloudfront/syncSecretToKvs.d.ts +9 -0
  100. package/lib/cloudfront/syncSecretToKvs.js +89 -0
  101. package/lib/index.d.ts +2 -0
  102. package/lib/index.js +19 -0
  103. package/package.json +105 -0
@@ -0,0 +1,73 @@
1
+ import * as core from 'aws-cdk-lib';
2
+ import { aws_cloudfront as cloudfront, aws_secretsmanager as secretsmanager, aws_kms as kms, aws_iam as iam } from 'aws-cdk-lib';
3
+ import * as constructs from 'constructs';
4
+ import { AuthSecurityTable } from '../authSecurityTable';
5
+ export declare enum Extension {
6
+ REQUIRE_AUTH = "REQUIRE_AUTH",
7
+ REQUIRE_TLS_13 = "REQUIRE_TLS_13",
8
+ REWRITE_TO_INDEX_HTML = "REWRITE_TO_INDEX_HTML"
9
+ }
10
+ export declare enum RoleMatchMode {
11
+ OR = "OR",
12
+ AND = "AND"
13
+ }
14
+ export interface ExtensionConfig<TRole extends string = string> {
15
+ readonly requiredRoles?: readonly TRole[];
16
+ readonly roleMatchMode?: RoleMatchMode;
17
+ }
18
+ export interface AddBehaviorOptions<TRole extends string = string> {
19
+ readonly extensions?: Extension[];
20
+ readonly extensionConfig?: ExtensionConfig<TRole>;
21
+ readonly behaviorOptions?: Omit<cloudfront.BehaviorOptions, 'origin'>;
22
+ }
23
+ export interface CloudFrontWithAzureAuthSplitProps<TRole extends string = string> {
24
+ readonly defaultBehavior: Omit<cloudfront.BehaviorOptions, 'functionAssociations'>;
25
+ readonly additionalBehaviors?: Record<string, Omit<cloudfront.BehaviorOptions, 'edgeLambdas'>>;
26
+ readonly domainNames: string[];
27
+ readonly certificate: any;
28
+ readonly redirectUri?: string;
29
+ readonly webAclId?: string;
30
+ readonly hmacSecretRotationSchedule?: core.Duration;
31
+ readonly securityAlertsTopicArn?: string;
32
+ readonly sessionRevocationTopicArn?: string;
33
+ readonly autoRevokeOnReuse?: boolean;
34
+ readonly jwtClaimsWhitelist?: string[];
35
+ readonly auditLogRetentionDays?: number;
36
+ readonly auditArchiveRetentionDays?: number;
37
+ readonly authSsmParamPrefix: string;
38
+ readonly authRegion: string;
39
+ readonly createOAuthCallback?: boolean;
40
+ readonly defaultExtensions?: Extension[];
41
+ readonly defaultExtensionConfig?: ExtensionConfig<TRole>;
42
+ readonly defaultRootObject?: string;
43
+ readonly errorResponsePagePath?: string;
44
+ readonly enableUserInfoInjection?: boolean;
45
+ readonly userInfoNameFields?: string[];
46
+ }
47
+ export declare class SecuredCloudFront<TRole extends string = string> extends constructs.Construct {
48
+ readonly distribution: cloudfront.Distribution;
49
+ readonly configSecret: secretsmanager.ISecret;
50
+ readonly secretArn: string;
51
+ readonly kmsKey: kms.IKey;
52
+ readonly authSecurityTable: AuthSecurityTable;
53
+ readonly auditLogArchive: any;
54
+ readonly lambdaEdgeRole: iam.Role;
55
+ private readonly authCheckFunction;
56
+ private readonly userInfoFunction?;
57
+ private readonly functionComposer;
58
+ private readonly composedFunctions;
59
+ private lastCreatedFunction;
60
+ private readonly tlsOriginRequestPolicy;
61
+ private readonly tenantId;
62
+ private readonly clientId;
63
+ private readonly redirectUri;
64
+ private readonly kvs;
65
+ constructor(scope: constructs.Construct, id: string, props: CloudFrontWithAzureAuthSplitProps<TRole>);
66
+ addBehavior(pathPattern: string, origin: cloudfront.IOrigin, options?: AddBehaviorOptions<TRole> | cloudfront.BehaviorOptions, applyAuth?: boolean): void;
67
+ private buildFunctionAssociations;
68
+ private generateFunctionCacheKey;
69
+ private generateFunctionId;
70
+ private determineRedirectUri;
71
+ private loadAndReplaceAuthCheckCode;
72
+ private loadAndReplaceUserInfoCode;
73
+ }
@@ -0,0 +1,416 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SecuredCloudFront = exports.RoleMatchMode = exports.Extension = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const core = __importStar(require("aws-cdk-lib"));
41
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
42
+ const constructs = __importStar(require("constructs"));
43
+ const function_composer_1 = require("../cloudfront-functions/function-composer");
44
+ var Extension;
45
+ (function (Extension) {
46
+ Extension["REQUIRE_AUTH"] = "REQUIRE_AUTH";
47
+ Extension["REQUIRE_TLS_13"] = "REQUIRE_TLS_13";
48
+ Extension["REWRITE_TO_INDEX_HTML"] = "REWRITE_TO_INDEX_HTML";
49
+ })(Extension || (exports.Extension = Extension = {}));
50
+ var RoleMatchMode;
51
+ (function (RoleMatchMode) {
52
+ RoleMatchMode["OR"] = "OR";
53
+ RoleMatchMode["AND"] = "AND";
54
+ })(RoleMatchMode || (exports.RoleMatchMode = RoleMatchMode = {}));
55
+ class SecuredCloudFront extends constructs.Construct {
56
+ constructor(scope, id, props) {
57
+ super(scope, id);
58
+ const redirectUri = this.determineRedirectUri(props.redirectUri, props.domainNames);
59
+ const p = props.authSsmParamPrefix;
60
+ const configSecretArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/configSecretArn`);
61
+ const kmsKeyArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/kmsKeyArn`);
62
+ const authTableArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/authTableArn`);
63
+ const kvsArn = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/kvsArn`);
64
+ const tenantId = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/tenantId`);
65
+ const clientId = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/clientId`);
66
+ const oauth2CallbackRoleName = aws_cdk_lib_1.aws_ssm.StringParameter.valueForStringParameter(this, `${p}/oauth2CallbackRoleName`);
67
+ this.configSecret = aws_cdk_lib_1.aws_secretsmanager.Secret.fromSecretCompleteArn(this, 'ImportedSecret', configSecretArn);
68
+ this.kmsKey = aws_cdk_lib_1.aws_kms.Key.fromKeyArn(this, 'ImportedKey', kmsKeyArn);
69
+ this.authSecurityTable = { table: { tableArn: authTableArn } };
70
+ this.auditLogArchive = null;
71
+ this.secretArn = configSecretArn;
72
+ this.lambdaEdgeRole = new aws_cdk_lib_1.aws_iam.Role(this, 'LambdaEdgeRole', {
73
+ roleName: oauth2CallbackRoleName,
74
+ assumedBy: new aws_cdk_lib_1.aws_iam.CompositePrincipal(new aws_cdk_lib_1.aws_iam.ServicePrincipal('lambda.amazonaws.com'), new aws_cdk_lib_1.aws_iam.ServicePrincipal('edgelambda.amazonaws.com')),
75
+ managedPolicies: [
76
+ aws_cdk_lib_1.aws_iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
77
+ ],
78
+ });
79
+ // we need to add these directly, rather than use grant methods, to avoid circular dependnacies.
80
+ this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
81
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
82
+ actions: ['secretsmanager:GetSecretValue', 'secretsmanager:DescribeSecret'],
83
+ resources: [configSecretArn],
84
+ }));
85
+ this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
86
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
87
+ actions: ['kms:Decrypt'],
88
+ resources: [kmsKeyArn],
89
+ }));
90
+ this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
91
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
92
+ actions: ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:Query', 'dynamodb:Scan', 'dynamodb:UpdateItem', 'dynamodb:DeleteItem'],
93
+ resources: [authTableArn],
94
+ }));
95
+ this.lambdaEdgeRole.addToPolicy(new aws_cdk_lib_1.aws_iam.PolicyStatement({
96
+ effect: aws_cdk_lib_1.aws_iam.Effect.ALLOW,
97
+ actions: ['sts:GetWebIdentityToken'],
98
+ resources: ['*'],
99
+ }));
100
+ const kvs = aws_cdk_lib_1.aws_cloudfront.KeyValueStore.fromKeyValueStoreArn(this, 'KVS', kvsArn);
101
+ this.kvs = kvs;
102
+ this.tenantId = tenantId;
103
+ this.clientId = clientId;
104
+ this.redirectUri = redirectUri;
105
+ const configPyContent = `# Generated configuration
106
+ import json
107
+ import boto3
108
+ import os
109
+ import logging
110
+
111
+ logger = logging.getLogger()
112
+
113
+ # Secret name and region - these must be concrete values, not CloudFormation tokens
114
+ # The secret name is constructed from the domain name
115
+ CONFIG_SECRET_NAME = 'cloudfront-auth-config-${props.domainNames[0]}'
116
+ CONFIG_REGION = '${props.authRegion}'
117
+
118
+ def get_config():
119
+ logger.info(f'Attempting to load config from Secrets Manager')
120
+ logger.info(f'CONFIG_SECRET_NAME: {CONFIG_SECRET_NAME}')
121
+ logger.info(f'CONFIG_REGION: {CONFIG_REGION}')
122
+ try:
123
+ client = boto3.client('secretsmanager', region_name=CONFIG_REGION)
124
+ response = client.get_secret_value(SecretId=CONFIG_SECRET_NAME)
125
+ return json.loads(response['SecretString'])
126
+ except Exception as e:
127
+ logger.error(f'Failed to get secret. Name="{CONFIG_SECRET_NAME}", Region="{CONFIG_REGION}"')
128
+ logger.error(f'Error: {str(e)}')
129
+ raise
130
+ `;
131
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'edge-auth-'));
132
+ const configPyPath = path.join(tempDir, 'config_generated.py');
133
+ fs.writeFileSync(configPyPath, configPyContent);
134
+ const oauthCallbackFunction = new aws_cdk_lib_1.aws_cloudfront.experimental.EdgeFunction(this, 'OAuthCallback', {
135
+ runtime: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_11,
136
+ handler: 'oauth-callback.lambda_handler',
137
+ code: aws_cdk_lib_1.aws_lambda.Code.fromAsset(path.join(__dirname, '../lambda/edge-auth'), {
138
+ bundling: {
139
+ image: aws_cdk_lib_1.aws_lambda.Runtime.PYTHON_3_11.bundlingImage,
140
+ command: [
141
+ 'bash', '-c',
142
+ 'pip install -r requirements.txt -t /asset-output && ' +
143
+ 'cp -r . /asset-output && ' +
144
+ 'cp /tmp/config_generated.py /asset-output/config_generated.py',
145
+ ],
146
+ volumes: [
147
+ {
148
+ hostPath: configPyPath,
149
+ containerPath: '/tmp/config_generated.py',
150
+ },
151
+ ],
152
+ },
153
+ }),
154
+ timeout: core.Duration.seconds(30),
155
+ memorySize: 128,
156
+ role: this.lambdaEdgeRole,
157
+ });
158
+ const authCheckCode = this.loadAndReplaceAuthCheckCode(tenantId, clientId, redirectUri);
159
+ this.authCheckFunction = new aws_cdk_lib_1.aws_cloudfront.Function(this, 'AuthCheck', {
160
+ code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(authCheckCode),
161
+ runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
162
+ keyValueStore: kvs,
163
+ comment: 'verifies tokens',
164
+ });
165
+ this.lastCreatedFunction = this.authCheckFunction;
166
+ // Create user info endpoint function if enabled
167
+ if (props.enableUserInfoInjection !== false) {
168
+ if (!props.userInfoNameFields || props.userInfoNameFields.length === 0) {
169
+ throw new Error('userInfoNameFields must be provided when enableUserInfoInjection is true');
170
+ }
171
+ const userInfoCode = this.loadAndReplaceUserInfoCode(props.userInfoNameFields);
172
+ this.userInfoFunction = new aws_cdk_lib_1.aws_cloudfront.Function(this, 'UserInfoEndpoint', {
173
+ code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(userInfoCode),
174
+ runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
175
+ keyValueStore: kvs,
176
+ comment: 'Returns user info JSON from JWT',
177
+ });
178
+ this.userInfoFunction.node.addDependency(this.authCheckFunction);
179
+ this.lastCreatedFunction = this.userInfoFunction;
180
+ }
181
+ const additionalBehaviors = {};
182
+ if (props.createOAuthCallback !== false) {
183
+ additionalBehaviors['/oauth2/callback'] = {
184
+ origin: props.defaultBehavior.origin,
185
+ viewerProtocolPolicy: aws_cdk_lib_1.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
186
+ ...props.additionalBehaviors?.['/oauth2/callback'],
187
+ edgeLambdas: [{
188
+ functionVersion: oauthCallbackFunction.currentVersion,
189
+ eventType: aws_cdk_lib_1.aws_cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
190
+ }],
191
+ cachePolicy: props.additionalBehaviors?.['/oauth2/callback']?.cachePolicy ?? new aws_cdk_lib_1.aws_cloudfront.CachePolicy(this, 'CallbackCachePolicy', {
192
+ cachePolicyName: `${core.Stack.of(this).stackName}-oauth-callback`,
193
+ comment: 'Cache policy for OAuth callback with state cookie forwarding',
194
+ defaultTtl: core.Duration.seconds(0),
195
+ minTtl: core.Duration.seconds(0),
196
+ maxTtl: core.Duration.seconds(1),
197
+ cookieBehavior: aws_cdk_lib_1.aws_cloudfront.CacheCookieBehavior.allowList('oauth_state'),
198
+ headerBehavior: aws_cdk_lib_1.aws_cloudfront.CacheHeaderBehavior.none(),
199
+ queryStringBehavior: aws_cdk_lib_1.aws_cloudfront.CacheQueryStringBehavior.all(),
200
+ enableAcceptEncodingGzip: false,
201
+ enableAcceptEncodingBrotli: false,
202
+ }),
203
+ };
204
+ }
205
+ if (props.additionalBehaviors) {
206
+ Object.entries(props.additionalBehaviors).forEach(([pathPattern, behavior]) => {
207
+ if (pathPattern !== '/oauth2/callback') {
208
+ additionalBehaviors[pathPattern] = behavior;
209
+ }
210
+ });
211
+ }
212
+ // Origin request policy that forwards CloudFront-Viewer-TLS header (required for REQUIRE_TLS_13)
213
+ this.tlsOriginRequestPolicy = new aws_cdk_lib_1.aws_cloudfront.OriginRequestPolicy(this, 'TlsOriginRequestPolicy', {
214
+ headerBehavior: aws_cdk_lib_1.aws_cloudfront.OriginRequestHeaderBehavior.allowList('CloudFront-Viewer-TLS'),
215
+ cookieBehavior: aws_cdk_lib_1.aws_cloudfront.OriginRequestCookieBehavior.none(),
216
+ queryStringBehavior: aws_cdk_lib_1.aws_cloudfront.OriginRequestQueryStringBehavior.none(),
217
+ });
218
+ // Initialize function composer
219
+ this.functionComposer = new function_composer_1.FunctionComposer();
220
+ this.composedFunctions = new Map();
221
+ this.distribution = new aws_cdk_lib_1.aws_cloudfront.Distribution(this, 'Distribution', {
222
+ httpVersion: aws_cdk_lib_1.aws_cloudfront.HttpVersion.HTTP2_AND_3,
223
+ minimumProtocolVersion: aws_cdk_lib_1.aws_cloudfront.SecurityPolicyProtocol.TLS_V1_2_2025,
224
+ defaultBehavior: (() => {
225
+ const defaultBuilt = this.buildFunctionAssociations(props.defaultExtensions, props.defaultExtensionConfig);
226
+ return {
227
+ ...props.defaultBehavior,
228
+ functionAssociations: defaultBuilt?.functionAssociations,
229
+ originRequestPolicy: defaultBuilt?.originRequestPolicy,
230
+ };
231
+ })(),
232
+ additionalBehaviors: additionalBehaviors,
233
+ domainNames: props.domainNames,
234
+ certificate: props.certificate,
235
+ webAclId: props.webAclId,
236
+ defaultRootObject: props.defaultRootObject ?? 'index.html',
237
+ errorResponses: [
238
+ {
239
+ httpStatus: 403,
240
+ responseHttpStatus: 200,
241
+ responsePagePath: props.errorResponsePagePath ?? '/error.html',
242
+ ttl: core.Duration.minutes(5),
243
+ },
244
+ {
245
+ httpStatus: 404,
246
+ responseHttpStatus: 200,
247
+ responsePagePath: props.errorResponsePagePath ?? '/error.html',
248
+ ttl: core.Duration.minutes(5),
249
+ },
250
+ {
251
+ httpStatus: 500,
252
+ responseHttpStatus: 200,
253
+ responsePagePath: props.errorResponsePagePath ?? '/error.html',
254
+ ttl: core.Duration.seconds(10),
255
+ },
256
+ {
257
+ httpStatus: 502,
258
+ responseHttpStatus: 200,
259
+ responsePagePath: props.errorResponsePagePath ?? '/error.html',
260
+ ttl: core.Duration.seconds(10),
261
+ },
262
+ {
263
+ httpStatus: 503,
264
+ responseHttpStatus: 200,
265
+ responsePagePath: props.errorResponsePagePath ?? '/error.html',
266
+ ttl: core.Duration.seconds(10),
267
+ },
268
+ {
269
+ httpStatus: 504,
270
+ responseHttpStatus: 200,
271
+ responsePagePath: props.errorResponsePagePath ?? '/error.html',
272
+ ttl: core.Duration.seconds(10),
273
+ },
274
+ ],
275
+ });
276
+ // Add /userinfo behavior if user info endpoint is enabled
277
+ if (this.userInfoFunction) {
278
+ this.distribution.addBehavior('/userinfo', props.defaultBehavior.origin, {
279
+ viewerProtocolPolicy: aws_cdk_lib_1.aws_cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
280
+ functionAssociations: [
281
+ {
282
+ function: this.userInfoFunction,
283
+ eventType: aws_cdk_lib_1.aws_cloudfront.FunctionEventType.VIEWER_REQUEST,
284
+ },
285
+ ],
286
+ cachePolicy: aws_cdk_lib_1.aws_cloudfront.CachePolicy.CACHING_DISABLED,
287
+ });
288
+ }
289
+ }
290
+ addBehavior(pathPattern, origin, options = {}, applyAuth) {
291
+ // Support legacy signature: addBehavior(path, behaviorOptions, applyAuth)
292
+ if ('origin' in options || 'viewerProtocolPolicy' in options) {
293
+ const behaviorOptions = options;
294
+ const shouldApplyAuth = applyAuth !== false;
295
+ if (shouldApplyAuth) {
296
+ const functionAssociations = [
297
+ ...(behaviorOptions.functionAssociations || []),
298
+ {
299
+ function: this.authCheckFunction,
300
+ eventType: aws_cdk_lib_1.aws_cloudfront.FunctionEventType.VIEWER_REQUEST,
301
+ },
302
+ ];
303
+ this.distribution.addBehavior(pathPattern, origin, {
304
+ ...behaviorOptions,
305
+ functionAssociations: functionAssociations,
306
+ });
307
+ }
308
+ else {
309
+ this.distribution.addBehavior(pathPattern, origin, behaviorOptions);
310
+ }
311
+ return;
312
+ }
313
+ // New signature: addBehavior(path, origin, AddBehaviorOptions)
314
+ const addBehaviorOptions = options;
315
+ const built = this.buildFunctionAssociations(addBehaviorOptions.extensions, addBehaviorOptions.extensionConfig);
316
+ this.distribution.addBehavior(pathPattern, origin, {
317
+ ...addBehaviorOptions.behaviorOptions,
318
+ functionAssociations: built?.functionAssociations ?? addBehaviorOptions.behaviorOptions?.functionAssociations,
319
+ originRequestPolicy: built?.originRequestPolicy ?? addBehaviorOptions.behaviorOptions?.originRequestPolicy,
320
+ });
321
+ }
322
+ buildFunctionAssociations(extensions, config) {
323
+ if (!extensions || extensions.length === 0) {
324
+ return undefined;
325
+ }
326
+ // Generate cache key for this combination of extensions + config
327
+ const cacheKey = this.generateFunctionCacheKey(extensions, config);
328
+ // Check if we already created this function
329
+ let func = this.composedFunctions.get(cacheKey);
330
+ if (!func) {
331
+ // Generate combined function code with Azure AD configuration
332
+ const code = this.functionComposer.compose(extensions, config, {
333
+ tenantId: this.tenantId,
334
+ clientId: this.clientId,
335
+ redirectUri: this.redirectUri,
336
+ });
337
+ // Create CloudFront Function
338
+ const functionId = this.generateFunctionId(extensions, config);
339
+ // Add KVS if auth extension is included
340
+ const functionProps = extensions.includes(Extension.REQUIRE_AUTH)
341
+ ? {
342
+ code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(code),
343
+ runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
344
+ comment: `Combined: ${extensions.join(', ')}`,
345
+ keyValueStore: this.kvs,
346
+ }
347
+ : {
348
+ code: aws_cdk_lib_1.aws_cloudfront.FunctionCode.fromInline(code),
349
+ runtime: aws_cdk_lib_1.aws_cloudfront.FunctionRuntime.JS_2_0,
350
+ comment: `Combined: ${extensions.join(', ')}`,
351
+ };
352
+ func = new aws_cdk_lib_1.aws_cloudfront.Function(this, functionId, functionProps);
353
+ if (this.lastCreatedFunction) {
354
+ func.node.addDependency(this.lastCreatedFunction);
355
+ }
356
+ this.lastCreatedFunction = func;
357
+ this.composedFunctions.set(cacheKey, func);
358
+ }
359
+ const result = {
360
+ functionAssociations: [{
361
+ function: func,
362
+ eventType: aws_cdk_lib_1.aws_cloudfront.FunctionEventType.VIEWER_REQUEST,
363
+ }],
364
+ };
365
+ if (extensions.includes(Extension.REQUIRE_TLS_13)) {
366
+ result.originRequestPolicy = this.tlsOriginRequestPolicy;
367
+ }
368
+ return result;
369
+ }
370
+ generateFunctionCacheKey(extensions, config) {
371
+ const parts = [extensions.sort().join(',')];
372
+ if (config?.requiredRoles) {
373
+ parts.push([...config.requiredRoles].sort().join(','));
374
+ }
375
+ if (config?.roleMatchMode && config.roleMatchMode !== RoleMatchMode.OR) {
376
+ parts.push(config.roleMatchMode);
377
+ }
378
+ return parts.join('|');
379
+ }
380
+ generateFunctionId(extensions, config) {
381
+ const extensionPart = extensions.map(e => e.replace('REQUIRE_', '')).join('');
382
+ if (config?.requiredRoles && config.requiredRoles.length > 0) {
383
+ const roleHash = config.requiredRoles.join('').replace(/[^a-zA-Z0-9]/g, '').substring(0, 8);
384
+ const modePart = config.roleMatchMode && config.roleMatchMode !== RoleMatchMode.OR ? config.roleMatchMode : '';
385
+ return `ComposedFunction${extensionPart}${roleHash}${modePart}`;
386
+ }
387
+ return `ComposedFunction${extensionPart}`;
388
+ }
389
+ determineRedirectUri(redirectUri, domainNames) {
390
+ if (redirectUri) {
391
+ return redirectUri;
392
+ }
393
+ if (!domainNames || domainNames.length === 0) {
394
+ throw new Error('Either redirectUri or domainNames must be provided');
395
+ }
396
+ return `https://${domainNames[0]}/oauth2/callback`;
397
+ }
398
+ loadAndReplaceAuthCheckCode(tenantId, clientId, redirectUri) {
399
+ const codePath = path.join(__dirname, '../cloudfront-functions/auth-check.js');
400
+ let code = fs.readFileSync(codePath, 'utf-8');
401
+ code = code.replace('TENANT_ID_PLACEHOLDER', tenantId);
402
+ code = code.replace('CLIENT_ID_PLACEHOLDER', clientId);
403
+ code = code.replace('REDIRECT_URI_PLACEHOLDER', redirectUri);
404
+ return code;
405
+ }
406
+ loadAndReplaceUserInfoCode(nameFields) {
407
+ const codePath = path.join(__dirname, '../cloudfront-functions/userinfo-endpoint.js');
408
+ let code = fs.readFileSync(codePath, 'utf-8');
409
+ // Replace the nameFields array with the provided fields
410
+ const nameFieldsJson = JSON.stringify(nameFields);
411
+ code = code.replace("var nameFields = ['key1', 'key2', 'key3'];", `var nameFields = ${nameFieldsJson};`);
412
+ return code;
413
+ }
414
+ }
415
+ exports.SecuredCloudFront = SecuredCloudFront;
416
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJlZENsb3VkRnJvbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xvdWRmcm9udC9wYXR0ZXJucy9zZWN1cmVkQ2xvdWRGcm9udC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1Q0FBeUI7QUFDekIsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUM3QixrREFBb0M7QUFDcEMsNkNBT3FCO0FBQ3JCLHVEQUF5QztBQUV6QyxpRkFBNkU7QUFFN0UsSUFBWSxTQUlYO0FBSkQsV0FBWSxTQUFTO0lBQ25CLDBDQUE2QixDQUFBO0lBQzdCLDhDQUFpQyxDQUFBO0lBQ2pDLDREQUErQyxDQUFBO0FBQ2pELENBQUMsRUFKVyxTQUFTLHlCQUFULFNBQVMsUUFJcEI7QUFFRCxJQUFZLGFBR1g7QUFIRCxXQUFZLGFBQWE7SUFDdkIsMEJBQVMsQ0FBQTtJQUNULDRCQUFXLENBQUE7QUFDYixDQUFDLEVBSFcsYUFBYSw2QkFBYixhQUFhLFFBR3hCO0FBc0NELE1BQWEsaUJBQWlELFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFvQnhGLFlBQVksS0FBMkIsRUFBRSxFQUFVLEVBQUUsS0FBK0M7UUFDbEcsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFcEYsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQ25DLE1BQU0sZUFBZSxHQUFHLHFCQUFHLENBQUMsZUFBZSxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNsRyxNQUFNLFNBQVMsR0FBRyxxQkFBRyxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3RGLE1BQU0sWUFBWSxHQUFHLHFCQUFHLENBQUMsZUFBZSxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDNUYsTUFBTSxNQUFNLEdBQUcscUJBQUcsQ0FBQyxlQUFlLENBQUMsdUJBQXVCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoRixNQUFNLFFBQVEsR0FBRyxxQkFBRyxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BGLE1BQU0sUUFBUSxHQUFHLHFCQUFHLENBQUMsZUFBZSxDQUFDLHVCQUF1QixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDcEYsTUFBTSxzQkFBc0IsR0FBRyxxQkFBRyxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFFaEgsSUFBSSxDQUFDLFlBQVksR0FBRyxnQ0FBYyxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDekcsSUFBSSxDQUFDLE1BQU0sR0FBRyxxQkFBRyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLEVBQVMsQ0FBQztRQUN0RSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztRQUM1QixJQUFJLENBQUMsU0FBUyxHQUFHLGVBQWUsQ0FBQztRQUVqQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUkscUJBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLGdCQUFnQixFQUFFO1lBQ3pELFFBQVEsRUFBRSxzQkFBc0I7WUFDaEMsU0FBUyxFQUFFLElBQUkscUJBQUcsQ0FBQyxrQkFBa0IsQ0FDbkMsSUFBSSxxQkFBRyxDQUFDLGdCQUFnQixDQUFDLHNCQUFzQixDQUFDLEVBQ2hELElBQUkscUJBQUcsQ0FBQyxnQkFBZ0IsQ0FBQywwQkFBMEIsQ0FBQyxDQUNyRDtZQUNELGVBQWUsRUFBRTtnQkFDZixxQkFBRyxDQUFDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQywwQ0FBMEMsQ0FBQzthQUN2RjtTQUNGLENBQUMsQ0FBQztRQUVILGdHQUFnRztRQUNoRyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxJQUFJLHFCQUFHLENBQUMsZUFBZSxDQUFDO1lBQ3RELE1BQU0sRUFBRSxxQkFBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLO1lBQ3hCLE9BQU8sRUFBRSxDQUFDLCtCQUErQixFQUFFLCtCQUErQixDQUFDO1lBQzNFLFNBQVMsRUFBRSxDQUFDLGVBQWUsQ0FBQztTQUM3QixDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7WUFDdEQsTUFBTSxFQUFFLHFCQUFHLENBQUMsTUFBTSxDQUFDLEtBQUs7WUFDeEIsT0FBTyxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ3hCLFNBQVMsRUFBRSxDQUFDLFNBQVMsQ0FBQztTQUN2QixDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7WUFDdEQsTUFBTSxFQUFFLHFCQUFHLENBQUMsTUFBTSxDQUFDLEtBQUs7WUFDeEIsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQUUsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLHFCQUFxQixFQUFFLHFCQUFxQixDQUFDO1lBQ2xJLFNBQVMsRUFBRSxDQUFDLFlBQVksQ0FBQztTQUMxQixDQUFDLENBQUMsQ0FBQztRQUVKLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLElBQUkscUJBQUcsQ0FBQyxlQUFlLENBQUM7WUFDdEQsTUFBTSxFQUFFLHFCQUFHLENBQUMsTUFBTSxDQUFDLEtBQUs7WUFDeEIsT0FBTyxFQUFFLENBQUMseUJBQXlCLENBQUM7WUFDcEMsU0FBUyxFQUFFLENBQUMsR0FBRyxDQUFDO1NBQ2pCLENBQUMsQ0FBQyxDQUFDO1FBRUosTUFBTSxHQUFHLEdBQUcsNEJBQVUsQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvRSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBRS9CLE1BQU0sZUFBZSxHQUFHOzs7Ozs7Ozs7OytDQVVtQixLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQzttQkFDaEQsS0FBSyxDQUFDLFVBQVU7Ozs7Ozs7Ozs7Ozs7O0NBY2xDLENBQUM7UUFFRSxNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDckUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUscUJBQXFCLENBQUMsQ0FBQztRQUMvRCxFQUFFLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUVoRCxNQUFNLHFCQUFxQixHQUFHLElBQUksNEJBQVUsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDNUYsT0FBTyxFQUFFLHdCQUFNLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDbkMsT0FBTyxFQUFFLCtCQUErQjtZQUN4QyxJQUFJLEVBQUUsd0JBQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLHFCQUFxQixDQUFDLEVBQUU7Z0JBQ3ZFLFFBQVEsRUFBRTtvQkFDUixLQUFLLEVBQUUsd0JBQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLGFBQWE7b0JBQy9DLE9BQU8sRUFBRTt3QkFDUCxNQUFNLEVBQUUsSUFBSTt3QkFDWixzREFBc0Q7NEJBQ3RELDJCQUEyQjs0QkFDM0IsK0RBQStEO3FCQUNoRTtvQkFDRCxPQUFPLEVBQUU7d0JBQ1A7NEJBQ0UsUUFBUSxFQUFFLFlBQVk7NEJBQ3RCLGFBQWEsRUFBRSwwQkFBMEI7eUJBQzFDO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQztZQUNGLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDbEMsVUFBVSxFQUFFLEdBQUc7WUFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLGNBQWM7U0FDMUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLDJCQUEyQixDQUNwRCxRQUFRLEVBQ1IsUUFBUSxFQUNSLFdBQVcsQ0FDWixDQUFDO1FBRUYsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksNEJBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRTtZQUNsRSxJQUFJLEVBQUUsNEJBQVUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztZQUN2RCxPQUFPLEVBQUUsNEJBQVUsQ0FBQyxlQUFlLENBQUMsTUFBTTtZQUMxQyxhQUFhLEVBQUUsR0FBRztZQUNsQixPQUFPLEVBQUUsaUJBQWlCO1NBQzNCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFFbEQsZ0RBQWdEO1FBQ2hELElBQUksS0FBSyxDQUFDLHVCQUF1QixLQUFLLEtBQUssRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLElBQUksS0FBSyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDdkUsTUFBTSxJQUFJLEtBQUssQ0FBQywwRUFBMEUsQ0FBQyxDQUFDO1lBQzlGLENBQUM7WUFDRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDL0UsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksNEJBQVUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFO2dCQUN4RSxJQUFJLEVBQUUsNEJBQVUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztnQkFDdEQsT0FBTyxFQUFFLDRCQUFVLENBQUMsZUFBZSxDQUFDLE1BQU07Z0JBQzFDLGFBQWEsRUFBRSxHQUFHO2dCQUNsQixPQUFPLEVBQUUsaUNBQWlDO2FBQzNDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDbkQsQ0FBQztRQUVELE1BQU0sbUJBQW1CLEdBQStDLEVBQUUsQ0FBQztRQUUzRSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUN4QyxtQkFBbUIsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHO2dCQUN4QyxNQUFNLEVBQUUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUFNO2dCQUNwQyxvQkFBb0IsRUFBRSw0QkFBVSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQjtnQkFDdkUsR0FBRyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQztnQkFDbEQsV0FBVyxFQUFFLENBQUM7d0JBQ1osZUFBZSxFQUFFLHFCQUFxQixDQUFDLGNBQWM7d0JBQ3JELFNBQVMsRUFBRSw0QkFBVSxDQUFDLG1CQUFtQixDQUFDLGNBQWM7cUJBQ3pELENBQUM7Z0JBQ0YsV0FBVyxFQUFFLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsV0FBVyxJQUFJLElBQUksNEJBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFO29CQUNuSSxlQUFlLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLGlCQUFpQjtvQkFDbEUsT0FBTyxFQUFFLDhEQUE4RDtvQkFDdkUsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztvQkFDcEMsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztvQkFDaEMsTUFBTSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztvQkFDaEMsY0FBYyxFQUFFLDRCQUFVLENBQUMsbUJBQW1CLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQztvQkFDdkUsY0FBYyxFQUFFLDRCQUFVLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFO29CQUNyRCxtQkFBbUIsRUFBRSw0QkFBVSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsRUFBRTtvQkFDOUQsd0JBQXdCLEVBQUUsS0FBSztvQkFDL0IsMEJBQTBCLEVBQUUsS0FBSztpQkFDbEMsQ0FBQzthQUNILENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QixNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxFQUFFLEVBQUU7Z0JBQzVFLElBQUksV0FBVyxLQUFLLGtCQUFrQixFQUFFLENBQUM7b0JBQ3ZDLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxHQUFHLFFBQVEsQ0FBQztnQkFDOUMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELGlHQUFpRztRQUNqRyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSw0QkFBVSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSx3QkFBd0IsRUFBRTtZQUMvRixjQUFjLEVBQUUsNEJBQVUsQ0FBQywyQkFBMkIsQ0FBQyxTQUFTLENBQUMsdUJBQXVCLENBQUM7WUFDekYsY0FBYyxFQUFFLDRCQUFVLENBQUMsMkJBQTJCLENBQUMsSUFBSSxFQUFFO1lBQzdELG1CQUFtQixFQUFFLDRCQUFVLENBQUMsZ0NBQWdDLENBQUMsSUFBSSxFQUFFO1NBQ3hFLENBQUMsQ0FBQztRQUVILCtCQUErQjtRQUMvQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxvQ0FBZ0IsRUFBRSxDQUFDO1FBQy9DLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBRW5DLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSw0QkFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsY0FBYyxFQUFFO1lBQ3BFLFdBQVcsRUFBRSw0QkFBVSxDQUFDLFdBQVcsQ0FBQyxXQUFXO1lBQy9DLHNCQUFzQixFQUFFLDRCQUFVLENBQUMsc0JBQXNCLENBQUMsYUFBYTtZQUN2RSxlQUFlLEVBQUUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3JCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUM7Z0JBQzNHLE9BQU87b0JBQ0wsR0FBRyxLQUFLLENBQUMsZUFBZTtvQkFDeEIsb0JBQW9CLEVBQUUsWUFBWSxFQUFFLG9CQUFvQjtvQkFDeEQsbUJBQW1CLEVBQUUsWUFBWSxFQUFFLG1CQUFtQjtpQkFDdkQsQ0FBQztZQUNKLENBQUMsQ0FBQyxFQUFFO1lBQ0osbUJBQW1CLEVBQUUsbUJBQW1CO1lBQ3hDLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM5QixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7WUFDOUIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO1lBQ3hCLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxZQUFZO1lBQzFELGNBQWMsRUFBRTtnQkFDZDtvQkFDRSxVQUFVLEVBQUUsR0FBRztvQkFDZixrQkFBa0IsRUFBRSxHQUFHO29CQUN2QixnQkFBZ0IsRUFBRSxLQUFLLENBQUMscUJBQXFCLElBQUksYUFBYTtvQkFDOUQsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztpQkFDOUI7Z0JBQ0Q7b0JBQ0UsVUFBVSxFQUFFLEdBQUc7b0JBQ2Ysa0JBQWtCLEVBQUUsR0FBRztvQkFDdkIsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLHFCQUFxQixJQUFJLGFBQWE7b0JBQzlELEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7aUJBQzlCO2dCQUNEO29CQUNFLFVBQVUsRUFBRSxHQUFHO29CQUNmLGtCQUFrQixFQUFFLEdBQUc7b0JBQ3ZCLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxhQUFhO29CQUM5RCxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2lCQUMvQjtnQkFDRDtvQkFDRSxVQUFVLEVBQUUsR0FBRztvQkFDZixrQkFBa0IsRUFBRSxHQUFHO29CQUN2QixnQkFBZ0IsRUFBRSxLQUFLLENBQUMscUJBQXFCLElBQUksYUFBYTtvQkFDOUQsR0FBRyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztpQkFDL0I7Z0JBQ0Q7b0JBQ0UsVUFBVSxFQUFFLEdBQUc7b0JBQ2Ysa0JBQWtCLEVBQUUsR0FBRztvQkFDdkIsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLHFCQUFxQixJQUFJLGFBQWE7b0JBQzlELEdBQUcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7aUJBQy9CO2dCQUNEO29CQUNFLFVBQVUsRUFBRSxHQUFHO29CQUNmLGtCQUFrQixFQUFFLEdBQUc7b0JBQ3ZCLGdCQUFnQixFQUFFLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxhQUFhO29CQUM5RCxHQUFHLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2lCQUMvQjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsMERBQTBEO1FBQzFELElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFO2dCQUN2RSxvQkFBb0IsRUFBRSw0QkFBVSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQjtnQkFDdkUsb0JBQW9CLEVBQUU7b0JBQ3BCO3dCQUNFLFFBQVEsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO3dCQUMvQixTQUFTLEVBQUUsNEJBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjO3FCQUN2RDtpQkFDRjtnQkFDRCxXQUFXLEVBQUUsNEJBQVUsQ0FBQyxXQUFXLENBQUMsZ0JBQWdCO2FBQ3JELENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRU0sV0FBVyxDQUNoQixXQUFtQixFQUNuQixNQUEwQixFQUMxQixVQUFrRSxFQUFFLEVBQ3BFLFNBQW1CO1FBRW5CLDBFQUEwRTtRQUMxRSxJQUFJLFFBQVEsSUFBSSxPQUFPLElBQUksc0JBQXNCLElBQUksT0FBTyxFQUFFLENBQUM7WUFDN0QsTUFBTSxlQUFlLEdBQUcsT0FBcUMsQ0FBQztZQUM5RCxNQUFNLGVBQWUsR0FBRyxTQUFTLEtBQUssS0FBSyxDQUFDO1lBRTVDLElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sb0JBQW9CLEdBQXFDO29CQUM3RCxHQUFHLENBQUMsZUFBZSxDQUFDLG9CQUFvQixJQUFJLEVBQUUsQ0FBQztvQkFDL0M7d0JBQ0UsUUFBUSxFQUFFLElBQUksQ0FBQyxpQkFBaUI7d0JBQ2hDLFNBQVMsRUFBRSw0QkFBVSxDQUFDLGlCQUFpQixDQUFDLGNBQWM7cUJBQ3ZEO2lCQUNGLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRTtvQkFDakQsR0FBRyxlQUFlO29CQUNsQixvQkFBb0IsRUFBRSxvQkFBb0I7aUJBQzNDLENBQUMsQ0FBQztZQUNMLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUVELCtEQUErRDtRQUMvRCxNQUFNLGtCQUFrQixHQUFHLE9BQW9DLENBQUM7UUFFaEUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUMxQyxrQkFBa0IsQ0FBQyxVQUFVLEVBQzdCLGtCQUFrQixDQUFDLGVBQWUsQ0FDbkMsQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxNQUFNLEVBQUU7WUFDakQsR0FBRyxrQkFBa0IsQ0FBQyxlQUFlO1lBQ3JDLG9CQUFvQixFQUFFLEtBQUssRUFBRSxvQkFBb0IsSUFBSSxrQkFBa0IsQ0FBQyxlQUFlLEVBQUUsb0JBQW9CO1lBQzdHLG1CQUFtQixFQUFFLEtBQUssRUFBRSxtQkFBbUIsSUFBSSxrQkFBa0IsQ0FBQyxlQUFlLEVBQUUsbUJBQW1CO1NBQzNHLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyx5QkFBeUIsQ0FDL0IsVUFBd0IsRUFDeEIsTUFBK0I7UUFFL0IsSUFBSSxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzNDLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFFRCxpRUFBaUU7UUFDakUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVuRSw0Q0FBNEM7UUFDNUMsSUFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDViw4REFBOEQ7WUFDOUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFO2dCQUM3RCxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7Z0JBQ3ZCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtnQkFDdkIsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2FBQzlCLENBQUMsQ0FBQztZQUVILDZCQUE2QjtZQUM3QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRS9ELHdDQUF3QztZQUN4QyxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUM7Z0JBQy9ELENBQUMsQ0FBQztvQkFDQSxJQUFJLEVBQUUsNEJBQVUsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQztvQkFDOUMsT0FBTyxFQUFFLDRCQUFVLENBQUMsZUFBZSxDQUFDLE1BQU07b0JBQzFDLE9BQU8sRUFBRSxhQUFhLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQzdDLGFBQWEsRUFBRSxJQUFJLENBQUMsR0FBRztpQkFDeEI7Z0JBQ0QsQ0FBQyxDQUFDO29CQUNBLElBQUksRUFBRSw0QkFBVSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO29CQUM5QyxPQUFPLEVBQUUsNEJBQVUsQ0FBQyxlQUFlLENBQUMsTUFBTTtvQkFDMUMsT0FBTyxFQUFFLGFBQWEsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtpQkFDOUMsQ0FBQztZQUVKLElBQUksR0FBRyxJQUFJLDRCQUFVLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7WUFFaEUsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUNELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7WUFFaEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDN0MsQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFxSDtZQUMvSCxvQkFBb0IsRUFBRSxDQUFDO29CQUNyQixRQUFRLEVBQUUsSUFBSTtvQkFDZCxTQUFTLEVBQUUsNEJBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxjQUFjO2lCQUN2RCxDQUFDO1NBQ0gsQ0FBQztRQUVGLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUNsRCxNQUFNLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDO1FBQzNELENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sd0JBQXdCLENBQUMsVUFBdUIsRUFBRSxNQUErQjtRQUN2RixNQUFNLEtBQUssR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM1QyxJQUFJLE1BQU0sRUFBRSxhQUFhLEVBQUUsQ0FBQztZQUMxQixLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDekQsQ0FBQztRQUNELElBQUksTUFBTSxFQUFFLGFBQWEsSUFBSSxNQUFNLENBQUMsYUFBYSxLQUFLLGFBQWEsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN2RSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxVQUF1QixFQUFFLE1BQStCO1FBQ2pGLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM5RSxJQUFJLE1BQU0sRUFBRSxhQUFhLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVGLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxhQUFhLElBQUksTUFBTSxDQUFDLGFBQWEsS0FBSyxhQUFhLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDL0csT0FBTyxtQkFBbUIsYUFBYSxHQUFHLFFBQVEsR0FBRyxRQUFRLEVBQUUsQ0FBQztRQUNsRSxDQUFDO1FBQ0QsT0FBTyxtQkFBbUIsYUFBYSxFQUFFLENBQUM7SUFDNUMsQ0FBQztJQUVPLG9CQUFvQixDQUFDLFdBQW9CLEVBQUUsV0FBc0I7UUFDdkUsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixPQUFPLFdBQVcsQ0FBQztRQUNyQixDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsSUFBSSxXQUFXLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzdDLE1BQU0sSUFBSSxLQUFLLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsT0FBTyxXQUFXLFdBQVcsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUM7SUFDckQsQ0FBQztJQUVPLDJCQUEyQixDQUFDLFFBQWdCLEVBQUUsUUFBZ0IsRUFBRSxXQUFtQjtRQUN6RixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSx1Q0FBdUMsQ0FBQyxDQUFDO1FBQy9FLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHVCQUF1QixFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZELElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHVCQUF1QixFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZELElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLDBCQUEwQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzdELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLDBCQUEwQixDQUFDLFVBQW9CO1FBQ3JELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLDhDQUE4QyxDQUFDLENBQUM7UUFDdEYsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFFOUMsd0RBQXdEO1FBQ3hELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEQsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQ2pCLDRDQUE0QyxFQUM1QyxvQkFBb0IsY0FBYyxHQUFHLENBQ3RDLENBQUM7UUFFRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRjtBQTNiRCw4Q0EyYkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgY29yZSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1xuICBhd3NfY2xvdWRmcm9udCBhcyBjbG91ZGZyb250LFxuICBhd3Nfc2VjcmV0c21hbmFnZXIgYXMgc2VjcmV0c21hbmFnZXIsXG4gIGF3c19rbXMgYXMga21zLFxuICBhd3NfaWFtIGFzIGlhbSxcbiAgYXdzX2xhbWJkYSBhcyBsYW1iZGEsXG4gIGF3c19zc20gYXMgc3NtLFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXV0aFNlY3VyaXR5VGFibGUgfSBmcm9tICcuLi9hdXRoU2VjdXJpdHlUYWJsZSc7XG5pbXBvcnQgeyBGdW5jdGlvbkNvbXBvc2VyIH0gZnJvbSAnLi4vY2xvdWRmcm9udC1mdW5jdGlvbnMvZnVuY3Rpb24tY29tcG9zZXInO1xuXG5leHBvcnQgZW51bSBFeHRlbnNpb24ge1xuICBSRVFVSVJFX0FVVEggPSAnUkVRVUlSRV9BVVRIJyxcbiAgUkVRVUlSRV9UTFNfMTMgPSAnUkVRVUlSRV9UTFNfMTMnLFxuICBSRVdSSVRFX1RPX0lOREVYX0hUTUwgPSAnUkVXUklURV9UT19JTkRFWF9IVE1MJyxcbn1cblxuZXhwb3J0IGVudW0gUm9sZU1hdGNoTW9kZSB7XG4gIE9SID0gJ09SJyxcbiAgQU5EID0gJ0FORCcsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0ZW5zaW9uQ29uZmlnPFRSb2xlIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG4gIHJlYWRvbmx5IHJlcXVpcmVkUm9sZXM/OiByZWFkb25seSBUUm9sZVtdO1xuICByZWFkb25seSByb2xlTWF0Y2hNb2RlPzogUm9sZU1hdGNoTW9kZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBZGRCZWhhdmlvck9wdGlvbnM8VFJvbGUgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IHtcbiAgcmVhZG9ubHkgZXh0ZW5zaW9ucz86IEV4dGVuc2lvbltdO1xuICByZWFkb25seSBleHRlbnNpb25Db25maWc/OiBFeHRlbnNpb25Db25maWc8VFJvbGU+O1xuICByZWFkb25seSBiZWhhdmlvck9wdGlvbnM/OiBPbWl0PGNsb3VkZnJvbnQuQmVoYXZpb3JPcHRpb25zLCAnb3JpZ2luJz47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvdWRGcm9udFdpdGhBenVyZUF1dGhTcGxpdFByb3BzPFRSb2xlIGV4dGVuZHMgc3RyaW5nID0gc3RyaW5nPiB7XG4gIHJlYWRvbmx5IGRlZmF1bHRCZWhhdmlvcjogT21pdDxjbG91ZGZyb250LkJlaGF2aW9yT3B0aW9ucywgJ2Z1bmN0aW9uQXNzb2NpYXRpb25zJz47XG4gIHJlYWRvbmx5IGFkZGl0aW9uYWxCZWhhdmlvcnM/OiBSZWNvcmQ8c3RyaW5nLCBPbWl0PGNsb3VkZnJvbnQuQmVoYXZpb3JPcHRpb25zLCAnZWRnZUxhbWJkYXMnPj47XG4gIHJlYWRvbmx5IGRvbWFpbk5hbWVzOiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgY2VydGlmaWNhdGU6IGFueTtcbiAgcmVhZG9ubHkgcmVkaXJlY3RVcmk/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHdlYkFjbElkPzogc3RyaW5nO1xuICByZWFkb25seSBobWFjU2VjcmV0Um90YXRpb25TY2hlZHVsZT86IGNvcmUuRHVyYXRpb247XG4gIHJlYWRvbmx5IHNlY3VyaXR5QWxlcnRzVG9waWNBcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNlc3Npb25SZXZvY2F0aW9uVG9waWNBcm4/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF1dG9SZXZva2VPblJldXNlPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgand0Q2xhaW1zV2hpdGVsaXN0Pzogc3RyaW5nW107XG4gIHJlYWRvbmx5IGF1ZGl0TG9nUmV0ZW50aW9uRGF5cz86IG51bWJlcjtcbiAgcmVhZG9ubHkgYXVkaXRBcmNoaXZlUmV0ZW50aW9uRGF5cz86IG51bWJlcjtcbiAgcmVhZG9ubHkgYXV0aFNzbVBhcmFtUHJlZml4OiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF1dGhSZWdpb246IHN0cmluZztcbiAgcmVhZG9ubHkgY3JlYXRlT0F1dGhDYWxsYmFjaz86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGRlZmF1bHRFeHRlbnNpb25zPzogRXh0ZW5zaW9uW107XG4gIHJlYWRvbmx5IGRlZmF1bHRFeHRlbnNpb25Db25maWc/OiBFeHRlbnNpb25Db25maWc8VFJvbGU+O1xuICByZWFkb25seSBkZWZhdWx0Um9vdE9iamVjdD86IHN0cmluZztcbiAgcmVhZG9ubHkgZXJyb3JSZXNwb25zZVBhZ2VQYXRoPzogc3RyaW5nO1xuICByZWFkb25seSBlbmFibGVVc2VySW5mb0luamVjdGlvbj86IGJvb2xlYW47XG4gIHJlYWRvbmx5IHVzZXJJbmZvTmFtZUZpZWxkcz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY2xhc3MgU2VjdXJlZENsb3VkRnJvbnQ8VFJvbGUgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+IGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuXG4gIHB1YmxpYyByZWFkb25seSBkaXN0cmlidXRpb246IGNsb3VkZnJvbnQuRGlzdHJpYnV0aW9uO1xuICBwdWJsaWMgcmVhZG9ubHkgY29uZmlnU2VjcmV0OiBzZWNyZXRzbWFuYWdlci5JU2VjcmV0O1xuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0QXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBrbXNLZXk6IGttcy5JS2V5O1xuICBwdWJsaWMgcmVhZG9ubHkgYXV0aFNlY3VyaXR5VGFibGU6IEF1dGhTZWN1cml0eVRhYmxlO1xuICBwdWJsaWMgcmVhZG9ubHkgYXVkaXRMb2dBcmNoaXZlOiBhbnk7XG4gIHB1YmxpYyByZWFkb25seSBsYW1iZGFFZGdlUm9sZTogaWFtLlJvbGU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXV0aENoZWNrRnVuY3Rpb246IGNsb3VkZnJvbnQuRnVuY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgdXNlckluZm9GdW5jdGlvbj86IGNsb3VkZnJvbnQuRnVuY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgZnVuY3Rpb25Db21wb3NlcjogRnVuY3Rpb25Db21wb3NlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21wb3NlZEZ1bmN0aW9uczogTWFwPHN0cmluZywgY2xvdWRmcm9udC5GdW5jdGlvbj47XG4gIHByaXZhdGUgbGFzdENyZWF0ZWRGdW5jdGlvbjogY2xvdWRmcm9udC5GdW5jdGlvbiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSB0bHNPcmlnaW5SZXF1ZXN0UG9saWN5OiBjbG91ZGZyb250Lk9yaWdpblJlcXVlc3RQb2xpY3k7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVuYW50SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnRJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZGlyZWN0VXJpOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkga3ZzOiBjbG91ZGZyb250LklLZXlWYWx1ZVN0b3JlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENsb3VkRnJvbnRXaXRoQXp1cmVBdXRoU3BsaXRQcm9wczxUUm9sZT4pIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgcmVkaXJlY3RVcmkgPSB0aGlzLmRldGVybWluZVJlZGlyZWN0VXJpKHByb3BzLnJlZGlyZWN0VXJpLCBwcm9wcy5kb21haW5OYW1lcyk7XG5cbiAgICBjb25zdCBwID0gcHJvcHMuYXV0aFNzbVBhcmFtUHJlZml4O1xuICAgIGNvbnN0IGNvbmZpZ1NlY3JldEFybiA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgYCR7cH0vY29uZmlnU2VjcmV0QXJuYCk7XG4gICAgY29uc3Qga21zS2V5QXJuID0gc3NtLlN0cmluZ1BhcmFtZXRlci52YWx1ZUZvclN0cmluZ1BhcmFtZXRlcih0aGlzLCBgJHtwfS9rbXNLZXlBcm5gKTtcbiAgICBjb25zdCBhdXRoVGFibGVBcm4gPSBzc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKHRoaXMsIGAke3B9L2F1dGhUYWJsZUFybmApO1xuICAgIGNvbnN0IGt2c0FybiA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgYCR7cH0va3ZzQXJuYCk7XG4gICAgY29uc3QgdGVuYW50SWQgPSBzc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKHRoaXMsIGAke3B9L3RlbmFudElkYCk7XG4gICAgY29uc3QgY2xpZW50SWQgPSBzc20uU3RyaW5nUGFyYW1ldGVyLnZhbHVlRm9yU3RyaW5nUGFyYW1ldGVyKHRoaXMsIGAke3B9L2NsaWVudElkYCk7XG4gICAgY29uc3Qgb2F1dGgyQ2FsbGJhY2tSb2xlTmFtZSA9IHNzbS5TdHJpbmdQYXJhbWV0ZXIudmFsdWVGb3JTdHJpbmdQYXJhbWV0ZXIodGhpcywgYCR7cH0vb2F1dGgyQ2FsbGJhY2tSb2xlTmFtZWApO1xuXG4gICAgdGhpcy5jb25maWdTZWNyZXQgPSBzZWNyZXRzbWFuYWdlci5TZWNyZXQuZnJvbVNlY3JldENvbXBsZXRlQXJuKHRoaXMsICdJbXBvcnRlZFNlY3JldCcsIGNvbmZpZ1NlY3JldEFybik7XG4gICAgdGhpcy5rbXNLZXkgPSBrbXMuS2V5LmZyb21LZXlBcm4odGhpcywgJ0ltcG9ydGVkS2V5Jywga21zS2V5QXJuKTtcbiAgICB0aGlzLmF1dGhTZWN1cml0eVRhYmxlID0geyB0YWJsZTogeyB0YWJsZUFybjogYXV0aFRhYmxlQXJuIH0gfSBhcyBhbnk7XG4gICAgdGhpcy5hdWRpdExvZ0FyY2hpdmUgPSBudWxsO1xuICAgIHRoaXMuc2VjcmV0QXJuID0gY29uZmlnU2VjcmV0QXJuO1xuXG4gICAgdGhpcy5sYW1iZGFFZGdlUm9sZSA9IG5ldyBpYW0uUm9sZSh0aGlzLCAnTGFtYmRhRWRnZVJvbGUnLCB7XG4gICAgICByb2xlTmFtZTogb2F1dGgyQ2FsbGJhY2tSb2xlTmFtZSxcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5Db21wb3NpdGVQcmluY2lwYWwoXG4gICAgICAgIG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICAgbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdlZGdlbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgICksXG4gICAgICBtYW5hZ2VkUG9saWNpZXM6IFtcbiAgICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJyksXG4gICAgICBdLFxuICAgIH0pO1xuXG4gICAgLy8gd2UgbmVlZCB0byBhZGQgdGhlc2UgZGlyZWN0bHksIHJhdGhlciB0aGFuIHVzZSBncmFudCBtZXRob2RzLCB0byBhdm9pZCBjaXJjdWxhciBkZXBlbmRuYWNpZXMuXG4gICAgdGhpcy5sYW1iZGFFZGdlUm9sZS5hZGRUb1BvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgICBhY3Rpb25zOiBbJ3NlY3JldHNtYW5hZ2VyOkdldFNlY3JldFZhbHVlJywgJ3NlY3JldHNtYW5hZ2VyOkRlc2NyaWJlU2VjcmV0J10sXG4gICAgICByZXNvdXJjZXM6IFtjb25maWdTZWNyZXRBcm5dLFxuICAgIH0pKTtcblxuICAgIHRoaXMubGFtYmRhRWRnZVJvbGUuYWRkVG9Qb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogWydrbXM6RGVjcnlwdCddLFxuICAgICAgcmVzb3VyY2VzOiBba21zS2V5QXJuXSxcbiAgICB9KSk7XG5cbiAgICB0aGlzLmxhbWJkYUVkZ2VSb2xlLmFkZFRvUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5BTExPVyxcbiAgICAgIGFjdGlvbnM6IFsnZHluYW1vZGI6R2V0SXRlbScsICdkeW5hbW9kYjpQdXRJdGVtJywgJ2R5bmFtb2RiOlF1ZXJ5JywgJ2R5bmFtb2RiOlNjYW4nLCAnZHluYW1vZGI6VXBkYXRlSXRlbScsICdkeW5hbW9kYjpEZWxldGVJdGVtJ10sXG4gICAgICByZXNvdXJjZXM6IFthdXRoVGFibGVBcm5dLFxuICAgIH0pKTtcblxuICAgIHRoaXMubGFtYmRhRWRnZVJvbGUuYWRkVG9Qb2xpY3kobmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgYWN0aW9uczogWydzdHM6R2V0V2ViSWRlbnRpdHlUb2tlbiddLFxuICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICB9KSk7XG5cbiAgICBjb25zdCBrdnMgPSBjbG91ZGZyb250LktleVZhbHVlU3RvcmUuZnJvbUtleVZhbHVlU3RvcmVBcm4odGhpcywgJ0tWUycsIGt2c0Fybik7XG4gICAgdGhpcy5rdnMgPSBrdnM7XG4gICAgdGhpcy50ZW5hbnRJZCA9IHRlbmFudElkO1xuICAgIHRoaXMuY2xpZW50SWQgPSBjbGllbnRJZDtcbiAgICB0aGlzLnJlZGlyZWN0VXJpID0gcmVkaXJlY3RVcmk7XG5cbiAgICBjb25zdCBjb25maWdQeUNvbnRlbnQgPSBgIyBHZW5lcmF0ZWQgY29uZmlndXJhdGlvblxuaW1wb3J0IGpzb25cbmltcG9ydCBib3RvM1xuaW1wb3J0IG9zXG5pbXBvcnQgbG9nZ2luZ1xuXG5sb2dnZXIgPSBsb2dnaW5nLmdldExvZ2dlcigpXG5cbiMgU2VjcmV0IG5hbWUgYW5kIHJlZ2lvbiAtIHRoZXNlIG11c3QgYmUgY29uY3JldGUgdmFsdWVzLCBub3QgQ2xvdWRGb3JtYXRpb24gdG9rZW5zXG4jIFRoZSBzZWNyZXQgbmFtZSBpcyBjb25zdHJ1Y3RlZCBmcm9tIHRoZSBkb21haW4gbmFtZVxuQ09ORklHX1NFQ1JFVF9OQU1FID0gJ2Nsb3VkZnJvbnQtYXV0aC1jb25maWctJHtwcm9wcy5kb21haW5OYW1lc1swXX0nXG5DT05GSUdfUkVHSU9OID0gJyR7cHJvcHMuYXV0aFJlZ2lvbn0nXG5cbmRlZiBnZXRfY29uZmlnKCk6XG4gICAgbG9nZ2VyLmluZm8oZidBdHRlbXB0aW5nIHRvIGxvYWQgY29uZmlnIGZyb20gU2VjcmV0cyBNYW5hZ2VyJylcbiAgICBsb2dnZXIuaW5mbyhmJ0NPTkZJR19TRUNSRVRfTkFNRToge0NPTkZJR19TRUNSRVRfTkFNRX0nKVxuICAgIGxvZ2dlci5pbmZvKGYnQ09ORklHX1JFR0lPTjoge0NPTkZJR19SRUdJT059JylcbiAgICB0cnk6XG4gICAgICAgIGNsaWVudCA9IGJvdG8zLmNsaWVudCgnc2VjcmV0c21hbmFnZXInLCByZWdpb25fbmFtZT1DT05GSUdfUkVHSU9OKVxuICAgICAgICByZXNwb25zZSA9IGNsaWVudC5nZXRfc2VjcmV0X3ZhbHVlKFNlY3JldElkPUNPTkZJR19TRUNSRVRfTkFNRSlcbiAgICAgICAgcmV0dXJuIGpzb24ubG9hZHMocmVzcG9uc2VbJ1NlY3JldFN0cmluZyddKVxuICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZTpcbiAgICAgICAgbG9nZ2VyLmVycm9yKGYnRmFpbGVkIHRvIGdldCBzZWNyZXQuIE5hbWU9XCJ7Q09ORklHX1NFQ1JFVF9OQU1FfVwiLCBSZWdpb249XCJ7Q09ORklHX1JFR0lPTn1cIicpXG4gICAgICAgIGxvZ2dlci5lcnJvcihmJ0Vycm9yOiB7c3RyKGUpfScpXG4gICAgICAgIHJhaXNlXG5gO1xuXG4gICAgY29uc3QgdGVtcERpciA9IGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihvcy50bXBkaXIoKSwgJ2VkZ2UtYXV0aC0nKSk7XG4gICAgY29uc3QgY29uZmlnUHlQYXRoID0gcGF0aC5qb2luKHRlbXBEaXIsICdjb25maWdfZ2VuZXJhdGVkLnB5Jyk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhjb25maWdQeVBhdGgsIGNvbmZpZ1B5Q29udGVudCk7XG5cbiAgICBjb25zdCBvYXV0aENhbGxiYWNrRnVuY3Rpb24gPSBuZXcgY2xvdWRmcm9udC5leHBlcmltZW50YWwuRWRnZUZ1bmN0aW9uKHRoaXMsICdPQXV0aENhbGxiYWNrJywge1xuICAgICAgcnVudGltZTogbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfMTEsXG4gICAgICBoYW5kbGVyOiAnb2F1dGgtY2FsbGJhY2subGFtYmRhX2hhbmRsZXInLFxuICAgICAgY29kZTogbGFtYmRhLkNvZGUuZnJvbUFzc2V0KHBhdGguam9pbihfX2Rpcm5hbWUsICcuLi9sYW1iZGEvZWRnZS1hdXRoJyksIHtcbiAgICAgICAgYnVuZGxpbmc6IHtcbiAgICAgICAgICBpbWFnZTogbGFtYmRhLlJ1bnRpbWUuUFlUSE9OXzNfMTEuYnVuZGxpbmdJbWFnZSxcbiAgICAgICAgICBjb21tYW5kOiBbXG4gICAgICAgICAgICAnYmFzaCcsICctYycsXG4gICAgICAgICAgICAncGlwIGluc3RhbGwgLXIgcmVxdWlyZW1lbnRzLnR4dCAtdCAvYXNzZXQtb3V0cHV0ICYmICcgK1xuICAgICAgICAgICAgJ2NwIC1yIC4gL2Fzc2V0LW91dHB1dCAmJiAnICtcbiAgICAgICAgICAgICdjcCAvdG1wL2NvbmZpZ19nZW5lcmF0ZWQucHkgL2Fzc2V0LW91dHB1dC9jb25maWdfZ2VuZXJhdGVkLnB5JyxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHZvbHVtZXM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgaG9zdFBhdGg6IGNvbmZpZ1B5UGF0aCxcbiAgICAgICAgICAgICAgY29udGFpbmVyUGF0aDogJy90bXAvY29uZmlnX2dlbmVyYXRlZC5weScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICAgIHRpbWVvdXQ6IGNvcmUuRHVyYXRpb24uc2Vjb25kcygzMCksXG4gICAgICBtZW1vcnlTaXplOiAxMjgsXG4gICAgICByb2xlOiB0aGlzLmxhbWJkYUVkZ2VSb2xlLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYXV0aENoZWNrQ29kZSA9IHRoaXMubG9hZEFuZFJlcGxhY2VBdXRoQ2hlY2tDb2RlKFxuICAgICAgdGVuYW50SWQsXG4gICAgICBjbGllbnRJZCxcbiAgICAgIHJlZGlyZWN0VXJpLFxuICAgICk7XG5cbiAgICB0aGlzLmF1dGhDaGVja0Z1bmN0aW9uID0gbmV3IGNsb3VkZnJvbnQuRnVuY3Rpb24odGhpcywgJ0F1dGhDaGVjaycsIHtcbiAgICAgIGNvZGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25Db2RlLmZyb21JbmxpbmUoYXV0aENoZWNrQ29kZSksXG4gICAgICBydW50aW1lOiBjbG91ZGZyb250LkZ1bmN0aW9uUnVudGltZS5KU18yXzAsXG4gICAgICBrZXlWYWx1ZVN0b3JlOiBrdnMsXG4gICAgICBjb21tZW50OiAndmVyaWZpZXMgdG9rZW5zJyxcbiAgICB9KTtcbiAgICB0aGlzLmxhc3RDcmVhdGVkRnVuY3Rpb24gPSB0aGlzLmF1dGhDaGVja0Z1bmN0aW9uO1xuXG4gICAgLy8gQ3JlYXRlIHVzZXIgaW5mbyBlbmRwb2ludCBmdW5jdGlvbiBpZiBlbmFibGVkXG4gICAgaWYgKHByb3BzLmVuYWJsZVVzZXJJbmZvSW5qZWN0aW9uICE9PSBmYWxzZSkge1xuICAgICAgaWYgKCFwcm9wcy51c2VySW5mb05hbWVGaWVsZHMgfHwgcHJvcHMudXNlckluZm9OYW1lRmllbGRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3VzZXJJbmZvTmFtZUZpZWxkcyBtdXN0IGJlIHByb3ZpZGVkIHdoZW4gZW5hYmxlVXNlckluZm9JbmplY3Rpb24gaXMgdHJ1ZScpO1xuICAgICAgfVxuICAgICAgY29uc3QgdXNlckluZm9Db2RlID0gdGhpcy5sb2FkQW5kUmVwbGFjZVVzZXJJbmZvQ29kZShwcm9wcy51c2VySW5mb05hbWVGaWVsZHMpO1xuICAgICAgdGhpcy51c2VySW5mb0Z1bmN0aW9uID0gbmV3IGNsb3VkZnJvbnQuRnVuY3Rpb24odGhpcywgJ1VzZXJJbmZvRW5kcG9pbnQnLCB7XG4gICAgICAgIGNvZGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25Db2RlLmZyb21JbmxpbmUodXNlckluZm9Db2RlKSxcbiAgICAgICAgcnVudGltZTogY2xvdWRmcm9udC5GdW5jdGlvblJ1bnRpbWUuSlNfMl8wLFxuICAgICAgICBrZXlWYWx1ZVN0b3JlOiBrdnMsXG4gICAgICAgIGNvbW1lbnQ6ICdSZXR1cm5zIHVzZXIgaW5mbyBKU09OIGZyb20gSldUJyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy51c2VySW5mb0Z1bmN0aW9uLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLmF1dGhDaGVja0Z1bmN0aW9uKTtcbiAgICAgIHRoaXMubGFzdENyZWF0ZWRGdW5jdGlvbiA9IHRoaXMudXNlckluZm9GdW5jdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBhZGRpdGlvbmFsQmVoYXZpb3JzOiBSZWNvcmQ8c3RyaW5nLCBjbG91ZGZyb250LkJlaGF2aW9yT3B0aW9ucz4gPSB7fTtcblxuICAgIGlmIChwcm9wcy5jcmVhdGVPQXV0aENhbGxiYWNrICE9PSBmYWxzZSkge1xuICAgICAgYWRkaXRpb25hbEJlaGF2aW9yc1snL29hdXRoMi9jYWxsYmFjayddID0ge1xuICAgICAgICBvcmlnaW46IHByb3BzLmRlZmF1bHRCZWhhdmlvci5vcmlnaW4sXG4gICAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBjbG91ZGZyb250LlZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgICAuLi5wcm9wcy5hZGRpdGlvbmFsQmVoYXZpb3JzPy5bJy9vYXV0aDIvY2FsbGJhY2snXSxcbiAgICAgICAgZWRnZUxhbWJkYXM6IFt7XG4gICAgICAgICAgZnVuY3Rpb25WZXJzaW9uOiBvYXV0aENhbGxiYWNrRnVuY3Rpb24uY3VycmVudFZlcnNpb24sXG4gICAgICAgICAgZXZlbnRUeXBlOiBjbG91ZGZyb250LkxhbWJkYUVkZ2VFdmVudFR5cGUuVklFV0VSX1JFUVVFU1QsXG4gICAgICAgIH1dLFxuICAgICAgICBjYWNoZVBvbGljeTogcHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycz8uWycvb2F1dGgyL2NhbGxiYWNrJ10/LmNhY2hlUG9saWN5ID8/IG5ldyBjbG91ZGZyb250LkNhY2hlUG9saWN5KHRoaXMsICdDYWxsYmFja0NhY2hlUG9saWN5Jywge1xuICAgICAgICAgIGNhY2hlUG9saWN5TmFtZTogYCR7Y29yZS5TdGFjay5vZih0aGlzKS5zdGFja05hbWV9LW9hdXRoLWNhbGxiYWNrYCxcbiAgICAgICAgICBjb21tZW50OiAnQ2FjaGUgcG9saWN5IGZvciBPQXV0aCBjYWxsYmFjayB3aXRoIHN0YXRlIGNvb2tpZSBmb3J3YXJkaW5nJyxcbiAgICAgICAgICBkZWZhdWx0VHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAgICAgbWluVHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMCksXG4gICAgICAgICAgbWF4VHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMSksXG4gICAgICAgICAgY29va2llQmVoYXZpb3I6IGNsb3VkZnJvbnQuQ2FjaGVDb29raWVCZWhhdmlvci5hbGxvd0xpc3QoJ29hdXRoX3N0YXRlJyksXG4gICAgICAgICAgaGVhZGVyQmVoYXZpb3I6IGNsb3VkZnJvbnQuQ2FjaGVIZWFkZXJCZWhhdmlvci5ub25lKCksXG4gICAgICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogY2xvdWRmcm9udC5DYWNoZVF1ZXJ5U3RyaW5nQmVoYXZpb3IuYWxsKCksXG4gICAgICAgICAgZW5hYmxlQWNjZXB0RW5jb2RpbmdHemlwOiBmYWxzZSxcbiAgICAgICAgICBlbmFibGVBY2NlcHRFbmNvZGluZ0Jyb3RsaTogZmFsc2UsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycykge1xuICAgICAgT2JqZWN0LmVudHJpZXMocHJvcHMuYWRkaXRpb25hbEJlaGF2aW9ycykuZm9yRWFjaCgoW3BhdGhQYXR0ZXJuLCBiZWhhdmlvcl0pID0+IHtcbiAgICAgICAgaWYgKHBhdGhQYXR0ZXJuICE9PSAnL29hdXRoMi9jYWxsYmFjaycpIHtcbiAgICAgICAgICBhZGRpdGlvbmFsQmVoYXZpb3JzW3BhdGhQYXR0ZXJuXSA9IGJlaGF2aW9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBPcmlnaW4gcmVxdWVzdCBwb2xpY3kgdGhhdCBmb3J3YXJkcyBDbG91ZEZyb250LVZpZXdlci1UTFMgaGVhZGVyIChyZXF1aXJlZCBmb3IgUkVRVUlSRV9UTFNfMTMpXG4gICAgdGhpcy50bHNPcmlnaW5SZXF1ZXN0UG9saWN5ID0gbmV3IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdFBvbGljeSh0aGlzLCAnVGxzT3JpZ2luUmVxdWVzdFBvbGljeScsIHtcbiAgICAgIGhlYWRlckJlaGF2aW9yOiBjbG91ZGZyb250Lk9yaWdpblJlcXVlc3RIZWFkZXJCZWhhdmlvci5hbGxvd0xpc3QoJ0Nsb3VkRnJvbnQtVmlld2VyLVRMUycpLFxuICAgICAgY29va2llQmVoYXZpb3I6IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdENvb2tpZUJlaGF2aW9yLm5vbmUoKSxcbiAgICAgIHF1ZXJ5U3RyaW5nQmVoYXZpb3I6IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdFF1ZXJ5U3RyaW5nQmVoYXZpb3Iubm9uZSgpLFxuICAgIH0pO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBmdW5jdGlvbiBjb21wb3NlclxuICAgIHRoaXMuZnVuY3Rpb25Db21wb3NlciA9IG5ldyBGdW5jdGlvbkNvbXBvc2VyKCk7XG4gICAgdGhpcy5jb21wb3NlZEZ1bmN0aW9ucyA9IG5ldyBNYXAoKTtcblxuICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gbmV3IGNsb3VkZnJvbnQuRGlzdHJpYnV0aW9uKHRoaXMsICdEaXN0cmlidXRpb24nLCB7XG4gICAgICBodHRwVmVyc2lvbjogY2xvdWRmcm9udC5IdHRwVmVyc2lvbi5IVFRQMl9BTkRfMyxcbiAgICAgIG1pbmltdW1Qcm90b2NvbFZlcnNpb246IGNsb3VkZnJvbnQuU2VjdXJpdHlQb2xpY3lQcm90b2NvbC5UTFNfVjFfMl8yMDI1LFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiAoKCkgPT4ge1xuICAgICAgICBjb25zdCBkZWZhdWx0QnVpbHQgPSB0aGlzLmJ1aWxkRnVuY3Rpb25Bc3NvY2lhdGlvbnMocHJvcHMuZGVmYXVsdEV4dGVuc2lvbnMsIHByb3BzLmRlZmF1bHRFeHRlbnNpb25Db25maWcpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnByb3BzLmRlZmF1bHRCZWhhdmlvcixcbiAgICAgICAgICBmdW5jdGlvbkFzc29jaWF0aW9uczogZGVmYXVsdEJ1aWx0Py5mdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgICAgICBvcmlnaW5SZXF1ZXN0UG9saWN5OiBkZWZhdWx0QnVpbHQ/Lm9yaWdpblJlcXVlc3RQb2xpY3ksXG4gICAgICAgIH07XG4gICAgICB9KSgpLFxuICAgICAgYWRkaXRpb25hbEJlaGF2aW9yczogYWRkaXRpb25hbEJlaGF2aW9ycyxcbiAgICAgIGRvbWFpbk5hbWVzOiBwcm9wcy5kb21haW5OYW1lcyxcbiAgICAgIGNlcnRpZmljYXRlOiBwcm9wcy5jZXJ0aWZpY2F0ZSxcbiAgICAgIHdlYkFjbElkOiBwcm9wcy53ZWJBY2xJZCxcbiAgICAgIGRlZmF1bHRSb290T2JqZWN0OiBwcm9wcy5kZWZhdWx0Um9vdE9iamVjdCA/PyAnaW5kZXguaHRtbCcsXG4gICAgICBlcnJvclJlc3BvbnNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNDAzLFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNDA0LFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNTAwLFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5zZWNvbmRzKDEwKSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIGh0dHBTdGF0dXM6IDUwMixcbiAgICAgICAgICByZXNwb25zZUh0dHBTdGF0dXM6IDIwMCxcbiAgICAgICAgICByZXNwb25zZVBhZ2VQYXRoOiBwcm9wcy5lcnJvclJlc3BvbnNlUGFnZVBhdGggPz8gJy9lcnJvci5odG1sJyxcbiAgICAgICAgICB0dGw6IGNvcmUuRHVyYXRpb24uc2Vjb25kcygxMCksXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBodHRwU3RhdHVzOiA1MDMsXG4gICAgICAgICAgcmVzcG9uc2VIdHRwU3RhdHVzOiAyMDAsXG4gICAgICAgICAgcmVzcG9uc2VQYWdlUGF0aDogcHJvcHMuZXJyb3JSZXNwb25zZVBhZ2VQYXRoID8/ICcvZXJyb3IuaHRtbCcsXG4gICAgICAgICAgdHRsOiBjb3JlLkR1cmF0aW9uLnNlY29uZHMoMTApLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaHR0cFN0YXR1czogNTA0LFxuICAgICAgICAgIHJlc3BvbnNlSHR0cFN0YXR1czogMjAwLFxuICAgICAgICAgIHJlc3BvbnNlUGFnZVBhdGg6IHByb3BzLmVycm9yUmVzcG9uc2VQYWdlUGF0aCA/PyAnL2Vycm9yLmh0bWwnLFxuICAgICAgICAgIHR0bDogY29yZS5EdXJhdGlvbi5zZWNvbmRzKDEwKSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyBBZGQgL3VzZXJpbmZvIGJlaGF2aW9yIGlmIHVzZXIgaW5mbyBlbmRwb2ludCBpcyBlbmFibGVkXG4gICAgaWYgKHRoaXMudXNlckluZm9GdW5jdGlvbikge1xuICAgICAgdGhpcy5kaXN0cmlidXRpb24uYWRkQmVoYXZpb3IoJy91c2VyaW5mbycsIHByb3BzLmRlZmF1bHRCZWhhdmlvci5vcmlnaW4sIHtcbiAgICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IGNsb3VkZnJvbnQuVmlld2VyUHJvdG9jb2xQb2xpY3kuUkVESVJFQ1RfVE9fSFRUUFMsXG4gICAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgZnVuY3Rpb246IHRoaXMudXNlckluZm9GdW5jdGlvbixcbiAgICAgICAgICAgIGV2ZW50VHlwZTogY2xvdWRmcm9udC5GdW5jdGlvbkV2ZW50VHlwZS5WSUVXRVJfUkVRVUVTVCxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBjYWNoZVBvbGljeTogY2xvdWRmcm9udC5DYWNoZVBvbGljeS5DQUNISU5HX0RJU0FCTEVELFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZEJlaGF2aW9yKFxuICAgIHBhdGhQYXR0ZXJuOiBzdHJpbmcsXG4gICAgb3JpZ2luOiBjbG91ZGZyb250LklPcmlnaW4sXG4gICAgb3B0aW9uczogQWRkQmVoYXZpb3JPcHRpb25zPFRSb2xlPiB8IGNsb3VkZnJvbnQuQmVoYXZpb3JPcHRpb25zID0ge30sXG4gICAgYXBwbHlBdXRoPzogYm9vbGVhbixcbiAgKTogdm9pZCB7XG4gICAgLy8gU3VwcG9ydCBsZWdhY3kgc2lnbmF0dXJlOiBhZGRCZWhhdmlvcihwYXRoLCBiZWhhdmlvck9wdGlvbnMsIGFwcGx5QXV0aClcbiAgICBpZiAoJ29yaWdpbicgaW4gb3B0aW9ucyB8fCAndmlld2VyUHJvdG9jb2xQb2xpY3knIGluIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IGJlaGF2aW9yT3B0aW9ucyA9IG9wdGlvbnMgYXMgY2xvdWRmcm9udC5CZWhhdmlvck9wdGlvbnM7XG4gICAgICBjb25zdCBzaG91bGRBcHBseUF1dGggPSBhcHBseUF1dGggIT09IGZhbHNlO1xuXG4gICAgICBpZiAoc2hvdWxkQXBwbHlBdXRoKSB7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBjbG91ZGZyb250LkZ1bmN0aW9uQXNzb2NpYXRpb25bXSA9IFtcbiAgICAgICAgICAuLi4oYmVoYXZpb3JPcHRpb25zLmZ1bmN0aW9uQXNzb2NpYXRpb25zIHx8IFtdKSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBmdW5jdGlvbjogdGhpcy5hdXRoQ2hlY2tGdW5jdGlvbixcbiAgICAgICAgICAgIGV2ZW50VHlwZTogY2xvdWRmcm9udC5GdW5jdGlvbkV2ZW50VHlwZS5WSUVXRVJfUkVRVUVTVCxcbiAgICAgICAgICB9LFxuICAgICAgICBdO1xuICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihwYXRoUGF0dGVybiwgb3JpZ2luLCB7XG4gICAgICAgICAgLi4uYmVoYXZpb3JPcHRpb25zLFxuICAgICAgICAgIGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBmdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihwYXRoUGF0dGVybiwgb3JpZ2luLCBiZWhhdmlvck9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE5ldyBzaWduYXR1cmU6IGFkZEJlaGF2aW9yKHBhdGgsIG9yaWdpbiwgQWRkQmVoYXZpb3JPcHRpb25zKVxuICAgIGNvbnN0IGFkZEJlaGF2aW9yT3B0aW9ucyA9IG9wdGlvbnMgYXMgQWRkQmVoYXZpb3JPcHRpb25zPFRSb2xlPjtcblxuICAgIGNvbnN0IGJ1aWx0ID0gdGhpcy5idWlsZEZ1bmN0aW9uQXNzb2NpYXRpb25zKFxuICAgICAgYWRkQmVoYXZpb3JPcHRpb25zLmV4dGVuc2lvbnMsXG4gICAgICBhZGRCZWhhdmlvck9wdGlvbnMuZXh0ZW5zaW9uQ29uZmlnLFxuICAgICk7XG5cbiAgICB0aGlzLmRpc3RyaWJ1dGlvbi5hZGRCZWhhdmlvcihwYXRoUGF0dGVybiwgb3JpZ2luLCB7XG4gICAgICAuLi5hZGRCZWhhdmlvck9wdGlvbnMuYmVoYXZpb3JPcHRpb25zLFxuICAgICAgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IGJ1aWx0Py5mdW5jdGlvbkFzc29jaWF0aW9ucyA/PyBhZGRCZWhhdmlvck9wdGlvbnMuYmVoYXZpb3JPcHRpb25zPy5mdW5jdGlvbkFzc29jaWF0aW9ucyxcbiAgICAgIG9yaWdpblJlcXVlc3RQb2xpY3k6IGJ1aWx0Py5vcmlnaW5SZXF1ZXN0UG9saWN5ID8/IGFkZEJlaGF2aW9yT3B0aW9ucy5iZWhhdmlvck9wdGlvbnM/Lm9yaWdpblJlcXVlc3RQb2xpY3ksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRnVuY3Rpb25Bc3NvY2lhdGlvbnMoXG4gICAgZXh0ZW5zaW9ucz86IEV4dGVuc2lvbltdLFxuICAgIGNvbmZpZz86IEV4dGVuc2lvbkNvbmZpZzxUUm9sZT4sXG4gICk6IHsgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IGNsb3VkZnJvbnQuRnVuY3Rpb25Bc3NvY2lhdGlvbltdOyBvcmlnaW5SZXF1ZXN0UG9saWN5PzogY2xvdWRmcm9udC5PcmlnaW5SZXF1ZXN0UG9saWN5IH0gfCB1bmRlZmluZWQge1xuICAgIGlmICghZXh0ZW5zaW9ucyB8fCBleHRlbnNpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICAvLyBHZW5lcmF0ZSBjYWNoZSBrZXkgZm9yIHRoaXMgY29tYmluYXRpb24gb2YgZXh0ZW5zaW9ucyArIGNvbmZpZ1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gdGhpcy5nZW5lcmF0ZUZ1bmN0aW9uQ2FjaGVLZXkoZXh0ZW5zaW9ucywgY29uZmlnKTtcblxuICAgIC8vIENoZWNrIGlmIHdlIGFscmVhZHkgY3JlYXRlZCB0aGlzIGZ1bmN0aW9uXG4gICAgbGV0IGZ1bmMgPSB0aGlzLmNvbXBvc2VkRnVuY3Rpb25zLmdldChjYWNoZUtleSk7XG4gICAgaWYgKCFmdW5jKSB7XG4gICAgICAvLyBHZW5lcmF0ZSBjb21iaW5lZCBmdW5jdGlvbiBjb2RlIHdpdGggQXp1cmUgQUQgY29uZmlndXJhdGlvblxuICAgICAgY29uc3QgY29kZSA9IHRoaXMuZnVuY3Rpb25Db21wb3Nlci5jb21wb3NlKGV4dGVuc2lvbnMsIGNvbmZpZywge1xuICAgICAgICB0ZW5hbnRJZDogdGhpcy50ZW5hbnRJZCxcbiAgICAgICAgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWQsXG4gICAgICAgIHJlZGlyZWN0VXJpOiB0aGlzLnJlZGlyZWN0VXJpLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIENyZWF0ZSBDbG91ZEZyb250IEZ1bmN0aW9uXG4gICAgICBjb25zdCBmdW5jdGlvbklkID0gdGhpcy5nZW5lcmF0ZUZ1bmN0aW9uSWQoZXh0ZW5zaW9ucywgY29uZmlnKTtcblxuICAgICAgLy8gQWRkIEtWUyBpZiBhdXRoIGV4dGVuc2lvbiBpcyBpbmNsdWRlZFxuICAgICAgY29uc3QgZnVuY3Rpb25Qcm9wcyA9IGV4dGVuc2lvbnMuaW5jbHVkZXMoRXh0ZW5zaW9uLlJFUVVJUkVfQVVUSClcbiAgICAgICAgPyB7XG4gICAgICAgICAgY29kZTogY2xvdWRmcm9udC5GdW5jdGlvbkNvZGUuZnJvbUlubGluZShjb2RlKSxcbiAgICAgICAgICBydW50aW1lOiBjbG91ZGZyb250LkZ1bmN0aW9uUnVudGltZS5KU18yXzAsXG4gICAgICAgICAgY29tbWVudDogYENvbWJpbmVkOiAke2V4dGVuc2lvbnMuam9pbignLCAnKX1gLFxuICAgICAgICAgIGtleVZhbHVlU3RvcmU6IHRoaXMua3ZzLFxuICAgICAgICB9XG4gICAgICAgIDoge1xuICAgICAgICAgIGNvZGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25Db2RlLmZyb21JbmxpbmUoY29kZSksXG4gICAgICAgICAgcnVudGltZTogY2xvdWRmcm9udC5GdW5jdGlvblJ1bnRpbWUuSlNfMl8wLFxuICAgICAgICAgIGNvbW1lbnQ6IGBDb21iaW5lZDogJHtleHRlbnNpb25zLmpvaW4oJywgJyl9YCxcbiAgICAgICAgfTtcblxuICAgICAgZnVuYyA9IG5ldyBjbG91ZGZyb250LkZ1bmN0aW9uKHRoaXMsIGZ1bmN0aW9uSWQsIGZ1bmN0aW9uUHJvcHMpO1xuXG4gICAgICBpZiAodGhpcy5sYXN0Q3JlYXRlZEZ1bmN0aW9uKSB7XG4gICAgICAgIGZ1bmMubm9kZS5hZGREZXBlbmRlbmN5KHRoaXMubGFzdENyZWF0ZWRGdW5jdGlvbik7XG4gICAgICB9XG4gICAgICB0aGlzLmxhc3RDcmVhdGVkRnVuY3Rpb24gPSBmdW5jO1xuXG4gICAgICB0aGlzLmNvbXBvc2VkRnVuY3Rpb25zLnNldChjYWNoZUtleSwgZnVuYyk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiB7IGZ1bmN0aW9uQXNzb2NpYXRpb25zOiBjbG91ZGZyb250LkZ1bmN0aW9uQXNzb2NpYXRpb25bXTsgb3JpZ2luUmVxdWVzdFBvbGljeT86IGNsb3VkZnJvbnQuT3JpZ2luUmVxdWVzdFBvbGljeSB9ID0ge1xuICAgICAgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IFt7XG4gICAgICAgIGZ1bmN0aW9uOiBmdW5jLFxuICAgICAgICBldmVudFR5cGU6IGNsb3VkZnJvbnQuRnVuY3Rpb25FdmVudFR5cGUuVklFV0VSX1JFUVVFU1QsXG4gICAgICB9XSxcbiAgICB9O1xuXG4gICAgaWYgKGV4dGVuc2lvbnMuaW5jbHVkZXMoRXh0ZW5zaW9uLlJFUVVJUkVfVExTXzEzKSkge1xuICAgICAgcmVzdWx0Lm9yaWdpblJlcXVlc3RQb2xpY3kgPSB0aGlzLnRsc09yaWdpblJlcXVlc3RQb2xpY3k7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVGdW5jdGlvbkNhY2hlS2V5KGV4dGVuc2lvbnM6IEV4dGVuc2lvbltdLCBjb25maWc/OiBFeHRlbnNpb25Db25maWc8VFJvbGU+KTogc3RyaW5nIHtcbiAgICBjb25zdCBwYXJ0cyA9IFtleHRlbnNpb25zLnNvcnQoKS5qb2luKCcsJyldO1xuICAgIGlmIChjb25maWc/LnJlcXVpcmVkUm9sZXMpIHtcbiAgICAgIHBhcnRzLnB1c2goWy4uLmNvbmZpZy5yZXF1aXJlZFJvbGVzXS5zb3J0KCkuam9pbignLCcpKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZz8ucm9sZU1hdGNoTW9kZSAmJiBjb25maWcucm9sZU1hdGNoTW9kZSAhPT0gUm9sZU1hdGNoTW9kZS5PUikge1xuICAgICAgcGFydHMucHVzaChjb25maWcucm9sZU1hdGNoTW9kZSk7XG4gICAgfVxuICAgIHJldHVybiBwYXJ0cy5qb2luKCd8Jyk7XG4gIH1cblxuICBwcml2YXRlIGdlbmVyYXRlRnVuY3Rpb25JZChleHRlbnNpb25zOiBFeHRlbnNpb25bXSwgY29uZmlnPzogRXh0ZW5zaW9uQ29uZmlnPFRSb2xlPik6IHN0cmluZyB7XG4gICAgY29uc3QgZXh0ZW5zaW9uUGFydCA9IGV4dGVuc2lvbnMubWFwKGUgPT4gZS5yZXBsYWNlKCdSRVFVSVJFXycsICcnKSkuam9pbignJyk7XG4gICAgaWYgKGNvbmZpZz8ucmVxdWlyZWRSb2xlcyAmJiBjb25maWcucmVxdWlyZWRSb2xlcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCByb2xlSGFzaCA9IGNvbmZpZy5yZXF1aXJlZFJvbGVzLmpvaW4oJycpLnJlcGxhY2UoL1teYS16QS1aMC05XS9nLCAnJykuc3Vic3RyaW5nKDAsIDgpO1xuICAgICAgY29uc3QgbW9kZVBhcnQgPSBjb25maWcucm9sZU1hdGNoTW9kZSAmJiBjb25maWcucm9sZU1hdGNoTW9kZSAhPT0gUm9sZU1hdGNoTW9kZS5PUiA/IGNvbmZpZy5yb2xlTWF0Y2hNb2RlIDogJyc7XG4gICAgICByZXR1cm4gYENvbXBvc2VkRnVuY3Rpb24ke2V4dGVuc2lvblBhcnR9JHtyb2xlSGFzaH0ke21vZGVQYXJ0fWA7XG4gICAgfVxuICAgIHJldHVybiBgQ29tcG9zZWRGdW5jdGlvbiR7ZXh0ZW5zaW9uUGFydH1gO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXRlcm1pbmVSZWRpcmVjdFVyaShyZWRpcmVjdFVyaT86IHN0cmluZywgZG9tYWluTmFtZXM/OiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgaWYgKHJlZGlyZWN0VXJpKSB7XG4gICAgICByZXR1cm4gcmVkaXJlY3RVcmk7XG4gICAgfVxuICAgIGlmICghZG9tYWluTmFtZXMgfHwgZG9tYWluTmFtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciByZWRpcmVjdFVyaSBvciBkb21haW5OYW1lcyBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gICAgfVxuICAgIHJldHVybiBgaHR0cHM6Ly8ke2RvbWFpbk5hbWVzWzBdfS9vYXV0aDIvY2FsbGJhY2tgO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2FkQW5kUmVwbGFjZUF1dGhDaGVja0NvZGUodGVuYW50SWQ6IHN0cmluZywgY2xpZW50SWQ6IHN0cmluZywgcmVkaXJlY3RVcmk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgY29kZVBhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vY2xvdWRmcm9udC1mdW5jdGlvbnMvYXV0aC1jaGVjay5qcycpO1xuICAgIGxldCBjb2RlID0gZnMucmVhZEZpbGVTeW5jKGNvZGVQYXRoLCAndXRmLTgnKTtcbiAgICBjb2RlID0gY29kZS5yZXBsYWNlKCdURU5BTlRfSURfUExBQ0VIT0xERVInLCB0ZW5hbnRJZCk7XG4gICAgY29kZSA9IGNvZGUucmVwbGFjZSgnQ0xJRU5UX0lEX1BMQUNFSE9MREVSJywgY2xpZW50SWQpO1xuICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UoJ1JFRElSRUNUX1VSSV9QTEFDRUhPTERFUicsIHJlZGlyZWN0VXJpKTtcbiAgICByZXR1cm4gY29kZTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEFuZFJlcGxhY2VVc2VySW5mb0NvZGUobmFtZUZpZWxkczogc3RyaW5nW10pOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvZGVQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uL2Nsb3VkZnJvbnQtZnVuY3Rpb25zL3VzZXJpbmZvLWVuZHBvaW50LmpzJyk7XG4gICAgbGV0IGNvZGUgPSBmcy5yZWFkRmlsZVN5bmMoY29kZVBhdGgsICd1dGYtOCcpO1xuXG4gICAgLy8gUmVwbGFjZSB0aGUgbmFtZUZpZWxkcyBhcnJheSB3aXRoIHRoZSBwcm92aWRlZCBmaWVsZHNcbiAgICBjb25zdCBuYW1lRmllbGRzSnNvbiA9IEpTT04uc3RyaW5naWZ5KG5hbWVGaWVsZHMpO1xuICAgIGNvZGUgPSBjb2RlLnJlcGxhY2UoXG4gICAgICBcInZhciBuYW1lRmllbGRzID0gWydrZXkxJywgJ2tleTInLCAna2V5MyddO1wiLFxuICAgICAgYHZhciBuYW1lRmllbGRzID0gJHtuYW1lRmllbGRzSnNvbn07YCxcbiAgICApO1xuXG4gICAgcmV0dXJuIGNvZGU7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,9 @@
1
+ import * as constructs from 'constructs';
2
+ export interface SsmCrossRegionWriterProps {
3
+ readonly prefix: string;
4
+ readonly region: string;
5
+ readonly params: Record<string, string>;
6
+ }
7
+ export declare class SsmCrossRegionWriter extends constructs.Construct {
8
+ constructor(scope: constructs.Construct, id: string, props: SsmCrossRegionWriterProps);
9
+ }