@aws-cdk/aws-bedrock-agentcore-alpha 2.250.0-alpha.0 → 2.252.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.jsii +11883 -7285
  2. package/.jsii.tabl.json.gz +0 -0
  3. package/.warnings.jsii.js +4 -0
  4. package/README.md +405 -0
  5. package/lib/gateway/gateway-base.js +1 -1
  6. package/lib/gateway/gateway.d.ts +58 -0
  7. package/lib/gateway/gateway.js +46 -3
  8. package/lib/gateway/inbound-auth/authorizer.d.ts +27 -1
  9. package/lib/gateway/inbound-auth/authorizer.js +37 -5
  10. package/lib/gateway/inbound-auth/custom-claim.js +1 -1
  11. package/lib/gateway/interceptor.js +1 -1
  12. package/lib/gateway/outbound-auth/api-key.js +1 -1
  13. package/lib/gateway/outbound-auth/credential-provider.js +1 -1
  14. package/lib/gateway/protocol.js +2 -2
  15. package/lib/gateway/targets/schema/api-schema.js +4 -4
  16. package/lib/gateway/targets/schema/tool-schema.js +4 -4
  17. package/lib/gateway/targets/target-base.js +1 -1
  18. package/lib/gateway/targets/target-configuration.js +6 -6
  19. package/lib/gateway/targets/target.js +1 -1
  20. package/lib/index.d.ts +8 -0
  21. package/lib/index.js +13 -1
  22. package/lib/memory/memory-strategy.js +1 -1
  23. package/lib/memory/memory.js +2 -2
  24. package/lib/memory/strategies/managed-strategy.js +1 -1
  25. package/lib/memory/strategies/self-managed-strategy.js +1 -1
  26. package/lib/network/network-configuration.js +4 -4
  27. package/lib/policy/perms.d.ts +50 -0
  28. package/lib/policy/perms.js +62 -0
  29. package/lib/policy/policy-base.d.ts +194 -0
  30. package/lib/policy/policy-base.js +120 -0
  31. package/lib/policy/policy-engine-base.d.ts +260 -0
  32. package/lib/policy/policy-engine-base.js +193 -0
  33. package/lib/policy/policy-engine.d.ts +150 -0
  34. package/lib/policy/policy-engine.js +290 -0
  35. package/lib/policy/policy-statement.d.ts +518 -0
  36. package/lib/policy/policy-statement.js +927 -0
  37. package/lib/policy/policy-types.d.ts +66 -0
  38. package/lib/policy/policy-types.js +30 -0
  39. package/lib/policy/policy.d.ts +127 -0
  40. package/lib/policy/policy.js +225 -0
  41. package/lib/policy/validation-helpers.d.ts +139 -0
  42. package/lib/policy/validation-helpers.js +276 -0
  43. package/lib/runtime/inbound-auth/custom-claim.js +1 -1
  44. package/lib/runtime/inbound-auth/runtime-authorizer-configuration.js +1 -1
  45. package/lib/runtime/observability.d.ts +105 -0
  46. package/lib/runtime/observability.js +317 -0
  47. package/lib/runtime/runtime-artifact.js +1 -1
  48. package/lib/runtime/runtime-base.js +1 -1
  49. package/lib/runtime/runtime-endpoint-base.js +1 -1
  50. package/lib/runtime/runtime-endpoint.js +1 -1
  51. package/lib/runtime/runtime.d.ts +17 -0
  52. package/lib/runtime/runtime.js +10 -2
  53. package/lib/tools/browser.js +2 -2
  54. package/lib/tools/code-interpreter.js +2 -2
  55. package/package.json +9 -9
  56. package/rosetta/default.ts-fixture +2 -0
@@ -0,0 +1,927 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PolicyStatement = exports.AttributeAccessor = exports.ConditionalAttributeAccessor = exports.ConditionalPolicyStatement = exports.ConditionBuilder = void 0;
4
+ const jsiiDeprecationWarnings = require("../../.warnings.jsii.js");
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ /**
7
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
10
+ * with the License. A copy of the License is located at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
15
+ * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
16
+ * and limitations under the License.
17
+ */
18
+ const errors_1 = require("aws-cdk-lib/core/lib/errors");
19
+ const helpers_internal_1 = require("aws-cdk-lib/core/lib/helpers-internal");
20
+ /**
21
+ * Effect of the policy statement - whether to permit or forbid the action.
22
+ * @internal
23
+ */
24
+ var PolicyEffect;
25
+ (function (PolicyEffect) {
26
+ /**
27
+ * Permit the action if conditions are met
28
+ */
29
+ PolicyEffect["PERMIT"] = "permit";
30
+ /**
31
+ * Forbid (deny) the action if conditions are met
32
+ */
33
+ PolicyEffect["FORBID"] = "forbid";
34
+ })(PolicyEffect || (PolicyEffect = {}));
35
+ /**
36
+ * Scope for principals - whether to apply to all principals or specific ones.
37
+ * @internal
38
+ */
39
+ var PrincipalScope;
40
+ (function (PrincipalScope) {
41
+ /**
42
+ * Apply to all principals
43
+ */
44
+ PrincipalScope["ALL"] = "all";
45
+ /**
46
+ * Apply to specific principal(s)
47
+ */
48
+ PrincipalScope["SPECIFIC"] = "specific";
49
+ })(PrincipalScope || (PrincipalScope = {}));
50
+ /**
51
+ * Scope for actions - whether to apply to all actions or specific ones.
52
+ * @internal
53
+ */
54
+ var ActionScope;
55
+ (function (ActionScope) {
56
+ /**
57
+ * Apply to all actions
58
+ */
59
+ ActionScope["ALL"] = "all";
60
+ /**
61
+ * Apply to specific action(s)
62
+ */
63
+ ActionScope["SPECIFIC"] = "specific";
64
+ })(ActionScope || (ActionScope = {}));
65
+ /**
66
+ * Scope for resources - whether to apply to all resources, resource types, or specific ones.
67
+ * @internal
68
+ */
69
+ var ResourceScope;
70
+ (function (ResourceScope) {
71
+ /**
72
+ * Apply to all resources (wildcard - may be rejected by service)
73
+ */
74
+ ResourceScope["ALL"] = "all";
75
+ /**
76
+ * Apply to all resources of a specific type
77
+ */
78
+ ResourceScope["TYPE"] = "type";
79
+ /**
80
+ * Apply to specific resource(s)
81
+ */
82
+ ResourceScope["SPECIFIC"] = "specific";
83
+ })(ResourceScope || (ResourceScope = {}));
84
+ /**
85
+ * A single condition expression in Cedar policy language.
86
+ */
87
+ class ConditionExpression {
88
+ attribute;
89
+ operator;
90
+ value;
91
+ constructor(attribute, operator, value) {
92
+ this.attribute = attribute;
93
+ this.operator = operator;
94
+ this.value = value;
95
+ }
96
+ toCedar() {
97
+ const formattedValue = typeof this.value === 'string' && !this.value.startsWith('ip(')
98
+ ? `"${this.value}"`
99
+ : this.value;
100
+ return `${this.attribute} ${this.operator} ${formattedValue}`;
101
+ }
102
+ }
103
+ /**
104
+ * Builder for condition expressions in Cedar policies.
105
+ *
106
+ * Conditions define when a policy statement should apply or not apply.
107
+ * Supports logical operators (AND, OR) and various comparison operators.
108
+ */
109
+ class ConditionBuilder {
110
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.ConditionBuilder", version: "2.252.0-alpha.0" };
111
+ conditions = [];
112
+ operators = [];
113
+ /**
114
+ * Access a principal attribute for comparison.
115
+ *
116
+ * Principal attributes come from the authenticated user/service making the request.
117
+ * Common attributes: username, role, department, groups, etc.
118
+ *
119
+ * @param attribute - The attribute name (e.g., 'department', 'role', 'username')
120
+ */
121
+ principalAttribute(attribute) {
122
+ return new AttributeAccessor(`principal.${attribute}`, this);
123
+ }
124
+ /**
125
+ * Access a resource attribute for comparison.
126
+ *
127
+ * Resource attributes come from the target resource being accessed.
128
+ * Common attributes: arn, type, tags, owner, etc.
129
+ *
130
+ * @param attribute - The attribute name (e.g., 'confidential', 'owner', 'classification')
131
+ */
132
+ resourceAttribute(attribute) {
133
+ return new AttributeAccessor(`resource.${attribute}`, this);
134
+ }
135
+ /**
136
+ * Access a context attribute for comparison.
137
+ *
138
+ * Context attributes come from the request environment.
139
+ * Common attributes: sourceIp, timestamp, environment, region, etc.
140
+ *
141
+ * @param attribute - The attribute name (e.g., 'sourceIp', 'environment', 'timestamp')
142
+ */
143
+ contextAttribute(attribute) {
144
+ return new AttributeAccessor(`context.${attribute}`, this);
145
+ }
146
+ /**
147
+ * Logical AND operator - all conditions must be true.
148
+ */
149
+ and() {
150
+ this.operators.push('&&');
151
+ return this;
152
+ }
153
+ /**
154
+ * Logical OR operator - at least one condition must be true.
155
+ */
156
+ or() {
157
+ this.operators.push('||');
158
+ return this;
159
+ }
160
+ /**
161
+ * Internal method to add a condition expression.
162
+ * @internal
163
+ */
164
+ _addCondition(condition) {
165
+ this.conditions.push(condition);
166
+ return this;
167
+ }
168
+ /**
169
+ * Generate Cedar condition syntax.
170
+ * @internal
171
+ */
172
+ _toCedar() {
173
+ if (this.conditions.length === 0) {
174
+ return '';
175
+ }
176
+ let cedar = '';
177
+ for (let i = 0; i < this.conditions.length; i++) {
178
+ cedar += `${this.conditions[i].toCedar()}`;
179
+ if (i < this.operators.length) {
180
+ cedar += ` ${this.operators[i]} `;
181
+ }
182
+ }
183
+ return cedar;
184
+ }
185
+ }
186
+ exports.ConditionBuilder = ConditionBuilder;
187
+ /**
188
+ * Wrapper class for conditionally building policy statements.
189
+ *
190
+ * This class allows chaining condition methods and returning to the parent
191
+ * PolicyStatement when done. It proxies condition building methods from
192
+ * ConditionBuilder.
193
+ */
194
+ class ConditionalPolicyStatement {
195
+ policyStatement;
196
+ conditionBuilder;
197
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.ConditionalPolicyStatement", version: "2.252.0-alpha.0" };
198
+ constructor(policyStatement, conditionBuilder) {
199
+ this.policyStatement = policyStatement;
200
+ this.conditionBuilder = conditionBuilder;
201
+ try {
202
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_PolicyStatement(policyStatement);
203
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ConditionBuilder(conditionBuilder);
204
+ }
205
+ catch (error) {
206
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
207
+ Error.captureStackTrace(error, ConditionalPolicyStatement);
208
+ }
209
+ throw error;
210
+ }
211
+ }
212
+ /**
213
+ * Access a principal attribute for comparison.
214
+ *
215
+ * @param attribute - The attribute name (e.g., 'department', 'role', 'username')
216
+ */
217
+ principalAttribute(attribute) {
218
+ return new ConditionalAttributeAccessor(`principal.${attribute}`, this, this.conditionBuilder);
219
+ }
220
+ /**
221
+ * Access a resource attribute for comparison.
222
+ *
223
+ * @param attribute - The attribute name (e.g., 'confidential', 'owner', 'classification')
224
+ */
225
+ resourceAttribute(attribute) {
226
+ return new ConditionalAttributeAccessor(`resource.${attribute}`, this, this.conditionBuilder);
227
+ }
228
+ /**
229
+ * Access a context attribute for comparison.
230
+ *
231
+ * @param attribute - The attribute name (e.g., 'sourceIp', 'environment', 'timestamp')
232
+ */
233
+ contextAttribute(attribute) {
234
+ return new ConditionalAttributeAccessor(`context.${attribute}`, this, this.conditionBuilder);
235
+ }
236
+ /**
237
+ * Logical AND operator - all conditions must be true.
238
+ */
239
+ and() {
240
+ this.conditionBuilder.and();
241
+ return this;
242
+ }
243
+ /**
244
+ * Logical OR operator - at least one condition must be true.
245
+ */
246
+ or() {
247
+ this.conditionBuilder.or();
248
+ return this;
249
+ }
250
+ /**
251
+ * Complete condition building and return to the PolicyStatement.
252
+ *
253
+ * Use this to finish building when/unless conditions and continue
254
+ * configuring the policy statement.
255
+ */
256
+ done() {
257
+ return this.policyStatement;
258
+ }
259
+ /**
260
+ * Alias for done() to support fluent unless() chaining.
261
+ */
262
+ unless() {
263
+ return this.policyStatement.unless();
264
+ }
265
+ }
266
+ exports.ConditionalPolicyStatement = ConditionalPolicyStatement;
267
+ /**
268
+ * Accessor for building type-safe attribute comparisons within conditional statements.
269
+ *
270
+ * Returns ConditionalPolicyStatement to allow chaining back to policy building.
271
+ */
272
+ class ConditionalAttributeAccessor {
273
+ path;
274
+ parent;
275
+ conditionBuilder;
276
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.ConditionalAttributeAccessor", version: "2.252.0-alpha.0" };
277
+ constructor(path, parent, conditionBuilder) {
278
+ this.path = path;
279
+ this.parent = parent;
280
+ this.conditionBuilder = conditionBuilder;
281
+ try {
282
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ConditionalPolicyStatement(parent);
283
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ConditionBuilder(conditionBuilder);
284
+ }
285
+ catch (error) {
286
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
287
+ Error.captureStackTrace(error, ConditionalAttributeAccessor);
288
+ }
289
+ throw error;
290
+ }
291
+ }
292
+ /**
293
+ * Equality comparison (==)
294
+ */
295
+ equalTo(value) {
296
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, '==', value));
297
+ return this.parent;
298
+ }
299
+ /**
300
+ * Inequality comparison (!=)
301
+ */
302
+ notEqualTo(value) {
303
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, '!=', value));
304
+ return this.parent;
305
+ }
306
+ /**
307
+ * Less than comparison (<)
308
+ */
309
+ lessThan(value) {
310
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, '<', value));
311
+ return this.parent;
312
+ }
313
+ /**
314
+ * Less than or equals comparison (<=)
315
+ */
316
+ lessThanOrEqualTo(value) {
317
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, '<=', value));
318
+ return this.parent;
319
+ }
320
+ /**
321
+ * Greater than comparison (>)
322
+ */
323
+ greaterThan(value) {
324
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, '>', value));
325
+ return this.parent;
326
+ }
327
+ /**
328
+ * Greater than or equals comparison (>=)
329
+ */
330
+ greaterThanOrEqualTo(value) {
331
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, '>=', value));
332
+ return this.parent;
333
+ }
334
+ /**
335
+ * IP range check - tests if IP address is in CIDR range.
336
+ *
337
+ * @param ipRange - CIDR notation (e.g., '192.168.1.0/24')
338
+ */
339
+ isInRange(ipRange) {
340
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, 'isInRange', `ip("${ipRange}")`));
341
+ return this.parent;
342
+ }
343
+ /**
344
+ * String contains check.
345
+ */
346
+ contains(value) {
347
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, 'contains', value));
348
+ return this.parent;
349
+ }
350
+ /**
351
+ * Check if attribute is in a set/list.
352
+ */
353
+ isIn(values) {
354
+ const formattedValues = values.map(v => typeof v === 'string' ? `"${v}"` : v).join(', ');
355
+ this.conditionBuilder._addCondition(new ConditionExpression(this.path, 'in', `[${formattedValues}]`));
356
+ return this.parent;
357
+ }
358
+ }
359
+ exports.ConditionalAttributeAccessor = ConditionalAttributeAccessor;
360
+ /**
361
+ * Accessor for building type-safe attribute comparisons.
362
+ *
363
+ * Provides methods for common comparison operators with proper type checking.
364
+ */
365
+ class AttributeAccessor {
366
+ path;
367
+ parent;
368
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.AttributeAccessor", version: "2.252.0-alpha.0" };
369
+ constructor(path, parent) {
370
+ this.path = path;
371
+ this.parent = parent;
372
+ try {
373
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ConditionBuilder(parent);
374
+ }
375
+ catch (error) {
376
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
377
+ Error.captureStackTrace(error, AttributeAccessor);
378
+ }
379
+ throw error;
380
+ }
381
+ }
382
+ /**
383
+ * Equality comparison (==)
384
+ */
385
+ equalTo(value) {
386
+ return this.parent._addCondition(new ConditionExpression(this.path, '==', value));
387
+ }
388
+ /**
389
+ * Inequality comparison (!=)
390
+ */
391
+ notEqualTo(value) {
392
+ return this.parent._addCondition(new ConditionExpression(this.path, '!=', value));
393
+ }
394
+ /**
395
+ * Less than comparison (<)
396
+ */
397
+ lessThan(value) {
398
+ return this.parent._addCondition(new ConditionExpression(this.path, '<', value));
399
+ }
400
+ /**
401
+ * Less than or equals comparison (<=)
402
+ */
403
+ lessThanOrEqualTo(value) {
404
+ return this.parent._addCondition(new ConditionExpression(this.path, '<=', value));
405
+ }
406
+ /**
407
+ * Greater than comparison (>)
408
+ */
409
+ greaterThan(value) {
410
+ return this.parent._addCondition(new ConditionExpression(this.path, '>', value));
411
+ }
412
+ /**
413
+ * Greater than or equals comparison (>=)
414
+ */
415
+ greaterThanOrEqualTo(value) {
416
+ return this.parent._addCondition(new ConditionExpression(this.path, '>=', value));
417
+ }
418
+ /**
419
+ * IP range check - tests if IP address is in CIDR range.
420
+ *
421
+ * @param ipRange - CIDR notation (e.g., '192.168.1.0/24')
422
+ */
423
+ isInRange(ipRange) {
424
+ return this.parent._addCondition(new ConditionExpression(this.path, 'isInRange', `ip("${ipRange}")`));
425
+ }
426
+ /**
427
+ * String contains check.
428
+ */
429
+ contains(value) {
430
+ return this.parent._addCondition(new ConditionExpression(this.path, 'contains', value));
431
+ }
432
+ /**
433
+ * Check if attribute is in a set/list.
434
+ */
435
+ isIn(values) {
436
+ const formattedValues = values.map(v => typeof v === 'string' ? `"${v}"` : v).join(', ');
437
+ return this.parent._addCondition(new ConditionExpression(this.path, 'in', `[${formattedValues}]`));
438
+ }
439
+ }
440
+ exports.AttributeAccessor = AttributeAccessor;
441
+ /**
442
+ * Type-safe builder for creating Cedar authorization policy statements.
443
+ *
444
+ * This builder provides a fluent API for constructing Cedar policies without
445
+ * requiring knowledge of Cedar syntax. It supports:
446
+ * - Permit and forbid effects
447
+ * - Principal, action, and resource specifications
448
+ * - Conditional logic (when/unless clauses)
449
+ * - Raw Cedar for advanced cases
450
+ *
451
+ * The builder generates valid Cedar policy statements that can be used with
452
+ * the Policy construct.
453
+ *
454
+ * @example
455
+ * import { Policy, PolicyEngine, PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
456
+ * declare const engine: PolicyEngine;
457
+ *
458
+ * // Example 1: Simple permit policy
459
+ * // Builder format:
460
+ * new Policy(this, 'AllowAll', {
461
+ * policyEngine: engine,
462
+ * statement: PolicyStatement.permit()
463
+ * .forAllPrincipals()
464
+ * .onAllActions()
465
+ * .onAllResources(),
466
+ * });
467
+ *
468
+ * // Generated Cedar:
469
+ * // permit(
470
+ * // principal,
471
+ * // action,
472
+ * // resource
473
+ * // );
474
+ *
475
+ * @example
476
+ * import { Policy, PolicyEngine, PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
477
+ * declare const engine: PolicyEngine;
478
+ * declare const gatewayArn: string;
479
+ *
480
+ * // Example 2: Specific actions policy
481
+ * // Builder format:
482
+ * new Policy(this, 'AllowSpecificActions', {
483
+ * policyEngine: engine,
484
+ * statement: PolicyStatement.permit()
485
+ * .forPrincipalInGroup('Group', 'Engineers')
486
+ * .onActions([
487
+ * 'AgentCore::Action::exampleaction1',
488
+ * 'AgentCore::Action::exampleaction2',
489
+ * ])
490
+ * .onResource('AgentCore::Gateway', gatewayArn),
491
+ * });
492
+ *
493
+ * // Generated Cedar:
494
+ * // permit(
495
+ * // principal in Group::"Engineers",
496
+ * // action in [AgentCore::Action::"exampleaction1", AgentCore::Action::"exampleaction2"],
497
+ * // resource == AgentCore::Gateway::"arn:aws:bedrock:us-east-1:123:gateway/gw-123"
498
+ * // );
499
+ *
500
+ * @example
501
+ * import { Policy, PolicyEngine, PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
502
+ * declare const engine: PolicyEngine;
503
+ *
504
+ * // Example 3: Policy with conditions
505
+ * // Builder format:
506
+ * new Policy(this, 'ConditionalPolicy', {
507
+ * policyEngine: engine,
508
+ * statement: PolicyStatement.permit()
509
+ * .forAllPrincipals()
510
+ * .onAllActions()
511
+ * .onAllResources()
512
+ * .when()
513
+ * .principalAttribute('department').equalTo('Engineering')
514
+ * .and()
515
+ * .contextAttribute('sourceIp').isInRange('192.168.1.0/24')
516
+ * .done()
517
+ * .unless()
518
+ * .principalAttribute('suspended').equalTo(true)
519
+ * .done(),
520
+ * });
521
+ *
522
+ * // Generated Cedar:
523
+ * // permit(
524
+ * // principal,
525
+ * // action,
526
+ * // resource
527
+ * // )
528
+ * // when {
529
+ * // principal.department == "Engineering" && context.sourceIp isInRange ip("192.168.1.0/24")
530
+ * // }
531
+ * // unless {
532
+ * // principal.suspended == true
533
+ * // };
534
+ *
535
+ * @example
536
+ * import { Policy, PolicyEngine, PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
537
+ * declare const engine: PolicyEngine;
538
+ *
539
+ * // Example 4: Raw Cedar policy
540
+ * // For advanced Cedar features not supported by the builder
541
+ * new Policy(this, 'CustomPolicy', {
542
+ * policyEngine: engine,
543
+ * definition: 'permit(principal, action, resource) when { context.custom > 10 };',
544
+ * });
545
+ *
546
+ * // Or using fromCedar():
547
+ * new Policy(this, 'ImportedPolicy', {
548
+ * policyEngine: engine,
549
+ * statement: PolicyStatement.fromCedar(
550
+ * 'forbid(principal, action, resource) when { resource.confidential == true };'
551
+ * ),
552
+ * });
553
+ */
554
+ class PolicyStatement {
555
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.PolicyStatement", version: "2.252.0-alpha.0" };
556
+ /**
557
+ * Create a permit statement - allows the action if conditions are met.
558
+ *
559
+ * Permit statements grant access when their conditions evaluate to true.
560
+ * Multiple permit statements can apply; any matching permit allows access.
561
+ */
562
+ static permit() {
563
+ return new PolicyStatement(PolicyEffect.PERMIT);
564
+ }
565
+ /**
566
+ * Create a forbid statement - denies the action if conditions are met.
567
+ *
568
+ * Forbid statements deny access when their conditions evaluate to true.
569
+ * Forbid always takes precedence over permit (explicit deny).
570
+ */
571
+ static forbid() {
572
+ return new PolicyStatement(PolicyEffect.FORBID);
573
+ }
574
+ /**
575
+ * Create from raw Cedar policy statement string.
576
+ *
577
+ * Use this for advanced Cedar features not supported by the builder,
578
+ * or when migrating existing Cedar policies.
579
+ *
580
+ * Validation is deferred to the Policy construct's validationMode setting.
581
+ *
582
+ * @param cedarStatement - Complete Cedar policy statement including effect, principal, action, resource, and conditions
583
+ */
584
+ static fromCedar(cedarStatement) {
585
+ const statement = new PolicyStatement(PolicyEffect.PERMIT);
586
+ statement.rawCedar = cedarStatement.trim();
587
+ return statement;
588
+ }
589
+ effect;
590
+ principalConfig;
591
+ actionConfig;
592
+ resourceConfig;
593
+ whenConditions;
594
+ unlessConditions;
595
+ rawCedar;
596
+ constructor(effect) {
597
+ this.effect = effect;
598
+ }
599
+ /**
600
+ * Apply to all principals (any user, service, or entity).
601
+ *
602
+ * Generates: `principal` in Cedar
603
+ */
604
+ forAllPrincipals() {
605
+ this.validateNotRawCedar();
606
+ this.principalConfig = { scope: PrincipalScope.ALL };
607
+ return this;
608
+ }
609
+ /**
610
+ * Apply to a specific principal entity.
611
+ *
612
+ * Generates: `principal == EntityType::"entityId"` in Cedar
613
+ *
614
+ * @param entityType - The entity type (e.g., 'AgentCore::OAuthUser')
615
+ * @param entityId - Optional specific entity ID
616
+ */
617
+ forPrincipal(entityType, entityId) {
618
+ this.validateNotRawCedar();
619
+ this.principalConfig = {
620
+ scope: PrincipalScope.SPECIFIC,
621
+ entityType,
622
+ entityId,
623
+ };
624
+ return this;
625
+ }
626
+ /**
627
+ * Apply to principals that are members of a specific group.
628
+ *
629
+ * Generates: `principal in Group::"groupId"` in Cedar
630
+ *
631
+ * @param groupType - The group entity type (e.g., 'Group')
632
+ * @param groupId - The group identifier (e.g., 'Admins', 'Engineers')
633
+ */
634
+ forPrincipalInGroup(groupType, groupId) {
635
+ this.validateNotRawCedar();
636
+ this.principalConfig = {
637
+ scope: PrincipalScope.SPECIFIC,
638
+ memberOf: { entityType: groupType, entityId: groupId },
639
+ };
640
+ return this;
641
+ }
642
+ /**
643
+ * Apply to all actions (any operation).
644
+ *
645
+ * Generates: `action` in Cedar
646
+ */
647
+ onAllActions() {
648
+ this.validateNotRawCedar();
649
+ this.actionConfig = { scope: ActionScope.ALL };
650
+ return this;
651
+ }
652
+ /**
653
+ * Apply to specific action(s).
654
+ *
655
+ * Generates: `action == Action::"name"` or `action in [Action::"name1", Action::"name2"]` in Cedar
656
+ *
657
+ * @param actions - Array of action names (e.g., ['AgentCore::Action::InsuranceAPI__get_policy'])
658
+ */
659
+ onActions(actions) {
660
+ this.validateNotRawCedar();
661
+ if (actions.length === 0) {
662
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `AtLeastOneAction`, 'At least one action must be specified');
663
+ }
664
+ this.actionConfig = {
665
+ scope: ActionScope.SPECIFIC,
666
+ actions,
667
+ };
668
+ return this;
669
+ }
670
+ /**
671
+ * Apply to a single specific action.
672
+ *
673
+ * Generates: `action == Action::"name"` in Cedar
674
+ *
675
+ * @param action - Action name (e.g., 'AgentCore::Action::InsuranceAPI__get_policy')
676
+ */
677
+ onAction(action) {
678
+ return this.onActions([action]);
679
+ }
680
+ /**
681
+ * Apply to all resources of a specific type.
682
+ *
683
+ * **AWS Requirement**: AWS Bedrock AgentCore Policy service does not allow wildcard
684
+ * resources (`resource`). This method provides type-constrained resources which are
685
+ * required for policy validation to succeed.
686
+ *
687
+ * Generates: `resource is EntityType` in Cedar
688
+ *
689
+ * @param entityType - The entity type (default: 'AgentCore::Gateway')
690
+ *
691
+ * @example
692
+ * import { PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
693
+ *
694
+ * // Constrain to Gateway resources (default)
695
+ * PolicyStatement.permit()
696
+ * .forAllPrincipals()
697
+ * .onAllActions()
698
+ * .onAllResources() // → "resource is AgentCore::Gateway"
699
+ *
700
+ * // Constrain to Runtime resources
701
+ * PolicyStatement.permit()
702
+ * .forAllPrincipals()
703
+ * .onAllActions()
704
+ * .onAllResources('AgentCore::Runtime') // → "resource is AgentCore::Runtime"
705
+ */
706
+ onAllResources(entityType = 'AgentCore::Gateway') {
707
+ this.validateNotRawCedar();
708
+ this.resourceConfig = {
709
+ scope: ResourceScope.TYPE,
710
+ entityType,
711
+ };
712
+ return this;
713
+ }
714
+ /**
715
+ * Apply to all resources of a specific type (explicit method).
716
+ *
717
+ * **AWS Requirement**: Resource type constraints are required by AWS Bedrock
718
+ * AgentCore when using wildcard principals or actions.
719
+ *
720
+ * Generates: `resource is EntityType` in Cedar
721
+ *
722
+ * @param entityType - The entity type (e.g., 'AgentCore::Gateway', 'AgentCore::Runtime')
723
+ *
724
+ * @example
725
+ * import { PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
726
+ *
727
+ * PolicyStatement.permit()
728
+ * .forAllPrincipals()
729
+ * .onAllActions()
730
+ * .onResourceType('AgentCore::Gateway') // → "resource is AgentCore::Gateway"
731
+ */
732
+ onResourceType(entityType) {
733
+ this.validateNotRawCedar();
734
+ this.resourceConfig = {
735
+ scope: ResourceScope.TYPE,
736
+ entityType,
737
+ };
738
+ return this;
739
+ }
740
+ /**
741
+ * Apply to a specific resource instance.
742
+ *
743
+ * **AWS Requirement**: When using specific actions (e.g., `action == Action::"Delete"`),
744
+ * you must constrain the resource to a specific instance, not just a type.
745
+ *
746
+ * Generates: `resource == EntityType::"arn"` in Cedar
747
+ *
748
+ * @param entityType - The entity type (e.g., 'AgentCore::Gateway')
749
+ * @param entityArn - The resource ARN or identifier
750
+ *
751
+ * @example
752
+ * import { PolicyStatement } from '@aws-cdk/aws-bedrock-agentcore-alpha';
753
+ * declare const gatewayArn: string;
754
+ *
755
+ * PolicyStatement.forbid()
756
+ * .forAllPrincipals()
757
+ * .onAction('AgentCore::Action::Delete')
758
+ * .onResource('AgentCore::Gateway', gatewayArn) // Must be specific resource
759
+ */
760
+ onResource(entityType, entityArn) {
761
+ this.validateNotRawCedar();
762
+ this.resourceConfig = {
763
+ scope: ResourceScope.SPECIFIC,
764
+ entityType,
765
+ entityArn,
766
+ };
767
+ return this;
768
+ }
769
+ /**
770
+ * Add when conditions - policy applies only if these conditions are true.
771
+ *
772
+ * When conditions define positive requirements that must be met.
773
+ * Multiple conditions can be combined with AND/OR operators.
774
+ *
775
+ * Returns a ConditionBuilder that you can chain condition methods on.
776
+ * Call done() when finished to return to the PolicyStatement.
777
+ */
778
+ when() {
779
+ this.validateNotRawCedar();
780
+ this.whenConditions = new ConditionBuilder();
781
+ return new ConditionalPolicyStatement(this, this.whenConditions);
782
+ }
783
+ /**
784
+ * Add unless conditions - policy applies only if these conditions are false.
785
+ *
786
+ * Unless conditions define negative requirements (exclusions).
787
+ * The policy applies when these conditions are NOT met.
788
+ *
789
+ * Returns a ConditionBuilder that you can chain condition methods on.
790
+ * Call done() when finished to return to the PolicyStatement.
791
+ */
792
+ unless() {
793
+ this.validateNotRawCedar();
794
+ this.unlessConditions = new ConditionBuilder();
795
+ return new ConditionalPolicyStatement(this, this.unlessConditions);
796
+ }
797
+ /**
798
+ * Generate the Cedar policy statement string.
799
+ *
800
+ * Converts the builder state into valid Cedar policy syntax.
801
+ * This is called internally by the Policy construct.
802
+ *
803
+ * @returns Valid Cedar policy statement
804
+ */
805
+ toCedar() {
806
+ // If raw Cedar was provided, return it directly
807
+ if (this.rawCedar) {
808
+ return this.rawCedar;
809
+ }
810
+ // Validate that all required parts are configured
811
+ if (!this.principalConfig) {
812
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `PrincipalRequired`, 'Principal must be specified using forAllPrincipals() or forPrincipal()');
813
+ }
814
+ if (!this.actionConfig) {
815
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `ActionRequired`, 'Action must be specified using onAllActions() or onActions()');
816
+ }
817
+ if (!this.resourceConfig) {
818
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `ResourceRequired`, 'Resource must be specified using onAllResources() or onResource()');
819
+ }
820
+ let cedar = `${this.effect}(\n`;
821
+ // Principal
822
+ cedar += ` ${this.principalToCedar()},\n`;
823
+ // Action
824
+ cedar += ` ${this.actionToCedar()},\n`;
825
+ // Resource
826
+ cedar += ` ${this.resourceToCedar()}\n`;
827
+ cedar += ')';
828
+ // When conditions
829
+ if (this.whenConditions) {
830
+ const whenCedar = this.whenConditions._toCedar();
831
+ if (whenCedar) {
832
+ cedar += `\nwhen {\n ${whenCedar}\n}`;
833
+ }
834
+ }
835
+ // Unless conditions
836
+ if (this.unlessConditions) {
837
+ const unlessCedar = this.unlessConditions._toCedar();
838
+ if (unlessCedar) {
839
+ cedar += `\nunless {\n ${unlessCedar}\n}`;
840
+ }
841
+ }
842
+ cedar += ';';
843
+ return cedar;
844
+ }
845
+ principalToCedar() {
846
+ if (!this.principalConfig) {
847
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `PrincipalConfigRequired`, 'Principal configuration is required');
848
+ }
849
+ if (this.principalConfig.scope === PrincipalScope.ALL) {
850
+ return 'principal';
851
+ }
852
+ // Check for group membership
853
+ if (this.principalConfig.memberOf) {
854
+ const { entityType, entityId } = this.principalConfig.memberOf;
855
+ return `principal in ${entityType}::"${entityId}"`;
856
+ }
857
+ // Specific principal
858
+ if (this.principalConfig.entityId) {
859
+ return `principal == ${this.principalConfig.entityType}::"${this.principalConfig.entityId}"`;
860
+ }
861
+ // Principal type only (is operator)
862
+ return `principal is ${this.principalConfig.entityType}`;
863
+ }
864
+ actionToCedar() {
865
+ if (!this.actionConfig) {
866
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `ActionConfigRequired`, 'Action configuration is required');
867
+ }
868
+ if (this.actionConfig.scope === ActionScope.ALL) {
869
+ return 'action';
870
+ }
871
+ const actions = this.actionConfig.actions;
872
+ // Format action: if it contains "::" it's already namespaced, just ensure quotes
873
+ // Otherwise treat as action identifier
874
+ const formatAction = (action) => {
875
+ if (action.includes('::')) {
876
+ // Already namespaced like "AgentCore::Action::actionname"
877
+ // Need to ensure the action name part is quoted
878
+ const parts = action.split('::');
879
+ if (parts.length >= 3) {
880
+ const actionName = parts.slice(2).join('::');
881
+ const namespace = parts.slice(0, 2).join('::');
882
+ return `${namespace}::"${actionName}"`;
883
+ }
884
+ }
885
+ // Otherwise return as-is (will be validated by Cedar)
886
+ return action;
887
+ };
888
+ if (actions.length === 1) {
889
+ return `action == ${formatAction(actions[0])}`;
890
+ }
891
+ // Multiple actions
892
+ const formattedActions = actions.map(a => formatAction(a)).join(', ');
893
+ return `action in [${formattedActions}]`;
894
+ }
895
+ resourceToCedar() {
896
+ if (!this.resourceConfig) {
897
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `ResourceConfigRequired`, 'Resource configuration is required');
898
+ }
899
+ switch (this.resourceConfig.scope) {
900
+ case ResourceScope.ALL:
901
+ // Note: Wildcard resources may be rejected by AWS Bedrock AgentCore service
902
+ return 'resource';
903
+ case ResourceScope.TYPE:
904
+ // Resource type constraint: "resource is EntityType"
905
+ if (!this.resourceConfig.entityType) {
906
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `EntityTypeRequired`, 'Entity type is required for TYPE resource scope');
907
+ }
908
+ return `resource is ${this.resourceConfig.entityType}`;
909
+ case ResourceScope.SPECIFIC:
910
+ // Specific resource: "resource == EntityType::"arn""
911
+ if (!this.resourceConfig.entityType || !this.resourceConfig.entityArn) {
912
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `EntityTypeAndArnRequired`, 'Entity type and ARN are required for SPECIFIC resource scope');
913
+ }
914
+ return `resource == ${this.resourceConfig.entityType}::"${this.resourceConfig.entityArn}"`;
915
+ default:
916
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `UnknownResourceScope`, `Unknown resource scope: ${this.resourceConfig.scope}`);
917
+ }
918
+ }
919
+ validateNotRawCedar() {
920
+ if (this.rawCedar) {
921
+ throw new errors_1.UnscopedValidationError((0, helpers_internal_1.lit) `RawCedarConflict`, 'Cannot use builder methods with raw Cedar. ' +
922
+ 'Either use PolicyStatement.fromCedar() or builder methods, not both.');
923
+ }
924
+ }
925
+ }
926
+ exports.PolicyStatement = PolicyStatement;
927
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LXN0YXRlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInBvbGljeS1zdGF0ZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7R0FXRztBQUVILHdEQUFzRTtBQUN0RSw0RUFBNEQ7QUFFNUQ7OztHQUdHO0FBQ0gsSUFBSyxZQVVKO0FBVkQsV0FBSyxZQUFZO0lBQ2Y7O09BRUc7SUFDSCxpQ0FBaUIsQ0FBQTtJQUVqQjs7T0FFRztJQUNILGlDQUFpQixDQUFBO0FBQ25CLENBQUMsRUFWSSxZQUFZLEtBQVosWUFBWSxRQVVoQjtBQUVEOzs7R0FHRztBQUNILElBQUssY0FVSjtBQVZELFdBQUssY0FBYztJQUNqQjs7T0FFRztJQUNILDZCQUFXLENBQUE7SUFFWDs7T0FFRztJQUNILHVDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFWSSxjQUFjLEtBQWQsY0FBYyxRQVVsQjtBQUVEOzs7R0FHRztBQUNILElBQUssV0FVSjtBQVZELFdBQUssV0FBVztJQUNkOztPQUVHO0lBQ0gsMEJBQVcsQ0FBQTtJQUVYOztPQUVHO0lBQ0gsb0NBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVZJLFdBQVcsS0FBWCxXQUFXLFFBVWY7QUFFRDs7O0dBR0c7QUFDSCxJQUFLLGFBZUo7QUFmRCxXQUFLLGFBQWE7SUFDaEI7O09BRUc7SUFDSCw0QkFBVyxDQUFBO0lBRVg7O09BRUc7SUFDSCw4QkFBYSxDQUFBO0lBRWI7O09BRUc7SUFDSCxzQ0FBcUIsQ0FBQTtBQUN2QixDQUFDLEVBZkksYUFBYSxLQUFiLGFBQWEsUUFlakI7QUFnQ0Q7O0dBRUc7QUFDSCxNQUFNLG1CQUFtQjtJQUVKO0lBQ0E7SUFDQTtJQUhuQixZQUNtQixTQUFpQixFQUNqQixRQUFnQixFQUNoQixLQUFnQztRQUZoQyxjQUFTLEdBQVQsU0FBUyxDQUFRO1FBQ2pCLGFBQVEsR0FBUixRQUFRLENBQVE7UUFDaEIsVUFBSyxHQUFMLEtBQUssQ0FBMkI7S0FD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SSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLGdDQUF1QixDQUMvQixJQUFBLHNCQUFHLEVBQUEsa0JBQWtCLEVBQ3JCLDZDQUE2QztnQkFDN0Msc0VBQXNFLENBQ3ZFLENBQUM7UUFDSixDQUFDO0tBQ0Y7O0FBOVpILDBDQStaQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogIENvcHlyaWdodCBBbWF6b24uY29tLCBJbmMuIG9yIGl0cyBhZmZpbGlhdGVzLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpLiBZb3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlXG4gKiAgd2l0aCB0aGUgTGljZW5zZS4gQSBjb3B5IG9mIHRoZSBMaWNlbnNlIGlzIGxvY2F0ZWQgYXRcbiAqXG4gKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqICBvciBpbiB0aGUgJ2xpY2Vuc2UnIGZpbGUgYWNjb21wYW55aW5nIHRoaXMgZmlsZS4gVGhpcyBmaWxlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICdBUyBJUycgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFU1xuICogIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGV4cHJlc3Mgb3IgaW1wbGllZC4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zXG4gKiAgYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnYXdzLWNkay1saWIvY29yZS9saWIvZXJyb3JzJztcbmltcG9ydCB7IGxpdCB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL2hlbHBlcnMtaW50ZXJuYWwnO1xuXG4vKipcbiAqIEVmZmVjdCBvZiB0aGUgcG9saWN5IHN0YXRlbWVudCAtIHdoZXRoZXIgdG8gcGVybWl0IG9yIGZvcmJpZCB0aGUgYWN0aW9uLlxuICogQGludGVybmFsXG4gKi9cbmVudW0gUG9saWN5RWZmZWN0IHtcbiAgLyoqXG4gICAqIFBlcm1pdCB0aGUgYWN0aW9uIGlmIGNvbmRpdGlvbnMgYXJlIG1ldFxuICAgKi9cbiAgUEVSTUlUID0gJ3Blcm1pdCcsXG5cbiAgLyoqXG4gICAqIEZvcmJpZCAoZGVueSkgdGhlIGFjdGlvbiBpZiBjb25kaXRpb25zIGFyZSBtZXRcbiAgICovXG4gIEZPUkJJRCA9ICdmb3JiaWQnLFxufVxuXG4vKipcbiAqIFNjb3BlIGZvciBwcmluY2lwYWxzIC0gd2hldGhlciB0byBhcHBseSB0byBhbGwgcHJpbmNpcGFscyBvciBzcGVjaWZpYyBvbmVzLlxuICogQGludGVybmFsXG4gKi9cbmVudW0gUHJpbmNpcGFsU2NvcGUge1xuICAvKipcbiAgICogQXBwbHkgdG8gYWxsIHByaW5jaXBhbHNcbiAgICovXG4gIEFMTCA9ICdhbGwnLFxuXG4gIC8qKlxuICAgKiBBcHBseSB0byBzcGVjaWZpYyBwcmluY2lwYWwocylcbiAgICovXG4gIFNQRUNJRklDID0gJ3NwZWNpZmljJyxcbn1cblxuLyoqXG4gKiBTY29wZSBmb3IgYWN0aW9ucyAtIHdoZXRoZXIgdG8gYXBwbHkgdG8gYWxsIGFjdGlvbnMgb3Igc3BlY2lmaWMgb25lcy5cbiAqIEBpbnRlcm5hbFxuICovXG5lbnVtIEFjdGlvblNjb3BlIHtcbiAgLyoqXG4gICAqIEFwcGx5IHRvIGFsbCBhY3Rpb25zXG4gICAqL1xuICBBTEwgPSAnYWxsJyxcblxuICAvKipcbiAgICogQXBwbHkgdG8gc3BlY2lmaWMgYWN0aW9uKHMpXG4gICAqL1xuICBTUEVDSUZJQyA9ICdzcGVjaWZpYycsXG59XG5cbi8qKlxuICogU2NvcGUgZm9yIHJlc291cmNlcyAtIHdoZXRoZXIgdG8gYXBwbHkgdG8gYWxsIHJlc291cmNlcywgcmVzb3VyY2UgdHlwZXMsIG9yIHNwZWNpZmljIG9uZXMuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZW51bSBSZXNvdXJjZVNjb3BlIHtcbiAgLyoqXG4gICAqIEFwcGx5IHRvIGFsbCByZXNvdXJjZXMgKHdpbGRjYXJkIC0gbWF5IGJlIHJlamVjdGVkIGJ5IHNlcnZpY2UpXG4gICAqL1xuICBBTEwgPSAnYWxsJyxcblxuICAvKipcbiAgICogQXBwbHkgdG8gYWxsIHJlc291cmNlcyBvZiBhIHNwZWNpZmljIHR5cGVcbiAgICovXG4gIFRZUEUgPSAndHlwZScsXG5cbiAgLyoqXG4gICAqIEFwcGx5IHRvIHNwZWNpZmljIHJlc291cmNlKHMpXG4gICAqL1xuICBTUEVDSUZJQyA9ICdzcGVjaWZpYycsXG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgcHJpbmNpcGFsIHNwZWNpZmljYXRpb24gaW4gYSBwb2xpY3kgc3RhdGVtZW50LlxuICovXG5pbnRlcmZhY2UgUHJpbmNpcGFsQ29uZmlnIHtcbiAgcmVhZG9ubHkgc2NvcGU6IFByaW5jaXBhbFNjb3BlO1xuICByZWFkb25seSBlbnRpdHlUeXBlPzogc3RyaW5nO1xuICByZWFkb25seSBlbnRpdHlJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgbWVtYmVyT2Y/OiB7XG4gICAgcmVhZG9ubHkgZW50aXR5VHlwZTogc3RyaW5nO1xuICAgIHJlYWRvbmx5IGVudGl0eUlkOiBzdHJpbmc7XG4gIH07XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgYWN0aW9uIHNwZWNpZmljYXRpb24gaW4gYSBwb2xpY3kgc3RhdGVtZW50LlxuICovXG5pbnRlcmZhY2UgQWN0aW9uQ29uZmlnIHtcbiAgcmVhZG9ubHkgc2NvcGU6IEFjdGlvblNjb3BlO1xuICByZWFkb25seSBhY3Rpb25zPzogc3RyaW5nW107XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgcmVzb3VyY2Ugc3BlY2lmaWNhdGlvbiBpbiBhIHBvbGljeSBzdGF0ZW1lbnQuXG4gKi9cbmludGVyZmFjZSBSZXNvdXJjZUNvbmZpZyB7XG4gIHJlYWRvbmx5IHNjb3BlOiBSZXNvdXJjZVNjb3BlO1xuICByZWFkb25seSBlbnRpdHlUeXBlPzogc3RyaW5nO1xuICByZWFkb25seSBlbnRpdHlBcm4/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBzaW5nbGUgY29uZGl0aW9uIGV4cHJlc3Npb24gaW4gQ2VkYXIgcG9saWN5IGxhbmd1YWdlLlxuICovXG5jbGFzcyBDb25kaXRpb25FeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBhdHRyaWJ1dGU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wZXJhdG9yOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbixcbiAgKSB7fVxuXG4gIHB1YmxpYyB0b0NlZGFyKCk6IHN0cmluZyB7XG4gICAgY29uc3QgZm9ybWF0dGVkVmFsdWUgPSB0eXBlb2YgdGhpcy52YWx1ZSA9PT0gJ3N0cmluZycgJiYgIXRoaXMudmFsdWUuc3RhcnRzV2l0aCgnaXAoJylcbiAgICAgID8gYFwiJHt0aGlzLnZhbHVlfVwiYFxuICAgICAgOiB0aGlzLnZhbHVlO1xuICAgIHJldHVybiBgJHt0aGlzLmF0dHJpYnV0ZX0gJHt0aGlzLm9wZXJhdG9yfSAke2Zvcm1hdHRlZFZhbHVlfWA7XG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZGVyIGZvciBjb25kaXRpb24gZXhwcmVzc2lvbnMgaW4gQ2VkYXIgcG9saWNpZXMuXG4gKlxuICogQ29uZGl0aW9ucyBkZWZpbmUgd2hlbiBhIHBvbGljeSBzdGF0ZW1lbnQgc2hvdWxkIGFwcGx5IG9yIG5vdCBhcHBseS5cbiAqIFN1cHBvcnRzIGxvZ2ljYWwgb3BlcmF0b3JzIChBTkQsIE9SKSBhbmQgdmFyaW91cyBjb21wYXJpc29uIG9wZXJhdG9ycy5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbmRpdGlvbkJ1aWxkZXIge1xuICBwcml2YXRlIGNvbmRpdGlvbnM6IENvbmRpdGlvbkV4cHJlc3Npb25bXSA9IFtdO1xuICBwcml2YXRlIG9wZXJhdG9yczogKCcmJicgfCAnfHwnKVtdID0gW107XG5cbiAgLyoqXG4gICAqIEFjY2VzcyBhIHByaW5jaXBhbCBhdHRyaWJ1dGUgZm9yIGNvbXBhcmlzb24uXG4gICAqXG4gICAqIFByaW5jaXBhbCBhdHRyaWJ1dGVzIGNvbWUgZnJvbSB0aGUgYXV0aGVudGljYXRlZCB1c2VyL3NlcnZpY2UgbWFraW5nIHRoZSByZXF1ZXN0LlxuICAgKiBDb21tb24gYXR0cmlidXRlczogdXNlcm5hbWUsIHJvbGUsIGRlcGFydG1lbnQsIGdyb3VwcywgZXRjLlxuICAgKlxuICAgKiBAcGFyYW0gYXR0cmlidXRlIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIChlLmcuLCAnZGVwYXJ0bWVudCcsICdyb2xlJywgJ3VzZXJuYW1lJylcbiAgICovXG4gIHB1YmxpYyBwcmluY2lwYWxBdHRyaWJ1dGUoYXR0cmlidXRlOiBzdHJpbmcpOiBBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVBY2Nlc3NvcihgcHJpbmNpcGFsLiR7YXR0cmlidXRlfWAsIHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VzcyBhIHJlc291cmNlIGF0dHJpYnV0ZSBmb3IgY29tcGFyaXNvbi5cbiAgICpcbiAgICogUmVzb3VyY2UgYXR0cmlidXRlcyBjb21lIGZyb20gdGhlIHRhcmdldCByZXNvdXJjZSBiZWluZyBhY2Nlc3NlZC5cbiAgICogQ29tbW9uIGF0dHJpYnV0ZXM6IGFybiwgdHlwZSwgdGFncywgb3duZXIsIGV0Yy5cbiAgICpcbiAgICogQHBhcmFtIGF0dHJpYnV0ZSAtIFRoZSBhdHRyaWJ1dGUgbmFtZSAoZS5nLiwgJ2NvbmZpZGVudGlhbCcsICdvd25lcicsICdjbGFzc2lmaWNhdGlvbicpXG4gICAqL1xuICBwdWJsaWMgcmVzb3VyY2VBdHRyaWJ1dGUoYXR0cmlidXRlOiBzdHJpbmcpOiBBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVBY2Nlc3NvcihgcmVzb3VyY2UuJHthdHRyaWJ1dGV9YCwgdGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQWNjZXNzIGEgY29udGV4dCBhdHRyaWJ1dGUgZm9yIGNvbXBhcmlzb24uXG4gICAqXG4gICAqIENvbnRleHQgYXR0cmlidXRlcyBjb21lIGZyb20gdGhlIHJlcXVlc3QgZW52aXJvbm1lbnQuXG4gICAqIENvbW1vbiBhdHRyaWJ1dGVzOiBzb3VyY2VJcCwgdGltZXN0YW1wLCBlbnZpcm9ubWVudCwgcmVnaW9uLCBldGMuXG4gICAqXG4gICAqIEBwYXJhbSBhdHRyaWJ1dGUgLSBUaGUgYXR0cmlidXRlIG5hbWUgKGUuZy4sICdzb3VyY2VJcCcsICdlbnZpcm9ubWVudCcsICd0aW1lc3RhbXAnKVxuICAgKi9cbiAgcHVibGljIGNvbnRleHRBdHRyaWJ1dGUoYXR0cmlidXRlOiBzdHJpbmcpOiBBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gICAgcmV0dXJuIG5ldyBBdHRyaWJ1dGVBY2Nlc3NvcihgY29udGV4dC4ke2F0dHJpYnV0ZX1gLCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dpY2FsIEFORCBvcGVyYXRvciAtIGFsbCBjb25kaXRpb25zIG11c3QgYmUgdHJ1ZS5cbiAgICovXG4gIHB1YmxpYyBhbmQoKTogdGhpcyB7XG4gICAgdGhpcy5vcGVyYXRvcnMucHVzaCgnJiYnKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dpY2FsIE9SIG9wZXJhdG9yIC0gYXQgbGVhc3Qgb25lIGNvbmRpdGlvbiBtdXN0IGJlIHRydWUuXG4gICAqL1xuICBwdWJsaWMgb3IoKTogdGhpcyB7XG4gICAgdGhpcy5vcGVyYXRvcnMucHVzaCgnfHwnKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlcm5hbCBtZXRob2QgdG8gYWRkIGEgY29uZGl0aW9uIGV4cHJlc3Npb24uXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9hZGRDb25kaXRpb24oY29uZGl0aW9uOiBDb25kaXRpb25FeHByZXNzaW9uKTogdGhpcyB7XG4gICAgdGhpcy5jb25kaXRpb25zLnB1c2goY29uZGl0aW9uKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBDZWRhciBjb25kaXRpb24gc3ludGF4LlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfdG9DZWRhcigpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmNvbmRpdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgbGV0IGNlZGFyID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbmRpdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNlZGFyICs9IGAke3RoaXMuY29uZGl0aW9uc1tpXS50b0NlZGFyKCl9YDtcbiAgICAgIGlmIChpIDwgdGhpcy5vcGVyYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgIGNlZGFyICs9IGAgJHt0aGlzLm9wZXJhdG9yc1tpXX0gYDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNlZGFyO1xuICB9XG59XG5cbi8qKlxuICogV3JhcHBlciBjbGFzcyBmb3IgY29uZGl0aW9uYWxseSBidWlsZGluZyBwb2xpY3kgc3RhdGVtZW50cy5cbiAqXG4gKiBUaGlzIGNsYXNzIGFsbG93cyBjaGFpbmluZyBjb25kaXRpb24gbWV0aG9kcyBhbmQgcmV0dXJuaW5nIHRvIHRoZSBwYXJlbnRcbiAqIFBvbGljeVN0YXRlbWVudCB3aGVuIGRvbmUuIEl0IHByb3hpZXMgY29uZGl0aW9uIGJ1aWxkaW5nIG1ldGhvZHMgZnJvbVxuICogQ29uZGl0aW9uQnVpbGRlci5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbmRpdGlvbmFsUG9saWN5U3RhdGVtZW50IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBwb2xpY3lTdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbmRpdGlvbkJ1aWxkZXI6IENvbmRpdGlvbkJ1aWxkZXIsXG4gICkge31cblxuICAvKipcbiAgICogQWNjZXNzIGEgcHJpbmNpcGFsIGF0dHJpYnV0ZSBmb3IgY29tcGFyaXNvbi5cbiAgICpcbiAgICogQHBhcmFtIGF0dHJpYnV0ZSAtIFRoZSBhdHRyaWJ1dGUgbmFtZSAoZS5nLiwgJ2RlcGFydG1lbnQnLCAncm9sZScsICd1c2VybmFtZScpXG4gICAqL1xuICBwdWJsaWMgcHJpbmNpcGFsQXR0cmlidXRlKGF0dHJpYnV0ZTogc3RyaW5nKTogQ29uZGl0aW9uYWxBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb25hbEF0dHJpYnV0ZUFjY2Vzc29yKGBwcmluY2lwYWwuJHthdHRyaWJ1dGV9YCwgdGhpcywgdGhpcy5jb25kaXRpb25CdWlsZGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBY2Nlc3MgYSByZXNvdXJjZSBhdHRyaWJ1dGUgZm9yIGNvbXBhcmlzb24uXG4gICAqXG4gICAqIEBwYXJhbSBhdHRyaWJ1dGUgLSBUaGUgYXR0cmlidXRlIG5hbWUgKGUuZy4sICdjb25maWRlbnRpYWwnLCAnb3duZXInLCAnY2xhc3NpZmljYXRpb24nKVxuICAgKi9cbiAgcHVibGljIHJlc291cmNlQXR0cmlidXRlKGF0dHJpYnV0ZTogc3RyaW5nKTogQ29uZGl0aW9uYWxBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb25hbEF0dHJpYnV0ZUFjY2Vzc29yKGByZXNvdXJjZS4ke2F0dHJpYnV0ZX1gLCB0aGlzLCB0aGlzLmNvbmRpdGlvbkJ1aWxkZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VzcyBhIGNvbnRleHQgYXR0cmlidXRlIGZvciBjb21wYXJpc29uLlxuICAgKlxuICAgKiBAcGFyYW0gYXR0cmlidXRlIC0gVGhlIGF0dHJpYnV0ZSBuYW1lIChlLmcuLCAnc291cmNlSXAnLCAnZW52aXJvbm1lbnQnLCAndGltZXN0YW1wJylcbiAgICovXG4gIHB1YmxpYyBjb250ZXh0QXR0cmlidXRlKGF0dHJpYnV0ZTogc3RyaW5nKTogQ29uZGl0aW9uYWxBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb25hbEF0dHJpYnV0ZUFjY2Vzc29yKGBjb250ZXh0LiR7YXR0cmlidXRlfWAsIHRoaXMsIHRoaXMuY29uZGl0aW9uQnVpbGRlcik7XG4gIH1cblxuICAvKipcbiAgICogTG9naWNhbCBBTkQgb3BlcmF0b3IgLSBhbGwgY29uZGl0aW9ucyBtdXN0IGJlIHRydWUuXG4gICAqL1xuICBwdWJsaWMgYW5kKCk6IHRoaXMge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5hbmQoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2dpY2FsIE9SIG9wZXJhdG9yIC0gYXQgbGVhc3Qgb25lIGNvbmRpdGlvbiBtdXN0IGJlIHRydWUuXG4gICAqL1xuICBwdWJsaWMgb3IoKTogdGhpcyB7XG4gICAgdGhpcy5jb25kaXRpb25CdWlsZGVyLm9yKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ29tcGxldGUgY29uZGl0aW9uIGJ1aWxkaW5nIGFuZCByZXR1cm4gdG8gdGhlIFBvbGljeVN0YXRlbWVudC5cbiAgICpcbiAgICogVXNlIHRoaXMgdG8gZmluaXNoIGJ1aWxkaW5nIHdoZW4vdW5sZXNzIGNvbmRpdGlvbnMgYW5kIGNvbnRpbnVlXG4gICAqIGNvbmZpZ3VyaW5nIHRoZSBwb2xpY3kgc3RhdGVtZW50LlxuICAgKi9cbiAgcHVibGljIGRvbmUoKTogUG9saWN5U3RhdGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5wb2xpY3lTdGF0ZW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogQWxpYXMgZm9yIGRvbmUoKSB0byBzdXBwb3J0IGZsdWVudCB1bmxlc3MoKSBjaGFpbmluZy5cbiAgICovXG4gIHB1YmxpYyB1bmxlc3MoKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHJldHVybiB0aGlzLnBvbGljeVN0YXRlbWVudC51bmxlc3MoKTtcbiAgfVxufVxuXG4vKipcbiAqIEFjY2Vzc29yIGZvciBidWlsZGluZyB0eXBlLXNhZmUgYXR0cmlidXRlIGNvbXBhcmlzb25zIHdpdGhpbiBjb25kaXRpb25hbCBzdGF0ZW1lbnRzLlxuICpcbiAqIFJldHVybnMgQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQgdG8gYWxsb3cgY2hhaW5pbmcgYmFjayB0byBwb2xpY3kgYnVpbGRpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb25kaXRpb25hbEF0dHJpYnV0ZUFjY2Vzc29yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXRoOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwYXJlbnQ6IENvbmRpdGlvbmFsUG9saWN5U3RhdGVtZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY29uZGl0aW9uQnVpbGRlcjogQ29uZGl0aW9uQnVpbGRlcixcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBFcXVhbGl0eSBjb21wYXJpc29uICg9PSlcbiAgICovXG4gIHB1YmxpYyBlcXVhbFRvKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnPT0nLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogSW5lcXVhbGl0eSBjb21wYXJpc29uICghPSlcbiAgICovXG4gIHB1YmxpYyBub3RFcXVhbFRvKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnIT0nLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogTGVzcyB0aGFuIGNvbXBhcmlzb24gKDwpXG4gICAqL1xuICBwdWJsaWMgbGVzc1RoYW4odmFsdWU6IG51bWJlcik6IENvbmRpdGlvbmFsUG9saWN5U3RhdGVtZW50IHtcbiAgICB0aGlzLmNvbmRpdGlvbkJ1aWxkZXIuX2FkZENvbmRpdGlvbihcbiAgICAgIG5ldyBDb25kaXRpb25FeHByZXNzaW9uKHRoaXMucGF0aCwgJzwnLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogTGVzcyB0aGFuIG9yIGVxdWFscyBjb21wYXJpc29uICg8PSlcbiAgICovXG4gIHB1YmxpYyBsZXNzVGhhbk9yRXF1YWxUbyh2YWx1ZTogbnVtYmVyKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnPD0nLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogR3JlYXRlciB0aGFuIGNvbXBhcmlzb24gKD4pXG4gICAqL1xuICBwdWJsaWMgZ3JlYXRlclRoYW4odmFsdWU6IG51bWJlcik6IENvbmRpdGlvbmFsUG9saWN5U3RhdGVtZW50IHtcbiAgICB0aGlzLmNvbmRpdGlvbkJ1aWxkZXIuX2FkZENvbmRpdGlvbihcbiAgICAgIG5ldyBDb25kaXRpb25FeHByZXNzaW9uKHRoaXMucGF0aCwgJz4nLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogR3JlYXRlciB0aGFuIG9yIGVxdWFscyBjb21wYXJpc29uICg+PSlcbiAgICovXG4gIHB1YmxpYyBncmVhdGVyVGhhbk9yRXF1YWxUbyh2YWx1ZTogbnVtYmVyKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnPj0nLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogSVAgcmFuZ2UgY2hlY2sgLSB0ZXN0cyBpZiBJUCBhZGRyZXNzIGlzIGluIENJRFIgcmFuZ2UuXG4gICAqXG4gICAqIEBwYXJhbSBpcFJhbmdlIC0gQ0lEUiBub3RhdGlvbiAoZS5nLiwgJzE5Mi4xNjguMS4wLzI0JylcbiAgICovXG4gIHB1YmxpYyBpc0luUmFuZ2UoaXBSYW5nZTogc3RyaW5nKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnaXNJblJhbmdlJywgYGlwKFwiJHtpcFJhbmdlfVwiKWApLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0cmluZyBjb250YWlucyBjaGVjay5cbiAgICovXG4gIHB1YmxpYyBjb250YWlucyh2YWx1ZTogc3RyaW5nKTogQ29uZGl0aW9uYWxQb2xpY3lTdGF0ZW1lbnQge1xuICAgIHRoaXMuY29uZGl0aW9uQnVpbGRlci5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnY29udGFpbnMnLCB2YWx1ZSksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYXR0cmlidXRlIGlzIGluIGEgc2V0L2xpc3QuXG4gICAqL1xuICBwdWJsaWMgaXNJbih2YWx1ZXM6IChzdHJpbmcgfCBudW1iZXIpW10pOiBDb25kaXRpb25hbFBvbGljeVN0YXRlbWVudCB7XG4gICAgY29uc3QgZm9ybWF0dGVkVmFsdWVzID0gdmFsdWVzLm1hcCh2ID0+XG4gICAgICB0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyBgXCIke3Z9XCJgIDogdixcbiAgICApLmpvaW4oJywgJyk7XG4gICAgdGhpcy5jb25kaXRpb25CdWlsZGVyLl9hZGRDb25kaXRpb24oXG4gICAgICBuZXcgQ29uZGl0aW9uRXhwcmVzc2lvbih0aGlzLnBhdGgsICdpbicsIGBbJHtmb3JtYXR0ZWRWYWx1ZXN9XWApLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50O1xuICB9XG59XG5cbi8qKlxuICogQWNjZXNzb3IgZm9yIGJ1aWxkaW5nIHR5cGUtc2FmZSBhdHRyaWJ1dGUgY29tcGFyaXNvbnMuXG4gKlxuICogUHJvdmlkZXMgbWV0aG9kcyBmb3IgY29tbW9uIGNvbXBhcmlzb24gb3BlcmF0b3JzIHdpdGggcHJvcGVyIHR5cGUgY2hlY2tpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBBdHRyaWJ1dGVBY2Nlc3NvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGF0aDogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcGFyZW50OiBDb25kaXRpb25CdWlsZGVyLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEVxdWFsaXR5IGNvbXBhcmlzb24gKD09KVxuICAgKi9cbiAgcHVibGljIGVxdWFsVG8odmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4pOiBDb25kaXRpb25CdWlsZGVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuX2FkZENvbmRpdGlvbihcbiAgICAgIG5ldyBDb25kaXRpb25FeHByZXNzaW9uKHRoaXMucGF0aCwgJz09JywgdmFsdWUpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogSW5lcXVhbGl0eSBjb21wYXJpc29uICghPSlcbiAgICovXG4gIHB1YmxpYyBub3RFcXVhbFRvKHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuKTogQ29uZGl0aW9uQnVpbGRlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50Ll9hZGRDb25kaXRpb24oXG4gICAgICBuZXcgQ29uZGl0aW9uRXhwcmVzc2lvbih0aGlzLnBhdGgsICchPScsIHZhbHVlKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIExlc3MgdGhhbiBjb21wYXJpc29uICg8KVxuICAgKi9cbiAgcHVibGljIGxlc3NUaGFuKHZhbHVlOiBudW1iZXIpOiBDb25kaXRpb25CdWlsZGVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuX2FkZENvbmRpdGlvbihcbiAgICAgIG5ldyBDb25kaXRpb25FeHByZXNzaW9uKHRoaXMucGF0aCwgJzwnLCB2YWx1ZSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMZXNzIHRoYW4gb3IgZXF1YWxzIGNvbXBhcmlzb24gKDw9KVxuICAgKi9cbiAgcHVibGljIGxlc3NUaGFuT3JFcXVhbFRvKHZhbHVlOiBudW1iZXIpOiBDb25kaXRpb25CdWlsZGVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuX2FkZENvbmRpdGlvbihcbiAgICAgIG5ldyBDb25kaXRpb25FeHByZXNzaW9uKHRoaXMucGF0aCwgJzw9JywgdmFsdWUpLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogR3JlYXRlciB0aGFuIGNvbXBhcmlzb24gKD4pXG4gICAqL1xuICBwdWJsaWMgZ3JlYXRlclRoYW4odmFsdWU6IG51bWJlcik6IENvbmRpdGlvbkJ1aWxkZXIge1xuICAgIHJldHVybiB0aGlzLnBhcmVudC5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnPicsIHZhbHVlKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyZWF0ZXIgdGhhbiBvciBlcXVhbHMgY29tcGFyaXNvbiAoPj0pXG4gICAqL1xuICBwdWJsaWMgZ3JlYXRlclRoYW5PckVxdWFsVG8odmFsdWU6IG51bWJlcik6IENvbmRpdGlvbkJ1aWxkZXIge1xuICAgIHJldHVybiB0aGlzLnBhcmVudC5fYWRkQ29uZGl0aW9uKFxuICAgICAgbmV3IENvbmRpdGlvbkV4cHJlc3Npb24odGhpcy5wYXRoLCAnPj0nLCB2YWx1ZSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJUCByYW5nZSBjaGVjayAtIHRlc3RzIGlmIElQIGFkZHJlc3MgaXMgaW4gQ0lEUiByYW5nZS5cbiAgICpcbiAgICogQHBhcmFtIGlwUmFuZ2UgLSBDSURSIG5vdGF0aW9uIChlLmcuLCAnMTkyLjE2OC4xLjAvMjQnKVxuICAgKi9cbiAgcHVibGljIGlzSW5SYW5nZShpcFJhbmdlOiBzdHJpbmcpOiBDb25kaXRpb25CdWlsZGVyIHtcbiAgICByZXR1cm4gdGhpcy5wYXJlbnQuX2FkZENvbmRpdGlvbihcbiAgICAgIG5ldyBDb25kaXRpb25FeHByZXNzaW9uKHRoaXMucGF0aCwgJ2lzSW5SYW5nZScsIGBpcChcIiR7aXBSYW5nZX1cIilgKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0cmluZyBjb250YWlucyBjaGVjay5cbiAgICovXG4gIHB1YmxpYyBjb250YWlucyh2YWx1ZTogc3RyaW5nKTogQ29uZGl0aW9uQnVpbGRlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50Ll9hZGRDb25kaXRpb24oXG4gICAgICBuZXcgQ29uZGl0aW9uRXhwcmVzc2lvbih0aGlzLnBhdGgsICdjb250YWlucycsIHZhbHVlKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGF0dHJpYnV0ZSBpcyBpbiBhIHNldC9saXN0LlxuICAgKi9cbiAgcHVibGljIGlzSW4odmFsdWVzOiAoc3RyaW5nIHwgbnVtYmVyKVtdKTogQ29uZGl0aW9uQnVpbGRlciB7XG4gICAgY29uc3QgZm9ybWF0dGVkVmFsdWVzID0gdmFsdWVzLm1hcCh2ID0+XG4gICAgICB0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyBgXCIke3Z9XCJgIDogdixcbiAgICApLmpvaW4oJywgJyk7XG4gICAgcmV0dXJuIHRoaXMucGFyZW50Ll9hZGRDb25kaXRpb24oXG4gICAgICBuZXcgQ29uZGl0aW9uRXhwcmVzc2lvbih0aGlzLnBhdGgsICdpbicsIGBbJHtmb3JtYXR0ZWRWYWx1ZXN9XWApLFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBUeXBlLXNhZmUgYnVpbGRlciBmb3IgY3JlYXRpbmcgQ2VkYXIgYXV0aG9yaXphdGlvbiBwb2xpY3kgc3RhdGVtZW50cy5cbiAqXG4gKiBUaGlzIGJ1aWxkZXIgcHJvdmlkZXMgYSBmbHVlbnQgQVBJIGZvciBjb25zdHJ1Y3RpbmcgQ2VkYXIgcG9saWNpZXMgd2l0aG91dFxuICogcmVxdWlyaW5nIGtub3dsZWRnZSBvZiBDZWRhciBzeW50YXguIEl0IHN1cHBvcnRzOlxuICogLSBQZXJtaXQgYW5kIGZvcmJpZCBlZmZlY3RzXG4gKiAtIFByaW5jaXBhbCwgYWN0aW9uLCBhbmQgcmVzb3VyY2Ugc3BlY2lmaWNhdGlvbnNcbiAqIC0gQ29uZGl0aW9uYWwgbG9naWMgKHdoZW4vdW5sZXNzIGNsYXVzZXMpXG4gKiAtIFJhdyBDZWRhciBmb3IgYWR2YW5jZWQgY2FzZXNcbiAqXG4gKiBUaGUgYnVpbGRlciBnZW5lcmF0ZXMgdmFsaWQgQ2VkYXIgcG9saWN5IHN0YXRlbWVudHMgdGhhdCBjYW4gYmUgdXNlZCB3aXRoXG4gKiB0aGUgUG9saWN5IGNvbnN0cnVjdC5cbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgUG9saWN5LCBQb2xpY3lFbmdpbmUsIFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ0Bhd3MtY2RrL2F3cy1iZWRyb2NrLWFnZW50Y29yZS1hbHBoYSc7XG4gKiBkZWNsYXJlIGNvbnN0IGVuZ2luZTogUG9saWN5RW5naW5lO1xuICpcbiAqIC8vIEV4YW1wbGUgMTogU2ltcGxlIHBlcm1pdCBwb2xpY3lcbiAqIC8vIEJ1aWxkZXIgZm9ybWF0OlxuICogbmV3IFBvbGljeSh0aGlzLCAnQWxsb3dBbGwnLCB7XG4gKiAgIHBvbGljeUVuZ2luZTogZW5naW5lLFxuICogICBzdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudC5wZXJtaXQoKVxuICogICAgIC5mb3JBbGxQcmluY2lwYWxzKClcbiAqICAgICAub25BbGxBY3Rpb25zKClcbiAqICAgICAub25BbGxSZXNvdXJjZXMoKSxcbiAqIH0pO1xuICpcbiAqIC8vIEdlbmVyYXRlZCBDZWRhcjpcbiAqIC8vIHBlcm1pdChcbiAqIC8vICAgcHJpbmNpcGFsLFxuICogLy8gICBhY3Rpb24sXG4gKiAvLyAgIHJlc291cmNlXG4gKiAvLyApO1xuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgeyBQb2xpY3ksIFBvbGljeUVuZ2luZSwgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnQGF3cy1jZGsvYXdzLWJlZHJvY2stYWdlbnRjb3JlLWFscGhhJztcbiAqIGRlY2xhcmUgY29uc3QgZW5naW5lOiBQb2xpY3lFbmdpbmU7XG4gKiBkZWNsYXJlIGNvbnN0IGdhdGV3YXlBcm46IHN0cmluZztcbiAqXG4gKiAvLyBFeGFtcGxlIDI6IFNwZWNpZmljIGFjdGlvbnMgcG9saWN5XG4gKiAvLyBCdWlsZGVyIGZvcm1hdDpcbiAqIG5ldyBQb2xpY3kodGhpcywgJ0FsbG93U3BlY2lmaWNBY3Rpb25zJywge1xuICogICBwb2xpY3lFbmdpbmU6IGVuZ2luZSxcbiAqICAgc3RhdGVtZW50OiBQb2xpY3lTdGF0ZW1lbnQucGVybWl0KClcbiAqICAgICAuZm9yUHJpbmNpcGFsSW5Hcm91cCgnR3JvdXAnLCAnRW5naW5lZXJzJylcbiAqICAgICAub25BY3Rpb25zKFtcbiAqICAgICAgICdBZ2VudENvcmU6OkFjdGlvbjo6ZXhhbXBsZWFjdGlvbjEnLFxuICogICAgICAgJ0FnZW50Q29yZTo6QWN0aW9uOjpleGFtcGxlYWN0aW9uMicsXG4gKiAgICAgXSlcbiAqICAgICAub25SZXNvdXJjZSgnQWdlbnRDb3JlOjpHYXRld2F5JywgZ2F0ZXdheUFybiksXG4gKiB9KTtcbiAqXG4gKiAvLyBHZW5lcmF0ZWQgQ2VkYXI6XG4gKiAvLyBwZXJtaXQoXG4gKiAvLyAgIHByaW5jaXBhbCBpbiBHcm91cDo6XCJFbmdpbmVlcnNcIixcbiAqIC8vICAgYWN0aW9uIGluIFtBZ2VudENvcmU6OkFjdGlvbjo6XCJleGFtcGxlYWN0aW9uMVwiLCBBZ2VudENvcmU6OkFjdGlvbjo6XCJleGFtcGxlYWN0aW9uMlwiXSxcbiAqIC8vICAgcmVzb3VyY2UgPT0gQWdlbnRDb3JlOjpHYXRld2F5OjpcImFybjphd3M6YmVkcm9jazp1cy1lYXN0LTE6MTIzOmdhdGV3YXkvZ3ctMTIzXCJcbiAqIC8vICk7XG4gKlxuICogQGV4YW1wbGVcbiAqIGltcG9ydCB7IFBvbGljeSwgUG9saWN5RW5naW5lLCBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdAYXdzLWNkay9hd3MtYmVkcm9jay1hZ2VudGNvcmUtYWxwaGEnO1xuICogZGVjbGFyZSBjb25zdCBlbmdpbmU6IFBvbGljeUVuZ2luZTtcbiAqXG4gKiAvLyBFeGFtcGxlIDM6IFBvbGljeSB3aXRoIGNvbmRpdGlvbnNcbiAqIC8vIEJ1aWxkZXIgZm9ybWF0OlxuICogbmV3IFBvbGljeSh0aGlzLCAnQ29uZGl0aW9uYWxQb2xpY3knLCB7XG4gKiAgIHBvbGljeUVuZ2luZTogZW5naW5lLFxuICogICBzdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudC5wZXJtaXQoKVxuICogICAgIC5mb3JBbGxQcmluY2lwYWxzKClcbiAqICAgICAub25BbGxBY3Rpb25zKClcbiAqICAgICAub25BbGxSZXNvdXJjZXMoKVxuICogICAgIC53aGVuKClcbiAqICAgICAgIC5wcmluY2lwYWxBdHRyaWJ1dGUoJ2RlcGFydG1lbnQnKS5lcXVhbFRvKCdFbmdpbmVlcmluZycpXG4gKiAgICAgICAuYW5kKClcbiAqICAgICAgIC5jb250ZXh0QXR0cmlidXRlKCdzb3VyY2VJcCcpLmlzSW5SYW5nZSgnMTkyLjE2OC4xLjAvMjQnKVxuICogICAgICAgLmRvbmUoKVxuICogICAgIC51bmxlc3MoKVxuICogICAgICAgLnByaW5jaXBhbEF0dHJpYnV0ZSgnc3VzcGVuZGVkJykuZXF1YWxUbyh0cnVlKVxuICogICAgICAgLmRvbmUoKSxcbiAqIH0pO1xuICpcbiAqIC8vIEdlbmVyYXRlZCBDZWRhcjpcbiAqIC8vIHBlcm1pdChcbiAqIC8vICAgcHJpbmNpcGFsLFxuICogLy8gICBhY3Rpb24sXG4gKiAvLyAgIHJlc291cmNlXG4gKiAvLyApXG4gKiAvLyB3aGVuIHtcbiAqIC8vICAgcHJpbmNpcGFsLmRlcGFydG1lbnQgPT0gXCJFbmdpbmVlcmluZ1wiICYmIGNvbnRleHQuc291cmNlSXAgaXNJblJhbmdlIGlwKFwiMTkyLjE2OC4xLjAvMjRcIilcbiAqIC8vIH1cbiAqIC8vIHVubGVzcyB7XG4gKiAvLyAgIHByaW5jaXBhbC5zdXNwZW5kZWQgPT0gdHJ1ZVxuICogLy8gfTtcbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgUG9saWN5LCBQb2xpY3lFbmdpbmUsIFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ0Bhd3MtY2RrL2F3cy1iZWRyb2NrLWFnZW50Y29yZS1hbHBoYSc7XG4gKiBkZWNsYXJlIGNvbnN0IGVuZ2luZTogUG9saWN5RW5naW5lO1xuICpcbiAqIC8vIEV4YW1wbGUgNDogUmF3IENlZGFyIHBvbGljeVxuICogLy8gRm9yIGFkdmFuY2VkIENlZGFyIGZlYXR1cmVzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGJ1aWxkZXJcbiAqIG5ldyBQb2xpY3kodGhpcywgJ0N1c3RvbVBvbGljeScsIHtcbiAqICAgcG9saWN5RW5naW5lOiBlbmdpbmUsXG4gKiAgIGRlZmluaXRpb246ICdwZXJtaXQocHJpbmNpcGFsLCBhY3Rpb24sIHJlc291cmNlKSB3aGVuIHsgY29udGV4dC5jdXN0b20gPiAxMCB9OycsXG4gKiB9KTtcbiAqXG4gKiAvLyBPciB1c2luZyBmcm9tQ2VkYXIoKTpcbiAqIG5ldyBQb2xpY3kodGhpcywgJ0ltcG9ydGVkUG9saWN5Jywge1xuICogICBwb2xpY3lFbmdpbmU6IGVuZ2luZSxcbiAqICAgc3RhdGVtZW50OiBQb2xpY3lTdGF0ZW1lbnQuZnJvbUNlZGFyKFxuICogICAgICdmb3JiaWQocHJpbmNpcGFsLCBhY3Rpb24sIHJlc291cmNlKSB3aGVuIHsgcmVzb3VyY2UuY29uZmlkZW50aWFsID09IHRydWUgfTsnXG4gKiAgICksXG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIFBvbGljeVN0YXRlbWVudCB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBwZXJtaXQgc3RhdGVtZW50IC0gYWxsb3dzIHRoZSBhY3Rpb24gaWYgY29uZGl0aW9ucyBhcmUgbWV0LlxuICAgKlxuICAgKiBQZXJtaXQgc3RhdGVtZW50cyBncmFudCBhY2Nlc3Mgd2hlbiB0aGVpciBjb25kaXRpb25zIGV2YWx1YXRlIHRvIHRydWUuXG4gICAqIE11bHRpcGxlIHBlcm1pdCBzdGF0ZW1lbnRzIGNhbiBhcHBseTsgYW55IG1hdGNoaW5nIHBlcm1pdCBhbGxvd3MgYWNjZXNzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBwZXJtaXQoKTogUG9saWN5U3RhdGVtZW50IHtcbiAgICByZXR1cm4gbmV3IFBvbGljeVN0YXRlbWVudChQb2xpY3lFZmZlY3QuUEVSTUlUKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBmb3JiaWQgc3RhdGVtZW50IC0gZGVuaWVzIHRoZSBhY3Rpb24gaWYgY29uZGl0aW9ucyBhcmUgbWV0LlxuICAgKlxuICAgKiBGb3JiaWQgc3RhdGVtZW50cyBkZW55IGFjY2VzcyB3aGVuIHRoZWlyIGNvbmRpdGlvbnMgZXZhbHVhdGUgdG8gdHJ1ZS5cbiAgICogRm9yYmlkIGFsd2F5cyB0YWtlcyBwcmVjZWRlbmNlIG92ZXIgcGVybWl0IChleHBsaWNpdCBkZW55KS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZm9yYmlkKCk6IFBvbGljeVN0YXRlbWVudCB7XG4gICAgcmV0dXJuIG5ldyBQb2xpY3lTdGF0ZW1lbnQoUG9saWN5RWZmZWN0LkZPUkJJRCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGZyb20gcmF3IENlZGFyIHBvbGljeSBzdGF0ZW1lbnQgc3RyaW5nLlxuICAgKlxuICAgKiBVc2UgdGhpcyBmb3IgYWR2YW5jZWQgQ2VkYXIgZmVhdHVyZXMgbm90IHN1cHBvcnRlZCBieSB0aGUgYnVpbGRlcixcbiAgICogb3Igd2hlbiBtaWdyYXRpbmcgZXhpc3RpbmcgQ2VkYXIgcG9saWNpZXMuXG4gICAqXG4gICAqIFZhbGlkYXRpb24gaXMgZGVmZXJyZWQgdG8gdGhlIFBvbGljeSBjb25zdHJ1Y3QncyB2YWxpZGF0aW9uTW9kZSBzZXR0aW5nLlxuICAgKlxuICAgKiBAcGFyYW0gY2VkYXJTdGF0ZW1lbnQgLSBDb21wbGV0ZSBDZWRhciBwb2xpY3kgc3RhdGVtZW50IGluY2x1ZGluZyBlZmZlY3QsIHByaW5jaXBhbCwgYWN0aW9uLCByZXNvdXJjZSwgYW5kIGNvbmRpdGlvbnNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUNlZGFyKGNlZGFyU3RhdGVtZW50OiBzdHJpbmcpOiBQb2xpY3lTdGF0ZW1lbnQge1xuICAgIGNvbnN0IHN0YXRlbWVudCA9IG5ldyBQb2xpY3lTdGF0ZW1lbnQoUG9saWN5RWZmZWN0LlBFUk1JVCk7XG4gICAgc3RhdGVtZW50LnJhd0NlZGFyID0gY2VkYXJTdGF0ZW1lbnQudHJpbSgpO1xuICAgIHJldHVybiBzdGF0ZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGVmZmVjdDogUG9saWN5RWZmZWN0O1xuICBwcml2YXRlIHByaW5jaXBhbENvbmZpZz86IFByaW5jaXBhbENvbmZpZztcbiAgcHJpdmF0ZSBhY3Rpb25Db25maWc/OiBBY3Rpb25Db25maWc7XG4gIHByaXZhdGUgcmVzb3VyY2VDb25maWc/OiBSZXNvdXJjZUNvbmZpZztcbiAgcHJpdmF0ZSB3aGVuQ29uZGl0aW9ucz86IENvbmRpdGlvbkJ1aWxkZXI7XG4gIHByaXZhdGUgdW5sZXNzQ29uZGl0aW9ucz86IENvbmRpdGlvbkJ1aWxkZXI7XG4gIHByaXZhdGUgcmF3Q2VkYXI/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihlZmZlY3Q6IFBvbGljeUVmZmVjdCkge1xuICAgIHRoaXMuZWZmZWN0ID0gZWZmZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRvIGFsbCBwcmluY2lwYWxzIChhbnkgdXNlciwgc2VydmljZSwgb3IgZW50aXR5KS5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgcHJpbmNpcGFsYCBpbiBDZWRhclxuICAgKi9cbiAgcHVibGljIGZvckFsbFByaW5jaXBhbHMoKTogdGhpcyB7XG4gICAgdGhpcy52YWxpZGF0ZU5vdFJhd0NlZGFyKCk7XG4gICAgdGhpcy5wcmluY2lwYWxDb25maWcgPSB7IHNjb3BlOiBQcmluY2lwYWxTY29wZS5BTEwgfTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBseSB0byBhIHNwZWNpZmljIHByaW5jaXBhbCBlbnRpdHkuXG4gICAqXG4gICAqIEdlbmVyYXRlczogYHByaW5jaXBhbCA9PSBFbnRpdHlUeXBlOjpcImVudGl0eUlkXCJgIGluIENlZGFyXG4gICAqXG4gICAqIEBwYXJhbSBlbnRpdHlUeXBlIC0gVGhlIGVudGl0eSB0eXBlIChlLmcuLCAnQWdlbnRDb3JlOjpPQXV0aFVzZXInKVxuICAgKiBAcGFyYW0gZW50aXR5SWQgLSBPcHRpb25hbCBzcGVjaWZpYyBlbnRpdHkgSURcbiAgICovXG4gIHB1YmxpYyBmb3JQcmluY2lwYWwoZW50aXR5VHlwZTogc3RyaW5nLCBlbnRpdHlJZD86IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMudmFsaWRhdGVOb3RSYXdDZWRhcigpO1xuICAgIHRoaXMucHJpbmNpcGFsQ29uZmlnID0ge1xuICAgICAgc2NvcGU6IFByaW5jaXBhbFNjb3BlLlNQRUNJRklDLFxuICAgICAgZW50aXR5VHlwZSxcbiAgICAgIGVudGl0eUlkLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQXBwbHkgdG8gcHJpbmNpcGFscyB0aGF0IGFyZSBtZW1iZXJzIG9mIGEgc3BlY2lmaWMgZ3JvdXAuXG4gICAqXG4gICAqIEdlbmVyYXRlczogYHByaW5jaXBhbCBpbiBHcm91cDo6XCJncm91cElkXCJgIGluIENlZGFyXG4gICAqXG4gICAqIEBwYXJhbSBncm91cFR5cGUgLSBUaGUgZ3JvdXAgZW50aXR5IHR5cGUgKGUuZy4sICdHcm91cCcpXG4gICAqIEBwYXJhbSBncm91cElkIC0gVGhlIGdyb3VwIGlkZW50aWZpZXIgKGUuZy4sICdBZG1pbnMnLCAnRW5naW5lZXJzJylcbiAgICovXG4gIHB1YmxpYyBmb3JQcmluY2lwYWxJbkdyb3VwKGdyb3VwVHlwZTogc3RyaW5nLCBncm91cElkOiBzdHJpbmcpOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlTm90UmF3Q2VkYXIoKTtcbiAgICB0aGlzLnByaW5jaXBhbENvbmZpZyA9IHtcbiAgICAgIHNjb3BlOiBQcmluY2lwYWxTY29wZS5TUEVDSUZJQyxcbiAgICAgIG1lbWJlck9mOiB7IGVudGl0eVR5cGU6IGdyb3VwVHlwZSwgZW50aXR5SWQ6IGdyb3VwSWQgfSxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRvIGFsbCBhY3Rpb25zIChhbnkgb3BlcmF0aW9uKS5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgYWN0aW9uYCBpbiBDZWRhclxuICAgKi9cbiAgcHVibGljIG9uQWxsQWN0aW9ucygpOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlTm90UmF3Q2VkYXIoKTtcbiAgICB0aGlzLmFjdGlvbkNvbmZpZyA9IHsgc2NvcGU6IEFjdGlvblNjb3BlLkFMTCB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRvIHNwZWNpZmljIGFjdGlvbihzKS5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgYWN0aW9uID09IEFjdGlvbjo6XCJuYW1lXCJgIG9yIGBhY3Rpb24gaW4gW0FjdGlvbjo6XCJuYW1lMVwiLCBBY3Rpb246OlwibmFtZTJcIl1gIGluIENlZGFyXG4gICAqXG4gICAqIEBwYXJhbSBhY3Rpb25zIC0gQXJyYXkgb2YgYWN0aW9uIG5hbWVzIChlLmcuLCBbJ0FnZW50Q29yZTo6QWN0aW9uOjpJbnN1cmFuY2VBUElfX2dldF9wb2xpY3knXSlcbiAgICovXG4gIHB1YmxpYyBvbkFjdGlvbnMoYWN0aW9uczogc3RyaW5nW10pOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlTm90UmF3Q2VkYXIoKTtcbiAgICBpZiAoYWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgQXRMZWFzdE9uZUFjdGlvbmAsICdBdCBsZWFzdCBvbmUgYWN0aW9uIG11c3QgYmUgc3BlY2lmaWVkJyk7XG4gICAgfVxuICAgIHRoaXMuYWN0aW9uQ29uZmlnID0ge1xuICAgICAgc2NvcGU6IEFjdGlvblNjb3BlLlNQRUNJRklDLFxuICAgICAgYWN0aW9ucyxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IHRvIGEgc2luZ2xlIHNwZWNpZmljIGFjdGlvbi5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgYWN0aW9uID09IEFjdGlvbjo6XCJuYW1lXCJgIGluIENlZGFyXG4gICAqXG4gICAqIEBwYXJhbSBhY3Rpb24gLSBBY3Rpb24gbmFtZSAoZS5nLiwgJ0FnZW50Q29yZTo6QWN0aW9uOjpJbnN1cmFuY2VBUElfX2dldF9wb2xpY3knKVxuICAgKi9cbiAgcHVibGljIG9uQWN0aW9uKGFjdGlvbjogc3RyaW5nKTogdGhpcyB7XG4gICAgcmV0dXJuIHRoaXMub25BY3Rpb25zKFthY3Rpb25dKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBseSB0byBhbGwgcmVzb3VyY2VzIG9mIGEgc3BlY2lmaWMgdHlwZS5cbiAgICpcbiAgICogKipBV1MgUmVxdWlyZW1lbnQqKjogQVdTIEJlZHJvY2sgQWdlbnRDb3JlIFBvbGljeSBzZXJ2aWNlIGRvZXMgbm90IGFsbG93IHdpbGRjYXJkXG4gICAqIHJlc291cmNlcyAoYHJlc291cmNlYCkuIFRoaXMgbWV0aG9kIHByb3ZpZGVzIHR5cGUtY29uc3RyYWluZWQgcmVzb3VyY2VzIHdoaWNoIGFyZVxuICAgKiByZXF1aXJlZCBmb3IgcG9saWN5IHZhbGlkYXRpb24gdG8gc3VjY2VlZC5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgcmVzb3VyY2UgaXMgRW50aXR5VHlwZWAgaW4gQ2VkYXJcbiAgICpcbiAgICogQHBhcmFtIGVudGl0eVR5cGUgLSBUaGUgZW50aXR5IHR5cGUgKGRlZmF1bHQ6ICdBZ2VudENvcmU6OkdhdGV3YXknKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBpbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICdAYXdzLWNkay9hd3MtYmVkcm9jay1hZ2VudGNvcmUtYWxwaGEnO1xuICAgKlxuICAgKiAvLyBDb25zdHJhaW4gdG8gR2F0ZXdheSByZXNvdXJjZXMgKGRlZmF1bHQpXG4gICAqIFBvbGljeVN0YXRlbWVudC5wZXJtaXQoKVxuICAgKiAgIC5mb3JBbGxQcmluY2lwYWxzKClcbiAgICogICAub25BbGxBY3Rpb25zKClcbiAgICogICAub25BbGxSZXNvdXJjZXMoKSAgLy8g4oaSIFwicmVzb3VyY2UgaXMgQWdlbnRDb3JlOjpHYXRld2F5XCJcbiAgICpcbiAgICogLy8gQ29uc3RyYWluIHRvIFJ1bnRpbWUgcmVzb3VyY2VzXG4gICAqIFBvbGljeVN0YXRlbWVudC5wZXJtaXQoKVxuICAgKiAgIC5mb3JBbGxQcmluY2lwYWxzKClcbiAgICogICAub25BbGxBY3Rpb25zKClcbiAgICogICAub25BbGxSZXNvdXJjZXMoJ0FnZW50Q29yZTo6UnVudGltZScpICAvLyDihpIgXCJyZXNvdXJjZSBpcyBBZ2VudENvcmU6OlJ1bnRpbWVcIlxuICAgKi9cbiAgcHVibGljIG9uQWxsUmVzb3VyY2VzKGVudGl0eVR5cGU6IHN0cmluZyA9ICdBZ2VudENvcmU6OkdhdGV3YXknKTogdGhpcyB7XG4gICAgdGhpcy52YWxpZGF0ZU5vdFJhd0NlZGFyKCk7XG4gICAgdGhpcy5yZXNvdXJjZUNvbmZpZyA9IHtcbiAgICAgIHNjb3BlOiBSZXNvdXJjZVNjb3BlLlRZUEUsXG4gICAgICBlbnRpdHlUeXBlLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQXBwbHkgdG8gYWxsIHJlc291cmNlcyBvZiBhIHNwZWNpZmljIHR5cGUgKGV4cGxpY2l0IG1ldGhvZCkuXG4gICAqXG4gICAqICoqQVdTIFJlcXVpcmVtZW50Kio6IFJlc291cmNlIHR5cGUgY29uc3RyYWludHMgYXJlIHJlcXVpcmVkIGJ5IEFXUyBCZWRyb2NrXG4gICAqIEFnZW50Q29yZSB3aGVuIHVzaW5nIHdpbGRjYXJkIHByaW5jaXBhbHMgb3IgYWN0aW9ucy5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgcmVzb3VyY2UgaXMgRW50aXR5VHlwZWAgaW4gQ2VkYXJcbiAgICpcbiAgICogQHBhcmFtIGVudGl0eVR5cGUgLSBUaGUgZW50aXR5IHR5cGUgKGUuZy4sICdBZ2VudENvcmU6OkdhdGV3YXknLCAnQWdlbnRDb3JlOjpSdW50aW1lJylcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnQGF3cy1jZGsvYXdzLWJlZHJvY2stYWdlbnRjb3JlLWFscGhhJztcbiAgICpcbiAgICogUG9saWN5U3RhdGVtZW50LnBlcm1pdCgpXG4gICAqICAgLmZvckFsbFByaW5jaXBhbHMoKVxuICAgKiAgIC5vbkFsbEFjdGlvbnMoKVxuICAgKiAgIC5vblJlc291cmNlVHlwZSgnQWdlbnRDb3JlOjpHYXRld2F5JykgIC8vIOKGkiBcInJlc291cmNlIGlzIEFnZW50Q29yZTo6R2F0ZXdheVwiXG4gICAqL1xuICBwdWJsaWMgb25SZXNvdXJjZVR5cGUoZW50aXR5VHlwZTogc3RyaW5nKTogdGhpcyB7XG4gICAgdGhpcy52YWxpZGF0ZU5vdFJhd0NlZGFyKCk7XG4gICAgdGhpcy5yZXNvdXJjZUNvbmZpZyA9IHtcbiAgICAgIHNjb3BlOiBSZXNvdXJjZVNjb3BlLlRZUEUsXG4gICAgICBlbnRpdHlUeXBlLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQXBwbHkgdG8gYSBzcGVjaWZpYyByZXNvdXJjZSBpbnN0YW5jZS5cbiAgICpcbiAgICogKipBV1MgUmVxdWlyZW1lbnQqKjogV2hlbiB1c2luZyBzcGVjaWZpYyBhY3Rpb25zIChlLmcuLCBgYWN0aW9uID09IEFjdGlvbjo6XCJEZWxldGVcImApLFxuICAgKiB5b3UgbXVzdCBjb25zdHJhaW4gdGhlIHJlc291cmNlIHRvIGEgc3BlY2lmaWMgaW5zdGFuY2UsIG5vdCBqdXN0IGEgdHlwZS5cbiAgICpcbiAgICogR2VuZXJhdGVzOiBgcmVzb3VyY2UgPT0gRW50aXR5VHlwZTo6XCJhcm5cImAgaW4gQ2VkYXJcbiAgICpcbiAgICogQHBhcmFtIGVudGl0eVR5cGUgLSBUaGUgZW50aXR5IHR5cGUgKGUuZy4sICdBZ2VudENvcmU6OkdhdGV3YXknKVxuICAgKiBAcGFyYW0gZW50aXR5QXJuIC0gVGhlIHJlc291cmNlIEFSTiBvciBpZGVudGlmaWVyXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGltcG9ydCB7IFBvbGljeVN0YXRlbWVudCB9IGZyb20gJ0Bhd3MtY2RrL2F3cy1iZWRyb2NrLWFnZW50Y29yZS1hbHBoYSc7XG4gICAqIGRlY2xhcmUgY29uc3QgZ2F0ZXdheUFybjogc3RyaW5nO1xuICAgKlxuICAgKiBQb2xpY3lTdGF0ZW1lbnQuZm9yYmlkKClcbiAgICogICAuZm9yQWxsUHJpbmNpcGFscygpXG4gICAqICAgLm9uQWN0aW9uKCdBZ2VudENvcmU6OkFjdGlvbjo6RGVsZXRlJylcbiAgICogICAub25SZXNvdXJjZSgnQWdlbnRDb3JlOjpHYXRld2F5JywgZ2F0ZXdheUFybikgIC8vIE11c3QgYmUgc3BlY2lmaWMgcmVzb3VyY2VcbiAgICovXG4gIHB1YmxpYyBvblJlc291cmNlKGVudGl0eVR5cGU6IHN0cmluZywgZW50aXR5QXJuOiBzdHJpbmcpOiB0aGlzIHtcbiAgICB0aGlzLnZhbGlkYXRlTm90UmF3Q2VkYXIoKTtcbiAgICB0aGlzLnJlc291cmNlQ29uZmlnID0ge1xuICAgICAgc2NvcGU6IFJlc291cmNlU2NvcGUuU1BFQ0lGSUMsXG4gICAgICBlbnRpdHlUeXBlLFxuICAgICAgZW50aXR5QXJuLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkIHdoZW4gY29uZGl0aW9ucyAtIHBvbGljeSBhcHBsaWVzIG9ubHkgaWYgdGhlc2UgY29uZGl0aW9ucyBhcmUgdHJ1ZS5cbiAgICpcbiAgICogV2hlbiBjb25kaXRpb25zIGRlZmluZSBwb3NpdGl2ZSByZXF1aXJlbWVudHMgdGhhdCBtdXN0IGJlIG1ldC5cbiAgICogTXVsdGlwbGUgY29uZGl0aW9ucyBjYW4gYmUgY29tYmluZWQgd2l0aCBBTkQvT1Igb3BlcmF0b3JzLlxuICAgKlxuICAgKiBSZXR1cm5zIGEgQ29uZGl0aW9uQnVpbGRlciB0aGF0IHlvdSBjYW4gY2hhaW4gY29uZGl0aW9uIG1ldGhvZHMgb24uXG4gICAqIENhbGwgZG9uZSgpIHdoZW4gZmluaXNoZWQgdG8gcmV0dXJuIHRvIHRoZSBQb2xpY3lTdGF0ZW1lbnQuXG4gICAqL1xuICBwdWJsaWMgd2hlbigpOiBDb25kaXRpb25hbFBvbGljeVN0YXRlbWVudCB7XG4gICAgdGhpcy52YWxpZGF0ZU5vdFJhd0NlZGFyKCk7XG4gICAgdGhpcy53aGVuQ29uZGl0aW9ucyA9IG5ldyBDb25kaXRpb25CdWlsZGVyKCk7XG4gICAgcmV0dXJuIG5ldyBDb25kaXRpb25hbFBvbGljeVN0YXRlbWVudCh0aGlzLCB0aGlzLndoZW5Db25kaXRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgdW5sZXNzIGNvbmRpdGlvbnMgLSBwb2xpY3kgYXBwbGllcyBvbmx5IGlmIHRoZXNlIGNvbmRpdGlvbnMgYXJlIGZhbHNlLlxuICAgKlxuICAgKiBVbmxlc3MgY29uZGl0aW9ucyBkZWZpbmUgbmVnYXRpdmUgcmVxdWlyZW1lbnRzIChleGNsdXNpb25zKS5cbiAgICogVGhlIHBvbGljeSBhcHBsaWVzIHdoZW4gdGhlc2UgY29uZGl0aW9ucyBhcmUgTk9UIG1ldC5cbiAgICpcbiAgICogUmV0dXJucyBhIENvbmRpdGlvbkJ1aWxkZXIgdGhhdCB5b3UgY2FuIGNoYWluIGNvbmRpdGlvbiBtZXRob2RzIG9uLlxuICAgKiBDYWxsIGRvbmUoKSB3aGVuIGZpbmlzaGVkIHRvIHJldHVybiB0byB0aGUgUG9saWN5U3RhdGVtZW50LlxuICAgKi9cbiAgcHVibGljIHVubGVzcygpOiBDb25kaXRpb25hbFBvbGljeVN0YXRlbWVudCB7XG4gICAgdGhpcy52YWxpZGF0ZU5vdFJhd0NlZGFyKCk7XG4gICAgdGhpcy51bmxlc3NDb25kaXRpb25zID0gbmV3IENvbmRpdGlvbkJ1aWxkZXIoKTtcbiAgICByZXR1cm4gbmV3IENvbmRpdGlvbmFsUG9saWN5U3RhdGVtZW50KHRoaXMsIHRoaXMudW5sZXNzQ29uZGl0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgdGhlIENlZGFyIHBvbGljeSBzdGF0ZW1lbnQgc3RyaW5nLlxuICAgKlxuICAgKiBDb252ZXJ0cyB0aGUgYnVpbGRlciBzdGF0ZSBpbnRvIHZhbGlkIENlZGFyIHBvbGljeSBzeW50YXguXG4gICAqIFRoaXMgaXMgY2FsbGVkIGludGVybmFsbHkgYnkgdGhlIFBvbGljeSBjb25zdHJ1Y3QuXG4gICAqXG4gICAqIEByZXR1cm5zIFZhbGlkIENlZGFyIHBvbGljeSBzdGF0ZW1lbnRcbiAgICovXG4gIHB1YmxpYyB0b0NlZGFyKCk6IHN0cmluZyB7XG4gICAgLy8gSWYgcmF3IENlZGFyIHdhcyBwcm92aWRlZCwgcmV0dXJuIGl0IGRpcmVjdGx5XG4gICAgaWYgKHRoaXMucmF3Q2VkYXIpIHtcbiAgICAgIHJldHVybiB0aGlzLnJhd0NlZGFyO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIHRoYXQgYWxsIHJlcXVpcmVkIHBhcnRzIGFyZSBjb25maWd1cmVkXG4gICAgaWYgKCF0aGlzLnByaW5jaXBhbENvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBQcmluY2lwYWxSZXF1aXJlZGAsICdQcmluY2lwYWwgbXVzdCBiZSBzcGVjaWZpZWQgdXNpbmcgZm9yQWxsUHJpbmNpcGFscygpIG9yIGZvclByaW5jaXBhbCgpJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5hY3Rpb25Db25maWcpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgQWN0aW9uUmVxdWlyZWRgLCAnQWN0aW9uIG11c3QgYmUgc3BlY2lmaWVkIHVzaW5nIG9uQWxsQWN0aW9ucygpIG9yIG9uQWN0aW9ucygpJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5yZXNvdXJjZUNvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBSZXNvdXJjZVJlcXVpcmVkYCwgJ1Jlc291cmNlIG11c3QgYmUgc3BlY2lmaWVkIHVzaW5nIG9uQWxsUmVzb3VyY2VzKCkgb3Igb25SZXNvdXJjZSgpJyk7XG4gICAgfVxuXG4gICAgbGV0IGNlZGFyID0gYCR7dGhpcy5lZmZlY3R9KFxcbmA7XG5cbiAgICAvLyBQcmluY2lwYWxcbiAgICBjZWRhciArPSBgICAke3RoaXMucHJpbmNpcGFsVG9DZWRhcigpfSxcXG5gO1xuXG4gICAgLy8gQWN0aW9uXG4gICAgY2VkYXIgKz0gYCAgJHt0aGlzLmFjdGlvblRvQ2VkYXIoKX0sXFxuYDtcblxuICAgIC8vIFJlc291cmNlXG4gICAgY2VkYXIgKz0gYCAgJHt0aGlzLnJlc291cmNlVG9DZWRhcigpfVxcbmA7XG5cbiAgICBjZWRhciArPSAnKSc7XG5cbiAgICAvLyBXaGVuIGNvbmRpdGlvbnNcbiAgICBpZiAodGhpcy53aGVuQ29uZGl0aW9ucykge1xuICAgICAgY29uc3Qgd2hlbkNlZGFyID0gdGhpcy53aGVuQ29uZGl0aW9ucy5fdG9DZWRhcigpO1xuICAgICAgaWYgKHdoZW5DZWRhcikge1xuICAgICAgICBjZWRhciArPSBgXFxud2hlbiB7XFxuICAke3doZW5DZWRhcn1cXG59YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBVbmxlc3MgY29uZGl0aW9uc1xuICAgIGlmICh0aGlzLnVubGVzc0NvbmRpdGlvbnMpIHtcbiAgICAgIGNvbnN0IHVubGVzc0NlZGFyID0gdGhpcy51bmxlc3NDb25kaXRpb25zLl90b0NlZGFyKCk7XG4gICAgICBpZiAodW5sZXNzQ2VkYXIpIHtcbiAgICAgICAgY2VkYXIgKz0gYFxcbnVubGVzcyB7XFxuICAke3VubGVzc0NlZGFyfVxcbn1gO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNlZGFyICs9ICc7JztcbiAgICByZXR1cm4gY2VkYXI7XG4gIH1cblxuICBwcml2YXRlIHByaW5jaXBhbFRvQ2VkYXIoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMucHJpbmNpcGFsQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IobGl0YFByaW5jaXBhbENvbmZpZ1JlcXVpcmVkYCwgJ1ByaW5jaXBhbCBjb25maWd1cmF0aW9uIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucHJpbmNpcGFsQ29uZmlnLnNjb3BlID09PSBQcmluY2lwYWxTY29wZS5BTEwpIHtcbiAgICAgIHJldHVybiAncHJpbmNpcGFsJztcbiAgICB9XG5cbiAgICAvLyBDaGVjayBmb3IgZ3JvdXAgbWVtYmVyc2hpcFxuICAgIGlmICh0aGlzLnByaW5jaXBhbENvbmZpZy5tZW1iZXJPZikge1xuICAgICAgY29uc3QgeyBlbnRpdHlUeXBlLCBlbnRpdHlJZCB9ID0gdGhpcy5wcmluY2lwYWxDb25maWcubWVtYmVyT2Y7XG4gICAgICByZXR1cm4gYHByaW5jaXBhbCBpbiAke2VudGl0eVR5cGV9OjpcIiR7ZW50aXR5SWR9XCJgO1xuICAgIH1cblxuICAgIC8vIFNwZWNpZmljIHByaW5jaXBhbFxuICAgIGlmICh0aGlzLnByaW5jaXBhbENvbmZpZy5lbnRpdHlJZCkge1xuICAgICAgcmV0dXJuIGBwcmluY2lwYWwgPT0gJHt0aGlzLnByaW5jaXBhbENvbmZpZy5lbnRpdHlUeXBlfTo6XCIke3RoaXMucHJpbmNpcGFsQ29uZmlnLmVudGl0eUlkfVwiYDtcbiAgICB9XG5cbiAgICAvLyBQcmluY2lwYWwgdHlwZSBvbmx5IChpcyBvcGVyYXRvcilcbiAgICByZXR1cm4gYHByaW5jaXBhbCBpcyAke3RoaXMucHJpbmNpcGFsQ29uZmlnLmVudGl0eVR5cGV9YDtcbiAgfVxuXG4gIHByaXZhdGUgYWN0aW9uVG9DZWRhcigpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5hY3Rpb25Db25maWcpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgQWN0aW9uQ29uZmlnUmVxdWlyZWRgLCAnQWN0aW9uIGNvbmZpZ3VyYXRpb24gaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hY3Rpb25Db25maWcuc2NvcGUgPT09IEFjdGlvblNjb3BlLkFMTCkge1xuICAgICAgcmV0dXJuICdhY3Rpb24nO1xuICAgIH1cblxuICAgIGNvbnN0IGFjdGlvbnMgPSB0aGlzLmFjdGlvbkNvbmZpZy5hY3Rpb25zITtcblxuICAgIC8vIEZvcm1hdCBhY3Rpb246IGlmIGl0IGNvbnRhaW5zIFwiOjpcIiBpdCdzIGFscmVhZHkgbmFtZXNwYWNlZCwganVzdCBlbnN1cmUgcXVvdGVzXG4gICAgLy8gT3RoZXJ3aXNlIHRyZWF0IGFzIGFjdGlvbiBpZGVudGlmaWVyXG4gICAgY29uc3QgZm9ybWF0QWN0aW9uID0gKGFjdGlvbjogc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgICAgIGlmIChhY3Rpb24uaW5jbHVkZXMoJzo6JykpIHtcbiAgICAgICAgLy8gQWxyZWFkeSBuYW1lc3BhY2VkIGxpa2UgXCJBZ2VudENvcmU6OkFjdGlvbjo6YWN0aW9ubmFtZVwiXG4gICAgICAgIC8vIE5lZWQgdG8gZW5zdXJlIHRoZSBhY3Rpb24gbmFtZSBwYXJ0IGlzIHF1b3RlZFxuICAgICAgICBjb25zdCBwYXJ0cyA9IGFjdGlvbi5zcGxpdCgnOjonKTtcbiAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICAgICAgY29uc3QgYWN0aW9uTmFtZSA9IHBhcnRzLnNsaWNlKDIpLmpvaW4oJzo6Jyk7XG4gICAgICAgICAgY29uc3QgbmFtZXNwYWNlID0gcGFydHMuc2xpY2UoMCwgMikuam9pbignOjonKTtcbiAgICAgICAgICByZXR1cm4gYCR7bmFtZXNwYWNlfTo6XCIke2FjdGlvbk5hbWV9XCJgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBPdGhlcndpc2UgcmV0dXJuIGFzLWlzICh3aWxsIGJlIHZhbGlkYXRlZCBieSBDZWRhcilcbiAgICAgIHJldHVybiBhY3Rpb247XG4gICAgfTtcblxuICAgIGlmIChhY3Rpb25zLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcmV0dXJuIGBhY3Rpb24gPT0gJHtmb3JtYXRBY3Rpb24oYWN0aW9uc1swXSl9YDtcbiAgICB9XG5cbiAgICAvLyBNdWx0aXBsZSBhY3Rpb25zXG4gICAgY29uc3QgZm9ybWF0dGVkQWN0aW9ucyA9IGFjdGlvbnMubWFwKGEgPT4gZm9ybWF0QWN0aW9uKGEpKS5qb2luKCcsICcpO1xuICAgIHJldHVybiBgYWN0aW9uIGluIFske2Zvcm1hdHRlZEFjdGlvbnN9XWA7XG4gIH1cblxuICBwcml2YXRlIHJlc291cmNlVG9DZWRhcigpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5yZXNvdXJjZUNvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBSZXNvdXJjZUNvbmZpZ1JlcXVpcmVkYCwgJ1Jlc291cmNlIGNvbmZpZ3VyYXRpb24gaXMgcmVxdWlyZWQnKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMucmVzb3VyY2VDb25maWcuc2NvcGUpIHtcbiAgICAgIGNhc2UgUmVzb3VyY2VTY29wZS5BTEw6XG4gICAgICAgIC8vIE5vdGU6IFdpbGRjYXJkIHJlc291cmNlcyBtYXkgYmUgcmVqZWN0ZWQgYnkgQVdTIEJlZHJvY2sgQWdlbnRDb3JlIHNlcnZpY2VcbiAgICAgICAgcmV0dXJuICdyZXNvdXJjZSc7XG5cbiAgICAgIGNhc2UgUmVzb3VyY2VTY29wZS5UWVBFOlxuICAgICAgICAvLyBSZXNvdXJjZSB0eXBlIGNvbnN0cmFpbnQ6IFwicmVzb3VyY2UgaXMgRW50aXR5VHlwZVwiXG4gICAgICAgIGlmICghdGhpcy5yZXNvdXJjZUNvbmZpZy5lbnRpdHlUeXBlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBFbnRpdHlUeXBlUmVxdWlyZWRgLCAnRW50aXR5IHR5cGUgaXMgcmVxdWlyZWQgZm9yIFRZUEUgcmVzb3VyY2Ugc2NvcGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYHJlc291cmNlIGlzICR7dGhpcy5yZXNvdXJjZUNvbmZpZy5lbnRpdHlUeXBlfWA7XG5cbiAgICAgIGNhc2UgUmVzb3VyY2VTY29wZS5TUEVDSUZJQzpcbiAgICAgICAgLy8gU3BlY2lmaWMgcmVzb3VyY2U6IFwicmVzb3VyY2UgPT0gRW50aXR5VHlwZTo6XCJhcm5cIlwiXG4gICAgICAgIGlmICghdGhpcy5yZXNvdXJjZUNvbmZpZy5lbnRpdHlUeXBlIHx8ICF0aGlzLnJlc291cmNlQ29uZmlnLmVudGl0eUFybikge1xuICAgICAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihsaXRgRW50aXR5VHlwZUFuZEFyblJlcXVpcmVkYCwgJ0VudGl0eSB0eXBlIGFuZCBBUk4gYXJlIHJlcXVpcmVkIGZvciBTUEVDSUZJQyByZXNvdXJjZSBzY29wZScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgcmVzb3VyY2UgPT0gJHt0aGlzLnJlc291cmNlQ29uZmlnLmVudGl0eVR5cGV9OjpcIiR7dGhpcy5yZXNvdXJjZUNvbmZpZy5lbnRpdHlBcm59XCJgO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IobGl0YFVua25vd25SZXNvdXJjZVNjb3BlYCwgYFVua25vd24gcmVzb3VyY2Ugc2NvcGU6ICR7dGhpcy5yZXNvdXJjZUNvbmZpZy5zY29wZX1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHZhbGlkYXRlTm90UmF3Q2VkYXIoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmF3Q2VkYXIpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YFJhd0NlZGFyQ29uZmxpY3RgLFxuICAgICAgICAnQ2Fubm90IHVzZSBidWlsZGVyIG1ldGhvZHMgd2l0aCByYXcgQ2VkYXIuICcgK1xuICAgICAgICAnRWl0aGVyIHVzZSBQb2xpY3lTdGF0ZW1lbnQuZnJvbUNlZGFyKCkgb3IgYnVpbGRlciBtZXRob2RzLCBub3QgYm90aC4nLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==