@aws-cdk/aws-bedrock-agentcore-alpha 2.225.0-alpha.0 → 2.227.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 (54) hide show
  1. package/.jsii +14021 -5792
  2. package/.jsii.tabl.json.gz +0 -0
  3. package/.warnings.jsii.js +343 -1
  4. package/README.md +880 -19
  5. package/agentcore/gateway/gateway-base.d.ts +292 -0
  6. package/agentcore/gateway/gateway-base.js +171 -0
  7. package/agentcore/gateway/gateway.d.ts +383 -0
  8. package/agentcore/gateway/gateway.js +521 -0
  9. package/agentcore/gateway/inbound-auth/authorizer.d.ts +121 -0
  10. package/agentcore/gateway/inbound-auth/authorizer.js +133 -0
  11. package/agentcore/gateway/outbound-auth/api-key.d.ts +117 -0
  12. package/agentcore/gateway/outbound-auth/api-key.js +141 -0
  13. package/agentcore/gateway/outbound-auth/credential-provider.d.ts +70 -0
  14. package/agentcore/gateway/outbound-auth/credential-provider.js +80 -0
  15. package/agentcore/gateway/outbound-auth/iam-role.d.ts +28 -0
  16. package/agentcore/gateway/outbound-auth/iam-role.js +40 -0
  17. package/agentcore/gateway/outbound-auth/oauth.d.ts +80 -0
  18. package/agentcore/gateway/outbound-auth/oauth.js +76 -0
  19. package/agentcore/gateway/perms.d.ts +75 -0
  20. package/agentcore/gateway/perms.js +112 -0
  21. package/agentcore/gateway/protocol.d.ts +121 -0
  22. package/agentcore/gateway/protocol.js +120 -0
  23. package/agentcore/gateway/targets/schema/api-schema.d.ts +110 -0
  24. package/agentcore/gateway/targets/schema/api-schema.js +207 -0
  25. package/agentcore/gateway/targets/schema/base-schema.d.ts +24 -0
  26. package/agentcore/gateway/targets/schema/base-schema.js +12 -0
  27. package/agentcore/gateway/targets/schema/tool-schema.d.ts +198 -0
  28. package/agentcore/gateway/targets/schema/tool-schema.js +213 -0
  29. package/agentcore/gateway/targets/target-base.d.ts +153 -0
  30. package/agentcore/gateway/targets/target-base.js +81 -0
  31. package/agentcore/gateway/targets/target-configuration.d.ts +230 -0
  32. package/agentcore/gateway/targets/target-configuration.js +407 -0
  33. package/agentcore/gateway/targets/target.d.ts +345 -0
  34. package/agentcore/gateway/targets/target.js +444 -0
  35. package/agentcore/gateway/validation-helpers.d.ts +65 -0
  36. package/agentcore/gateway/validation-helpers.js +333 -0
  37. package/agentcore/index.d.ts +15 -0
  38. package/agentcore/index.js +32 -1
  39. package/agentcore/memory/memory-strategy.js +1 -1
  40. package/agentcore/memory/memory.js +6 -3
  41. package/agentcore/memory/strategies/managed-strategy.js +1 -1
  42. package/agentcore/memory/strategies/self-managed-strategy.js +1 -1
  43. package/agentcore/network/network-configuration.js +4 -4
  44. package/agentcore/runtime/runtime-artifact.js +1 -1
  45. package/agentcore/runtime/runtime-authorizer-configuration.d.ts +1 -1
  46. package/agentcore/runtime/runtime-authorizer-configuration.js +6 -5
  47. package/agentcore/runtime/runtime-base.js +1 -1
  48. package/agentcore/runtime/runtime-endpoint-base.js +1 -1
  49. package/agentcore/runtime/runtime-endpoint.js +1 -1
  50. package/agentcore/runtime/runtime.js +1 -1
  51. package/agentcore/tools/browser.js +2 -2
  52. package/agentcore/tools/code-interpreter.js +2 -2
  53. package/package.json +9 -9
  54. package/rosetta/default.ts-fixture +15 -6
@@ -0,0 +1,407 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.McpServerTargetConfiguration = exports.SmithyTargetConfiguration = exports.OpenApiTargetConfiguration = exports.LambdaTargetConfiguration = exports.McpTargetConfiguration = void 0;
4
+ const jsiiDeprecationWarnings = require("../../../.warnings.jsii.js");
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const fs = require("fs");
8
+ const api_schema_1 = require("./schema/api-schema");
9
+ const target_base_1 = require("./target-base");
10
+ const validation_helpers_1 = require("../validation-helpers");
11
+ /******************************************************************************
12
+ * MCP Target Configuration Base
13
+ *****************************************************************************/
14
+ /**
15
+ * Abstract base class for MCP target configurations
16
+ * Provides common functionality for all MCP target types
17
+ */
18
+ class McpTargetConfiguration {
19
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.McpTargetConfiguration", version: "2.227.0-alpha.0" };
20
+ /**
21
+ * Renders the configuration as CloudFormation properties
22
+ * @internal
23
+ */
24
+ _render() {
25
+ return {
26
+ mcp: this.renderMcpConfiguration(),
27
+ };
28
+ }
29
+ }
30
+ exports.McpTargetConfiguration = McpTargetConfiguration;
31
+ /******************************************************************************
32
+ * Lambda Target Configuration
33
+ *****************************************************************************/
34
+ /**
35
+ * Configuration for Lambda-based MCP targets
36
+ *
37
+ * This configuration wraps a Lambda function as MCP tools,
38
+ * allowing the gateway to invoke the function to provide tool capabilities.
39
+ */
40
+ class LambdaTargetConfiguration extends McpTargetConfiguration {
41
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.LambdaTargetConfiguration", version: "2.227.0-alpha.0" };
42
+ /**
43
+ * Create a Lambda target configuration
44
+ *
45
+ * @param lambdaFunction The Lambda function to invoke
46
+ * @param toolSchema The schema defining the tools
47
+ * @returns A new LambdaTargetConfiguration instance
48
+ */
49
+ static create(lambdaFunction, toolSchema) {
50
+ try {
51
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ToolSchema(toolSchema);
52
+ }
53
+ catch (error) {
54
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
55
+ Error.captureStackTrace(error, this.create);
56
+ }
57
+ throw error;
58
+ }
59
+ return new LambdaTargetConfiguration(lambdaFunction, toolSchema);
60
+ }
61
+ targetType = target_base_1.McpTargetType.LAMBDA;
62
+ /**
63
+ * The Lambda function that implements the MCP server logic
64
+ */
65
+ lambdaFunction;
66
+ /**
67
+ * The tool schema that defines the available tools
68
+ */
69
+ toolSchema;
70
+ constructor(lambdaFunction, toolSchema) {
71
+ super();
72
+ try {
73
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ToolSchema(toolSchema);
74
+ }
75
+ catch (error) {
76
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
77
+ Error.captureStackTrace(error, LambdaTargetConfiguration);
78
+ }
79
+ throw error;
80
+ }
81
+ this.lambdaFunction = lambdaFunction;
82
+ this.toolSchema = toolSchema;
83
+ }
84
+ /**
85
+ * Binds this configuration to a construct scope
86
+ * Sets up necessary permissions for the gateway to invoke the Lambda function
87
+ *
88
+ * @param scope The construct scope
89
+ * @param gateway The gateway that will use this target
90
+ */
91
+ bind(scope, gateway) {
92
+ try {
93
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_IGateway(gateway);
94
+ }
95
+ catch (error) {
96
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
97
+ Error.captureStackTrace(error, this.bind);
98
+ }
99
+ throw error;
100
+ }
101
+ // Bind the tool schema
102
+ this.toolSchema.bind(scope);
103
+ // Grant permissions to gateway role
104
+ this.toolSchema.grantPermissionsToRole(gateway.role);
105
+ this.lambdaFunction.grantInvoke(gateway.role);
106
+ return { bound: true };
107
+ }
108
+ /**
109
+ * Renders the MCP-specific configuration
110
+ */
111
+ renderMcpConfiguration() {
112
+ return {
113
+ lambda: {
114
+ lambdaArn: this.lambdaFunction.functionArn,
115
+ toolSchema: this.toolSchema._render(),
116
+ },
117
+ };
118
+ }
119
+ }
120
+ exports.LambdaTargetConfiguration = LambdaTargetConfiguration;
121
+ /******************************************************************************
122
+ * OpenAPI Target Configuration
123
+ *****************************************************************************/
124
+ /**
125
+ * Configuration for OpenAPI-based MCP targets
126
+ *
127
+ * This configuration exposes an OpenAPI/REST API as MCP tools,
128
+ * allowing the gateway to transform API operations into tool calls.
129
+ */
130
+ class OpenApiTargetConfiguration extends McpTargetConfiguration {
131
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.OpenApiTargetConfiguration", version: "2.227.0-alpha.0" };
132
+ /**
133
+ * Create an OpenAPI target configuration
134
+ *
135
+ * @param apiSchema The OpenAPI schema
136
+ * @param validateSchema Whether to validate the OpenAPI schema (only applies to inline schemas)
137
+ * @returns A new OpenApiTargetConfiguration instance
138
+ */
139
+ static create(apiSchema, validateSchema) {
140
+ try {
141
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ApiSchema(apiSchema);
142
+ }
143
+ catch (error) {
144
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
145
+ Error.captureStackTrace(error, this.create);
146
+ }
147
+ throw error;
148
+ }
149
+ return new OpenApiTargetConfiguration(apiSchema, validateSchema);
150
+ }
151
+ targetType = target_base_1.McpTargetType.OPENAPI_SCHEMA;
152
+ /**
153
+ * The OpenAPI schema that defines the API
154
+ */
155
+ apiSchema;
156
+ /**
157
+ * Whether to validate the OpenAPI schema
158
+ */
159
+ shouldValidateSchema;
160
+ constructor(apiSchema, validateSchema) {
161
+ super();
162
+ try {
163
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ApiSchema(apiSchema);
164
+ }
165
+ catch (error) {
166
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
167
+ Error.captureStackTrace(error, OpenApiTargetConfiguration);
168
+ }
169
+ throw error;
170
+ }
171
+ this.apiSchema = apiSchema;
172
+ this.shouldValidateSchema = validateSchema ?? true;
173
+ }
174
+ /**
175
+ * Binds this configuration to a construct scope
176
+ * Sets up necessary permissions for the gateway to access the API schema
177
+ *
178
+ * @param scope The construct scope
179
+ * @param gateway The gateway that will use this target
180
+ */
181
+ bind(scope, gateway) {
182
+ try {
183
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_IGateway(gateway);
184
+ }
185
+ catch (error) {
186
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
187
+ Error.captureStackTrace(error, this.bind);
188
+ }
189
+ throw error;
190
+ }
191
+ if (this.shouldValidateSchema) {
192
+ // For inline schemas
193
+ if (this.apiSchema.inlineSchema) {
194
+ const errors = (0, validation_helpers_1.validateOpenApiSchema)({
195
+ schema: this.apiSchema.inlineSchema,
196
+ schemaName: 'OpenAPI schema for target',
197
+ });
198
+ if (errors.length > 0) {
199
+ throw new validation_helpers_1.ValidationError(`OpenAPI schema validation failed:\n${errors.join('\n')}`);
200
+ }
201
+ }
202
+ else if (this.apiSchema instanceof api_schema_1.AssetApiSchema) {
203
+ // For asset schemas (local files)
204
+ try {
205
+ const schemaContent = fs.readFileSync(this.apiSchema._getFilePath(), 'utf-8');
206
+ const errors = (0, validation_helpers_1.validateOpenApiSchema)({
207
+ schema: schemaContent,
208
+ schemaName: `OpenAPI schema from file ${this.apiSchema._getFilePath()}`,
209
+ });
210
+ if (errors.length > 0) {
211
+ throw new validation_helpers_1.ValidationError(`OpenAPI schema validation failed:\n${errors.join('\n')}`);
212
+ }
213
+ }
214
+ catch (e) {
215
+ if (e instanceof validation_helpers_1.ValidationError) {
216
+ throw e;
217
+ }
218
+ throw new validation_helpers_1.ValidationError(`Failed to read OpenAPI schema from ${this.apiSchema._getFilePath()}: ${e instanceof Error ? e.message : String(e)}`);
219
+ }
220
+ }
221
+ // S3 schemas cannot be validated at synthesis time
222
+ }
223
+ // Bind the API schema
224
+ this.apiSchema.bind(scope);
225
+ // Grant permissions to gateway role if schema is in S3
226
+ this.apiSchema.grantPermissionsToRole(gateway.role);
227
+ return { bound: true };
228
+ }
229
+ /**
230
+ * Renders the MCP-specific configuration
231
+ */
232
+ renderMcpConfiguration() {
233
+ return {
234
+ openApiSchema: this.apiSchema._render(),
235
+ };
236
+ }
237
+ }
238
+ exports.OpenApiTargetConfiguration = OpenApiTargetConfiguration;
239
+ /******************************************************************************
240
+ * Smithy Target Configuration
241
+ *****************************************************************************/
242
+ /**
243
+ * Configuration for Smithy-based MCP targets
244
+ *
245
+ * This configuration exposes a Smithy-modeled API as MCP tools,
246
+ * allowing the gateway to transform Smithy operations into tool calls.
247
+ */
248
+ class SmithyTargetConfiguration extends McpTargetConfiguration {
249
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.SmithyTargetConfiguration", version: "2.227.0-alpha.0" };
250
+ /**
251
+ * Create a Smithy target configuration
252
+ *
253
+ * @param smithyModel The Smithy model schema
254
+ * @returns A new SmithyTargetConfiguration instance
255
+ */
256
+ static create(smithyModel) {
257
+ try {
258
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ApiSchema(smithyModel);
259
+ }
260
+ catch (error) {
261
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
262
+ Error.captureStackTrace(error, this.create);
263
+ }
264
+ throw error;
265
+ }
266
+ return new SmithyTargetConfiguration(smithyModel);
267
+ }
268
+ targetType = target_base_1.McpTargetType.SMITHY_MODEL;
269
+ /**
270
+ * The Smithy model that defines the API
271
+ */
272
+ smithyModel;
273
+ constructor(smithyModel) {
274
+ super();
275
+ try {
276
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_ApiSchema(smithyModel);
277
+ }
278
+ catch (error) {
279
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
280
+ Error.captureStackTrace(error, SmithyTargetConfiguration);
281
+ }
282
+ throw error;
283
+ }
284
+ this.smithyModel = smithyModel;
285
+ }
286
+ /**
287
+ * Binds this configuration to a construct scope
288
+ * Sets up necessary permissions for the gateway to access the Smithy model
289
+ *
290
+ * @param scope The construct scope
291
+ * @param gateway The gateway that will use this target
292
+ */
293
+ bind(scope, gateway) {
294
+ try {
295
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_IGateway(gateway);
296
+ }
297
+ catch (error) {
298
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
299
+ Error.captureStackTrace(error, this.bind);
300
+ }
301
+ throw error;
302
+ }
303
+ // Bind the Smithy model
304
+ this.smithyModel.bind(scope);
305
+ // Grant permissions to gateway role if schema is in S3
306
+ this.smithyModel.grantPermissionsToRole(gateway.role);
307
+ return { bound: true };
308
+ }
309
+ /**
310
+ * Renders the MCP-specific configuration
311
+ */
312
+ renderMcpConfiguration() {
313
+ return {
314
+ smithyModel: this.smithyModel._render(),
315
+ };
316
+ }
317
+ }
318
+ exports.SmithyTargetConfiguration = SmithyTargetConfiguration;
319
+ /******************************************************************************
320
+ * MCP Server Target Configuration
321
+ *****************************************************************************/
322
+ /**
323
+ * Configuration for MCP Server-based targets
324
+ *
325
+ * MCP (Model Context Protocol) servers provide tools, data access, and custom
326
+ * functions for AI agents. When you configure an MCP server as a gateway target,
327
+ * the gateway automatically discovers and indexes available tools through
328
+ * synchronization.
329
+ */
330
+ class McpServerTargetConfiguration extends McpTargetConfiguration {
331
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-bedrock-agentcore-alpha.McpServerTargetConfiguration", version: "2.227.0-alpha.0" };
332
+ /**
333
+ * Create an MCP server target configuration
334
+ *
335
+ * @param endpoint The HTTPS endpoint URL of the MCP server
336
+ * @returns A new McpServerTargetConfiguration instance
337
+ */
338
+ static create(endpoint) {
339
+ return new McpServerTargetConfiguration(endpoint);
340
+ }
341
+ targetType = target_base_1.McpTargetType.MCP_SERVER;
342
+ /**
343
+ * The HTTPS endpoint URL of the MCP server
344
+ */
345
+ endpoint;
346
+ constructor(endpoint) {
347
+ super();
348
+ this.endpoint = endpoint;
349
+ this.validateEndpoint(endpoint);
350
+ }
351
+ /**
352
+ * Binds this configuration to a construct scope
353
+ * No additional permissions are needed for MCP server targets
354
+ *
355
+ * @param _scope The construct scope
356
+ * @param _gateway The gateway that will use this target
357
+ */
358
+ bind(_scope, _gateway) {
359
+ try {
360
+ jsiiDeprecationWarnings._aws_cdk_aws_bedrock_agentcore_alpha_IGateway(_gateway);
361
+ }
362
+ catch (error) {
363
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
364
+ Error.captureStackTrace(error, this.bind);
365
+ }
366
+ throw error;
367
+ }
368
+ // MCP server targets don't require additional permissions setup
369
+ // Authentication is handled through credential provider configurations
370
+ return { bound: true };
371
+ }
372
+ /**
373
+ * Renders the MCP-specific configuration
374
+ */
375
+ renderMcpConfiguration() {
376
+ return {
377
+ mcpServer: {
378
+ endpoint: this.endpoint,
379
+ },
380
+ };
381
+ }
382
+ /**
383
+ * Validates the MCP server endpoint
384
+ * - Must use HTTPS protocol
385
+ * - Should be properly URL encoded
386
+ *
387
+ * @param endpoint The endpoint URL to validate
388
+ * @throws ValidationError if the endpoint is invalid
389
+ * @internal
390
+ */
391
+ validateEndpoint(endpoint) {
392
+ if (aws_cdk_lib_1.Token.isUnresolved(endpoint)) {
393
+ return;
394
+ }
395
+ const errors = (0, validation_helpers_1.validateFieldPattern)(endpoint, 'MCP server endpoint', /^https:\/\/.+/, 'MCP server endpoint must use HTTPS protocol (e.g., https://my-server.example.com). Ensure the URL is properly encoded.');
396
+ if (errors.length > 0) {
397
+ throw new validation_helpers_1.ValidationError(errors.join('\n'));
398
+ }
399
+ // Additional helpful validation for common URL encoding issues
400
+ if (endpoint.includes(' ') || endpoint.includes('<') || endpoint.includes('>')) {
401
+ throw new validation_helpers_1.ValidationError('MCP server endpoint contains characters that should be URL-encoded. ' +
402
+ 'Please ensure the URL is properly encoded before passing to the construct.');
403
+ }
404
+ }
405
+ }
406
+ exports.McpServerTargetConfiguration = McpServerTargetConfiguration;
407
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFyZ2V0LWNvbmZpZ3VyYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0YXJnZXQtY29uZmlndXJhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUFvQztBQUdwQyx5QkFBeUI7QUFFekIsb0RBQWdFO0FBRWhFLCtDQUE4QztBQUM5Qyw4REFBcUc7QUFzQ3JHOzsrRUFFK0U7QUFFL0U7OztHQUdHO0FBQ0gsTUFBc0Isc0JBQXNCOztJQWlCMUM7OztPQUdHO0lBQ0ksT0FBTztRQUNaLE9BQU87WUFDTCxHQUFHLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixFQUFFO1NBQ25DLENBQUM7S0FDSDs7QUF6Qkgsd0RBMEJDO0FBRUQ7OytFQUUrRTtBQUUvRTs7Ozs7R0FLRztBQUNILE1BQWEseUJBQTBCLFNBQVEsc0JBQXNCOztJQUNuRTs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsTUFBTSxDQUNsQixjQUF5QixFQUN6QixVQUFzQjs7Ozs7Ozs7OztRQUV0QixPQUFPLElBQUkseUJBQXlCLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0tBQ2xFO0lBRWUsVUFBVSxHQUFHLDJCQUFhLENBQUMsTUFBTSxDQUFDO0lBRWxEOztPQUVHO0lBQ2EsY0FBYyxDQUFZO0lBRTFDOztPQUVHO0lBQ2EsVUFBVSxDQUFhO0lBRXZDLFlBQVksY0FBeUIsRUFBRSxVQUFzQjtRQUMzRCxLQUFLLEVBQUUsQ0FBQzs7Ozs7OytDQTVCQyx5QkFBeUI7Ozs7UUE2QmxDLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0tBQzlCO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksSUFBSSxDQUFDLEtBQWdCLEVBQUUsT0FBaUI7Ozs7Ozs7Ozs7UUFDN0MsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzVCLG9DQUFvQztR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O1lBQ2pDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBQSx5Q0FBb0IsRUFDakMsUUFBUSxFQUNSLHFCQUFxQixFQUNyQixlQUFlLEVBQ2Ysd0hBQXdILENBQ3pILENBQUM7UUFFRixJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdEIsTUFBTSxJQUFJLG9DQUFlLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQy9DLENBQUM7UUFFRCwrREFBK0Q7UUFDL0QsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQy9FLE1BQU0sSUFBSSxvQ0FBZSxDQUN2QixzRUFBc0U7Z0JBQ3RFLDRFQUE0RSxDQUM3RSxDQUFDO1FBQ0osQ0FBQztLQUNGOztBQWhGSCxvRUFpRkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUb2tlbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IElGdW5jdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgeyBJR2F0ZXdheSB9IGZyb20gJy4uL2dhdGV3YXktYmFzZSc7XG5pbXBvcnQgeyBBcGlTY2hlbWEsIEFzc2V0QXBpU2NoZW1hIH0gZnJvbSAnLi9zY2hlbWEvYXBpLXNjaGVtYSc7XG5pbXBvcnQgeyBUb29sU2NoZW1hIH0gZnJvbSAnLi9zY2hlbWEvdG9vbC1zY2hlbWEnO1xuaW1wb3J0IHsgTWNwVGFyZ2V0VHlwZSB9IGZyb20gJy4vdGFyZ2V0LWJhc2UnO1xuaW1wb3J0IHsgdmFsaWRhdGVPcGVuQXBpU2NoZW1hLCB2YWxpZGF0ZUZpZWxkUGF0dGVybiwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vdmFsaWRhdGlvbi1oZWxwZXJzJztcblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICAgICAgIEludGVyZmFjZVxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gcmV0dXJuZWQgYnkgYmluZGluZyBhIHRhcmdldCBjb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFyZ2V0Q29uZmlndXJhdGlvbkNvbmZpZyB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgdGhhdCB0aGUgY29uZmlndXJhdGlvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgYm91bmRcbiAgICovXG4gIHJlYWRvbmx5IGJvdW5kOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEJhc2UgaW50ZXJmYWNlIGZvciB0YXJnZXQgY29uZmlndXJhdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJVGFyZ2V0Q29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBUaGUgdGFyZ2V0IHR5cGVcbiAgICovXG4gIHJlYWRvbmx5IHRhcmdldFR5cGU6IE1jcFRhcmdldFR5cGU7XG5cbiAgLyoqXG4gICAqIEJpbmRzIHRoZSBjb25maWd1cmF0aW9uIHRvIGEgY29uc3RydWN0IHNjb3BlXG4gICAqIFNldHMgdXAgcGVybWlzc2lvbnMgYW5kIGRlcGVuZGVuY2llc1xuICAgKi9cbiAgYmluZChzY29wZTogQ29uc3RydWN0LCBnYXRld2F5OiBJR2F0ZXdheSk6IFRhcmdldENvbmZpZ3VyYXRpb25Db25maWc7XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIGNvbmZpZ3VyYXRpb24gYXMgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllc1xuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF9yZW5kZXIoKTogYW55O1xufVxuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiAgICAgICAgICAgICAgICAgICAgIE1DUCBUYXJnZXQgQ29uZmlndXJhdGlvbiBCYXNlXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG5cbi8qKlxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgTUNQIHRhcmdldCBjb25maWd1cmF0aW9uc1xuICogUHJvdmlkZXMgY29tbW9uIGZ1bmN0aW9uYWxpdHkgZm9yIGFsbCBNQ1AgdGFyZ2V0IHR5cGVzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBNY3BUYXJnZXRDb25maWd1cmF0aW9uIGltcGxlbWVudHMgSVRhcmdldENvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogVGhlIHRhcmdldCB0eXBlXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgdGFyZ2V0VHlwZTogTWNwVGFyZ2V0VHlwZTtcblxuICAvKipcbiAgICogQmluZHMgdGhlIGNvbmZpZ3VyYXRpb24gdG8gYSBjb25zdHJ1Y3Qgc2NvcGVcbiAgICogU2V0cyB1cCBwZXJtaXNzaW9ucyBhbmQgZGVwZW5kZW5jaWVzXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgYmluZChzY29wZTogQ29uc3RydWN0LCBnYXRld2F5OiBJR2F0ZXdheSk6IFRhcmdldENvbmZpZ3VyYXRpb25Db25maWc7XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIE1DUC1zcGVjaWZpYyBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVuZGVyTWNwQ29uZmlndXJhdGlvbigpOiBhbnk7XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIGNvbmZpZ3VyYXRpb24gYXMgQ2xvdWRGb3JtYXRpb24gcHJvcGVydGllc1xuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfcmVuZGVyKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1jcDogdGhpcy5yZW5kZXJNY3BDb25maWd1cmF0aW9uKCksXG4gICAgfTtcbiAgfVxufVxuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiAgICAgICAgICAgICAgICAgICAgIExhbWJkYSBUYXJnZXQgQ29uZmlndXJhdGlvblxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIExhbWJkYS1iYXNlZCBNQ1AgdGFyZ2V0c1xuICpcbiAqIFRoaXMgY29uZmlndXJhdGlvbiB3cmFwcyBhIExhbWJkYSBmdW5jdGlvbiBhcyBNQ1AgdG9vbHMsXG4gKiBhbGxvd2luZyB0aGUgZ2F0ZXdheSB0byBpbnZva2UgdGhlIGZ1bmN0aW9uIHRvIHByb3ZpZGUgdG9vbCBjYXBhYmlsaXRpZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBMYW1iZGFUYXJnZXRDb25maWd1cmF0aW9uIGV4dGVuZHMgTWNwVGFyZ2V0Q29uZmlndXJhdGlvbiB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBMYW1iZGEgdGFyZ2V0IGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogQHBhcmFtIGxhbWJkYUZ1bmN0aW9uIFRoZSBMYW1iZGEgZnVuY3Rpb24gdG8gaW52b2tlXG4gICAqIEBwYXJhbSB0b29sU2NoZW1hIFRoZSBzY2hlbWEgZGVmaW5pbmcgdGhlIHRvb2xzXG4gICAqIEByZXR1cm5zIEEgbmV3IExhbWJkYVRhcmdldENvbmZpZ3VyYXRpb24gaW5zdGFuY2VcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY3JlYXRlKFxuICAgIGxhbWJkYUZ1bmN0aW9uOiBJRnVuY3Rpb24sXG4gICAgdG9vbFNjaGVtYTogVG9vbFNjaGVtYSxcbiAgKTogTGFtYmRhVGFyZ2V0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBMYW1iZGFUYXJnZXRDb25maWd1cmF0aW9uKGxhbWJkYUZ1bmN0aW9uLCB0b29sU2NoZW1hKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSB0YXJnZXRUeXBlID0gTWNwVGFyZ2V0VHlwZS5MQU1CREE7XG5cbiAgLyoqXG4gICAqIFRoZSBMYW1iZGEgZnVuY3Rpb24gdGhhdCBpbXBsZW1lbnRzIHRoZSBNQ1Agc2VydmVyIGxvZ2ljXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbGFtYmRhRnVuY3Rpb246IElGdW5jdGlvbjtcblxuICAvKipcbiAgICogVGhlIHRvb2wgc2NoZW1hIHRoYXQgZGVmaW5lcyB0aGUgYXZhaWxhYmxlIHRvb2xzXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdG9vbFNjaGVtYTogVG9vbFNjaGVtYTtcblxuICBjb25zdHJ1Y3RvcihsYW1iZGFGdW5jdGlvbjogSUZ1bmN0aW9uLCB0b29sU2NoZW1hOiBUb29sU2NoZW1hKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uID0gbGFtYmRhRnVuY3Rpb247XG4gICAgdGhpcy50b29sU2NoZW1hID0gdG9vbFNjaGVtYTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kcyB0aGlzIGNvbmZpZ3VyYXRpb24gdG8gYSBjb25zdHJ1Y3Qgc2NvcGVcbiAgICogU2V0cyB1cCBuZWNlc3NhcnkgcGVybWlzc2lvbnMgZm9yIHRoZSBnYXRld2F5IHRvIGludm9rZSB0aGUgTGFtYmRhIGZ1bmN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgY29uc3RydWN0IHNjb3BlXG4gICAqIEBwYXJhbSBnYXRld2F5IFRoZSBnYXRld2F5IHRoYXQgd2lsbCB1c2UgdGhpcyB0YXJnZXRcbiAgICovXG4gIHB1YmxpYyBiaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIGdhdGV3YXk6IElHYXRld2F5KTogVGFyZ2V0Q29uZmlndXJhdGlvbkNvbmZpZyB7XG4gICAgLy8gQmluZCB0aGUgdG9vbCBzY2hlbWFcbiAgICB0aGlzLnRvb2xTY2hlbWEuYmluZChzY29wZSk7XG4gICAgLy8gR3JhbnQgcGVybWlzc2lvbnMgdG8gZ2F0ZXdheSByb2xlXG4gICAgdGhpcy50b29sU2NoZW1hLmdyYW50UGVybWlzc2lvbnNUb1JvbGUoZ2F0ZXdheS5yb2xlKTtcbiAgICB0aGlzLmxhbWJkYUZ1bmN0aW9uLmdyYW50SW52b2tlKGdhdGV3YXkucm9sZSk7XG5cbiAgICByZXR1cm4geyBib3VuZDogdHJ1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIE1DUC1zcGVjaWZpYyBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVuZGVyTWNwQ29uZmlndXJhdGlvbigpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBsYW1iZGE6IHtcbiAgICAgICAgbGFtYmRhQXJuOiB0aGlzLmxhbWJkYUZ1bmN0aW9uLmZ1bmN0aW9uQXJuLFxuICAgICAgICB0b29sU2NoZW1hOiB0aGlzLnRvb2xTY2hlbWEuX3JlbmRlcigpLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcbiAqICAgICAgICAgICAgICAgICAgICAgT3BlbkFQSSBUYXJnZXQgQ29uZmlndXJhdGlvblxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIE9wZW5BUEktYmFzZWQgTUNQIHRhcmdldHNcbiAqXG4gKiBUaGlzIGNvbmZpZ3VyYXRpb24gZXhwb3NlcyBhbiBPcGVuQVBJL1JFU1QgQVBJIGFzIE1DUCB0b29scyxcbiAqIGFsbG93aW5nIHRoZSBnYXRld2F5IHRvIHRyYW5zZm9ybSBBUEkgb3BlcmF0aW9ucyBpbnRvIHRvb2wgY2FsbHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuQXBpVGFyZ2V0Q29uZmlndXJhdGlvbiBleHRlbmRzIE1jcFRhcmdldENvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogQ3JlYXRlIGFuIE9wZW5BUEkgdGFyZ2V0IGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogQHBhcmFtIGFwaVNjaGVtYSBUaGUgT3BlbkFQSSBzY2hlbWFcbiAgICogQHBhcmFtIHZhbGlkYXRlU2NoZW1hIFdoZXRoZXIgdG8gdmFsaWRhdGUgdGhlIE9wZW5BUEkgc2NoZW1hIChvbmx5IGFwcGxpZXMgdG8gaW5saW5lIHNjaGVtYXMpXG4gICAqIEByZXR1cm5zIEEgbmV3IE9wZW5BcGlUYXJnZXRDb25maWd1cmF0aW9uIGluc3RhbmNlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNyZWF0ZShhcGlTY2hlbWE6IEFwaVNjaGVtYSwgdmFsaWRhdGVTY2hlbWE/OiBib29sZWFuKTogT3BlbkFwaVRhcmdldENvbmZpZ3VyYXRpb24ge1xuICAgIHJldHVybiBuZXcgT3BlbkFwaVRhcmdldENvbmZpZ3VyYXRpb24oYXBpU2NoZW1hLCB2YWxpZGF0ZVNjaGVtYSk7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0VHlwZSA9IE1jcFRhcmdldFR5cGUuT1BFTkFQSV9TQ0hFTUE7XG5cbiAgLyoqXG4gICAqIFRoZSBPcGVuQVBJIHNjaGVtYSB0aGF0IGRlZmluZXMgdGhlIEFQSVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGFwaVNjaGVtYTogQXBpU2NoZW1hO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHZhbGlkYXRlIHRoZSBPcGVuQVBJIHNjaGVtYVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBzaG91bGRWYWxpZGF0ZVNjaGVtYTogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihhcGlTY2hlbWE6IEFwaVNjaGVtYSwgdmFsaWRhdGVTY2hlbWE/OiBib29sZWFuKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmFwaVNjaGVtYSA9IGFwaVNjaGVtYTtcbiAgICB0aGlzLnNob3VsZFZhbGlkYXRlU2NoZW1hID0gdmFsaWRhdGVTY2hlbWEgPz8gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kcyB0aGlzIGNvbmZpZ3VyYXRpb24gdG8gYSBjb25zdHJ1Y3Qgc2NvcGVcbiAgICogU2V0cyB1cCBuZWNlc3NhcnkgcGVybWlzc2lvbnMgZm9yIHRoZSBnYXRld2F5IHRvIGFjY2VzcyB0aGUgQVBJIHNjaGVtYVxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgVGhlIGNvbnN0cnVjdCBzY29wZVxuICAgKiBAcGFyYW0gZ2F0ZXdheSBUaGUgZ2F0ZXdheSB0aGF0IHdpbGwgdXNlIHRoaXMgdGFyZ2V0XG4gICAqL1xuICBwdWJsaWMgYmluZChzY29wZTogQ29uc3RydWN0LCBnYXRld2F5OiBJR2F0ZXdheSk6IFRhcmdldENvbmZpZ3VyYXRpb25Db25maWcge1xuICAgIGlmICh0aGlzLnNob3VsZFZhbGlkYXRlU2NoZW1hKSB7XG4gICAgICAvLyBGb3IgaW5saW5lIHNjaGVtYXNcbiAgICAgIGlmICh0aGlzLmFwaVNjaGVtYS5pbmxpbmVTY2hlbWEpIHtcbiAgICAgICAgY29uc3QgZXJyb3JzID0gdmFsaWRhdGVPcGVuQXBpU2NoZW1hKHtcbiAgICAgICAgICBzY2hlbWE6IHRoaXMuYXBpU2NoZW1hLmlubGluZVNjaGVtYSxcbiAgICAgICAgICBzY2hlbWFOYW1lOiAnT3BlbkFQSSBzY2hlbWEgZm9yIHRhcmdldCcsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBPcGVuQVBJIHNjaGVtYSB2YWxpZGF0aW9uIGZhaWxlZDpcXG4ke2Vycm9ycy5qb2luKCdcXG4nKX1gKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLmFwaVNjaGVtYSBpbnN0YW5jZW9mIEFzc2V0QXBpU2NoZW1hKSB7XG4gICAgICAgIC8vIEZvciBhc3NldCBzY2hlbWFzIChsb2NhbCBmaWxlcylcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBzY2hlbWFDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHRoaXMuYXBpU2NoZW1hLl9nZXRGaWxlUGF0aCgpLCAndXRmLTgnKTtcbiAgICAgICAgICBjb25zdCBlcnJvcnMgPSB2YWxpZGF0ZU9wZW5BcGlTY2hlbWEoe1xuICAgICAgICAgICAgc2NoZW1hOiBzY2hlbWFDb250ZW50LFxuICAgICAgICAgICAgc2NoZW1hTmFtZTogYE9wZW5BUEkgc2NoZW1hIGZyb20gZmlsZSAke3RoaXMuYXBpU2NoZW1hLl9nZXRGaWxlUGF0aCgpfWAsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGBPcGVuQVBJIHNjaGVtYSB2YWxpZGF0aW9uIGZhaWxlZDpcXG4ke2Vycm9ycy5qb2luKCdcXG4nKX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFZhbGlkYXRpb25FcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICAgIGBGYWlsZWQgdG8gcmVhZCBPcGVuQVBJIHNjaGVtYSBmcm9tICR7dGhpcy5hcGlTY2hlbWEuX2dldEZpbGVQYXRoKCl9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKX1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIFMzIHNjaGVtYXMgY2Fubm90IGJlIHZhbGlkYXRlZCBhdCBzeW50aGVzaXMgdGltZVxuICAgIH1cblxuICAgIC8vIEJpbmQgdGhlIEFQSSBzY2hlbWFcbiAgICB0aGlzLmFwaVNjaGVtYS5iaW5kKHNjb3BlKTtcbiAgICAvLyBHcmFudCBwZXJtaXNzaW9ucyB0byBnYXRld2F5IHJvbGUgaWYgc2NoZW1hIGlzIGluIFMzXG4gICAgdGhpcy5hcGlTY2hlbWEuZ3JhbnRQZXJtaXNzaW9uc1RvUm9sZShnYXRld2F5LnJvbGUpO1xuXG4gICAgcmV0dXJuIHsgYm91bmQ6IHRydWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXJzIHRoZSBNQ1Atc3BlY2lmaWMgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcHJvdGVjdGVkIHJlbmRlck1jcENvbmZpZ3VyYXRpb24oKTogYW55IHtcbiAgICByZXR1cm4ge1xuICAgICAgb3BlbkFwaVNjaGVtYTogdGhpcy5hcGlTY2hlbWEuX3JlbmRlcigpLFxuICAgIH07XG4gIH1cbn1cblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICogICAgICAgICAgICAgICAgICAgICBTbWl0aHkgVGFyZ2V0IENvbmZpZ3VyYXRpb25cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBTbWl0aHktYmFzZWQgTUNQIHRhcmdldHNcbiAqXG4gKiBUaGlzIGNvbmZpZ3VyYXRpb24gZXhwb3NlcyBhIFNtaXRoeS1tb2RlbGVkIEFQSSBhcyBNQ1AgdG9vbHMsXG4gKiBhbGxvd2luZyB0aGUgZ2F0ZXdheSB0byB0cmFuc2Zvcm0gU21pdGh5IG9wZXJhdGlvbnMgaW50byB0b29sIGNhbGxzLlxuICovXG5leHBvcnQgY2xhc3MgU21pdGh5VGFyZ2V0Q29uZmlndXJhdGlvbiBleHRlbmRzIE1jcFRhcmdldENvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogQ3JlYXRlIGEgU21pdGh5IHRhcmdldCBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBzbWl0aHlNb2RlbCBUaGUgU21pdGh5IG1vZGVsIHNjaGVtYVxuICAgKiBAcmV0dXJucyBBIG5ldyBTbWl0aHlUYXJnZXRDb25maWd1cmF0aW9uIGluc3RhbmNlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNyZWF0ZShzbWl0aHlNb2RlbDogQXBpU2NoZW1hKTogU21pdGh5VGFyZ2V0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBTbWl0aHlUYXJnZXRDb25maWd1cmF0aW9uKHNtaXRoeU1vZGVsKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSB0YXJnZXRUeXBlID0gTWNwVGFyZ2V0VHlwZS5TTUlUSFlfTU9ERUw7XG5cbiAgLyoqXG4gICAqIFRoZSBTbWl0aHkgbW9kZWwgdGhhdCBkZWZpbmVzIHRoZSBBUElcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBzbWl0aHlNb2RlbDogQXBpU2NoZW1hO1xuXG4gIGNvbnN0cnVjdG9yKHNtaXRoeU1vZGVsOiBBcGlTY2hlbWEpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc21pdGh5TW9kZWwgPSBzbWl0aHlNb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCaW5kcyB0aGlzIGNvbmZpZ3VyYXRpb24gdG8gYSBjb25zdHJ1Y3Qgc2NvcGVcbiAgICogU2V0cyB1cCBuZWNlc3NhcnkgcGVybWlzc2lvbnMgZm9yIHRoZSBnYXRld2F5IHRvIGFjY2VzcyB0aGUgU21pdGh5IG1vZGVsXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgY29uc3RydWN0IHNjb3BlXG4gICAqIEBwYXJhbSBnYXRld2F5IFRoZSBnYXRld2F5IHRoYXQgd2lsbCB1c2UgdGhpcyB0YXJnZXRcbiAgICovXG4gIHB1YmxpYyBiaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIGdhdGV3YXk6IElHYXRld2F5KTogVGFyZ2V0Q29uZmlndXJhdGlvbkNvbmZpZyB7XG4gICAgLy8gQmluZCB0aGUgU21pdGh5IG1vZGVsXG4gICAgdGhpcy5zbWl0aHlNb2RlbC5iaW5kKHNjb3BlKTtcbiAgICAvLyBHcmFudCBwZXJtaXNzaW9ucyB0byBnYXRld2F5IHJvbGUgaWYgc2NoZW1hIGlzIGluIFMzXG4gICAgdGhpcy5zbWl0aHlNb2RlbC5ncmFudFBlcm1pc3Npb25zVG9Sb2xlKGdhdGV3YXkucm9sZSk7XG5cbiAgICByZXR1cm4geyBib3VuZDogdHJ1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIE1DUC1zcGVjaWZpYyBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVuZGVyTWNwQ29uZmlndXJhdGlvbigpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBzbWl0aHlNb2RlbDogdGhpcy5zbWl0aHlNb2RlbC5fcmVuZGVyKCksXG4gICAgfTtcbiAgfVxufVxuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiAgICAgICAgICAgICAgICAgICAgIE1DUCBTZXJ2ZXIgVGFyZ2V0IENvbmZpZ3VyYXRpb25cbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBNQ1AgU2VydmVyLWJhc2VkIHRhcmdldHNcbiAqXG4gKiBNQ1AgKE1vZGVsIENvbnRleHQgUHJvdG9jb2wpIHNlcnZlcnMgcHJvdmlkZSB0b29scywgZGF0YSBhY2Nlc3MsIGFuZCBjdXN0b21cbiAqIGZ1bmN0aW9ucyBmb3IgQUkgYWdlbnRzLiBXaGVuIHlvdSBjb25maWd1cmUgYW4gTUNQIHNlcnZlciBhcyBhIGdhdGV3YXkgdGFyZ2V0LFxuICogdGhlIGdhdGV3YXkgYXV0b21hdGljYWxseSBkaXNjb3ZlcnMgYW5kIGluZGV4ZXMgYXZhaWxhYmxlIHRvb2xzIHRocm91Z2hcbiAqIHN5bmNocm9uaXphdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIE1jcFNlcnZlclRhcmdldENvbmZpZ3VyYXRpb24gZXh0ZW5kcyBNY3BUYXJnZXRDb25maWd1cmF0aW9uIHtcbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBNQ1Agc2VydmVyIHRhcmdldCBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEBwYXJhbSBlbmRwb2ludCBUaGUgSFRUUFMgZW5kcG9pbnQgVVJMIG9mIHRoZSBNQ1Agc2VydmVyXG4gICAqIEByZXR1cm5zIEEgbmV3IE1jcFNlcnZlclRhcmdldENvbmZpZ3VyYXRpb24gaW5zdGFuY2VcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgY3JlYXRlKGVuZHBvaW50OiBzdHJpbmcpOiBNY3BTZXJ2ZXJUYXJnZXRDb25maWd1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IE1jcFNlcnZlclRhcmdldENvbmZpZ3VyYXRpb24oZW5kcG9pbnQpO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHRhcmdldFR5cGUgPSBNY3BUYXJnZXRUeXBlLk1DUF9TRVJWRVI7XG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQUyBlbmRwb2ludCBVUkwgb2YgdGhlIE1DUCBzZXJ2ZXJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBlbmRwb2ludDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKGVuZHBvaW50OiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuZW5kcG9pbnQgPSBlbmRwb2ludDtcbiAgICB0aGlzLnZhbGlkYXRlRW5kcG9pbnQoZW5kcG9pbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJpbmRzIHRoaXMgY29uZmlndXJhdGlvbiB0byBhIGNvbnN0cnVjdCBzY29wZVxuICAgKiBObyBhZGRpdGlvbmFsIHBlcm1pc3Npb25zIGFyZSBuZWVkZWQgZm9yIE1DUCBzZXJ2ZXIgdGFyZ2V0c1xuICAgKlxuICAgKiBAcGFyYW0gX3Njb3BlIFRoZSBjb25zdHJ1Y3Qgc2NvcGVcbiAgICogQHBhcmFtIF9nYXRld2F5IFRoZSBnYXRld2F5IHRoYXQgd2lsbCB1c2UgdGhpcyB0YXJnZXRcbiAgICovXG4gIHB1YmxpYyBiaW5kKF9zY29wZTogQ29uc3RydWN0LCBfZ2F0ZXdheTogSUdhdGV3YXkpOiBUYXJnZXRDb25maWd1cmF0aW9uQ29uZmlnIHtcbiAgICAvLyBNQ1Agc2VydmVyIHRhcmdldHMgZG9uJ3QgcmVxdWlyZSBhZGRpdGlvbmFsIHBlcm1pc3Npb25zIHNldHVwXG4gICAgLy8gQXV0aGVudGljYXRpb24gaXMgaGFuZGxlZCB0aHJvdWdoIGNyZWRlbnRpYWwgcHJvdmlkZXIgY29uZmlndXJhdGlvbnNcbiAgICByZXR1cm4geyBib3VuZDogdHJ1ZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlcnMgdGhlIE1DUC1zcGVjaWZpYyBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVuZGVyTWNwQ29uZmlndXJhdGlvbigpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBtY3BTZXJ2ZXI6IHtcbiAgICAgICAgZW5kcG9pbnQ6IHRoaXMuZW5kcG9pbnQsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIHRoZSBNQ1Agc2VydmVyIGVuZHBvaW50XG4gICAqIC0gTXVzdCB1c2UgSFRUUFMgcHJvdG9jb2xcbiAgICogLSBTaG91bGQgYmUgcHJvcGVybHkgVVJMIGVuY29kZWRcbiAgICpcbiAgICogQHBhcmFtIGVuZHBvaW50IFRoZSBlbmRwb2ludCBVUkwgdG8gdmFsaWRhdGVcbiAgICogQHRocm93cyBWYWxpZGF0aW9uRXJyb3IgaWYgdGhlIGVuZHBvaW50IGlzIGludmFsaWRcbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlRW5kcG9pbnQoZW5kcG9pbnQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQoZW5kcG9pbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzID0gdmFsaWRhdGVGaWVsZFBhdHRlcm4oXG4gICAgICBlbmRwb2ludCxcbiAgICAgICdNQ1Agc2VydmVyIGVuZHBvaW50JyxcbiAgICAgIC9eaHR0cHM6XFwvXFwvLisvLFxuICAgICAgJ01DUCBzZXJ2ZXIgZW5kcG9pbnQgbXVzdCB1c2UgSFRUUFMgcHJvdG9jb2wgKGUuZy4sIGh0dHBzOi8vbXktc2VydmVyLmV4YW1wbGUuY29tKS4gRW5zdXJlIHRoZSBVUkwgaXMgcHJvcGVybHkgZW5jb2RlZC4nLFxuICAgICk7XG5cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzLmpvaW4oJ1xcbicpKTtcbiAgICB9XG5cbiAgICAvLyBBZGRpdGlvbmFsIGhlbHBmdWwgdmFsaWRhdGlvbiBmb3IgY29tbW9uIFVSTCBlbmNvZGluZyBpc3N1ZXNcbiAgICBpZiAoZW5kcG9pbnQuaW5jbHVkZXMoJyAnKSB8fCBlbmRwb2ludC5pbmNsdWRlcygnPCcpIHx8IGVuZHBvaW50LmluY2x1ZGVzKCc+JykpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICdNQ1Agc2VydmVyIGVuZHBvaW50IGNvbnRhaW5zIGNoYXJhY3RlcnMgdGhhdCBzaG91bGQgYmUgVVJMLWVuY29kZWQuICcgK1xuICAgICAgICAnUGxlYXNlIGVuc3VyZSB0aGUgVVJMIGlzIHByb3Blcmx5IGVuY29kZWQgYmVmb3JlIHBhc3NpbmcgdG8gdGhlIGNvbnN0cnVjdC4nLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==