cdk-serverless 2.22.5 → 3.1.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 (42) hide show
  1. package/.agents/tasks/task-api-gateway-authorizer/2025-01-20-120000-review.md +79 -0
  2. package/.agents/tasks/task-api-gateway-authorizer/context.json +25 -0
  3. package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-001.json +22 -0
  4. package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-002.json +31 -0
  5. package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-003.json +25 -0
  6. package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-004.json +24 -0
  7. package/.agents/tasks/task-api-gateway-authorizer/features/FEAT-005.json +22 -0
  8. package/.agents/tasks/task-api-gateway-authorizer/task.json +14 -0
  9. package/README.md +64 -0
  10. package/docs/constructs/assets/hierarchy.js +1 -1
  11. package/docs/constructs/assets/highlight.css +4 -4
  12. package/docs/constructs/assets/search.js +1 -1
  13. package/docs/constructs/classes/LambdaFunction.html +8 -8
  14. package/docs/constructs/classes/RestApi.html +22 -5
  15. package/docs/constructs/classes/SingleTableDatastore.html +1 -1
  16. package/docs/constructs/classes/Workflow.html +1 -1
  17. package/docs/constructs/hierarchy.html +1 -1
  18. package/docs/constructs/index.html +45 -1
  19. package/docs/constructs/interfaces/RestApiProps.html +39 -14
  20. package/docs/lambda/assets/highlight.css +9 -2
  21. package/docs/lambda/classes/errors.BadRequestError.html +1 -1
  22. package/docs/lambda/classes/errors.ForbiddenError.html +1 -1
  23. package/docs/lambda/classes/errors.HttpError.html +1 -1
  24. package/docs/lambda/classes/errors.NotFoundError.html +1 -1
  25. package/docs/lambda/classes/errors.UnauthenticatedError.html +1 -1
  26. package/docs/lambda/index.html +45 -1
  27. package/docs/projen/assets/highlight.css +13 -6
  28. package/docs/projen/index.html +45 -1
  29. package/docs/projen/interfaces/ServerlessProjectOptions.html +4 -4
  30. package/lib/constructs/rest-api.d.ts +88 -0
  31. package/lib/constructs/rest-api.js +194 -3
  32. package/lib/lambda/auth.js +10 -4
  33. package/lib/lambda/rest-api.jwt-authorizer.d.ts +1 -0
  34. package/lib/lambda/rest-api.jwt-authorizer.js +154 -0
  35. package/lib/tests/http-client.d.ts +48 -0
  36. package/lib/tests/http-client.js +82 -0
  37. package/lib/tests/index.d.ts +1 -0
  38. package/lib/tests/index.js +2 -1
  39. package/lib/tests/integ-test-util.d.ts +4 -3
  40. package/lib/tests/integ-test-util.js +14 -27
  41. package/package.json +1 -2
  42. package/specs/remove-axios-dependency.md +240 -0
@@ -297,7 +297,7 @@ this will be what your <code>package.json</code> will eventually include.</p>
297
297
 
298
298
  </div></div><aside class="tsd-sources"><p>Inherited from pj.awscdk.AwsCdkTypeScriptAppOptions.bunVersion</p></aside></section><section class="tsd-panel tsd-member tsd-is-inherited tsd-is-external"><h3 class="tsd-anchor-link" id="cdkassert"><code class="tsd-tag">Optional</code> <code class="tsd-tag">Readonly</code><span class="deprecated">cdk<wbr/>Assert</span><a href="#cdkassert" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">cdkAssert</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">boolean</span></div><div class="tsd-comment tsd-typography"><p>Warning: NodeJS only.
299
299
  Install the @aws-cdk/assert library?</p>
300
- </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-18">Default<a href="#default-18" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- </span><span class="hl-4">will</span><span class="hl-1"> </span><span class="hl-4">be</span><span class="hl-1"> </span><span class="hl-4">included</span><span class="hl-1"> </span><span class="hl-4">by</span><span class="hl-1"> </span><span class="hl-3">default</span><span class="hl-1"> </span><span class="hl-4">for</span><span class="hl-1"> </span><span class="hl-7">AWS</span><span class="hl-1"> </span><span class="hl-7">CDK</span><span class="hl-1"> &gt;= </span><span class="hl-8">1.0</span><span class="hl-1">.</span><span class="hl-8">0</span><span class="hl-1"> &lt; </span><span class="hl-8">2.0</span><span class="hl-1">.</span><span class="hl-8">0</span>
300
+ </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-18">Default<a href="#default-18" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- </span><span class="hl-4">will</span><span class="hl-1"> </span><span class="hl-4">be</span><span class="hl-1"> </span><span class="hl-4">included</span><span class="hl-1"> </span><span class="hl-4">by</span><span class="hl-1"> </span><span class="hl-3">default</span><span class="hl-1"> </span><span class="hl-4">for</span><span class="hl-1"> </span><span class="hl-7">AWS</span><span class="hl-1"> </span><span class="hl-7">CDK</span><span class="hl-1"> &gt;= </span><span class="hl-9">1.0</span><span class="hl-1">.</span><span class="hl-9">0</span><span class="hl-1"> &lt; </span><span class="hl-9">2.0</span><span class="hl-1">.</span><span class="hl-9">0</span>
301
301
  </code><button type="button">Copy</button></pre>
302
302
 
303
303
  </div><div class="tsd-tag-deprecated"><h4 class="tsd-anchor-link" id="deprecated-1">Deprecated<a href="#deprecated-1" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><p>The @aws-cdk/assert library is deprecated in favor of
@@ -305,7 +305,7 @@ Install the @aws-cdk/assert library?</p>
305
305
  </div></div><aside class="tsd-sources"><p>Inherited from pj.awscdk.AwsCdkTypeScriptAppOptions.cdkAssert</p></aside></section><section class="tsd-panel tsd-member tsd-is-inherited tsd-is-external"><h3 class="tsd-anchor-link" id="cdkassertions"><code class="tsd-tag">Optional</code> <code class="tsd-tag">Readonly</code><span>cdk<wbr/>Assertions</span><a href="#cdkassertions" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">cdkAssertions</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">boolean</span></div><div class="tsd-comment tsd-typography"><p>Install the assertions library?</p>
306
306
  <p>Only needed for CDK 1.x. If using CDK 2.x then
307
307
  assertions is already included in 'aws-cdk-lib'</p>
308
- </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-19">Default<a href="#default-19" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- </span><span class="hl-4">will</span><span class="hl-1"> </span><span class="hl-4">be</span><span class="hl-1"> </span><span class="hl-4">included</span><span class="hl-1"> </span><span class="hl-4">by</span><span class="hl-1"> </span><span class="hl-3">default</span><span class="hl-1"> </span><span class="hl-4">for</span><span class="hl-1"> </span><span class="hl-7">AWS</span><span class="hl-1"> </span><span class="hl-7">CDK</span><span class="hl-1"> &gt;= </span><span class="hl-8">1.111</span><span class="hl-1">.</span><span class="hl-8">0</span><span class="hl-1"> &lt; </span><span class="hl-8">2.0</span><span class="hl-1">.</span><span class="hl-8">0</span>
308
+ </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-19">Default<a href="#default-19" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- </span><span class="hl-4">will</span><span class="hl-1"> </span><span class="hl-4">be</span><span class="hl-1"> </span><span class="hl-4">included</span><span class="hl-1"> </span><span class="hl-4">by</span><span class="hl-1"> </span><span class="hl-3">default</span><span class="hl-1"> </span><span class="hl-4">for</span><span class="hl-1"> </span><span class="hl-7">AWS</span><span class="hl-1"> </span><span class="hl-7">CDK</span><span class="hl-1"> &gt;= </span><span class="hl-9">1.111</span><span class="hl-1">.</span><span class="hl-9">0</span><span class="hl-1"> &lt; </span><span class="hl-9">2.0</span><span class="hl-1">.</span><span class="hl-9">0</span>
309
309
  </code><button type="button">Copy</button></pre>
310
310
 
311
311
  </div></div><aside class="tsd-sources"><p>Inherited from pj.awscdk.AwsCdkTypeScriptAppOptions.cdkAssertions</p></aside></section><section class="tsd-panel tsd-member tsd-is-inherited tsd-is-external"><h3 class="tsd-anchor-link" id="cdkcliversion"><code class="tsd-tag">Optional</code> <code class="tsd-tag">Readonly</code><span>cdk<wbr/>Cli<wbr/>Version</span><a href="#cdkcliversion" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">cdkCliVersion</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>Version range of the AWS CDK CLI to depend on.</p>
@@ -483,7 +483,7 @@ manually add an <code>awscdk.AutoDiscover</code> component to your project.</p>
483
483
  </code><button type="button">Copy</button></pre>
484
484
 
485
485
  </div></div><aside class="tsd-sources"><p>Inherited from pj.awscdk.AwsCdkTypeScriptAppOptions.entrypoint</p></aside></section><section class="tsd-panel tsd-member tsd-is-inherited tsd-is-external"><h3 class="tsd-anchor-link" id="entrypointtypes"><code class="tsd-tag">Optional</code> <code class="tsd-tag">Readonly</code><span>entrypoint<wbr/>Types</span><a href="#entrypointtypes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">entrypointTypes</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>The .d.ts file that includes the type declarations for this module.</p>
486
- </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-49">Default<a href="#default-49" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- .</span><span class="hl-4">d</span><span class="hl-1">.</span><span class="hl-4">ts</span><span class="hl-1"> </span><span class="hl-4">file</span><span class="hl-1"> </span><span class="hl-4">derived</span><span class="hl-1"> </span><span class="hl-4">from</span><span class="hl-1"> </span><span class="hl-4">the</span><span class="hl-1"> </span><span class="hl-4">project</span><span class="hl-2">&#39;s entrypoint (usually lib/index.d.ts</span><span class="hl-9">)</span>
486
+ </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-49">Default<a href="#default-49" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- .</span><span class="hl-4">d</span><span class="hl-1">.</span><span class="hl-4">ts</span><span class="hl-1"> </span><span class="hl-4">file</span><span class="hl-1"> </span><span class="hl-4">derived</span><span class="hl-1"> </span><span class="hl-4">from</span><span class="hl-1"> </span><span class="hl-4">the</span><span class="hl-1"> </span><span class="hl-4">project</span><span class="hl-2">&#39;s entrypoint (usually lib/index.d.ts</span><span class="hl-10">)</span>
487
487
  </code><button type="button">Copy</button></pre>
488
488
 
489
489
  </div></div><aside class="tsd-sources"><p>Inherited from pj.awscdk.AwsCdkTypeScriptAppOptions.entrypointTypes</p></aside></section><section class="tsd-panel tsd-member tsd-is-inherited tsd-is-external"><h3 class="tsd-anchor-link" id="eslint"><code class="tsd-tag">Optional</code> <code class="tsd-tag">Readonly</code><span>eslint</span><a href="#eslint" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">eslint</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">boolean</span></div><div class="tsd-comment tsd-typography"><p>Setup eslint.</p>
@@ -839,7 +839,7 @@ in order to create a publishing task for each publishing activity.</p>
839
839
  </code><button type="button">Copy</button></pre>
840
840
 
841
841
  </div></div><aside class="tsd-sources"><p>Inherited from pj.awscdk.AwsCdkTypeScriptAppOptions.pullRequestTemplateContents</p></aside></section><section class="tsd-panel tsd-member tsd-is-inherited tsd-is-external"><h3 class="tsd-anchor-link" id="readme"><code class="tsd-tag">Optional</code> <code class="tsd-tag">Readonly</code><span>readme</span><a href="#readme" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">readme</span><span class="tsd-signature-symbol">?:</span> <span class="tsd-signature-type">SampleReadmeProps</span></div><div class="tsd-comment tsd-typography"><p>The README setup.</p>
842
- </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-110">Default<a href="#default-110" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- { </span><span class="hl-10">filename</span><span class="hl-1">: </span><span class="hl-2">&#39;README.md&#39;</span><span class="hl-1">, </span><span class="hl-10">contents</span><span class="hl-1">: </span><span class="hl-2">&#39;# replace this&#39;</span><span class="hl-1"> }</span>
842
+ </div><div class="tsd-comment tsd-typography"><div class="tsd-tag-default"><h4 class="tsd-anchor-link" id="default-110">Default<a href="#default-110" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-1">- { </span><span class="hl-11">filename</span><span class="hl-1">: </span><span class="hl-2">&#39;README.md&#39;</span><span class="hl-1">, </span><span class="hl-11">contents</span><span class="hl-1">: </span><span class="hl-2">&#39;# replace this&#39;</span><span class="hl-1"> }</span>
843
843
  </code><button type="button">Copy</button></pre>
844
844
 
845
845
  </div><div class="tsd-tag-example"><h4 class="tsd-anchor-link" id="example-2">Example<a href="#example-2" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h4><pre><code class="ts"><span class="hl-2">&quot;{ filename: &#39;readme.md&#39;, contents: &#39;# title&#39; }&quot;</span>
@@ -26,6 +26,36 @@ export interface RestApiProps<OPS> extends BaseApiProps {
26
26
  };
27
27
  definitionFileName: string;
28
28
  cors: boolean;
29
+ /**
30
+ * A list of operation IDs that should skip the authorizer entirely.
31
+ * These operations will have `security: []` in the OpenAPI spec, meaning
32
+ * they are publicly accessible without authentication.
33
+ *
34
+ * @default - no anonymous operations
35
+ */
36
+ anonymousOperations?: (keyof OPS)[];
37
+ /**
38
+ * Controls whether the JWT Lambda authorizer uses the TOKEN or REQUEST type.
39
+ *
40
+ * **token (default):** The API Gateway validates that the Authorization header is present
41
+ * before invoking the Lambda authorizer. If the header is missing, API Gateway immediately
42
+ * returns 401 without invoking the Lambda. This is cheaper for unauthenticated requests
43
+ * because no Lambda invocation occurs, but it does not support optional authentication
44
+ * (every request must carry a token or be rejected).
45
+ *
46
+ * **request:** The API Gateway always invokes the Lambda authorizer regardless of whether
47
+ * the Authorization header is present. This enables optional authentication: the Lambda
48
+ * can inspect the request, return Allow with an anonymous principal when no token is
49
+ * provided, and return Allow with user claims when a valid token is present. The trade-off
50
+ * is that you pay for a Lambda invocation on every request, including unauthenticated ones.
51
+ *
52
+ * Use 'request' when you need endpoints that behave differently for authenticated vs
53
+ * anonymous users (e.g., personalized responses for logged-in users, generic responses
54
+ * for guests) without splitting them into separate operations.
55
+ *
56
+ * @default 'token'
57
+ */
58
+ jwtAuthorizerType?: 'token' | 'request';
29
59
  }
30
60
  /**
31
61
  * The RestApi construct sets up an AWS API Gateway REST API using OpenAPI specification.
@@ -66,6 +96,25 @@ export declare class RestApi<PATHS, OPS> extends BaseApi {
66
96
  * @private
67
97
  */
68
98
  private _functions;
99
+ private readonly apiMethods;
100
+ /**
101
+ * The JWT authorizer Lambda function, if JWT authentication is configured.
102
+ * Stored so the invoke permission can be granted after the SpecRestApi is created.
103
+ * @private
104
+ */
105
+ private _authorizerFn?;
106
+ /**
107
+ * Set of operationIds that should have security disabled (security: []).
108
+ * @private
109
+ */
110
+ private _anonymousOperations;
111
+ /**
112
+ * Stores the original per-operation security arrays as assigned by patchSecurity,
113
+ * keyed by operationId. Used by setAnonymousOperations to restore security on
114
+ * operations removed from the anonymous set.
115
+ * @private
116
+ */
117
+ private _originalOperationSecurity;
69
118
  /**
70
119
  * Creates an instance of RestApi.
71
120
  *
@@ -94,9 +143,48 @@ export declare class RestApi<PATHS, OPS> extends BaseApi {
94
143
  * @param op the function to call for every function
95
144
  */
96
145
  modifyOperationFunctions(operationIds: (keyof OPS)[], op: (fn: LambdaFunction) => void): void;
146
+ /**
147
+ * Replace the full set of anonymous operations.
148
+ * Anonymous operations will have `security: []` applied in the OpenAPI spec,
149
+ * making them publicly accessible without authentication.
150
+ *
151
+ * Since CDK serializes the OpenAPI spec at synth time (fromInline stores the
152
+ * object reference), mutations after SpecRestApi construction still take effect.
153
+ *
154
+ * @param operationIds - The operation IDs to mark as anonymous. Replaces any previously set anonymous operations.
155
+ */
156
+ setAnonymousOperations(operationIds: (keyof OPS)[]): void;
157
+ /**
158
+ * Add additional operations to the set of anonymous operations.
159
+ * Newly added operations will have `security: []` applied in the OpenAPI spec.
160
+ *
161
+ * Since CDK serializes the OpenAPI spec at synth time (fromInline stores the
162
+ * object reference), mutations after SpecRestApi construction still take effect.
163
+ *
164
+ * @param operationIds - The operation IDs to add to the anonymous set.
165
+ */
166
+ addAnonymousOperations(operationIds: (keyof OPS)[]): void;
167
+ /**
168
+ * Re-applies security settings to all operations based on the current anonymous set.
169
+ * Operations in the anonymous set get `security: []`; operations removed from the set
170
+ * have their original security restored.
171
+ * @private
172
+ */
173
+ private applyAnonymousSecurity;
174
+ /**
175
+ * Applies `security: []` only to the specified operations.
176
+ * @private
177
+ */
178
+ private applyAnonymousSecurityForOps;
97
179
  addRestResource<P extends keyof PATHS>(path: P, method: keyof PATHS[P]): LambdaFunction | undefined;
98
180
  addCustomRestResource(operation: OperationObject, method: string, description: string, additionalLambdaOptions?: LambdaOptions): LambdaFunction | undefined;
99
181
  private tableWriteAccessForMethod;
182
+ /**
183
+ * Injects securityDefinitions into the OpenAPI spec based on the authentication type.
184
+ * For Cognito: adds a cognito_user_pools authorizer referencing the user pool ARN.
185
+ * For JWT: creates a Lambda authorizer function and adds a token authorizer referencing its ARN.
186
+ */
187
+ protected patchSecuritySchemes(spec: OpenAPI3): void;
100
188
  /**
101
189
  * AWS does not properly apply the 'security' option to every single path-method.
102
190
  * According to documentation, global security gets applied, if there is no security
@@ -81,6 +81,19 @@ class RestApi extends base_api_1.BaseApi {
81
81
  * @private
82
82
  */
83
83
  this._functions = {};
84
+ this.apiMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];
85
+ /**
86
+ * Set of operationIds that should have security disabled (security: []).
87
+ * @private
88
+ */
89
+ this._anonymousOperations = new Set();
90
+ /**
91
+ * Stores the original per-operation security arrays as assigned by patchSecurity,
92
+ * keyed by operationId. Used by setAnonymousOperations to restore security on
93
+ * operations removed from the anonymous set.
94
+ * @private
95
+ */
96
+ this._originalOperationSecurity = new Map();
84
97
  this.apiSpec = yaml.load(fs.readFileSync(props.definitionFileName).toString());
85
98
  let customDomainName;
86
99
  if (this.apiFQDN) {
@@ -208,6 +221,13 @@ class RestApi extends base_api_1.BaseApi {
208
221
  },
209
222
  };
210
223
  }
224
+ this.patchSecuritySchemes(this.apiSpec);
225
+ // Initialize anonymous operations from props before patchSecurity distributes security
226
+ if (props.anonymousOperations) {
227
+ for (const opId of props.anonymousOperations) {
228
+ this._anonymousOperations.add(opId);
229
+ }
230
+ }
211
231
  this.patchSecurity(this.apiSpec);
212
232
  // TODO patch spec for Cognito user pool
213
233
  this.api = new aws_cdk_lib_1.aws_apigateway.SpecRestApi(this, 'Resource', {
@@ -224,6 +244,14 @@ class RestApi extends base_api_1.BaseApi {
224
244
  sourceArn: this.api.arnForExecuteApi(),
225
245
  });
226
246
  }
247
+ // Grant API Gateway permission to invoke the JWT authorizer Lambda
248
+ if (this._authorizerFn) {
249
+ this._authorizerFn.addPermission('ApiGatewayAuthorizerInvoke', {
250
+ principal: new aws_cdk_lib_1.aws_iam.ServicePrincipal('apigateway.amazonaws.com'),
251
+ action: 'lambda:InvokeFunction',
252
+ sourceArn: this.api.arnForExecuteApi(),
253
+ });
254
+ }
227
255
  if (customDomainName && this.api.domainName) {
228
256
  new aws_cdk_lib_1.aws_route53.ARecord(this, 'DnsRecord', {
229
257
  zone: this.hostedZone,
@@ -266,6 +294,79 @@ class RestApi extends base_api_1.BaseApi {
266
294
  op(this.getFunctionForOperation(operationId));
267
295
  }
268
296
  }
297
+ /**
298
+ * Replace the full set of anonymous operations.
299
+ * Anonymous operations will have `security: []` applied in the OpenAPI spec,
300
+ * making them publicly accessible without authentication.
301
+ *
302
+ * Since CDK serializes the OpenAPI spec at synth time (fromInline stores the
303
+ * object reference), mutations after SpecRestApi construction still take effect.
304
+ *
305
+ * @param operationIds - The operation IDs to mark as anonymous. Replaces any previously set anonymous operations.
306
+ */
307
+ setAnonymousOperations(operationIds) {
308
+ this._anonymousOperations.clear();
309
+ for (const opId of operationIds) {
310
+ this._anonymousOperations.add(opId);
311
+ }
312
+ this.applyAnonymousSecurity();
313
+ }
314
+ /**
315
+ * Add additional operations to the set of anonymous operations.
316
+ * Newly added operations will have `security: []` applied in the OpenAPI spec.
317
+ *
318
+ * Since CDK serializes the OpenAPI spec at synth time (fromInline stores the
319
+ * object reference), mutations after SpecRestApi construction still take effect.
320
+ *
321
+ * @param operationIds - The operation IDs to add to the anonymous set.
322
+ */
323
+ addAnonymousOperations(operationIds) {
324
+ for (const opId of operationIds) {
325
+ this._anonymousOperations.add(opId);
326
+ }
327
+ this.applyAnonymousSecurityForOps(operationIds.map(op => op));
328
+ }
329
+ /**
330
+ * Re-applies security settings to all operations based on the current anonymous set.
331
+ * Operations in the anonymous set get `security: []`; operations removed from the set
332
+ * have their original security restored.
333
+ * @private
334
+ */
335
+ applyAnonymousSecurity() {
336
+ for (const specPath of Object.values(this.apiSpec.paths || [])) {
337
+ for (const key in specPath) {
338
+ if (!this.apiMethods.includes(key)) {
339
+ continue;
340
+ }
341
+ const specMethod = specPath[key];
342
+ if (specMethod.operationId && this._anonymousOperations.has(specMethod.operationId)) {
343
+ specMethod.security = [];
344
+ }
345
+ else if (specMethod.operationId && this._originalOperationSecurity.has(specMethod.operationId)) {
346
+ // Restore original security for operations removed from the anonymous set
347
+ specMethod.security = this._originalOperationSecurity.get(specMethod.operationId);
348
+ }
349
+ }
350
+ }
351
+ }
352
+ /**
353
+ * Applies `security: []` only to the specified operations.
354
+ * @private
355
+ */
356
+ applyAnonymousSecurityForOps(operationIds) {
357
+ const opsSet = new Set(operationIds);
358
+ for (const specPath of Object.values(this.apiSpec.paths || [])) {
359
+ for (const key in specPath) {
360
+ if (!this.apiMethods.includes(key)) {
361
+ continue;
362
+ }
363
+ const specMethod = specPath[key];
364
+ if (specMethod.operationId && opsSet.has(specMethod.operationId)) {
365
+ specMethod.security = [];
366
+ }
367
+ }
368
+ }
369
+ }
269
370
  addRestResource(path, method) {
270
371
  const oaPath = this.apiSpec.paths[path];
271
372
  const operation = oaPath[method];
@@ -349,6 +450,79 @@ class RestApi extends base_api_1.BaseApi {
349
450
  return false;
350
451
  }
351
452
  }
453
+ /**
454
+ * Injects securityDefinitions into the OpenAPI spec based on the authentication type.
455
+ * For Cognito: adds a cognito_user_pools authorizer referencing the user pool ARN.
456
+ * For JWT: creates a Lambda authorizer function and adds a token authorizer referencing its ARN.
457
+ */
458
+ patchSecuritySchemes(spec) {
459
+ if (!this.props.authentication) {
460
+ return;
461
+ }
462
+ const specAny = spec;
463
+ if (!specAny.securityDefinitions) {
464
+ specAny.securityDefinitions = {};
465
+ }
466
+ if (this.props.authentication.hasOwnProperty('userpool')) {
467
+ // Cognito User Pool authorizer
468
+ const cognitoAuth = this.props.authentication;
469
+ const authorizerName = 'CognitoAuthorizer';
470
+ specAny.securityDefinitions[authorizerName] = {
471
+ 'type': 'apiKey',
472
+ 'name': 'Authorization',
473
+ 'in': 'header',
474
+ 'x-amazon-apigateway-authtype': 'cognito_user_pools',
475
+ 'x-amazon-apigateway-authorizer': {
476
+ type: 'cognito_user_pools',
477
+ providerARNs: [cognitoAuth.userpool.userPoolArn],
478
+ },
479
+ };
480
+ // Ensure global security references the authorizer so patchSecurity distributes it
481
+ if (!spec.security) {
482
+ spec.security = [{ [authorizerName]: [] }];
483
+ }
484
+ }
485
+ else {
486
+ // JWT (Lambda) authorizer
487
+ const jwtAuth = this.props.authentication;
488
+ const authorizerName = 'JwtAuthorizer';
489
+ const authorizerFn = new func_1.LambdaFunction(this, 'JwtAuthorizerFn', {
490
+ stageName: this.props.stageName,
491
+ entry: 'src/lambda/rest-api.jwt-authorizer.ts',
492
+ description: `[${this.props.stageName}] JWT Authorizer for ${this.props.apiName}`,
493
+ jwt: jwtAuth,
494
+ lambdaOptions: this.props.lambdaOptions,
495
+ lambdaTracing: this.props.lambdaTracing,
496
+ });
497
+ const authorizerUri = cdk.Stack.of(this).formatArn({
498
+ resource: 'path',
499
+ service: 'apigateway',
500
+ account: 'lambda',
501
+ arnFormat: cdk.ArnFormat.SLASH_RESOURCE_NAME,
502
+ resourceName: `2015-03-31/functions/${authorizerFn.functionArn}/invocations`,
503
+ });
504
+ specAny.securityDefinitions[authorizerName] = {
505
+ 'type': 'apiKey',
506
+ 'name': 'Authorization',
507
+ 'in': 'header',
508
+ 'x-amazon-apigateway-authtype': 'custom',
509
+ 'x-amazon-apigateway-authorizer': {
510
+ type: this.props.jwtAuthorizerType === 'request' ? 'request' : 'token',
511
+ authorizerUri: authorizerUri,
512
+ authorizerResultTtlInSeconds: this.props.jwtAuthorizerType === 'request' ? 0 : 300,
513
+ ...(this.props.jwtAuthorizerType !== 'request' && {
514
+ identitySource: 'method.request.header.Authorization',
515
+ }),
516
+ },
517
+ };
518
+ // Store the authorizer function so we can grant permission after the SpecRestApi is created
519
+ this._authorizerFn = authorizerFn;
520
+ // Ensure global security references the authorizer so patchSecurity distributes it
521
+ if (!spec.security) {
522
+ spec.security = [{ [authorizerName]: [] }];
523
+ }
524
+ }
525
+ }
352
526
  /**
353
527
  * AWS does not properly apply the 'security' option to every single path-method.
354
528
  * According to documentation, global security gets applied, if there is no security
@@ -362,13 +536,30 @@ class RestApi extends base_api_1.BaseApi {
362
536
  if ('security' in spec) {
363
537
  for (const specPath of Object.values(spec.paths || [])) {
364
538
  for (const key in specPath) {
365
- // @ts-expect-error -> There is a wrong definition for method includes! It allows any value to be given!
366
539
  if (!this.apiMethods.includes(key)) {
367
540
  continue; // Skip if not http method definition
368
541
  }
369
542
  const specMethod = specPath[key];
370
543
  if (!('security' in specMethod)) {
371
- specMethod.security = spec.security;
544
+ const operationId = specMethod.operationId;
545
+ if (operationId && this._anonymousOperations.has(operationId)) {
546
+ // Store what security would have been applied so we can restore later
547
+ this._originalOperationSecurity.set(operationId, spec.security);
548
+ specMethod.security = [];
549
+ }
550
+ else {
551
+ specMethod.security = spec.security;
552
+ if (operationId) {
553
+ this._originalOperationSecurity.set(operationId, spec.security);
554
+ }
555
+ }
556
+ }
557
+ else {
558
+ // Operation already has explicit security defined in the spec
559
+ const operationId = specMethod.operationId;
560
+ if (operationId) {
561
+ this._originalOperationSecurity.set(operationId, specMethod.security);
562
+ }
372
563
  }
373
564
  }
374
565
  }
@@ -377,4 +568,4 @@ class RestApi extends base_api_1.BaseApi {
377
568
  }
378
569
  }
379
570
  exports.RestApi = RestApi;
380
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9yZXN0LWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw0Q0FBOEI7QUFDOUIsNkNBTXFCO0FBQ3JCLGlEQUFtQztBQUVuQyw4Q0FBZ0M7QUFHaEMseUNBQW1EO0FBQ25ELGlDQUF1RDtBQUN2RCwrQ0FBd0c7QUE4QnhHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUNILE1BQWEsT0FBb0IsU0FBUSxrQkFBTztJQWtCOUM7Ozs7OztPQU1HO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBVSxLQUF3QjtRQUN4RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUR3QixVQUFLLEdBQUwsS0FBSyxDQUFtQjtRQWIxRTs7O1dBR0c7UUFDSyxlQUFVLEdBQThDLEVBQUUsQ0FBQztRQVlqRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBYSxDQUFDO1FBRTNGLElBQUksZ0JBQThELENBQUM7UUFDbkUsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsZ0JBQWdCLEdBQUc7Z0JBQ2pCLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTztnQkFDeEIsV0FBVyxFQUFFLElBQUksb0NBQXNCLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUU7b0JBQ2hFLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTztvQkFDeEIsVUFBVSxFQUFFLG9DQUFzQixDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO2lCQUNsRixDQUFDO2FBQ0gsQ0FBQztZQUNGLElBQUks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TztnQkFDVixPQUFPLElBQUksQ0FBQztZQUNkLEtBQUssU0FBUyxDQUFDO1lBQ2YsS0FBSyxLQUFLLENBQUM7WUFDWCxLQUFLLE1BQU0sQ0FBQztZQUNaO2dCQUNFLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTyxhQUFhLENBQUMsSUFBYztRQUNwQyxJQUFJLFVBQVUsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixLQUFLLE1BQU0sUUFBUSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUN2RCxLQUFLLE1BQU0sR0FBRyxJQUFJLFFBQVEsRUFBRSxDQUFDO29CQUMzQix3R0FBd0c7b0JBQ3hHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO3dCQUNuQyxTQUFTLENBQUMscUNBQXFDO29CQUNqRCxDQUFDO29CQUVELE1BQU0sVUFBVSxHQUFJLFFBQTJCLENBQUMsR0FBMkIsQ0FBRSxDQUFDO29CQUM5RSxJQUFJLENBQUMsQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQzt3QkFDaEMsVUFBVSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO29CQUN0QyxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBQ0QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3ZCLENBQUM7SUFDSCxDQUFDO0NBRUY7QUFuV0QsMEJBbVdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQge1xuICBhd3NfY2VydGlmaWNhdGVtYW5hZ2VyLFxuICBhd3NfaWFtLFxuICBhd3Nfcm91dGU1MyxcbiAgYXdzX3JvdXRlNTNfdGFyZ2V0cyxcbiAgYXdzX2FwaWdhdGV3YXksXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAnanMteWFtbCc7XG5pbXBvcnQgeyBPcGVuQVBJMywgT3BlcmF0aW9uT2JqZWN0LCBQYXRoSXRlbU9iamVjdCB9IGZyb20gJ29wZW5hcGktdHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBJQ29nbml0b0F1dGhlbnRpY2F0aW9uLCBJSnd0QXV0aGVudGljYXRpb24gfSBmcm9tICcuL2F1dGhlbnRpY2F0aW9uJztcbmltcG9ydCB7IEJhc2VBcGksIEJhc2VBcGlQcm9wcyB9IGZyb20gJy4vYmFzZS1hcGknO1xuaW1wb3J0IHsgTGFtYmRhRnVuY3Rpb24sIExhbWJkYU9wdGlvbnMgfSBmcm9tICcuL2Z1bmMnO1xuaW1wb3J0IHsgQ0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9ET01BSU5OQU1FLCBDRk5fT1VUUFVUX1NVRkZJWF9SRVNUQVBJX1VSTCB9IGZyb20gJy4uL3NoYXJlZC9vdXRwdXRzJztcblxuZXhwb3J0IGludGVyZmFjZSBSZXN0QXBpUHJvcHM8T1BTPiBleHRlbmRzIEJhc2VBcGlQcm9wcyB7XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHJvdXRlcyBmb3IgYWxsIGVuZHBvaW50cyBjb25maWd1cmVkIGluIHRoZSBvcGVuYXBpLnlhbWwgZmlsZVxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBhdXRvR2VuZXJhdGVSb3V0ZXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBjdXN0b20gb3B0aW9ucyBmb3IgdGhlIGNyZWF0ZWQgSHR0cEFwaVxuICAgKlxuICAgKiBAZGVmYXVsdCAtXG4gICAqL1xuICByZXN0QXBpUHJvcHM/OiBhd3NfYXBpZ2F0ZXdheS5SZXN0QXBpQmFzZVByb3BzO1xuXG4gIC8qKlxuICAgKiBhZGRpdGlvbmFsIG9wdGlvbnMgZm9yIHRoZSB1bmRlcmx5aW5nIExhbWJkYSBmdW5jdGlvbiBjb25zdHJ1Y3QgcGVyIG9wZXJhdGlvbklkXG4gICAqXG4gICAqIEBkZWZhdWx0IC1cbiAgICovXG4gIGxhbWJkYU9wdGlvbnNCeU9wZXJhdGlvbj86IHsgW29wZXJhdGlvbklkIGluIGtleW9mIE9QU10/OiBMYW1iZGFPcHRpb25zIH07XG5cbiAgZGVmaW5pdGlvbkZpbGVOYW1lOiBzdHJpbmc7XG5cbiAgY29yczogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBUaGUgUmVzdEFwaSBjb25zdHJ1Y3Qgc2V0cyB1cCBhbiBBV1MgQVBJIEdhdGV3YXkgUkVTVCBBUEkgdXNpbmcgT3BlbkFQSSBzcGVjaWZpY2F0aW9uLlxuICogVGhpcyBjb25zdHJ1Y3QgZmFjaWxpdGF0ZXMgdGhlIGNyZWF0aW9uIG9mIGEgUkVTVCBBUEkgd2l0aCB2YXJpb3VzIGNvbmZpZ3VyYXRpb25zLCBpbmNsdWRpbmcgY3VzdG9tIGRvbWFpbiwgQ09SUyBzdXBwb3J0LCBhbmQgaW50ZWdyYXRpb24gd2l0aCBMYW1iZGEgZnVuY3Rpb25zLlxuICogSXQgYWxsb3dzIGF1dG8tZ2VuZXJhdGluZyByb3V0ZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIE9wZW5BUEkgZGVmaW5pdGlvbiBhbmQgcHJvdmlkZXMgbWV0aG9kcyB0byBkeW5hbWljYWxseSBhZGQgY3VzdG9tIHJvdXRlcyBhbmQgbWFuYWdlIExhbWJkYSBmdW5jdGlvbiBpbnRlZ3JhdGlvbnMuXG4gKlxuICogQHRlbXBsYXRlIFBBVEhTIC0gVGhlIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIEFQSSBwYXRocy5cbiAqIEB0ZW1wbGF0ZSBPUFMgLSBUaGUgdHlwZSBkZWZpbml0aW9uIGZvciB0aGUgQVBJIG9wZXJhdGlvbnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGFwaSA9IG5ldyBSZXN0QXBpKHRoaXMsICdNeVJlc3RBcGknLCB7XG4gKiAgIGFwaU5hbWU6ICdNeUFQSScsXG4gKiAgIHN0YWdlTmFtZTogJ2RldicsXG4gKiAgIGRlZmluaXRpb25GaWxlTmFtZTogJ29wZW5hcGkueWFtbCcsXG4gKiAgIGF1dGhlbnRpY2F0aW9uOiBteUNvZ25pdG9BdXRoLFxuICogICBzaW5nbGVUYWJsZURhdGFzdG9yZTogbXlEeW5hbW9EQlRhYmxlLFxuICogICBhdXRvR2VuZXJhdGVSb3V0ZXM6IHRydWUsXG4gKiB9KTtcbiAqXG4gKiAvLyBBZGQgYSBjdXN0b20gUkVTVCByZXNvdXJjZVxuICogYXBpLmFkZFJlc3RSZXNvdXJjZSgnL2l0ZW1zJywgJ2dldCcpO1xuICpcbiAqIC8vIEdldCB0aGUgTGFtYmRhIGZ1bmN0aW9uIGZvciBhIHNwZWNpZmljIG9wZXJhdGlvblxuICogY29uc3QgbGFtYmRhRnVuY3Rpb24gPSBhcGkuZ2V0RnVuY3Rpb25Gb3JPcGVyYXRpb24oJ2dldEl0ZW1zJyk7XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXN0QXBpPFBBVEhTLCBPUFM+IGV4dGVuZHMgQmFzZUFwaSB7XG5cbiAgLyoqXG4gICAqIFRoZSBBV1MgQVBJIEdhdGV3YXkgUkVTVCBBUEkgaW5zdGFuY2UuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXBpOiBhd3NfYXBpZ2F0ZXdheS5TcGVjUmVzdEFwaTtcblxuICAvKipcbiAgICogVGhlIE9wZW5BUEkgc3BlY2lmaWNhdGlvbiBmb3IgdGhlIFJFU1QgQVBJLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwaVNwZWM6IE9wZW5BUEkzO1xuXG4gIC8qKlxuICAgKiBBIGNvbGxlY3Rpb24gb2YgTGFtYmRhIGZ1bmN0aW9ucyB1c2VkIGFzIGludGVncmF0aW9ucyBmb3IgdGhlIEFQSSBvcGVyYXRpb25zLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfZnVuY3Rpb25zOiB7IFtvcGVyYXRpb25JZDogc3RyaW5nXTogTGFtYmRhRnVuY3Rpb24gfSA9IHt9O1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFJlc3RBcGkuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSAtIFRoZSBzY29wZSBpbiB3aGljaCB0aGlzIGNvbnN0cnVjdCBpcyBkZWZpbmVkLlxuICAgKiBAcGFyYW0gaWQgLSBUaGUgc2NvcGVkIGNvbnN0cnVjdCBJRC5cbiAgICogQHBhcmFtIHByb3BzIC0gVGhlIHByb3BlcnRpZXMgb2YgdGhlIFJlc3RBcGkgY29uc3RydWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJpdmF0ZSBwcm9wczogUmVzdEFwaVByb3BzPE9QUz4pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHByb3BzKTtcblxuICAgIHRoaXMuYXBpU3BlYyA9IHlhbWwubG9hZChmcy5yZWFkRmlsZVN5bmMocHJvcHMuZGVmaW5pdGlvbkZpbGVOYW1lKS50b1N0cmluZygpKSBhcyBPcGVuQVBJMztcblxuICAgIGxldCBjdXN0b21Eb21haW5OYW1lOiBhd3NfYXBpZ2F0ZXdheS5Eb21haW5OYW1lT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICBpZiAodGhpcy5hcGlGUUROKSB7XG4gICAgICBjdXN0b21Eb21haW5OYW1lID0ge1xuICAgICAgICBkb21haW5OYW1lOiB0aGlzLmFwaUZRRE4sXG4gICAgICAgIGNlcnRpZmljYXRlOiBuZXcgYXdzX2NlcnRpZmljYXRlbWFuYWdlci5DZXJ0aWZpY2F0ZSh0aGlzLCAnQ2VydCcsIHtcbiAgICAgICAgICBkb21haW5OYW1lOiB0aGlzLmFwaUZRRE4sXG4gICAgICAgICAgdmFsaWRhdGlvbjogYXdzX2NlcnRpZmljYXRlbWFuYWdlci5DZXJ0aWZpY2F0ZVZhbGlkYXRpb24uZnJvbURucyh0aGlzLmhvc3RlZFpvbmUpLFxuICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgICBuZXcgY2RrLkNmbk91dHB1dCh0aGlzLCAnUmVzdEFwaURvbWFpbk5hbWUnLCB7XG4gICAgICAgIGtleTogYCR7dGhpcy5wcm9wcy5hcGlOYW1lfSR7Q0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9ET01BSU5OQU1FfWAsXG4gICAgICAgIHZhbHVlOiB0aGlzLmFwaUZRRE4sXG4gICAgICB9KTtcbiAgICAgIG5ldyBjZGsuQ2ZuT3V0cHV0KHRoaXMsICdSZXN0QXBpVXJsT3V0cHV0Jywge1xuICAgICAgICBrZXk6IGAke3RoaXMucHJvcHMuYXBpTmFtZX0ke0NGTl9PVVRQVVRfU1VGRklYX1JFU1RBUElfVVJMfWAsXG4gICAgICAgIHZhbHVlOiAnaHR0cHM6Ly8nICsgdGhpcy5hcGlGUUROLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gaWYgKChwcm9wcy5tb25pdG9yaW5nID8/IHRydWUpICYmIHRoaXMubW9uaXRvcmluZykge1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUVycm9yc1dpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY1NlcnZlckVycm9yKHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNDbGllbnRFcnJvcih7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgLy8gICB9KSk7XG5cbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5V2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ0F2ZXJhZ2UnLFxuICAgIC8vICAgfSkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUxhdGVuY3lXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNMYXRlbmN5KHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAncDkwJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5VGFpbFdpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY0xhdGVuY3koe1xuICAgIC8vICAgICBzdGF0aXN0aWM6ICdwOTUnLFxuICAgIC8vICAgfSkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmFwaUxhdGVuY3lUYWlsV2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3A5OScsXG4gICAgLy8gICB9KSk7XG4gICAgLy8gfVxuXG4gICAgaWYgKHByb3BzLmF1dG9HZW5lcmF0ZVJvdXRlcyA/PyB0cnVlKSB7XG4gICAgICBmb3IgKGNvbnN0IHBhdGggaW4gdGhpcy5hcGlTcGVjLnBhdGhzKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hcGlTcGVjLnBhdGhzLCBwYXRoKSkge1xuICAgICAgICAgIGNvbnN0IHBhdGhJdGVtID0gdGhpcy5hcGlTcGVjLnBhdGhzW3BhdGhdO1xuICAgICAgICAgIGZvciAoY29uc3QgbWV0aG9kIGluIHBhdGhJdGVtKSB7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhdGhJdGVtLCBtZXRob2QpICYmXG4gICAgICAgICAgICAgIFsnZ2V0JywgJ3Bvc3QnLCAncHV0JywgJ2RlbGV0ZScsICdwYXRjaCcsICdvcHRpb25zJywgJ2hlYWQnXS5pbmRleE9mKG1ldGhvZCkgPj0gMCkge1xuICAgICAgICAgICAgICAvLyBBZGQgYWxsIG9wZXJhdGlvbnNcbiAgICAgICAgICAgICAgdGhpcy5hZGRSZXN0UmVzb3VyY2UocGF0aCBhcyBhbnksIG1ldGhvZCBhcyBhbnkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFkZCBfc3BlYyBFbmRwb2ludFxuICAgIHRoaXMuYXBpU3BlYy5wYXRocyFbJy9vcGVuYXBpLmpzb24nXSA9IHtcbiAgICAgIGdldDoge1xuICAgICAgICAnc3VtbWFyeSc6ICdSZXR1cm5zIHRoZSByYXcgT3BlbkFQSSBzcGVjIG9mIHRoaXMgQVBJJyxcbiAgICAgICAgJ2Rlc2NyaXB0aW9uJzogJ1JldHVybnMgdGhlIHJhdyBPcGVuQVBJIHNwZWMgb2YgdGhpcyBBUEknLFxuICAgICAgICAnb3BlcmF0aW9uSWQnOiAnX3NwZWMnLFxuICAgICAgICAncmVzcG9uc2VzJzoge1xuICAgICAgICAgIDIwMDoge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdPcGVuQVBJIHNwZWMgb2YgdGhpcyBBUEknLFxuICAgICAgICAgICAgY29udGVudDoge1xuICAgICAgICAgICAgICAnYXBwbGljYXRpb24vb3BlbmFwaStqc29uJzoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC8vIEB0cy1pZ25vcmUgQ3VzdG9tIHByb3BlcnR5IGZvciBBV1NcbiAgICAgICAgJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nOiB7XG4gICAgICAgICAgdHlwZTogJ21vY2snLFxuICAgICAgICAgIGh0dHBNZXRob2Q6ICdHRVQnLFxuICAgICAgICAgIHBheWxvYWRGb3JtYXRWZXJzaW9uOiAnMS4wJyxcbiAgICAgICAgICByZXF1ZXN0VGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6ICd7XFwnc3RhdHVzQ29kZVxcJzogMjAwfScsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXNwb25zZXM6IHtcbiAgICAgICAgICAgIDIwMDoge1xuICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgIHJlc3BvbnNlVGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL29wZW5hcGkranNvbic6IEpTT04uc3RyaW5naWZ5KHRoaXMuY2xlYW51cFNwZWMoSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSgodGhpcy5hcGlTcGVjKSkpKSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBpZiAocHJvcHMuY29ycykge1xuICAgICAgdGhpcy5hcGlTcGVjLnBhdGhzIVsnL3twcm94eSt9J10gPSB7XG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAnc3VtbWFyeSc6ICdDT1JTIHN1cHBvcnQnLFxuICAgICAgICAgICdkZXNjcmlwdGlvbic6ICdFbmFibGUgQ09SUyBieSByZXR1cm5pbmcgY29ycmVjdCBoZWFkZXJzJyxcbiAgICAgICAgICAndGFncyc6IFsnQ09SUyddLFxuICAgICAgICAgICdyZXNwb25zZXMnOiB7XG4gICAgICAgICAgICAyMDA6IHtcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdEZWZhdWx0IHJlc3BvbnNlIGZvciBDT1JTIG1ldGhvZCcsXG4gICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogeyBzY2hlbWE6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogeyBzY2hlbWE6IHsgdHlwZTogJ3N0cmluZycgfSB9LFxuICAgICAgICAgICAgICAgICdBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgY29udGVudDoge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nOiB7XG4gICAgICAgICAgICB0eXBlOiAnbW9jaycsXG4gICAgICAgICAgICByZXF1ZXN0VGVtcGxhdGVzOiB7XG4gICAgICAgICAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogJyNzZXQoJGNvbnRleHQucmVxdWVzdE92ZXJyaWRlLmhlYWRlci5vcmlnaW4gPSAkbWV0aG9kLnJlcXVlc3QuaGVhZGVyLm9yaWdpbilcXG57XFxuICBcInN0YXR1c0NvZGVcIiA6IDIwMFxcbn1cXG4nLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlc3BvbnNlczoge1xuICAgICAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogJzIwMCcsXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJzogXCInQ29udGVudC1UeXBlLFgtQW16LURhdGUsQXV0aG9yaXphdGlvbixYLUFwaS1LZXknXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyc6IFwiJ3RydWUnXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJzogXCInUFVULEdFVCxQT1NULERFTEVURSxQQVRDSCxIRUFELE9QVElPTlMnXCIsXG4gICAgICAgICAgICAgICAgICAnbWV0aG9kLnJlc3BvbnNlLmhlYWRlci5BY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nOiAnY29udGV4dC5yZXF1ZXN0T3ZlcnJpZGUuaGVhZGVyLm9yaWdpbicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZXNwb25zZVRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiAne30nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMucGF0Y2hTZWN1cml0eSh0aGlzLmFwaVNwZWMpO1xuXG4gICAgLy8gVE9ETyBwYXRjaCBzcGVjIGZvciBDb2duaXRvIHVzZXIgcG9vbFxuXG4gICAgdGhpcy5hcGkgPSBuZXcgYXdzX2FwaWdhdGV3YXkuU3BlY1Jlc3RBcGkodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgcmVzdEFwaU5hbWU6IGAke3Byb3BzLmFwaU5hbWV9IFske3Byb3BzLnN0YWdlTmFtZX1dYCxcbiAgICAgIGRvbWFpbk5hbWU6IGN1c3RvbURvbWFpbk5hbWUsXG4gICAgICBhcGlEZWZpbml0aW9uOiBhd3NfYXBpZ2F0ZXdheS5BcGlEZWZpbml0aW9uLmZyb21JbmxpbmUodGhpcy5hcGlTcGVjKSxcbiAgICAgIC4uLnByb3BzLnJlc3RBcGlQcm9wcyxcbiAgICB9KTtcblxuICAgIC8vIGFkZCBpbnZva2UgcGVybWlzc2lvbnMgdG8gTGFtYmRhIGZ1bmN0aW9uc1xuICAgIGZvciAoY29uc3QgZm4gb2YgT2JqZWN0LnZhbHVlcyh0aGlzLl9mdW5jdGlvbnMpKSB7XG4gICAgICBmbi5hZGRQZXJtaXNzaW9uKCdSZXN0QXBpSW52b2tlJywge1xuICAgICAgICBwcmluY2lwYWw6IG5ldyBhd3NfaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2FwaWdhdGV3YXkuYW1hem9uYXdzLmNvbScpLFxuICAgICAgICBhY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICBzb3VyY2VBcm46IHRoaXMuYXBpLmFybkZvckV4ZWN1dGVBcGkoKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChjdXN0b21Eb21haW5OYW1lICYmIHRoaXMuYXBpLmRvbWFpbk5hbWUpIHtcbiAgICAgIG5ldyBhd3Nfcm91dGU1My5BUmVjb3JkKHRoaXMsICdEbnNSZWNvcmQnLCB7XG4gICAgICAgIHpvbmU6IHRoaXMuaG9zdGVkWm9uZSEsXG4gICAgICAgIHJlY29yZE5hbWU6IGN1c3RvbURvbWFpbk5hbWUuZG9tYWluTmFtZSxcbiAgICAgICAgdGFyZ2V0OiBhd3Nfcm91dGU1My5SZWNvcmRUYXJnZXQuZnJvbUFsaWFzKFxuICAgICAgICAgIG5ldyBhd3Nfcm91dGU1M190YXJnZXRzLkFwaUdhdGV3YXlEb21haW4odGhpcy5hcGkuZG9tYWluTmFtZSksXG4gICAgICAgICksXG4gICAgICB9KTtcbiAgICB9XG5cbiAgfVxuXG4gIHByb3RlY3RlZCBjbGVhbnVwU3BlYyhzcGVjOiB7IFtrZXk6IHN0cmluZ106IGFueSB9KTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgT2JqZWN0LmVudHJpZXMoc3BlYykuZm9yRWFjaCgoW3Byb3AsIHZhbHVlXTogW3N0cmluZywgYW55XSkgPT4ge1xuICAgICAgaWYgKHByb3Auc3RhcnRzV2l0aCgneC0nKSkge1xuICAgICAgICBkZWxldGUgc3BlY1twcm9wXTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLmNsZWFudXBTcGVjKHNwZWNbcHJvcF0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHNwZWM7XG4gIH1cblxuICAvKipcbiAgICogcmV0dXJuIHRoZSBnZW5lcmF0ZWQgTGFtYmRhIGZ1bmN0aW9uIGZvciB0aGUgc3BlY2lmaWVkIEFQSSBvcGVyYXRpb25cbiAgICovXG4gIHB1YmxpYyBnZXRGdW5jdGlvbkZvck9wZXJhdGlvbihvcGVyYXRpb25JZDoga2V5b2YgT1BTKTogTGFtYmRhRnVuY3Rpb24ge1xuICAgIHJldHVybiB0aGlzLl9mdW5jdGlvbnNbb3BlcmF0aW9uSWQgYXMgc3RyaW5nXTtcbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm4gYSBsaXN0IG9mIGFsbCBnZW5lcmF0ZWQgTGFtYmRhIGZ1bmN0aW9uc1xuICAgKi9cbiAgcHVibGljIGdldEZ1bmN0aW9ucygpOiBMYW1iZGFGdW5jdGlvbltdIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLl9mdW5jdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFZpc2l0b3IgbWV0aG9kIHRvIG1vZGlmeSB0aGUgZ2l2ZW4gZnVuY3Rpb25zXG4gICAqXG4gICAqIEBwYXJhbSBvcGVyYXRpb25JZHMgdGhlIGxpc3Qgb2YgZnVuY3Rpb25zIHRvIHZpc2l0XG4gICAqIEBwYXJhbSBvcCB0aGUgZnVuY3Rpb24gdG8gY2FsbCBmb3IgZXZlcnkgZnVuY3Rpb25cbiAgICovXG4gIHB1YmxpYyBtb2RpZnlPcGVyYXRpb25GdW5jdGlvbnMob3BlcmF0aW9uSWRzOiAoa2V5b2YgT1BTKVtdLCBvcDogKGZuOiBMYW1iZGFGdW5jdGlvbikgPT4gdm9pZCkge1xuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uSWQgb2Ygb3BlcmF0aW9uSWRzKSB7XG4gICAgICBvcCh0aGlzLmdldEZ1bmN0aW9uRm9yT3BlcmF0aW9uKG9wZXJhdGlvbklkKSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFkZFJlc3RSZXNvdXJjZTxQIGV4dGVuZHMga2V5b2YgUEFUSFM+KHBhdGg6IFAsIG1ldGhvZDoga2V5b2YgUEFUSFNbUF0pIHtcbiAgICBjb25zdCBvYVBhdGggPSB0aGlzLmFwaVNwZWMucGF0aHMhW3BhdGggYXMgc3RyaW5nXSBhcyBQYXRoSXRlbU9iamVjdDtcbiAgICBjb25zdCBvcGVyYXRpb24gPSBvYVBhdGhbbWV0aG9kIGFzIGtleW9mIFBhdGhJdGVtT2JqZWN0XSBhcyBPcGVyYXRpb25PYmplY3Q7XG4gICAgY29uc3Qgb3BlcmF0aW9uSWQgPSBvcGVyYXRpb24ub3BlcmF0aW9uSWQhO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gYCR7bWV0aG9kIGFzIHN0cmluZ30gJHtwYXRoIGFzIHN0cmluZ30gLSAke29wZXJhdGlvbi5zdW1tYXJ5fWA7XG5cbiAgICBjb25zdCBjdXN0b21MYW1iZGFPcHRpb25zID0gdGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zQnlPcGVyYXRpb24gPyB0aGlzLnByb3BzLmxhbWJkYU9wdGlvbnNCeU9wZXJhdGlvbltvcGVyYXRpb25JZCBhcyBrZXlvZiBPUFNdIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB0aGlzLmFkZEN1c3RvbVJlc3RSZXNvdXJjZShvcGVyYXRpb24sIG1ldGhvZCBhcyBzdHJpbmcsIGRlc2NyaXB0aW9uLCBjdXN0b21MYW1iZGFPcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRDdXN0b21SZXN0UmVzb3VyY2Uob3BlcmF0aW9uOiBPcGVyYXRpb25PYmplY3QsIG1ldGhvZDogc3RyaW5nLCBkZXNjcmlwdGlvbjogc3RyaW5nLCBhZGRpdGlvbmFsTGFtYmRhT3B0aW9uczogTGFtYmRhT3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCd4LWFtYXpvbi1hcGlnYXRld2F5LWludGVncmF0aW9uJyBpbiBvcGVyYXRpb24pIHtcbiAgICAgIHJldHVybjsgLy8gU2tpcCBpZiBvcGVyYXRpb24gd2FzIGRlY2xhcmVkIGluIHNwZWMgZmlsZSBhbHJlYWR5IVxuICAgIH1cblxuICAgIGNvbnN0IGVudHJ5RmlsZSA9IGAuL3NyYy9sYW1iZGEvcmVzdC4ke3RoaXMucHJvcHMuYXBpTmFtZS50b0xvd2VyQ2FzZSgpfS4ke29wZXJhdGlvbi5vcGVyYXRpb25JZH0udHNgO1xuXG4gICAgY29uc3QgbGFtYmRhT3B0aW9ucyA9IHtcbiAgICAgIC4uLnRoaXMucHJvcHMubGFtYmRhT3B0aW9ucyAmJiB7XG4gICAgICAgIC4uLnRoaXMucHJvcHMubGFtYmRhT3B0aW9ucyxcbiAgICAgIH0sXG4gICAgICAuLi5hZGRpdGlvbmFsTGFtYmRhT3B0aW9ucyxcbiAgICB9O1xuXG4gICAgY29uc3QgYXV0aGVudGljYXRpb24gPSB0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uICYmICh0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uLmhhc093blByb3BlcnR5KCd1c2VycG9vbCcpXG4gICAgICA/IHsgdXNlclBvb2w6ICh0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uIGFzIElDb2duaXRvQXV0aGVudGljYXRpb24pLnVzZXJwb29sIH1cbiAgICAgIDogeyBqd3Q6IHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gYXMgSUp3dEF1dGhlbnRpY2F0aW9uIH0pO1xuXG4gICAgY29uc3QgZm4gPSBuZXcgTGFtYmRhRnVuY3Rpb24odGhpcywgYEZuJHtvcGVyYXRpb24ub3BlcmF0aW9uSWR9YCwge1xuICAgICAgc3RhZ2VOYW1lOiB0aGlzLnByb3BzLnN0YWdlTmFtZSxcbiAgICAgIGFkZGl0aW9uYWxFbnY6IHtcbiAgICAgICAgLi4udGhpcy5wcm9wcy5kb21haW5OYW1lICYmIHtcbiAgICAgICAgICBET01BSU5fTkFNRTogdGhpcy5wcm9wcy5kb21haW5OYW1lLFxuICAgICAgICB9LFxuICAgICAgICAuLi50aGlzLnByb3BzLmFkZGl0aW9uYWxFbnYsXG4gICAgICB9LFxuICAgICAgZW50cnk6IGVudHJ5RmlsZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBgWyR7dGhpcy5wcm9wcy5zdGFnZU5hbWV9XSAke2Rlc2NyaXB0aW9ufWAsXG4gICAgICAuLi5hdXRoZW50aWNhdGlvbixcbiAgICAgIC4uLnRoaXMucHJvcHMuc2luZ2xlVGFibGVEYXRhc3RvcmUgJiYge1xuICAgICAgICB0YWJsZTogdGhpcy5wcm9wcy5zaW5nbGVUYWJsZURhdGFzdG9yZS50YWJsZSxcbiAgICAgICAgdGFibGVXcml0ZXM6IHRoaXMudGFibGVXcml0ZUFjY2Vzc0Zvck1ldGhvZChtZXRob2QpLFxuICAgICAgfSxcbiAgICAgIC4uLnRoaXMucHJvcHMuYXNzZXRDZG4gJiYge1xuICAgICAgICBhc3NldERvbWFpbk5hbWU6IHRoaXMucHJvcHMuYXNzZXRDZG4uYXNzZXREb21haW5OYW1lLFxuICAgICAgICBhc3NldEJ1Y2tldDogdGhpcy5wcm9wcy5hc3NldENkbi5hc3NldEJ1Y2tldCxcbiAgICAgIH0sXG4gICAgICBsYW1iZGFPcHRpb25zLFxuICAgICAgbGFtYmRhVHJhY2luZzogdGhpcy5wcm9wcy5sYW1iZGFUcmFjaW5nLFxuICAgIH0pO1xuICAgIHRoaXMuX2Z1bmN0aW9uc1tvcGVyYXRpb24ub3BlcmF0aW9uSWQhXSA9IGZuO1xuICAgIGNkay5UYWdzLm9mKGZuKS5hZGQoJ09wZW5BUEknLCBkZXNjcmlwdGlvbi5yZXBsYWNlKC9bXlxcd1xcc1xcZF8uOi89K1xcLUBdL2csICcnKSk7XG5cbiAgICAvLyBpZiAodGhpcy5tb25pdG9yaW5nKSB7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcubGFtYmRhRHVyYXRpb25zV2lkZ2V0LmFkZExlZnRNZXRyaWMoZm4ubWV0cmljRHVyYXRpb24oKSk7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcubGFtYmRhSW52b2tlc1dpZGdldC5hZGRMZWZ0TWV0cmljKGZuLm1ldHJpY0ludm9jYXRpb25zKCkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmxhbWJkYUVycm9yc1dpZGdldC5hZGRMZWZ0TWV0cmljKGZuLm1ldHJpY0Vycm9ycygpKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5sYW1iZGFFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyhmbi5tZXRyaWNUaHJvdHRsZXMoKSk7XG4gICAgLy8gfVxuXG4gICAgY29uc3QgaGFzVmVyc2lvbkNvbmZpZyA9IGxhbWJkYU9wdGlvbnMuY3VycmVudFZlcnNpb25PcHRpb25zICE9IHVuZGVmaW5lZDtcblxuICAgIG9wZXJhdGlvblsneC1hbWF6b24tYXBpZ2F0ZXdheS1pbnRlZ3JhdGlvbiddID0ge1xuICAgICAgdHlwZTogJ2F3c19wcm94eScsXG4gICAgICBodHRwTWV0aG9kOiAnUE9TVCcsXG4gICAgICB1cmk6IGNkay5TdGFjay5vZih0aGlzKS5mb3JtYXRBcm4oe1xuICAgICAgICByZXNvdXJjZTogJ3BhdGgnLFxuICAgICAgICBzZXJ2aWNlOiAnYXBpZ2F0ZXdheScsXG4gICAgICAgIGFjY291bnQ6ICdsYW1iZGEnLFxuICAgICAgICBhcm5Gb3JtYXQ6IGNkay5Bcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSxcbiAgICAgICAgcmVzb3VyY2VOYW1lOiBgMjAxNS0wMy0zMS9mdW5jdGlvbnMvJHsoaGFzVmVyc2lvbkNvbmZpZyA/IGZuLmN1cnJlbnRWZXJzaW9uIDogZm4pLmZ1bmN0aW9uQXJufS9pbnZvY2F0aW9uc2AsXG4gICAgICAgIC8vICAgICAgICAgICAgIF5eXl5eXl5eXl4gLSBUSElTIE5FRURTIFRPIEJFIFRISVMgREFURS4gRVhBQ1RMWSFcbiAgICAgIH0pLFxuICAgICAgcGFzc3Rocm91Z2hCZWhhdmlvcjogJ3doZW5fbm9fdGVtcGxhdGVzJyxcbiAgICAgIHBheWxvYWRGb3JtYXRWZXJzaW9uOiAnMS4wJyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZuO1xuICB9XG5cbiAgcHJpdmF0ZSB0YWJsZVdyaXRlQWNjZXNzRm9yTWV0aG9kKG1ldGhvZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgc3dpdGNoIChtZXRob2QudG9Mb3dlckNhc2UoKSkge1xuICAgICAgY2FzZSAnZGVsZXRlJzpcbiAgICAgIGNhc2UgJ3Bvc3QnOlxuICAgICAgY2FzZSAncHV0JzpcbiAgICAgIGNhc2UgJ3BhdGNoJzpcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICBjYXNlICdvcHRpb25zJzpcbiAgICAgIGNhc2UgJ2dldCc6XG4gICAgICBjYXNlICdoZWFkJzpcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQVdTIGRvZXMgbm90IHByb3Blcmx5IGFwcGx5IHRoZSAnc2VjdXJpdHknIG9wdGlvbiB0byBldmVyeSBzaW5nbGUgcGF0aC1tZXRob2QuXG4gICAqIEFjY29yZGluZyB0byBkb2N1bWVudGF0aW9uLCBnbG9iYWwgc2VjdXJpdHkgZ2V0cyBhcHBsaWVkLCBpZiB0aGVyZSBpcyBubyBzZWN1cml0eVxuICAgKiBzZXQgZm9yIHRoZSBwYXJ0aWN1bGFyIHBhdGgtbWV0aG9kLiBJZiB0aGVyZSBpcyBhbnksIGV2ZW4gZW1wdHksIGl0IHdpbGwgZ2V0IHByZWNlZGVuY2UuXG4gICAqIFRISVMgRE9FUyBOT1QgSEFQUEVOIE9OIEFXUy4gSVQgSlVTVCBBTFdBWVMgVVNFUyBUSEUgR0xPQkFMIFNFVFRJTkchXG4gICAqXG4gICAqICdzZWN1cml0eSBhcHBsaWVzIFsuLi5dIHNjaGVtZXMgZ2xvYmFsbHkgdG8gYWxsIEFQSSBvcGVyYXRpb25zLCB1bmxlc3Mgb3ZlcnJpZGRlbiBvbiB0aGUgb3BlcmF0aW9uIGxldmVsJ1xuICAgKiBAc2VlIGh0dHBzOi8vc3dhZ2dlci5pby9kb2NzL3NwZWNpZmljYXRpb24vYXV0aGVudGljYXRpb24vXG4gICAqL1xuICBwcm90ZWN0ZWQgcGF0Y2hTZWN1cml0eShzcGVjOiBPcGVuQVBJMykge1xuICAgIGlmICgnc2VjdXJpdHknIGluIHNwZWMpIHtcbiAgICAgIGZvciAoY29uc3Qgc3BlY1BhdGggb2YgT2JqZWN0LnZhbHVlcyhzcGVjLnBhdGhzIHx8IFtdKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzcGVjUGF0aCkge1xuICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgLT4gVGhlcmUgaXMgYSB3cm9uZyBkZWZpbml0aW9uIGZvciBtZXRob2QgaW5jbHVkZXMhIEl0IGFsbG93cyBhbnkgdmFsdWUgdG8gYmUgZ2l2ZW4hXG4gICAgICAgICAgaWYgKCF0aGlzLmFwaU1ldGhvZHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgY29udGludWU7IC8vIFNraXAgaWYgbm90IGh0dHAgbWV0aG9kIGRlZmluaXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzcGVjTWV0aG9kID0gKHNwZWNQYXRoIGFzIFBhdGhJdGVtT2JqZWN0KVtrZXkgYXMga2V5b2YgUGF0aEl0ZW1PYmplY3RdITtcbiAgICAgICAgICBpZiAoISgnc2VjdXJpdHknIGluIHNwZWNNZXRob2QpKSB7XG4gICAgICAgICAgICBzcGVjTWV0aG9kLnNlY3VyaXR5ID0gc3BlYy5zZWN1cml0eTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBzcGVjLnNlY3VyaXR5O1xuICAgIH1cbiAgfVxuXG59XG4iXX0=
571
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdC1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uc3RydWN0cy9yZXN0LWFwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw0Q0FBOEI7QUFDOUIsNkNBTXFCO0FBQ3JCLGlEQUFtQztBQUVuQyw4Q0FBZ0M7QUFHaEMseUNBQW1EO0FBQ25ELGlDQUF1RDtBQUN2RCwrQ0FBd0c7QUE4RHhHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRztBQUNILE1BQWEsT0FBb0IsU0FBUSxrQkFBTztJQXlDOUM7Ozs7OztPQU1HO0lBQ0gsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBVSxLQUF3QjtRQUN4RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUR3QixVQUFLLEdBQUwsS0FBSyxDQUFtQjtRQXBDMUU7OztXQUdHO1FBQ0ssZUFBVSxHQUE4QyxFQUFFLENBQUM7UUFFbEQsZUFBVSxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFTM0Y7OztXQUdHO1FBQ0sseUJBQW9CLEdBQWdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFFdEQ7Ozs7O1dBS0c7UUFDSywrQkFBMEIsR0FBdUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQVlqRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBYSxDQUFDO1FBRTNGLElBQUksZ0JBQThELENBQUM7UUFDbkUsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsZ0JBQWdCLEdBQUc7Z0JBQ2pCLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FB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SSxDQUFDLDBCQUEwQixDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFFBQWlCLENBQUMsQ0FBQzs0QkFDM0UsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7eUJBQU0sQ0FBQzt3QkFDTiw4REFBOEQ7d0JBQzlELE1BQU0sV0FBVyxHQUFJLFVBQThCLENBQUMsV0FBVyxDQUFDO3dCQUNoRSxJQUFJLFdBQVcsRUFBRSxDQUFDOzRCQUNoQixJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxVQUFVLENBQUMsUUFBaUIsQ0FBQyxDQUFDO3dCQUNqRixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7Q0FFRjtBQXpqQkQsMEJBeWpCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ25vZGU6ZnMnO1xuaW1wb3J0IHtcbiAgYXdzX2NlcnRpZmljYXRlbWFuYWdlcixcbiAgYXdzX2lhbSxcbiAgYXdzX3JvdXRlNTMsXG4gIGF3c19yb3V0ZTUzX3RhcmdldHMsXG4gIGF3c19hcGlnYXRld2F5LFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyB5YW1sIGZyb20gJ2pzLXlhbWwnO1xuaW1wb3J0IHsgT3BlbkFQSTMsIE9wZXJhdGlvbk9iamVjdCwgUGF0aEl0ZW1PYmplY3QgfSBmcm9tICdvcGVuYXBpLXR5cGVzY3JpcHQnO1xuaW1wb3J0IHsgSUNvZ25pdG9BdXRoZW50aWNhdGlvbiwgSUp3dEF1dGhlbnRpY2F0aW9uIH0gZnJvbSAnLi9hdXRoZW50aWNhdGlvbic7XG5pbXBvcnQgeyBCYXNlQXBpLCBCYXNlQXBpUHJvcHMgfSBmcm9tICcuL2Jhc2UtYXBpJztcbmltcG9ydCB7IExhbWJkYUZ1bmN0aW9uLCBMYW1iZGFPcHRpb25zIH0gZnJvbSAnLi9mdW5jJztcbmltcG9ydCB7IENGTl9PVVRQVVRfU1VGRklYX1JFU1RBUElfRE9NQUlOTkFNRSwgQ0ZOX09VVFBVVF9TVUZGSVhfUkVTVEFQSV9VUkwgfSBmcm9tICcuLi9zaGFyZWQvb3V0cHV0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdEFwaVByb3BzPE9QUz4gZXh0ZW5kcyBCYXNlQXBpUHJvcHMge1xuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSByb3V0ZXMgZm9yIGFsbCBlbmRwb2ludHMgY29uZmlndXJlZCBpbiB0aGUgb3BlbmFwaS55YW1sIGZpbGVcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgYXV0b0dlbmVyYXRlUm91dGVzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogY3VzdG9tIG9wdGlvbnMgZm9yIHRoZSBjcmVhdGVkIEh0dHBBcGlcbiAgICpcbiAgICogQGRlZmF1bHQgLVxuICAgKi9cbiAgcmVzdEFwaVByb3BzPzogYXdzX2FwaWdhdGV3YXkuUmVzdEFwaUJhc2VQcm9wcztcblxuICAvKipcbiAgICogYWRkaXRpb25hbCBvcHRpb25zIGZvciB0aGUgdW5kZXJseWluZyBMYW1iZGEgZnVuY3Rpb24gY29uc3RydWN0IHBlciBvcGVyYXRpb25JZFxuICAgKlxuICAgKiBAZGVmYXVsdCAtXG4gICAqL1xuICBsYW1iZGFPcHRpb25zQnlPcGVyYXRpb24/OiB7IFtvcGVyYXRpb25JZCBpbiBrZXlvZiBPUFNdPzogTGFtYmRhT3B0aW9ucyB9O1xuXG4gIGRlZmluaXRpb25GaWxlTmFtZTogc3RyaW5nO1xuXG4gIGNvcnM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgbGlzdCBvZiBvcGVyYXRpb24gSURzIHRoYXQgc2hvdWxkIHNraXAgdGhlIGF1dGhvcml6ZXIgZW50aXJlbHkuXG4gICAqIFRoZXNlIG9wZXJhdGlvbnMgd2lsbCBoYXZlIGBzZWN1cml0eTogW11gIGluIHRoZSBPcGVuQVBJIHNwZWMsIG1lYW5pbmdcbiAgICogdGhleSBhcmUgcHVibGljbHkgYWNjZXNzaWJsZSB3aXRob3V0IGF1dGhlbnRpY2F0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFub255bW91cyBvcGVyYXRpb25zXG4gICAqL1xuICBhbm9ueW1vdXNPcGVyYXRpb25zPzogKGtleW9mIE9QUylbXTtcblxuICAvKipcbiAgICogQ29udHJvbHMgd2hldGhlciB0aGUgSldUIExhbWJkYSBhdXRob3JpemVyIHVzZXMgdGhlIFRPS0VOIG9yIFJFUVVFU1QgdHlwZS5cbiAgICpcbiAgICogKip0b2tlbiAoZGVmYXVsdCk6KiogVGhlIEFQSSBHYXRld2F5IHZhbGlkYXRlcyB0aGF0IHRoZSBBdXRob3JpemF0aW9uIGhlYWRlciBpcyBwcmVzZW50XG4gICAqIGJlZm9yZSBpbnZva2luZyB0aGUgTGFtYmRhIGF1dGhvcml6ZXIuIElmIHRoZSBoZWFkZXIgaXMgbWlzc2luZywgQVBJIEdhdGV3YXkgaW1tZWRpYXRlbHlcbiAgICogcmV0dXJucyA0MDEgd2l0aG91dCBpbnZva2luZyB0aGUgTGFtYmRhLiBUaGlzIGlzIGNoZWFwZXIgZm9yIHVuYXV0aGVudGljYXRlZCByZXF1ZXN0c1xuICAgKiBiZWNhdXNlIG5vIExhbWJkYSBpbnZvY2F0aW9uIG9jY3VycywgYnV0IGl0IGRvZXMgbm90IHN1cHBvcnQgb3B0aW9uYWwgYXV0aGVudGljYXRpb25cbiAgICogKGV2ZXJ5IHJlcXVlc3QgbXVzdCBjYXJyeSBhIHRva2VuIG9yIGJlIHJlamVjdGVkKS5cbiAgICpcbiAgICogKipyZXF1ZXN0OioqIFRoZSBBUEkgR2F0ZXdheSBhbHdheXMgaW52b2tlcyB0aGUgTGFtYmRhIGF1dGhvcml6ZXIgcmVnYXJkbGVzcyBvZiB3aGV0aGVyXG4gICAqIHRoZSBBdXRob3JpemF0aW9uIGhlYWRlciBpcyBwcmVzZW50LiBUaGlzIGVuYWJsZXMgb3B0aW9uYWwgYXV0aGVudGljYXRpb246IHRoZSBMYW1iZGFcbiAgICogY2FuIGluc3BlY3QgdGhlIHJlcXVlc3QsIHJldHVybiBBbGxvdyB3aXRoIGFuIGFub255bW91cyBwcmluY2lwYWwgd2hlbiBubyB0b2tlbiBpc1xuICAgKiBwcm92aWRlZCwgYW5kIHJldHVybiBBbGxvdyB3aXRoIHVzZXIgY2xhaW1zIHdoZW4gYSB2YWxpZCB0b2tlbiBpcyBwcmVzZW50LiBUaGUgdHJhZGUtb2ZmXG4gICAqIGlzIHRoYXQgeW91IHBheSBmb3IgYSBMYW1iZGEgaW52b2NhdGlvbiBvbiBldmVyeSByZXF1ZXN0LCBpbmNsdWRpbmcgdW5hdXRoZW50aWNhdGVkIG9uZXMuXG4gICAqXG4gICAqIFVzZSAncmVxdWVzdCcgd2hlbiB5b3UgbmVlZCBlbmRwb2ludHMgdGhhdCBiZWhhdmUgZGlmZmVyZW50bHkgZm9yIGF1dGhlbnRpY2F0ZWQgdnNcbiAgICogYW5vbnltb3VzIHVzZXJzIChlLmcuLCBwZXJzb25hbGl6ZWQgcmVzcG9uc2VzIGZvciBsb2dnZWQtaW4gdXNlcnMsIGdlbmVyaWMgcmVzcG9uc2VzXG4gICAqIGZvciBndWVzdHMpIHdpdGhvdXQgc3BsaXR0aW5nIHRoZW0gaW50byBzZXBhcmF0ZSBvcGVyYXRpb25zLlxuICAgKlxuICAgKiBAZGVmYXVsdCAndG9rZW4nXG4gICAqL1xuICBqd3RBdXRob3JpemVyVHlwZT86ICd0b2tlbicgfCAncmVxdWVzdCc7XG59XG5cbi8qKlxuICogVGhlIFJlc3RBcGkgY29uc3RydWN0IHNldHMgdXAgYW4gQVdTIEFQSSBHYXRld2F5IFJFU1QgQVBJIHVzaW5nIE9wZW5BUEkgc3BlY2lmaWNhdGlvbi5cbiAqIFRoaXMgY29uc3RydWN0IGZhY2lsaXRhdGVzIHRoZSBjcmVhdGlvbiBvZiBhIFJFU1QgQVBJIHdpdGggdmFyaW91cyBjb25maWd1cmF0aW9ucywgaW5jbHVkaW5nIGN1c3RvbSBkb21haW4sIENPUlMgc3VwcG9ydCwgYW5kIGludGVncmF0aW9uIHdpdGggTGFtYmRhIGZ1bmN0aW9ucy5cbiAqIEl0IGFsbG93cyBhdXRvLWdlbmVyYXRpbmcgcm91dGVzIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBPcGVuQVBJIGRlZmluaXRpb24gYW5kIHByb3ZpZGVzIG1ldGhvZHMgdG8gZHluYW1pY2FsbHkgYWRkIGN1c3RvbSByb3V0ZXMgYW5kIG1hbmFnZSBMYW1iZGEgZnVuY3Rpb24gaW50ZWdyYXRpb25zLlxuICpcbiAqIEB0ZW1wbGF0ZSBQQVRIUyAtIFRoZSB0eXBlIGRlZmluaXRpb24gZm9yIHRoZSBBUEkgcGF0aHMuXG4gKiBAdGVtcGxhdGUgT1BTIC0gVGhlIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIEFQSSBvcGVyYXRpb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBhcGkgPSBuZXcgUmVzdEFwaSh0aGlzLCAnTXlSZXN0QXBpJywge1xuICogICBhcGlOYW1lOiAnTXlBUEknLFxuICogICBzdGFnZU5hbWU6ICdkZXYnLFxuICogICBkZWZpbml0aW9uRmlsZU5hbWU6ICdvcGVuYXBpLnlhbWwnLFxuICogICBhdXRoZW50aWNhdGlvbjogbXlDb2duaXRvQXV0aCxcbiAqICAgc2luZ2xlVGFibGVEYXRhc3RvcmU6IG15RHluYW1vREJUYWJsZSxcbiAqICAgYXV0b0dlbmVyYXRlUm91dGVzOiB0cnVlLFxuICogfSk7XG4gKlxuICogLy8gQWRkIGEgY3VzdG9tIFJFU1QgcmVzb3VyY2VcbiAqIGFwaS5hZGRSZXN0UmVzb3VyY2UoJy9pdGVtcycsICdnZXQnKTtcbiAqXG4gKiAvLyBHZXQgdGhlIExhbWJkYSBmdW5jdGlvbiBmb3IgYSBzcGVjaWZpYyBvcGVyYXRpb25cbiAqIGNvbnN0IGxhbWJkYUZ1bmN0aW9uID0gYXBpLmdldEZ1bmN0aW9uRm9yT3BlcmF0aW9uKCdnZXRJdGVtcycpO1xuICovXG5leHBvcnQgY2xhc3MgUmVzdEFwaTxQQVRIUywgT1BTPiBleHRlbmRzIEJhc2VBcGkge1xuXG4gIC8qKlxuICAgKiBUaGUgQVdTIEFQSSBHYXRld2F5IFJFU1QgQVBJIGluc3RhbmNlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwaTogYXdzX2FwaWdhdGV3YXkuU3BlY1Jlc3RBcGk7XG5cbiAgLyoqXG4gICAqIFRoZSBPcGVuQVBJIHNwZWNpZmljYXRpb24gZm9yIHRoZSBSRVNUIEFQSS5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBhcGlTcGVjOiBPcGVuQVBJMztcblxuICAvKipcbiAgICogQSBjb2xsZWN0aW9uIG9mIExhbWJkYSBmdW5jdGlvbnMgdXNlZCBhcyBpbnRlZ3JhdGlvbnMgZm9yIHRoZSBBUEkgb3BlcmF0aW9ucy5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX2Z1bmN0aW9uczogeyBbb3BlcmF0aW9uSWQ6IHN0cmluZ106IExhbWJkYUZ1bmN0aW9uIH0gPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGFwaU1ldGhvZHMgPSBbJ2dldCcsICdwb3N0JywgJ3B1dCcsICdkZWxldGUnLCAncGF0Y2gnLCAnb3B0aW9ucycsICdoZWFkJ107XG5cbiAgLyoqXG4gICAqIFRoZSBKV1QgYXV0aG9yaXplciBMYW1iZGEgZnVuY3Rpb24sIGlmIEpXVCBhdXRoZW50aWNhdGlvbiBpcyBjb25maWd1cmVkLlxuICAgKiBTdG9yZWQgc28gdGhlIGludm9rZSBwZXJtaXNzaW9uIGNhbiBiZSBncmFudGVkIGFmdGVyIHRoZSBTcGVjUmVzdEFwaSBpcyBjcmVhdGVkLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfYXV0aG9yaXplckZuPzogTGFtYmRhRnVuY3Rpb247XG5cbiAgLyoqXG4gICAqIFNldCBvZiBvcGVyYXRpb25JZHMgdGhhdCBzaG91bGQgaGF2ZSBzZWN1cml0eSBkaXNhYmxlZCAoc2VjdXJpdHk6IFtdKS5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX2Fub255bW91c09wZXJhdGlvbnM6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuXG4gIC8qKlxuICAgKiBTdG9yZXMgdGhlIG9yaWdpbmFsIHBlci1vcGVyYXRpb24gc2VjdXJpdHkgYXJyYXlzIGFzIGFzc2lnbmVkIGJ5IHBhdGNoU2VjdXJpdHksXG4gICAqIGtleWVkIGJ5IG9wZXJhdGlvbklkLiBVc2VkIGJ5IHNldEFub255bW91c09wZXJhdGlvbnMgdG8gcmVzdG9yZSBzZWN1cml0eSBvblxuICAgKiBvcGVyYXRpb25zIHJlbW92ZWQgZnJvbSB0aGUgYW5vbnltb3VzIHNldC5cbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX29yaWdpbmFsT3BlcmF0aW9uU2VjdXJpdHk6IE1hcDxzdHJpbmcsIGFueVtdPiA9IG5ldyBNYXAoKTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBSZXN0QXBpLlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgLSBUaGUgc2NvcGUgaW4gd2hpY2ggdGhpcyBjb25zdHJ1Y3QgaXMgZGVmaW5lZC5cbiAgICogQHBhcmFtIGlkIC0gVGhlIHNjb3BlZCBjb25zdHJ1Y3QgSUQuXG4gICAqIEBwYXJhbSBwcm9wcyAtIFRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBSZXN0QXBpIGNvbnN0cnVjdC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByaXZhdGUgcHJvcHM6IFJlc3RBcGlQcm9wczxPUFM+KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICB0aGlzLmFwaVNwZWMgPSB5YW1sLmxvYWQoZnMucmVhZEZpbGVTeW5jKHByb3BzLmRlZmluaXRpb25GaWxlTmFtZSkudG9TdHJpbmcoKSkgYXMgT3BlbkFQSTM7XG5cbiAgICBsZXQgY3VzdG9tRG9tYWluTmFtZTogYXdzX2FwaWdhdGV3YXkuRG9tYWluTmFtZU9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMuYXBpRlFETikge1xuICAgICAgY3VzdG9tRG9tYWluTmFtZSA9IHtcbiAgICAgICAgZG9tYWluTmFtZTogdGhpcy5hcGlGUUROLFxuICAgICAgICBjZXJ0aWZpY2F0ZTogbmV3IGF3c19jZXJ0aWZpY2F0ZW1hbmFnZXIuQ2VydGlmaWNhdGUodGhpcywgJ0NlcnQnLCB7XG4gICAgICAgICAgZG9tYWluTmFtZTogdGhpcy5hcGlGUUROLFxuICAgICAgICAgIHZhbGlkYXRpb246IGF3c19jZXJ0aWZpY2F0ZW1hbmFnZXIuQ2VydGlmaWNhdGVWYWxpZGF0aW9uLmZyb21EbnModGhpcy5ob3N0ZWRab25lKSxcbiAgICAgICAgfSksXG4gICAgICB9O1xuICAgICAgbmV3IGNkay5DZm5PdXRwdXQodGhpcywgJ1Jlc3RBcGlEb21haW5OYW1lJywge1xuICAgICAgICBrZXk6IGAke3RoaXMucHJvcHMuYXBpTmFtZX0ke0NGTl9PVVRQVVRfU1VGRklYX1JFU1RBUElfRE9NQUlOTkFNRX1gLFxuICAgICAgICB2YWx1ZTogdGhpcy5hcGlGUUROLFxuICAgICAgfSk7XG4gICAgICBuZXcgY2RrLkNmbk91dHB1dCh0aGlzLCAnUmVzdEFwaVVybE91dHB1dCcsIHtcbiAgICAgICAga2V5OiBgJHt0aGlzLnByb3BzLmFwaU5hbWV9JHtDRk5fT1VUUFVUX1NVRkZJWF9SRVNUQVBJX1VSTH1gLFxuICAgICAgICB2YWx1ZTogJ2h0dHBzOi8vJyArIHRoaXMuYXBpRlFETixcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGlmICgocHJvcHMubW9uaXRvcmluZyA/PyB0cnVlKSAmJiB0aGlzLm1vbml0b3JpbmcpIHtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlFcnJvcnNXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNTZXJ2ZXJFcnJvcih7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgLy8gICB9KSk7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcuYXBpRXJyb3JzV2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljQ2xpZW50RXJyb3Ioe1xuICAgIC8vICAgICBzdGF0aXN0aWM6ICdzdW0nLFxuICAgIC8vICAgfSkpO1xuXG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcuYXBpTGF0ZW5jeVdpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY0xhdGVuY3koe1xuICAgIC8vICAgICBzdGF0aXN0aWM6ICdBdmVyYWdlJyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5V2lkZ2V0LmFkZExlZnRNZXRyaWModGhpcy5hcGkubWV0cmljTGF0ZW5jeSh7XG4gICAgLy8gICAgIHN0YXRpc3RpYzogJ3A5MCcsXG4gICAgLy8gICB9KSk7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcuYXBpTGF0ZW5jeVRhaWxXaWRnZXQuYWRkTGVmdE1ldHJpYyh0aGlzLmFwaS5tZXRyaWNMYXRlbmN5KHtcbiAgICAvLyAgICAgc3RhdGlzdGljOiAncDk1JyxcbiAgICAvLyAgIH0pKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5hcGlMYXRlbmN5VGFpbFdpZGdldC5hZGRMZWZ0TWV0cmljKHRoaXMuYXBpLm1ldHJpY0xhdGVuY3koe1xuICAgIC8vICAgICBzdGF0aXN0aWM6ICdwOTknLFxuICAgIC8vICAgfSkpO1xuICAgIC8vIH1cblxuICAgIGlmIChwcm9wcy5hdXRvR2VuZXJhdGVSb3V0ZXMgPz8gdHJ1ZSkge1xuICAgICAgZm9yIChjb25zdCBwYXRoIGluIHRoaXMuYXBpU3BlYy5wYXRocykge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYXBpU3BlYy5wYXRocywgcGF0aCkpIHtcbiAgICAgICAgICBjb25zdCBwYXRoSXRlbSA9IHRoaXMuYXBpU3BlYy5wYXRoc1twYXRoXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IG1ldGhvZCBpbiBwYXRoSXRlbSkge1xuICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwYXRoSXRlbSwgbWV0aG9kKSAmJlxuICAgICAgICAgICAgICBbJ2dldCcsICdwb3N0JywgJ3B1dCcsICdkZWxldGUnLCAncGF0Y2gnLCAnb3B0aW9ucycsICdoZWFkJ10uaW5kZXhPZihtZXRob2QpID49IDApIHtcbiAgICAgICAgICAgICAgLy8gQWRkIGFsbCBvcGVyYXRpb25zXG4gICAgICAgICAgICAgIHRoaXMuYWRkUmVzdFJlc291cmNlKHBhdGggYXMgYW55LCBtZXRob2QgYXMgYW55KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBZGQgX3NwZWMgRW5kcG9pbnRcbiAgICB0aGlzLmFwaVNwZWMucGF0aHMhWycvb3BlbmFwaS5qc29uJ10gPSB7XG4gICAgICBnZXQ6IHtcbiAgICAgICAgJ3N1bW1hcnknOiAnUmV0dXJucyB0aGUgcmF3IE9wZW5BUEkgc3BlYyBvZiB0aGlzIEFQSScsXG4gICAgICAgICdkZXNjcmlwdGlvbic6ICdSZXR1cm5zIHRoZSByYXcgT3BlbkFQSSBzcGVjIG9mIHRoaXMgQVBJJyxcbiAgICAgICAgJ29wZXJhdGlvbklkJzogJ19zcGVjJyxcbiAgICAgICAgJ3Jlc3BvbnNlcyc6IHtcbiAgICAgICAgICAyMDA6IHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnT3BlbkFQSSBzcGVjIG9mIHRoaXMgQVBJJyxcbiAgICAgICAgICAgIGNvbnRlbnQ6IHtcbiAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL29wZW5hcGkranNvbic6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICAvLyBAdHMtaWdub3JlIEN1c3RvbSBwcm9wZXJ0eSBmb3IgQVdTXG4gICAgICAgICd4LWFtYXpvbi1hcGlnYXRld2F5LWludGVncmF0aW9uJzoge1xuICAgICAgICAgIHR5cGU6ICdtb2NrJyxcbiAgICAgICAgICBodHRwTWV0aG9kOiAnR0VUJyxcbiAgICAgICAgICBwYXlsb2FkRm9ybWF0VmVyc2lvbjogJzEuMCcsXG4gICAgICAgICAgcmVxdWVzdFRlbXBsYXRlczoge1xuICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL2pzb24nOiAne1xcJ3N0YXR1c0NvZGVcXCc6IDIwMH0nLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2VzOiB7XG4gICAgICAgICAgICAyMDA6IHtcbiAgICAgICAgICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgICAgICAgICByZXNwb25zZVRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAgICdhcHBsaWNhdGlvbi9vcGVuYXBpK2pzb24nOiBKU09OLnN0cmluZ2lmeSh0aGlzLmNsZWFudXBTcGVjKEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoKHRoaXMuYXBpU3BlYykpKSkpLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgaWYgKHByb3BzLmNvcnMpIHtcbiAgICAgIHRoaXMuYXBpU3BlYy5wYXRocyFbJy97cHJveHkrfSddID0ge1xuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgJ3N1bW1hcnknOiAnQ09SUyBzdXBwb3J0JyxcbiAgICAgICAgICAnZGVzY3JpcHRpb24nOiAnRW5hYmxlIENPUlMgYnkgcmV0dXJuaW5nIGNvcnJlY3QgaGVhZGVycycsXG4gICAgICAgICAgJ3RhZ3MnOiBbJ0NPUlMnXSxcbiAgICAgICAgICAncmVzcG9uc2VzJzoge1xuICAgICAgICAgICAgMjAwOiB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRGVmYXVsdCByZXNwb25zZSBmb3IgQ09SUyBtZXRob2QnLFxuICAgICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbic6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcyc6IHsgc2NoZW1hOiB7IHR5cGU6ICdzdHJpbmcnIH0gfSxcbiAgICAgICAgICAgICAgICAnQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHMnOiB7IHNjaGVtYTogeyB0eXBlOiAnc3RyaW5nJyB9IH0sXG4gICAgICAgICAgICAgICAgJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnOiB7IHNjaGVtYTogeyB0eXBlOiAnc3RyaW5nJyB9IH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGNvbnRlbnQ6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICd4LWFtYXpvbi1hcGlnYXRld2F5LWludGVncmF0aW9uJzoge1xuICAgICAgICAgICAgdHlwZTogJ21vY2snLFxuICAgICAgICAgICAgcmVxdWVzdFRlbXBsYXRlczoge1xuICAgICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6ICcjc2V0KCRjb250ZXh0LnJlcXVlc3RPdmVycmlkZS5oZWFkZXIub3JpZ2luID0gJG1ldGhvZC5yZXF1ZXN0LmhlYWRlci5vcmlnaW4pXFxue1xcbiAgXCJzdGF0dXNDb2RlXCIgOiAyMDBcXG59XFxuJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXNwb25zZXM6IHtcbiAgICAgICAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgICAgICAgIHN0YXR1c0NvZGU6ICcyMDAnLFxuICAgICAgICAgICAgICAgIHJlc3BvbnNlUGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICAgICAgJ21ldGhvZC5yZXNwb25zZS5oZWFkZXIuQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyc6IFwiJ0NvbnRlbnQtVHlwZSxYLUFtei1EYXRlLEF1dGhvcml6YXRpb24sWC1BcGktS2V5J1wiLFxuICAgICAgICAgICAgICAgICAgJ21ldGhvZC5yZXNwb25zZS5oZWFkZXIuQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHMnOiBcIid0cnVlJ1wiLFxuICAgICAgICAgICAgICAgICAgJ21ldGhvZC5yZXNwb25zZS5oZWFkZXIuQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcyc6IFwiJ1BVVCxHRVQsUE9TVCxERUxFVEUsUEFUQ0gsSEVBRCxPUFRJT05TJ1wiLFxuICAgICAgICAgICAgICAgICAgJ21ldGhvZC5yZXNwb25zZS5oZWFkZXIuQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJzogJ2NvbnRleHQucmVxdWVzdE92ZXJyaWRlLmhlYWRlci5vcmlnaW4nLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VUZW1wbGF0ZXM6IHtcbiAgICAgICAgICAgICAgICAgICdhcHBsaWNhdGlvbi9qc29uJzogJ3t9JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0aGlzLnBhdGNoU2VjdXJpdHlTY2hlbWVzKHRoaXMuYXBpU3BlYyk7XG5cbiAgICAvLyBJbml0aWFsaXplIGFub255bW91cyBvcGVyYXRpb25zIGZyb20gcHJvcHMgYmVmb3JlIHBhdGNoU2VjdXJpdHkgZGlzdHJpYnV0ZXMgc2VjdXJpdHlcbiAgICBpZiAocHJvcHMuYW5vbnltb3VzT3BlcmF0aW9ucykge1xuICAgICAgZm9yIChjb25zdCBvcElkIG9mIHByb3BzLmFub255bW91c09wZXJhdGlvbnMpIHtcbiAgICAgICAgdGhpcy5fYW5vbnltb3VzT3BlcmF0aW9ucy5hZGQob3BJZCBhcyBzdHJpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMucGF0Y2hTZWN1cml0eSh0aGlzLmFwaVNwZWMpO1xuXG4gICAgLy8gVE9ETyBwYXRjaCBzcGVjIGZvciBDb2duaXRvIHVzZXIgcG9vbFxuXG4gICAgdGhpcy5hcGkgPSBuZXcgYXdzX2FwaWdhdGV3YXkuU3BlY1Jlc3RBcGkodGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgcmVzdEFwaU5hbWU6IGAke3Byb3BzLmFwaU5hbWV9IFske3Byb3BzLnN0YWdlTmFtZX1dYCxcbiAgICAgIGRvbWFpbk5hbWU6IGN1c3RvbURvbWFpbk5hbWUsXG4gICAgICBhcGlEZWZpbml0aW9uOiBhd3NfYXBpZ2F0ZXdheS5BcGlEZWZpbml0aW9uLmZyb21JbmxpbmUodGhpcy5hcGlTcGVjKSxcbiAgICAgIC4uLnByb3BzLnJlc3RBcGlQcm9wcyxcbiAgICB9KTtcblxuICAgIC8vIGFkZCBpbnZva2UgcGVybWlzc2lvbnMgdG8gTGFtYmRhIGZ1bmN0aW9uc1xuICAgIGZvciAoY29uc3QgZm4gb2YgT2JqZWN0LnZhbHVlcyh0aGlzLl9mdW5jdGlvbnMpKSB7XG4gICAgICBmbi5hZGRQZXJtaXNzaW9uKCdSZXN0QXBpSW52b2tlJywge1xuICAgICAgICBwcmluY2lwYWw6IG5ldyBhd3NfaWFtLlNlcnZpY2VQcmluY2lwYWwoJ2FwaWdhdGV3YXkuYW1hem9uYXdzLmNvbScpLFxuICAgICAgICBhY3Rpb246ICdsYW1iZGE6SW52b2tlRnVuY3Rpb24nLFxuICAgICAgICBzb3VyY2VBcm46IHRoaXMuYXBpLmFybkZvckV4ZWN1dGVBcGkoKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIEdyYW50IEFQSSBHYXRld2F5IHBlcm1pc3Npb24gdG8gaW52b2tlIHRoZSBKV1QgYXV0aG9yaXplciBMYW1iZGFcbiAgICBpZiAodGhpcy5fYXV0aG9yaXplckZuKSB7XG4gICAgICB0aGlzLl9hdXRob3JpemVyRm4uYWRkUGVybWlzc2lvbignQXBpR2F0ZXdheUF1dGhvcml6ZXJJbnZva2UnLCB7XG4gICAgICAgIHByaW5jaXBhbDogbmV3IGF3c19pYW0uU2VydmljZVByaW5jaXBhbCgnYXBpZ2F0ZXdheS5hbWF6b25hd3MuY29tJyksXG4gICAgICAgIGFjdGlvbjogJ2xhbWJkYTpJbnZva2VGdW5jdGlvbicsXG4gICAgICAgIHNvdXJjZUFybjogdGhpcy5hcGkuYXJuRm9yRXhlY3V0ZUFwaSgpLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGN1c3RvbURvbWFpbk5hbWUgJiYgdGhpcy5hcGkuZG9tYWluTmFtZSkge1xuICAgICAgbmV3IGF3c19yb3V0ZTUzLkFSZWNvcmQodGhpcywgJ0Ruc1JlY29yZCcsIHtcbiAgICAgICAgem9uZTogdGhpcy5ob3N0ZWRab25lISxcbiAgICAgICAgcmVjb3JkTmFtZTogY3VzdG9tRG9tYWluTmFtZS5kb21haW5OYW1lLFxuICAgICAgICB0YXJnZXQ6IGF3c19yb3V0ZTUzLlJlY29yZFRhcmdldC5mcm9tQWxpYXMoXG4gICAgICAgICAgbmV3IGF3c19yb3V0ZTUzX3RhcmdldHMuQXBpR2F0ZXdheURvbWFpbih0aGlzLmFwaS5kb21haW5OYW1lKSxcbiAgICAgICAgKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICB9XG5cbiAgcHJvdGVjdGVkIGNsZWFudXBTcGVjKHNwZWM6IHsgW2tleTogc3RyaW5nXTogYW55IH0pOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgICBPYmplY3QuZW50cmllcyhzcGVjKS5mb3JFYWNoKChbcHJvcCwgdmFsdWVdOiBbc3RyaW5nLCBhbnldKSA9PiB7XG4gICAgICBpZiAocHJvcC5zdGFydHNXaXRoKCd4LScpKSB7XG4gICAgICAgIGRlbGV0ZSBzcGVjW3Byb3BdO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIHRoaXMuY2xlYW51cFNwZWMoc3BlY1twcm9wXSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc3BlYztcbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm4gdGhlIGdlbmVyYXRlZCBMYW1iZGEgZnVuY3Rpb24gZm9yIHRoZSBzcGVjaWZpZWQgQVBJIG9wZXJhdGlvblxuICAgKi9cbiAgcHVibGljIGdldEZ1bmN0aW9uRm9yT3BlcmF0aW9uKG9wZXJhdGlvbklkOiBrZXlvZiBPUFMpOiBMYW1iZGFGdW5jdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuX2Z1bmN0aW9uc1tvcGVyYXRpb25JZCBhcyBzdHJpbmddO1xuICB9XG5cbiAgLyoqXG4gICAqIHJldHVybiBhIGxpc3Qgb2YgYWxsIGdlbmVyYXRlZCBMYW1iZGEgZnVuY3Rpb25zXG4gICAqL1xuICBwdWJsaWMgZ2V0RnVuY3Rpb25zKCk6IExhbWJkYUZ1bmN0aW9uW10ge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuX2Z1bmN0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogVmlzaXRvciBtZXRob2QgdG8gbW9kaWZ5IHRoZSBnaXZlbiBmdW5jdGlvbnNcbiAgICpcbiAgICogQHBhcmFtIG9wZXJhdGlvbklkcyB0aGUgbGlzdCBvZiBmdW5jdGlvbnMgdG8gdmlzaXRcbiAgICogQHBhcmFtIG9wIHRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBldmVyeSBmdW5jdGlvblxuICAgKi9cbiAgcHVibGljIG1vZGlmeU9wZXJhdGlvbkZ1bmN0aW9ucyhvcGVyYXRpb25JZHM6IChrZXlvZiBPUFMpW10sIG9wOiAoZm46IExhbWJkYUZ1bmN0aW9uKSA9PiB2b2lkKSB7XG4gICAgZm9yIChjb25zdCBvcGVyYXRpb25JZCBvZiBvcGVyYXRpb25JZHMpIHtcbiAgICAgIG9wKHRoaXMuZ2V0RnVuY3Rpb25Gb3JPcGVyYXRpb24ob3BlcmF0aW9uSWQpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVwbGFjZSB0aGUgZnVsbCBzZXQgb2YgYW5vbnltb3VzIG9wZXJhdGlvbnMuXG4gICAqIEFub255bW91cyBvcGVyYXRpb25zIHdpbGwgaGF2ZSBgc2VjdXJpdHk6IFtdYCBhcHBsaWVkIGluIHRoZSBPcGVuQVBJIHNwZWMsXG4gICAqIG1ha2luZyB0aGVtIHB1YmxpY2x5IGFjY2Vzc2libGUgd2l0aG91dCBhdXRoZW50aWNhdGlvbi5cbiAgICpcbiAgICogU2luY2UgQ0RLIHNlcmlhbGl6ZXMgdGhlIE9wZW5BUEkgc3BlYyBhdCBzeW50aCB0aW1lIChmcm9tSW5saW5lIHN0b3JlcyB0aGVcbiAgICogb2JqZWN0IHJlZmVyZW5jZSksIG11dGF0aW9ucyBhZnRlciBTcGVjUmVzdEFwaSBjb25zdHJ1Y3Rpb24gc3RpbGwgdGFrZSBlZmZlY3QuXG4gICAqXG4gICAqIEBwYXJhbSBvcGVyYXRpb25JZHMgLSBUaGUgb3BlcmF0aW9uIElEcyB0byBtYXJrIGFzIGFub255bW91cy4gUmVwbGFjZXMgYW55IHByZXZpb3VzbHkgc2V0IGFub255bW91cyBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHVibGljIHNldEFub255bW91c09wZXJhdGlvbnMob3BlcmF0aW9uSWRzOiAoa2V5b2YgT1BTKVtdKSB7XG4gICAgdGhpcy5fYW5vbnltb3VzT3BlcmF0aW9ucy5jbGVhcigpO1xuICAgIGZvciAoY29uc3Qgb3BJZCBvZiBvcGVyYXRpb25JZHMpIHtcbiAgICAgIHRoaXMuX2Fub255bW91c09wZXJhdGlvbnMuYWRkKG9wSWQgYXMgc3RyaW5nKTtcbiAgICB9XG4gICAgdGhpcy5hcHBseUFub255bW91c1NlY3VyaXR5KCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGFkZGl0aW9uYWwgb3BlcmF0aW9ucyB0byB0aGUgc2V0IG9mIGFub255bW91cyBvcGVyYXRpb25zLlxuICAgKiBOZXdseSBhZGRlZCBvcGVyYXRpb25zIHdpbGwgaGF2ZSBgc2VjdXJpdHk6IFtdYCBhcHBsaWVkIGluIHRoZSBPcGVuQVBJIHNwZWMuXG4gICAqXG4gICAqIFNpbmNlIENESyBzZXJpYWxpemVzIHRoZSBPcGVuQVBJIHNwZWMgYXQgc3ludGggdGltZSAoZnJvbUlubGluZSBzdG9yZXMgdGhlXG4gICAqIG9iamVjdCByZWZlcmVuY2UpLCBtdXRhdGlvbnMgYWZ0ZXIgU3BlY1Jlc3RBcGkgY29uc3RydWN0aW9uIHN0aWxsIHRha2UgZWZmZWN0LlxuICAgKlxuICAgKiBAcGFyYW0gb3BlcmF0aW9uSWRzIC0gVGhlIG9wZXJhdGlvbiBJRHMgdG8gYWRkIHRvIHRoZSBhbm9ueW1vdXMgc2V0LlxuICAgKi9cbiAgcHVibGljIGFkZEFub255bW91c09wZXJhdGlvbnMob3BlcmF0aW9uSWRzOiAoa2V5b2YgT1BTKVtdKSB7XG4gICAgZm9yIChjb25zdCBvcElkIG9mIG9wZXJhdGlvbklkcykge1xuICAgICAgdGhpcy5fYW5vbnltb3VzT3BlcmF0aW9ucy5hZGQob3BJZCBhcyBzdHJpbmcpO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5QW5vbnltb3VzU2VjdXJpdHlGb3JPcHMob3BlcmF0aW9uSWRzLm1hcChvcCA9PiBvcCBhcyBzdHJpbmcpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZS1hcHBsaWVzIHNlY3VyaXR5IHNldHRpbmdzIHRvIGFsbCBvcGVyYXRpb25zIGJhc2VkIG9uIHRoZSBjdXJyZW50IGFub255bW91cyBzZXQuXG4gICAqIE9wZXJhdGlvbnMgaW4gdGhlIGFub255bW91cyBzZXQgZ2V0IGBzZWN1cml0eTogW11gOyBvcGVyYXRpb25zIHJlbW92ZWQgZnJvbSB0aGUgc2V0XG4gICAqIGhhdmUgdGhlaXIgb3JpZ2luYWwgc2VjdXJpdHkgcmVzdG9yZWQuXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGFwcGx5QW5vbnltb3VzU2VjdXJpdHkoKSB7XG4gICAgZm9yIChjb25zdCBzcGVjUGF0aCBvZiBPYmplY3QudmFsdWVzKHRoaXMuYXBpU3BlYy5wYXRocyB8fCBbXSkpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHNwZWNQYXRoKSB7XG4gICAgICAgIGlmICghdGhpcy5hcGlNZXRob2RzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzcGVjTWV0aG9kID0gKHNwZWNQYXRoIGFzIFBhdGhJdGVtT2JqZWN0KVtrZXkgYXMga2V5b2YgUGF0aEl0ZW1PYmplY3RdISBhcyBPcGVyYXRpb25PYmplY3Q7XG4gICAgICAgIGlmIChzcGVjTWV0aG9kLm9wZXJhdGlvbklkICYmIHRoaXMuX2Fub255bW91c09wZXJhdGlvbnMuaGFzKHNwZWNNZXRob2Qub3BlcmF0aW9uSWQpKSB7XG4gICAgICAgICAgc3BlY01ldGhvZC5zZWN1cml0eSA9IFtdO1xuICAgICAgICB9IGVsc2UgaWYgKHNwZWNNZXRob2Qub3BlcmF0aW9uSWQgJiYgdGhpcy5fb3JpZ2luYWxPcGVyYXRpb25TZWN1cml0eS5oYXMoc3BlY01ldGhvZC5vcGVyYXRpb25JZCkpIHtcbiAgICAgICAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIHNlY3VyaXR5IGZvciBvcGVyYXRpb25zIHJlbW92ZWQgZnJvbSB0aGUgYW5vbnltb3VzIHNldFxuICAgICAgICAgIHNwZWNNZXRob2Quc2VjdXJpdHkgPSB0aGlzLl9vcmlnaW5hbE9wZXJhdGlvblNlY3VyaXR5LmdldChzcGVjTWV0aG9kLm9wZXJhdGlvbklkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIGBzZWN1cml0eTogW11gIG9ubHkgdG8gdGhlIHNwZWNpZmllZCBvcGVyYXRpb25zLlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUFub255bW91c1NlY3VyaXR5Rm9yT3BzKG9wZXJhdGlvbklkczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBvcHNTZXQgPSBuZXcgU2V0KG9wZXJhdGlvbklkcyk7XG4gICAgZm9yIChjb25zdCBzcGVjUGF0aCBvZiBPYmplY3QudmFsdWVzKHRoaXMuYXBpU3BlYy5wYXRocyB8fCBbXSkpIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIHNwZWNQYXRoKSB7XG4gICAgICAgIGlmICghdGhpcy5hcGlNZXRob2RzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzcGVjTWV0aG9kID0gKHNwZWNQYXRoIGFzIFBhdGhJdGVtT2JqZWN0KVtrZXkgYXMga2V5b2YgUGF0aEl0ZW1PYmplY3RdISBhcyBPcGVyYXRpb25PYmplY3Q7XG4gICAgICAgIGlmIChzcGVjTWV0aG9kLm9wZXJhdGlvbklkICYmIG9wc1NldC5oYXMoc3BlY01ldGhvZC5vcGVyYXRpb25JZCkpIHtcbiAgICAgICAgICBzcGVjTWV0aG9kLnNlY3VyaXR5ID0gW107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYWRkUmVzdFJlc291cmNlPFAgZXh0ZW5kcyBrZXlvZiBQQVRIUz4ocGF0aDogUCwgbWV0aG9kOiBrZXlvZiBQQVRIU1tQXSkge1xuICAgIGNvbnN0IG9hUGF0aCA9IHRoaXMuYXBpU3BlYy5wYXRocyFbcGF0aCBhcyBzdHJpbmddIGFzIFBhdGhJdGVtT2JqZWN0O1xuICAgIGNvbnN0IG9wZXJhdGlvbiA9IG9hUGF0aFttZXRob2QgYXMga2V5b2YgUGF0aEl0ZW1PYmplY3RdIGFzIE9wZXJhdGlvbk9iamVjdDtcbiAgICBjb25zdCBvcGVyYXRpb25JZCA9IG9wZXJhdGlvbi5vcGVyYXRpb25JZCE7XG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSBgJHttZXRob2QgYXMgc3RyaW5nfSAke3BhdGggYXMgc3RyaW5nfSAtICR7b3BlcmF0aW9uLnN1bW1hcnl9YDtcblxuICAgIGNvbnN0IGN1c3RvbUxhbWJkYU9wdGlvbnMgPSB0aGlzLnByb3BzLmxhbWJkYU9wdGlvbnNCeU9wZXJhdGlvbiA/IHRoaXMucHJvcHMubGFtYmRhT3B0aW9uc0J5T3BlcmF0aW9uW29wZXJhdGlvbklkIGFzIGtleW9mIE9QU10gOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHRoaXMuYWRkQ3VzdG9tUmVzdFJlc291cmNlKG9wZXJhdGlvbiwgbWV0aG9kIGFzIHN0cmluZywgZGVzY3JpcHRpb24sIGN1c3RvbUxhbWJkYU9wdGlvbnMpO1xuICB9XG5cbiAgcHVibGljIGFkZEN1c3RvbVJlc3RSZXNvdXJjZShvcGVyYXRpb246IE9wZXJhdGlvbk9iamVjdCwgbWV0aG9kOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcsIGFkZGl0aW9uYWxMYW1iZGFPcHRpb25zOiBMYW1iZGFPcHRpb25zID0ge30pIHtcbiAgICBpZiAoJ3gtYW1hem9uLWFwaWdhdGV3YXktaW50ZWdyYXRpb24nIGluIG9wZXJhdGlvbikge1xuICAgICAgcmV0dXJuOyAvLyBTa2lwIGlmIG9wZXJhdGlvbiB3YXMgZGVjbGFyZWQgaW4gc3BlYyBmaWxlIGFscmVhZHkhXG4gICAgfVxuXG4gICAgY29uc3QgZW50cnlGaWxlID0gYC4vc3JjL2xhbWJkYS9yZXN0LiR7dGhpcy5wcm9wcy5hcGlOYW1lLnRvTG93ZXJDYXNlKCl9LiR7b3BlcmF0aW9uLm9wZXJhdGlvbklkfS50c2A7XG5cbiAgICBjb25zdCBsYW1iZGFPcHRpb25zID0ge1xuICAgICAgLi4udGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zICYmIHtcbiAgICAgICAgLi4udGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zLFxuICAgICAgfSxcbiAgICAgIC4uLmFkZGl0aW9uYWxMYW1iZGFPcHRpb25zLFxuICAgIH07XG5cbiAgICBjb25zdCBhdXRoZW50aWNhdGlvbiA9IHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gJiYgKHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24uaGFzT3duUHJvcGVydHkoJ3VzZXJwb29sJylcbiAgICAgID8geyB1c2VyUG9vbDogKHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gYXMgSUNvZ25pdG9BdXRoZW50aWNhdGlvbikudXNlcnBvb2wgfVxuICAgICAgOiB7IGp3dDogdGhpcy5wcm9wcy5hdXRoZW50aWNhdGlvbiBhcyBJSnd0QXV0aGVudGljYXRpb24gfSk7XG5cbiAgICBjb25zdCBmbiA9IG5ldyBMYW1iZGFGdW5jdGlvbih0aGlzLCBgRm4ke29wZXJhdGlvbi5vcGVyYXRpb25JZH1gLCB7XG4gICAgICBzdGFnZU5hbWU6IHRoaXMucHJvcHMuc3RhZ2VOYW1lLFxuICAgICAgYWRkaXRpb25hbEVudjoge1xuICAgICAgICAuLi50aGlzLnByb3BzLmRvbWFpbk5hbWUgJiYge1xuICAgICAgICAgIERPTUFJTl9OQU1FOiB0aGlzLnByb3BzLmRvbWFpbk5hbWUsXG4gICAgICAgIH0sXG4gICAgICAgIC4uLnRoaXMucHJvcHMuYWRkaXRpb25hbEVudixcbiAgICAgIH0sXG4gICAgICBlbnRyeTogZW50cnlGaWxlLFxuICAgICAgZGVzY3JpcHRpb246IGBbJHt0aGlzLnByb3BzLnN0YWdlTmFtZX1dICR7ZGVzY3JpcHRpb259YCxcbiAgICAgIC4uLmF1dGhlbnRpY2F0aW9uLFxuICAgICAgLi4udGhpcy5wcm9wcy5zaW5nbGVUYWJsZURhdGFzdG9yZSAmJiB7XG4gICAgICAgIHRhYmxlOiB0aGlzLnByb3BzLnNpbmdsZVRhYmxlRGF0YXN0b3JlLnRhYmxlLFxuICAgICAgICB0YWJsZVdyaXRlczogdGhpcy50YWJsZVdyaXRlQWNjZXNzRm9yTWV0aG9kKG1ldGhvZCksXG4gICAgICB9LFxuICAgICAgLi4udGhpcy5wcm9wcy5hc3NldENkbiAmJiB7XG4gICAgICAgIGFzc2V0RG9tYWluTmFtZTogdGhpcy5wcm9wcy5hc3NldENkbi5hc3NldERvbWFpbk5hbWUsXG4gICAgICAgIGFzc2V0QnVja2V0OiB0aGlzLnByb3BzLmFzc2V0Q2RuLmFzc2V0QnVja2V0LFxuICAgICAgfSxcbiAgICAgIGxhbWJkYU9wdGlvbnMsXG4gICAgICBsYW1iZGFUcmFjaW5nOiB0aGlzLnByb3BzLmxhbWJkYVRyYWNpbmcsXG4gICAgfSk7XG4gICAgdGhpcy5fZnVuY3Rpb25zW29wZXJhdGlvbi5vcGVyYXRpb25JZCFdID0gZm47XG4gICAgY2RrLlRhZ3Mub2YoZm4pLmFkZCgnT3BlbkFQSScsIGRlc2NyaXB0aW9uLnJlcGxhY2UoL1teXFx3XFxzXFxkXy46Lz0rXFwtQF0vZywgJycpKTtcblxuICAgIC8vIGlmICh0aGlzLm1vbml0b3JpbmcpIHtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5sYW1iZGFEdXJhdGlvbnNXaWRnZXQuYWRkTGVmdE1ldHJpYyhmbi5tZXRyaWNEdXJhdGlvbigpKTtcbiAgICAvLyAgIHRoaXMubW9uaXRvcmluZy5sYW1iZGFJbnZva2VzV2lkZ2V0LmFkZExlZnRNZXRyaWMoZm4ubWV0cmljSW52b2NhdGlvbnMoKSk7XG4gICAgLy8gICB0aGlzLm1vbml0b3JpbmcubGFtYmRhRXJyb3JzV2lkZ2V0LmFkZExlZnRNZXRyaWMoZm4ubWV0cmljRXJyb3JzKCkpO1xuICAgIC8vICAgdGhpcy5tb25pdG9yaW5nLmxhbWJkYUVycm9yc1dpZGdldC5hZGRMZWZ0TWV0cmljKGZuLm1ldHJpY1Rocm90dGxlcygpKTtcbiAgICAvLyB9XG5cbiAgICBjb25zdCBoYXNWZXJzaW9uQ29uZmlnID0gbGFtYmRhT3B0aW9ucy5jdXJyZW50VmVyc2lvbk9wdGlvbnMgIT0gdW5kZWZpbmVkO1xuXG4gICAgb3BlcmF0aW9uWyd4LWFtYXpvbi1hcGlnYXRld2F5LWludGVncmF0aW9uJ10gPSB7XG4gICAgICB0eXBlOiAnYXdzX3Byb3h5JyxcbiAgICAgIGh0dHBNZXRob2Q6ICdQT1NUJyxcbiAgICAgIHVyaTogY2RrLlN0YWNrLm9mKHRoaXMpLmZvcm1hdEFybih7XG4gICAgICAgIHJlc291cmNlOiAncGF0aCcsXG4gICAgICAgIHNlcnZpY2U6ICdhcGlnYXRld2F5JyxcbiAgICAgICAgYWNjb3VudDogJ2xhbWJkYScsXG4gICAgICAgIGFybkZvcm1hdDogY2RrLkFybkZvcm1hdC5TTEFTSF9SRVNPVVJDRV9OQU1FLFxuICAgICAgICByZXNvdXJjZU5hbWU6IGAyMDE1LTAzLTMxL2Z1bmN0aW9ucy8keyhoYXNWZXJzaW9uQ29uZmlnID8gZm4uY3VycmVudFZlcnNpb24gOiBmbikuZnVuY3Rpb25Bcm59L2ludm9jYXRpb25zYCxcbiAgICAgICAgLy8gICAgICAgICAgICAgXl5eXl5eXl5eXiAtIFRISVMgTkVFRFMgVE8gQkUgVEhJUyBEQVRFLiBFWEFDVExZIVxuICAgICAgfSksXG4gICAgICBwYXNzdGhyb3VnaEJlaGF2aW9yOiAnd2hlbl9ub190ZW1wbGF0ZXMnLFxuICAgICAgcGF5bG9hZEZvcm1hdFZlcnNpb246ICcxLjAnLFxuICAgIH07XG5cbiAgICByZXR1cm4gZm47XG4gIH1cblxuICBwcml2YXRlIHRhYmxlV3JpdGVBY2Nlc3NGb3JNZXRob2QobWV0aG9kOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBzd2l0Y2ggKG1ldGhvZC50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICdkZWxldGUnOlxuICAgICAgY2FzZSAncG9zdCc6XG4gICAgICBjYXNlICdwdXQnOlxuICAgICAgY2FzZSAncGF0Y2gnOlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGNhc2UgJ29wdGlvbnMnOlxuICAgICAgY2FzZSAnZ2V0JzpcbiAgICAgIGNhc2UgJ2hlYWQnOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbmplY3RzIHNlY3VyaXR5RGVmaW5pdGlvbnMgaW50byB0aGUgT3BlbkFQSSBzcGVjIGJhc2VkIG9uIHRoZSBhdXRoZW50aWNhdGlvbiB0eXBlLlxuICAgKiBGb3IgQ29nbml0bzogYWRkcyBhIGNvZ25pdG9fdXNlcl9wb29scyBhdXRob3JpemVyIHJlZmVyZW5jaW5nIHRoZSB1c2VyIHBvb2wgQVJOLlxuICAgKiBGb3IgSldUOiBjcmVhdGVzIGEgTGFtYmRhIGF1dGhvcml6ZXIgZnVuY3Rpb24gYW5kIGFkZHMgYSB0b2tlbiBhdXRob3JpemVyIHJlZmVyZW5jaW5nIGl0cyBBUk4uXG4gICAqL1xuICBwcm90ZWN0ZWQgcGF0Y2hTZWN1cml0eVNjaGVtZXMoc3BlYzogT3BlbkFQSTMpIHtcbiAgICBpZiAoIXRoaXMucHJvcHMuYXV0aGVudGljYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzcGVjQW55ID0gc3BlYyBhcyBhbnk7XG4gICAgaWYgKCFzcGVjQW55LnNlY3VyaXR5RGVmaW5pdGlvbnMpIHtcbiAgICAgIHNwZWNBbnkuc2VjdXJpdHlEZWZpbml0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByb3BzLmF1dGhlbnRpY2F0aW9uLmhhc093blByb3BlcnR5KCd1c2VycG9vbCcpKSB7XG4gICAgICAvLyBDb2duaXRvIFVzZXIgUG9vbCBhdXRob3JpemVyXG4gICAgICBjb25zdCBjb2duaXRvQXV0aCA9IHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gYXMgSUNvZ25pdG9BdXRoZW50aWNhdGlvbjtcbiAgICAgIGNvbnN0IGF1dGhvcml6ZXJOYW1lID0gJ0NvZ25pdG9BdXRob3JpemVyJztcblxuICAgICAgc3BlY0FueS5zZWN1cml0eURlZmluaXRpb25zW2F1dGhvcml6ZXJOYW1lXSA9IHtcbiAgICAgICAgJ3R5cGUnOiAnYXBpS2V5JyxcbiAgICAgICAgJ25hbWUnOiAnQXV0aG9yaXphdGlvbicsXG4gICAgICAgICdpbic6ICdoZWFkZXInLFxuICAgICAgICAneC1hbWF6b24tYXBpZ2F0ZXdheS1hdXRodHlwZSc6ICdjb2duaXRvX3VzZXJfcG9vbHMnLFxuICAgICAgICAneC1hbWF6b24tYXBpZ2F0ZXdheS1hdXRob3JpemVyJzoge1xuICAgICAgICAgIHR5cGU6ICdjb2duaXRvX3VzZXJfcG9vbHMnLFxuICAgICAgICAgIHByb3ZpZGVyQVJOczogW2NvZ25pdG9BdXRoLnVzZXJwb29sLnVzZXJQb29sQXJuXSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIEVuc3VyZSBnbG9iYWwgc2VjdXJpdHkgcmVmZXJlbmNlcyB0aGUgYXV0aG9yaXplciBzbyBwYXRjaFNlY3VyaXR5IGRpc3RyaWJ1dGVzIGl0XG4gICAgICBpZiAoIXNwZWMuc2VjdXJpdHkpIHtcbiAgICAgICAgc3BlYy5zZWN1cml0eSA9IFt7IFthdXRob3JpemVyTmFtZV06IFtdIH1dO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBKV1QgKExhbWJkYSkgYXV0aG9yaXplclxuICAgICAgY29uc3Qgand0QXV0aCA9IHRoaXMucHJvcHMuYXV0aGVudGljYXRpb24gYXMgSUp3dEF1dGhlbnRpY2F0aW9uO1xuICAgICAgY29uc3QgYXV0aG9yaXplck5hbWUgPSAnSnd0QXV0aG9yaXplcic7XG5cbiAgICAgIGNvbnN0IGF1dGhvcml6ZXJGbiA9IG5ldyBMYW1iZGFGdW5jdGlvbih0aGlzLCAnSnd0QXV0aG9yaXplckZuJywge1xuICAgICAgICBzdGFnZU5hbWU6IHRoaXMucHJvcHMuc3RhZ2VOYW1lLFxuICAgICAgICBlbnRyeTogJ3NyYy9sYW1iZGEvcmVzdC1hcGkuand0LWF1dGhvcml6ZXIudHMnLFxuICAgICAgICBkZXNjcmlwdGlvbjogYFske3RoaXMucHJvcHMuc3RhZ2VOYW1lfV0gSldUIEF1dGhvcml6ZXIgZm9yICR7dGhpcy5wcm9wcy5hcGlOYW1lfWAsXG4gICAgICAgIGp3dDogand0QXV0aCxcbiAgICAgICAgbGFtYmRhT3B0aW9uczogdGhpcy5wcm9wcy5sYW1iZGFPcHRpb25zLFxuICAgICAgICBsYW1iZGFUcmFjaW5nOiB0aGlzLnByb3BzLmxhbWJkYVRyYWNpbmcsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgYXV0aG9yaXplclVyaSA9IGNkay5TdGFjay5vZih0aGlzKS5mb3JtYXRBcm4oe1xuICAgICAgICByZXNvdXJjZTogJ3BhdGgnLFxuICAgICAgICBzZXJ2aWNlOiAnYXBpZ2F0ZXdheScsXG4gICAgICAgIGFjY291bnQ6ICdsYW1iZGEnLFxuICAgICAgICBhcm5Gb3JtYXQ6IGNkay5Bcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSxcbiAgICAgICAgcmVzb3VyY2VOYW1lOiBgMjAxNS0wMy0zMS9mdW5jdGlvbnMvJHthdXRob3JpemVyRm4uZnVuY3Rpb25Bcm59L2ludm9jYXRpb25zYCxcbiAgICAgIH0pO1xuXG4gICAgICBzcGVjQW55LnNlY3VyaXR5RGVmaW5pdGlvbnNbYXV0aG9yaXplck5hbWVdID0ge1xuICAgICAgICAndHlwZSc6ICdhcGlLZXknLFxuICAgICAgICAnbmFtZSc6ICdBdXRob3JpemF0aW9uJyxcbiAgICAgICAgJ2luJzogJ2hlYWRlcicsXG4gICAgICAgICd4LWFtYXpvbi1hcGlnYXRld2F5LWF1dGh0eXBlJzogJ2N1c3RvbScsXG4gICAgICAgICd4LWFtYXpvbi1hcGlnYXRld2F5LWF1dGhvcml6ZXInOiB7XG4gICAgICAgICAgdHlwZTogdGhpcy5wcm9wcy5qd3RBdXRob3JpemVyVHlwZSA9PT0gJ3JlcXVlc3QnID8gJ3JlcXVlc3QnIDogJ3Rva2VuJyxcbiAgICAgICAgICBhdXRob3JpemVyVXJpOiBhdXRob3JpemVyVXJpLFxuICAgICAgICAgIGF1dGhvcml6ZXJSZXN1bHRUdGxJblNlY29uZHM6IHRoaXMucHJvcHMuand0QXV0aG9yaXplclR5cGUgPT09ICdyZXF1ZXN0JyA/IDAgOiAzMDAsXG4gICAgICAgICAgLi4uKHRoaXMucHJvcHMuand0QXV0aG9yaXplclR5cGUgIT09ICdyZXF1ZXN0JyAmJiB7XG4gICAgICAgICAgICBpZGVudGl0eVNvdXJjZTogJ21ldGhvZC5yZXF1ZXN0LmhlYWRlci5BdXRob3JpemF0aW9uJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIC8vIFN0b3JlIHRoZSBhdXRob3JpemVyIGZ1bmN0aW9uIHNvIHdlIGNhbiBncmFudCBwZXJtaXNzaW9uIGFmdGVyIHRoZSBTcGVjUmVzdEFwaSBpcyBjcmVhdGVkXG4gICAgICB0aGlzLl9hdXRob3JpemVyRm4gPSBhdXRob3JpemVyRm47XG5cbiAgICAgIC8vIEVuc3VyZSBnbG9iYWwgc2VjdXJpdHkgcmVmZXJlbmNlcyB0aGUgYXV0aG9yaXplciBzbyBwYXRjaFNlY3VyaXR5IGRpc3RyaWJ1dGVzIGl0XG4gICAgICBpZiAoIXNwZWMuc2VjdXJpdHkpIHtcbiAgICAgICAgc3BlYy5zZWN1cml0eSA9IFt7IFthdXRob3JpemVyTmFtZV06IFtdIH1dO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBV1MgZG9lcyBub3QgcHJvcGVybHkgYXBwbHkgdGhlICdzZWN1cml0eScgb3B0aW9uIHRvIGV2ZXJ5IHNpbmdsZSBwYXRoLW1ldGhvZC5cbiAgICogQWNjb3JkaW5nIHRvIGRvY3VtZW50YXRpb24sIGdsb2JhbCBzZWN1cml0eSBnZXRzIGFwcGxpZWQsIGlmIHRoZXJlIGlzIG5vIHNlY3VyaXR5XG4gICAqIHNldCBmb3IgdGhlIHBhcnRpY3VsYXIgcGF0aC1tZXRob2QuIElmIHRoZXJlIGlzIGFueSwgZXZlbiBlbXB0eSwgaXQgd2lsbCBnZXQgcHJlY2VkZW5jZS5cbiAgICogVEhJUyBET0VTIE5PVCBIQVBQRU4gT04gQVdTLiBJVCBKVVNUIEFMV0FZUyBVU0VTIFRIRSBHTE9CQUwgU0VUVElORyFcbiAgICpcbiAgICogJ3NlY3VyaXR5IGFwcGxpZXMgWy4uLl0gc2NoZW1lcyBnbG9iYWxseSB0byBhbGwgQVBJIG9wZXJhdGlvbnMsIHVubGVzcyBvdmVycmlkZGVuIG9uIHRoZSBvcGVyYXRpb24gbGV2ZWwnXG4gICAqIEBzZWUgaHR0cHM6Ly9zd2FnZ2VyLmlvL2RvY3Mvc3BlY2lmaWNhdGlvbi9hdXRoZW50aWNhdGlvbi9cbiAgICovXG4gIHByb3RlY3RlZCBwYXRjaFNlY3VyaXR5KHNwZWM6IE9wZW5BUEkzKSB7XG4gICAgaWYgKCdzZWN1cml0eScgaW4gc3BlYykge1xuICAgICAgZm9yIChjb25zdCBzcGVjUGF0aCBvZiBPYmplY3QudmFsdWVzKHNwZWMucGF0aHMgfHwgW10pKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNwZWNQYXRoKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLmFwaU1ldGhvZHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICAgICAgY29udGludWU7IC8vIFNraXAgaWYgbm90IGh0dHAgbWV0aG9kIGRlZmluaXRpb25cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBzcGVjTWV0aG9kID0gKHNwZWNQYXRoIGFzIFBhdGhJdGVtT2JqZWN0KVtrZXkgYXMga2V5b2YgUGF0aEl0ZW1PYmplY3RdITtcbiAgICAgICAgICBpZiAoISgnc2VjdXJpdHknIGluIHNwZWNNZXRob2QpKSB7XG4gICAgICAgICAgICBjb25zdCBvcGVyYXRpb25JZCA9IChzcGVjTWV0aG9kIGFzIE9wZXJhdGlvbk9iamVjdCkub3BlcmF0aW9uSWQ7XG4gICAgICAgICAgICBpZiAob3BlcmF0aW9uSWQgJiYgdGhpcy5fYW5vbnltb3VzT3BlcmF0aW9ucy5oYXMob3BlcmF0aW9uSWQpKSB7XG4gICAgICAgICAgICAgIC8vIFN0b3JlIHdoYXQgc2VjdXJpdHkgd291bGQgaGF2ZSBiZWVuIGFwcGxpZWQgc28gd2UgY2FuIHJlc3RvcmUgbGF0ZXJcbiAgICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxPcGVyYXRpb25TZWN1cml0eS5zZXQob3BlcmF0aW9uSWQsIHNwZWMuc2VjdXJpdHkgYXMgYW55W10pO1xuICAgICAgICAgICAgICBzcGVjTWV0aG9kLnNlY3VyaXR5ID0gW107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzcGVjTWV0aG9kLnNlY3VyaXR5ID0gc3BlYy5zZWN1cml0eTtcbiAgICAgICAgICAgICAgaWYgKG9wZXJhdGlvbklkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxPcGVyYXRpb25TZWN1cml0eS5zZXQob3BlcmF0aW9uSWQsIHNwZWMuc2VjdXJpdHkgYXMgYW55W10pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE9wZXJhdGlvbiBhbHJlYWR5IGhhcyBleHBsaWNpdCBzZWN1cml0eSBkZWZpbmVkIGluIHRoZSBzcGVjXG4gICAgICAgICAgICBjb25zdCBvcGVyYXRpb25JZCA9IChzcGVjTWV0aG9kIGFzIE9wZXJhdGlvbk9iamVjdCkub3BlcmF0aW9uSWQ7XG4gICAgICAgICAgICBpZiAob3BlcmF0aW9uSWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxPcGVyYXRpb25TZWN1cml0eS5zZXQob3BlcmF0aW9uSWQsIHNwZWNNZXRob2Quc2VjdXJpdHkgYXMgYW55W10pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZGVsZXRlIHNwZWMuc2VjdXJpdHk7XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==