@pipeline-builder/pipeline-manager 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +74 -0
  3. package/cdk.json +91 -0
  4. package/config.yml +94 -0
  5. package/dist/boilerplate.d.ts +3 -0
  6. package/dist/boilerplate.d.ts.map +1 -0
  7. package/dist/boilerplate.js +58 -0
  8. package/dist/cdk.json +91 -0
  9. package/dist/cli.d.ts +62 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +372 -0
  12. package/dist/commands/bootstrap.d.ts +11 -0
  13. package/dist/commands/bootstrap.d.ts.map +1 -0
  14. package/dist/commands/bootstrap.js +159 -0
  15. package/dist/commands/create-pipeline.d.ts +12 -0
  16. package/dist/commands/create-pipeline.d.ts.map +1 -0
  17. package/dist/commands/create-pipeline.js +291 -0
  18. package/dist/commands/deploy.d.ts +15 -0
  19. package/dist/commands/deploy.d.ts.map +1 -0
  20. package/dist/commands/deploy.js +167 -0
  21. package/dist/commands/get-pipeline.d.ts +13 -0
  22. package/dist/commands/get-pipeline.d.ts.map +1 -0
  23. package/dist/commands/get-pipeline.js +97 -0
  24. package/dist/commands/get-plugin.d.ts +13 -0
  25. package/dist/commands/get-plugin.d.ts.map +1 -0
  26. package/dist/commands/get-plugin.js +98 -0
  27. package/dist/commands/list-pipelines.d.ts +20 -0
  28. package/dist/commands/list-pipelines.d.ts.map +1 -0
  29. package/dist/commands/list-pipelines.js +172 -0
  30. package/dist/commands/list-plugins.d.ts +20 -0
  31. package/dist/commands/list-plugins.d.ts.map +1 -0
  32. package/dist/commands/list-plugins.js +167 -0
  33. package/dist/commands/login.d.ts +21 -0
  34. package/dist/commands/login.d.ts.map +1 -0
  35. package/dist/commands/login.js +179 -0
  36. package/dist/commands/setup-events.d.ts +15 -0
  37. package/dist/commands/setup-events.d.ts.map +1 -0
  38. package/dist/commands/setup-events.js +177 -0
  39. package/dist/commands/status.d.ts +11 -0
  40. package/dist/commands/status.d.ts.map +1 -0
  41. package/dist/commands/status.js +89 -0
  42. package/dist/commands/store-token.d.ts +20 -0
  43. package/dist/commands/store-token.d.ts.map +1 -0
  44. package/dist/commands/store-token.js +233 -0
  45. package/dist/commands/synth.d.ts +21 -0
  46. package/dist/commands/synth.d.ts.map +1 -0
  47. package/dist/commands/synth.js +143 -0
  48. package/dist/commands/upload-plugin.d.ts +21 -0
  49. package/dist/commands/upload-plugin.d.ts.map +1 -0
  50. package/dist/commands/upload-plugin.js +311 -0
  51. package/dist/commands/version.d.ts +12 -0
  52. package/dist/commands/version.d.ts.map +1 -0
  53. package/dist/commands/version.js +223 -0
  54. package/dist/config/cli.constants.d.ts +101 -0
  55. package/dist/config/cli.constants.d.ts.map +1 -0
  56. package/dist/config/cli.constants.js +165 -0
  57. package/dist/config.yml +94 -0
  58. package/dist/templates/events-stack.json +141 -0
  59. package/dist/types/config.d.ts +44 -0
  60. package/dist/types/config.d.ts.map +1 -0
  61. package/dist/types/config.js +5 -0
  62. package/dist/types/error.d.ts +61 -0
  63. package/dist/types/error.d.ts.map +1 -0
  64. package/dist/types/error.js +39 -0
  65. package/dist/types/index.d.ts +8 -0
  66. package/dist/types/index.d.ts.map +1 -0
  67. package/dist/types/index.js +26 -0
  68. package/dist/types/pipeline.d.ts +144 -0
  69. package/dist/types/pipeline.d.ts.map +1 -0
  70. package/dist/types/pipeline.js +5 -0
  71. package/dist/types/plugin.d.ts +160 -0
  72. package/dist/types/plugin.d.ts.map +1 -0
  73. package/dist/types/plugin.js +5 -0
  74. package/dist/utils/api-client.d.ts +26 -0
  75. package/dist/utils/api-client.d.ts.map +1 -0
  76. package/dist/utils/api-client.js +160 -0
  77. package/dist/utils/audit-log.d.ts +8 -0
  78. package/dist/utils/audit-log.d.ts.map +1 -0
  79. package/dist/utils/audit-log.js +53 -0
  80. package/dist/utils/auth-guard.d.ts +16 -0
  81. package/dist/utils/auth-guard.d.ts.map +1 -0
  82. package/dist/utils/auth-guard.js +25 -0
  83. package/dist/utils/aws-secrets.d.ts +21 -0
  84. package/dist/utils/aws-secrets.d.ts.map +1 -0
  85. package/dist/utils/aws-secrets.js +74 -0
  86. package/dist/utils/banner.d.ts +19 -0
  87. package/dist/utils/banner.d.ts.map +1 -0
  88. package/dist/utils/banner.js +59 -0
  89. package/dist/utils/cdk-utils.d.ts +51 -0
  90. package/dist/utils/cdk-utils.d.ts.map +1 -0
  91. package/dist/utils/cdk-utils.js +101 -0
  92. package/dist/utils/command-utils.d.ts +56 -0
  93. package/dist/utils/command-utils.d.ts.map +1 -0
  94. package/dist/utils/command-utils.js +138 -0
  95. package/dist/utils/config-loader.d.ts +27 -0
  96. package/dist/utils/config-loader.d.ts.map +1 -0
  97. package/dist/utils/config-loader.js +166 -0
  98. package/dist/utils/error-handler.d.ts +29 -0
  99. package/dist/utils/error-handler.d.ts.map +1 -0
  100. package/dist/utils/error-handler.js +255 -0
  101. package/dist/utils/list-command-utils.d.ts +23 -0
  102. package/dist/utils/list-command-utils.d.ts.map +1 -0
  103. package/dist/utils/list-command-utils.js +60 -0
  104. package/dist/utils/output-utils.d.ts +60 -0
  105. package/dist/utils/output-utils.d.ts.map +1 -0
  106. package/dist/utils/output-utils.js +320 -0
  107. package/dist/utils/rate-limiter.d.ts +14 -0
  108. package/dist/utils/rate-limiter.d.ts.map +1 -0
  109. package/dist/utils/rate-limiter.js +73 -0
  110. package/package.json +144 -0
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
+ if (k2 === undefined) k2 = k;
6
+ var desc = Object.getOwnPropertyDescriptor(m, k);
7
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
+ desc = { enumerable: true, get: function() { return m[k]; } };
9
+ }
10
+ Object.defineProperty(o, k2, desc);
11
+ }) : (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ o[k2] = m[k];
14
+ }));
15
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
17
+ }) : function(o, v) {
18
+ o["default"] = v;
19
+ });
20
+ var __importStar = (this && this.__importStar) || (function () {
21
+ var ownKeys = function(o) {
22
+ ownKeys = Object.getOwnPropertyNames || function (o) {
23
+ var ar = [];
24
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
+ return ar;
26
+ };
27
+ return ownKeys(o);
28
+ };
29
+ return function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ })();
37
+ var __importDefault = (this && this.__importDefault) || function (mod) {
38
+ return (mod && mod.__esModule) ? mod : { "default": mod };
39
+ };
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.uploadPlugin = uploadPlugin;
42
+ const fs = __importStar(require("fs"));
43
+ const path = __importStar(require("path"));
44
+ const form_data_1 = __importDefault(require("form-data"));
45
+ const ora_1 = __importDefault(require("ora"));
46
+ const picocolors_1 = __importDefault(require("picocolors"));
47
+ const cli_constants_1 = require("../config/cli.constants");
48
+ const command_utils_1 = require("../utils/command-utils");
49
+ const error_handler_1 = require("../utils/error-handler");
50
+ const output_utils_1 = require("../utils/output-utils");
51
+ const { bold, green } = picocolors_1.default;
52
+ /**
53
+ * Registers the `upload-plugin` command with the CLI program.
54
+ *
55
+ * Validates a local plugin ZIP file (size, extension, readability),
56
+ * builds a multipart form, and uploads it to the platform API.
57
+ * Plugin name and version can be auto-detected from the package
58
+ * or overridden via CLI flags.
59
+ *
60
+ * @param program - The root Commander program instance to attach the command to.
61
+ *
62
+ * @example
63
+ * ```bash
64
+ * cli upload-plugin --file plugin.zip --organization acme
65
+ * cli upload-plugin --file plugin.zip --organization acme --public
66
+ * cli upload-plugin --file plugin.zip --organization acme --name my-plugin --version 1.0.0
67
+ * cli upload-plugin --file plugin.zip --organization acme --no-verify-ssl
68
+ * ```
69
+ */
70
+ function uploadPlugin(program) {
71
+ program
72
+ .command('upload-plugin')
73
+ .description('Upload and deploy a plugin package')
74
+ .requiredOption('-f, --file <file>', 'Path to plugin ZIP file')
75
+ .requiredOption('-o, --organization <organization>', 'Organization name')
76
+ .option('-n, --name <name>', 'Plugin name (optional, extracted from package if not provided)')
77
+ .option('-v, --version <version>', 'Plugin version (optional, extracted from package if not provided)')
78
+ .option('--public', 'Make plugin publicly accessible', false)
79
+ .option('--active', 'Set plugin as active', true)
80
+ .option('--verify-ssl', 'Enable SSL certificate verification')
81
+ .option('--no-verify-ssl', 'Disable SSL certificate verification')
82
+ .option('--dry-run', 'Validate file without uploading', false)
83
+ .action(async (options) => {
84
+ const executionId = (0, command_utils_1.printCommandHeader)('Upload Plugin');
85
+ try {
86
+ // Display parameters
87
+ (0, output_utils_1.printInfo)('Upload parameters', {
88
+ file: options.file,
89
+ organization: options.organization,
90
+ name: options.name || '(auto-detect)',
91
+ version: options.version || '(auto-detect)',
92
+ public: options.public ? 'Yes' : 'No',
93
+ active: options.active ? 'Yes' : 'No',
94
+ dryRun: options.dryRun,
95
+ verifySsl: options.verifySsl,
96
+ });
97
+ // Security warning for SSL verification disabled
98
+ (0, command_utils_1.printSslWarning)(options.verifySsl);
99
+ // Validate organization
100
+ if (!options.organization || typeof options.organization !== 'string' || options.organization.trim().length === 0) {
101
+ (0, output_utils_1.printError)('Invalid organization name', { provided: options.organization });
102
+ throw new error_handler_1.ValidationError('Organization must be a non-empty string', 'organization', options.organization);
103
+ }
104
+ // Validate file path
105
+ if (!options.file || typeof options.file !== 'string' || options.file.trim().length === 0) {
106
+ (0, output_utils_1.printError)('Invalid file path', { provided: options.file });
107
+ throw new error_handler_1.ValidationError('File path must be a non-empty string', 'file', options.file);
108
+ }
109
+ const filePath = path.resolve(options.file);
110
+ // Validate file exists
111
+ (0, output_utils_1.printInfo)('Validating plugin file', { path: filePath });
112
+ if (!(0, output_utils_1.fileExists)(filePath)) {
113
+ (0, output_utils_1.printError)('Plugin file not found', { path: filePath });
114
+ throw new error_handler_1.ValidationError(`Plugin file not found: ${filePath}`, 'file', filePath);
115
+ }
116
+ // Validate file extension
117
+ const fileExt = path.extname(filePath).toLowerCase();
118
+ if (fileExt !== '.zip') {
119
+ (0, output_utils_1.printWarning)('File extension is not .zip', {
120
+ provided: fileExt,
121
+ expected: '.zip',
122
+ });
123
+ throw new error_handler_1.ValidationError('Plugin file must be a ZIP archive', 'file', filePath);
124
+ }
125
+ // Get file stats
126
+ const stats = fs.statSync(filePath);
127
+ const sizeBytes = stats.size;
128
+ const sizeFormatted = (0, cli_constants_1.formatFileSize)(sizeBytes);
129
+ (0, output_utils_1.printSuccess)('Plugin file found', {
130
+ path: filePath,
131
+ size: sizeFormatted,
132
+ modified: new Date(stats.mtime).toLocaleString(),
133
+ });
134
+ // Check file size
135
+ if (sizeBytes > cli_constants_1.FILE_SIZE_LIMITS.PLUGIN) {
136
+ (0, output_utils_1.printError)('Plugin file too large', {
137
+ size: sizeFormatted,
138
+ maximum: (0, cli_constants_1.formatFileSize)(cli_constants_1.FILE_SIZE_LIMITS.PLUGIN),
139
+ exceededBy: (0, cli_constants_1.formatFileSize)(sizeBytes - cli_constants_1.FILE_SIZE_LIMITS.PLUGIN),
140
+ });
141
+ throw new error_handler_1.ValidationError(`Plugin file exceeds maximum size of ${(0, cli_constants_1.formatFileSize)(cli_constants_1.FILE_SIZE_LIMITS.PLUGIN)} (actual: ${sizeFormatted})`, 'file.size', sizeBytes);
142
+ }
143
+ // Check if file is readable
144
+ try {
145
+ fs.accessSync(filePath, fs.constants.R_OK);
146
+ }
147
+ catch (error) {
148
+ (0, output_utils_1.printError)('Cannot read plugin file', {
149
+ path: filePath,
150
+ error: error instanceof Error ? error.message : String(error),
151
+ });
152
+ throw new error_handler_1.ValidationError('Plugin file is not readable', 'file', filePath);
153
+ }
154
+ (0, output_utils_1.printSuccess)('Plugin file validated');
155
+ // Validate version format if provided
156
+ if (options.version) {
157
+ const versionRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
158
+ if (!versionRegex.test(options.version)) {
159
+ (0, output_utils_1.printWarning)('Version format may be invalid', {
160
+ provided: options.version,
161
+ expected: 'semantic version (e.g., 1.0.0, 1.2.3-beta.1)',
162
+ });
163
+ }
164
+ }
165
+ // Validate name format if provided
166
+ if (options.name) {
167
+ const nameRegex = /^[a-z0-9-]+$/;
168
+ if (!nameRegex.test(options.name)) {
169
+ (0, output_utils_1.printWarning)('Plugin name format may be invalid', {
170
+ provided: options.name,
171
+ expected: 'lowercase alphanumeric with dashes (e.g., my-plugin-name)',
172
+ });
173
+ }
174
+ }
175
+ // Dry run mode
176
+ if (options.dryRun) {
177
+ console.log('');
178
+ (0, output_utils_1.printSection)('Dry Run - Validation Complete');
179
+ (0, output_utils_1.printSuccess)('File validation passed - no upload performed');
180
+ (0, output_utils_1.printKeyValue)({
181
+ File: filePath,
182
+ Size: sizeFormatted,
183
+ Organization: options.organization,
184
+ Name: options.name || '(will be auto-detected)',
185
+ Version: options.version || '(will be auto-detected)',
186
+ Public: options.public ? 'Yes' : 'No',
187
+ Active: options.active ? 'Yes' : 'No',
188
+ });
189
+ return;
190
+ }
191
+ // Create authenticated API client
192
+ const client = (0, command_utils_1.createAuthenticatedClient)(options);
193
+ const config = client.getConfig();
194
+ // Create form data
195
+ console.log('');
196
+ (0, output_utils_1.printSection)('Uploading Plugin');
197
+ (0, output_utils_1.printInfo)('Preparing upload', {
198
+ file: path.basename(filePath),
199
+ size: sizeFormatted,
200
+ });
201
+ const formData = new form_data_1.default();
202
+ formData.append('plugin', fs.createReadStream(filePath), {
203
+ filename: path.basename(filePath),
204
+ contentType: 'application/zip',
205
+ });
206
+ formData.append('organization', options.organization);
207
+ if (options.name)
208
+ formData.append('name', options.name);
209
+ if (options.version)
210
+ formData.append('version', options.version);
211
+ formData.append('isPublic', options.public ? 'true' : 'false');
212
+ formData.append('isActive', options.active ? 'true' : 'false');
213
+ // Make API request
214
+ const endpoint = config.api.pluginUploadUrl;
215
+ (0, output_utils_1.printInfo)('Uploading to API', {
216
+ endpoint: `${config.api.baseUrl}${endpoint}`,
217
+ });
218
+ console.log('');
219
+ const spinner = (0, ora_1.default)('Uploading plugin...').start();
220
+ let rawResponse;
221
+ let duration;
222
+ try {
223
+ const startTime = Date.now();
224
+ rawResponse = await client.postForm(endpoint, formData);
225
+ duration = Date.now() - startTime;
226
+ spinner.succeed('Plugin uploaded');
227
+ }
228
+ catch (error) {
229
+ spinner.fail('Upload failed');
230
+ throw error;
231
+ }
232
+ const response = (0, output_utils_1.extractSingleResponse)(rawResponse, 'plugin', 'name');
233
+ if (!response) {
234
+ (0, output_utils_1.printError)('No valid plugin data in response', {
235
+ responseKeys: rawResponse ? Object.keys(rawResponse) : '(null)',
236
+ });
237
+ throw new Error('Upload failed - no valid plugin data received');
238
+ }
239
+ console.log('');
240
+ (0, output_utils_1.printSection)('Plugin Uploaded Successfully');
241
+ // Display plugin information
242
+ (0, output_utils_1.printKeyValue)({
243
+ 'Plugin ID': green(bold(response.id)),
244
+ 'Name': response.name,
245
+ 'Version': response.version,
246
+ 'Organization': response.organization,
247
+ 'Description': response.description || '(not set)',
248
+ });
249
+ console.log('');
250
+ (0, output_utils_1.printKeyValue)({
251
+ 'File URL': response.fileUrl || '(not available)',
252
+ 'File Size': response.fileSize ? `${(response.fileSize / 1024).toFixed(2)} KB` : '(not available)',
253
+ 'Checksum': response.checksum ? `${response.checksum.substring(0, 16)}...` : '(not available)',
254
+ });
255
+ console.log('');
256
+ (0, output_utils_1.printKeyValue)({
257
+ 'Public': response.isPublic ? 'Yes' : 'No',
258
+ 'Active': response.isActive ? 'Yes' : 'No',
259
+ 'Created At': response.createdAt || '(not available)',
260
+ 'Uploaded By': response.uploadedBy || '(not available)',
261
+ });
262
+ console.log('');
263
+ (0, output_utils_1.printKeyValue)({
264
+ 'Execution ID': executionId,
265
+ 'Upload Duration': `${(duration / 1000).toFixed(2)}s`,
266
+ 'Status': green('✓ Success'),
267
+ });
268
+ // Print additional information if available
269
+ if (response.metadata) {
270
+ console.log('');
271
+ (0, output_utils_1.printInfo)('Plugin metadata available', {
272
+ keys: Object.keys(response.metadata).length,
273
+ });
274
+ }
275
+ // Print deployment logs URL if available
276
+ const resp = response;
277
+ const requestId = resp['X-Request-Id'] || resp.requestId;
278
+ if (requestId) {
279
+ console.log('');
280
+ (0, output_utils_1.printInfo)('Deployment logs available', {
281
+ requestId,
282
+ url: `${config.api.baseUrl}/logs/${requestId}`,
283
+ });
284
+ }
285
+ // Next steps
286
+ console.log('');
287
+ (0, output_utils_1.printInfo)('Next steps', {
288
+ view: `Use "get-plugin --id ${response.id}" to view plugin details`,
289
+ list: 'Use "list-plugins" to see all plugins',
290
+ });
291
+ }
292
+ catch (error) {
293
+ (0, error_handler_1.handleError)(error, error_handler_1.ERROR_CODES.API_REQUEST, {
294
+ debug: program.opts().debug,
295
+ exit: true,
296
+ context: {
297
+ command: 'upload-plugin',
298
+ executionId,
299
+ file: options.file,
300
+ organization: options.organization,
301
+ name: options.name,
302
+ version: options.version,
303
+ public: options.public,
304
+ active: options.active,
305
+ verifySsl: options.verifySsl,
306
+ },
307
+ });
308
+ }
309
+ });
310
+ }
311
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy91cGxvYWQtcGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtDdEMsb0NBb1JDO0FBcFRELHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFFN0IsMERBQWlDO0FBQ2pDLDhDQUFzQjtBQUN0Qiw0REFBOEI7QUFDOUIsMkRBQTJFO0FBRTNFLDBEQUF3RztBQUN4RywwREFBbUY7QUFDbkYsd0RBQTBKO0FBRTFKLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsb0JBQUksQ0FBQztBQUU3Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxTQUFnQixZQUFZLENBQUMsT0FBZ0I7SUFDM0MsT0FBTztTQUNKLE9BQU8sQ0FBQyxlQUFlLENBQUM7U0FDeEIsV0FBVyxDQUFDLG9DQUFvQyxDQUFDO1NBQ2pELGNBQWMsQ0FBQyxtQkFBbUIsRUFBRSx5QkFBeUIsQ0FBQztTQUM5RCxjQUFjLENBQUMsbUNBQW1DLEVBQUUsbUJBQW1CLENBQUM7U0FDeEUsTUFBTSxDQUFDLG1CQUFtQixFQUFFLGdFQUFnRSxDQUFDO1NBQzdGLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSxtRUFBbUUsQ0FBQztTQUN0RyxNQUFNLENBQUMsVUFBVSxFQUFFLGlDQUFpQyxFQUFFLEtBQUssQ0FBQztTQUM1RCxNQUFNLENBQUMsVUFBVSxFQUFFLHNCQUFzQixFQUFFLElBQUksQ0FBQztTQUNoRCxNQUFNLENBQUMsY0FBYyxFQUFFLHFDQUFxQyxDQUFDO1NBQzdELE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxzQ0FBc0MsQ0FBQztTQUNqRSxNQUFNLENBQUMsV0FBVyxFQUFFLGlDQUFpQyxFQUFFLEtBQUssQ0FBQztTQUM3RCxNQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1FBQ3hCLE1BQU0sV0FBVyxHQUFHLElBQUEsa0NBQWtCLEVBQUMsZUFBZSxDQUFDLENBQUM7UUFFeEQsSUFBSSxDQUFDO1lBRUgscUJBQXFCO1lBQ3JCLElBQUEsd0JBQVMsRUFBQyxtQkFBbUIsRUFBRTtnQkFDN0IsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO2dCQUNsQixZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVk7Z0JBQ2xDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLGVBQWU7Z0JBQ3JDLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxJQUFJLGVBQWU7Z0JBQzNDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQ3JDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUk7Z0JBQ3JDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtnQkFDdEIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO2FBQzdCLENBQUMsQ0FBQztZQUVILGlEQUFpRDtZQUNqRCxJQUFBLCtCQUFlLEVBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRW5DLHdCQUF3QjtZQUN4QixJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksSUFBSSxPQUFPLE9BQU8sQ0FBQyxZQUFZLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNsSCxJQUFBLHlCQUFVLEVBQUMsMkJBQTJCLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7Z0JBQzVFLE1BQU0sSUFBSSwrQkFBZSxDQUFDLHlDQUF5QyxFQUFFLGNBQWMsRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDN0csQ0FBQztZQUVELHFCQUFxQjtZQUNyQixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxPQUFPLE9BQU8sQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxRixJQUFBLHlCQUFVLEVBQUMsbUJBQW1CLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzVELE1BQU0sSUFBSSwrQkFBZSxDQUFDLHNDQUFzQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUYsQ0FBQztZQUVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRTVDLHVCQUF1QjtZQUN2QixJQUFBLHdCQUFTLEVBQUMsd0JBQXdCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUV4RCxJQUFJLENBQUMsSUFBQSx5QkFBVSxFQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7Z0JBQzFCLElBQUEseUJBQVUsRUFBQyx1QkFBdUIsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO2dCQUN4RCxNQUFNLElBQUksK0JBQWUsQ0FBQywwQkFBMEIsUUFBUSxFQUFFLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3BGLENBQUM7WUFFRCwwQkFBMEI7WUFDMUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyRCxJQUFJLE9BQU8sS0FBSyxNQUFNLEVBQUUsQ0FBQztnQkFDdkIsSUFBQSwyQkFBWSxFQUFDLDRCQUE0QixFQUFFO29CQUN6QyxRQUFRLEVBQUUsT0FBTztvQkFDakIsUUFBUSxFQUFFLE1BQU07aUJBQ2pCLENBQUMsQ0FBQztnQkFDSCxNQUFNLElBQUksK0JBQWUsQ0FBQyxtQ0FBbUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDbkYsQ0FBQztZQUVELGlCQUFpQjtZQUNqQixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3BDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDN0IsTUFBTSxhQUFhLEdBQUcsSUFBQSw4QkFBYyxFQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRWhELElBQUEsMkJBQVksRUFBQyxtQkFBbUIsRUFBRTtnQkFDaEMsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLFFBQVEsRUFBRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsY0FBYyxFQUFFO2FBQ2pELENBQUMsQ0FBQztZQUVILGtCQUFrQjtZQUNsQixJQUFJLFNBQVMsR0FBRyxnQ0FBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDeEMsSUFBQSx5QkFBVSxFQUFDLHVCQUF1QixFQUFFO29CQUNsQyxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsT0FBTyxFQUFFLElBQUEsOEJBQWMsRUFBQyxnQ0FBZ0IsQ0FBQyxNQUFNLENBQUM7b0JBQ2hELFVBQVUsRUFBRSxJQUFBLDhCQUFjLEVBQUMsU0FBUyxHQUFHLGdDQUFnQixDQUFDLE1BQU0sQ0FBQztpQkFDaEUsQ0FBQyxDQUFDO2dCQUNILE1BQU0sSUFBSSwrQkFBZSxDQUN2Qix1Q0FBdUMsSUFBQSw4QkFBYyxFQUFDLGdDQUFnQixDQUFDLE1BQU0sQ0FBQyxhQUFhLGFBQWEsR0FBRyxFQUMzRyxXQUFXLEVBQ1gsU0FBUyxDQUNWLENBQUM7WUFDSixDQUFDO1lBRUQsNEJBQTRCO1lBQzVCLElBQUksQ0FBQztnQkFDSCxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUEseUJBQVUsRUFBQyx5QkFBeUIsRUFBRTtvQkFDcEMsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsS0FBSyxFQUFFLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7aUJBQzlELENBQUMsQ0FBQztnQkFDSCxNQUFNLElBQUksK0JBQWUsQ0FBQyw2QkFBNkIsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDN0UsQ0FBQztZQUVELElBQUEsMkJBQVksRUFBQyx1QkFBdUIsQ0FBQyxDQUFDO1lBRXRDLHNDQUFzQztZQUN0QyxJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxZQUFZLEdBQUcsbUNBQW1DLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO29CQUN4QyxJQUFBLDJCQUFZLEVBQUMsK0JBQStCLEVBQUU7d0JBQzVDLFFBQVEsRUFBRSxPQUFPLENBQUMsT0FBTzt3QkFDekIsUUFBUSxFQUFFLDhDQUE4QztxQkFDekQsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDO1lBRUQsbUNBQW1DO1lBQ25DLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNqQixNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNsQyxJQUFBLDJCQUFZLEVBQUMsbUNBQW1DLEVBQUU7d0JBQ2hELFFBQVEsRUFBRSxPQUFPLENBQUMsSUFBSTt3QkFDdEIsUUFBUSxFQUFFLDJEQUEyRDtxQkFDdEUsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDO1lBRUQsZUFBZTtZQUNmLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNoQixJQUFBLDJCQUFZLEVBQUMsK0JBQStCLENBQUMsQ0FBQztnQkFDOUMsSUFBQSwyQkFBWSxFQUFDLDhDQUE4QyxDQUFDLENBQUM7Z0JBRTdELElBQUEsNEJBQWEsRUFBQztvQkFDWixJQUFJLEVBQUUsUUFBUTtvQkFDZCxJQUFJLEVBQUUsYUFBYTtvQkFDbkIsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZO29CQUNsQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSx5QkFBeUI7b0JBQy9DLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTyxJQUFJLHlCQUF5QjtvQkFDckQsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtvQkFDckMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtpQkFDdEMsQ0FBQyxDQUFDO2dCQUVILE9BQU87WUFDVCxDQUFDO1lBRUQsa0NBQWtDO1lBQ2xDLE1BQU0sTUFBTSxHQUFHLElBQUEseUNBQXlCLEVBQUMsT0FBTyxDQUFDLENBQUM7WUFDbEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBRWxDLG1CQUFtQjtZQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLElBQUEsMkJBQVksRUFBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ2pDLElBQUEsd0JBQVMsRUFBQyxrQkFBa0IsRUFBRTtnQkFDNUIsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUM3QixJQUFJLEVBQUUsYUFBYTthQUNwQixDQUFDLENBQUM7WUFFSCxNQUFNLFFBQVEsR0FBRyxJQUFJLG1CQUFRLEVBQUUsQ0FBQztZQUNoQyxRQUFRLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEVBQUU7Z0JBQ3ZELFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDakMsV0FBVyxFQUFFLGlCQUFpQjthQUMvQixDQUFDLENBQUM7WUFDSCxRQUFRLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7WUFFdEQsSUFBSSxPQUFPLENBQUMsSUFBSTtnQkFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEQsSUFBSSxPQUFPLENBQUMsT0FBTztnQkFBRSxRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDakUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvRCxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRS9ELG1CQUFtQjtZQUNuQixNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQztZQUM1QyxJQUFBLHdCQUFTLEVBQUMsa0JBQWtCLEVBQUU7Z0JBQzVCLFFBQVEsRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFHLFFBQVEsRUFBRTthQUM3QyxDQUFDLENBQUM7WUFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRWhCLE1BQU0sT0FBTyxHQUFHLElBQUEsYUFBRyxFQUFDLHFCQUFxQixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDbkQsSUFBSSxXQUEyQixDQUFDO1lBQ2hDLElBQUksUUFBZ0IsQ0FBQztZQUNyQixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO2dCQUM3QixXQUFXLEdBQUcsTUFBTSxNQUFNLENBQUMsUUFBUSxDQUFpQixRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7Z0JBQ3hFLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDO2dCQUNsQyxPQUFPLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDckMsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxLQUFLLENBQUM7WUFDZCxDQUFDO1lBRUQsTUFBTSxRQUFRLEdBQUcsSUFBQSxvQ0FBcUIsRUFBUyxXQUFXLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBRTlFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxJQUFBLHlCQUFVLEVBQUMsa0NBQWtDLEVBQUU7b0JBQzdDLFlBQVksRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVE7aUJBQ2hFLENBQUMsQ0FBQztnQkFDSCxNQUFNLElBQUksS0FBSyxDQUFDLCtDQUErQyxDQUFDLENBQUM7WUFDbkUsQ0FBQztZQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEIsSUFBQSwyQkFBWSxFQUFDLDhCQUE4QixDQUFDLENBQUM7WUFFN0MsNkJBQTZCO1lBQzdCLElBQUEsNEJBQWEsRUFBQztnQkFDWixXQUFXLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3JDLE1BQU0sRUFBRSxRQUFRLENBQUMsSUFBSTtnQkFDckIsU0FBUyxFQUFFLFFBQVEsQ0FBQyxPQUFPO2dCQUMzQixjQUFjLEVBQUUsUUFBUSxDQUFDLFlBQVk7Z0JBQ3JDLGFBQWEsRUFBRSxRQUFRLENBQUMsV0FBVyxJQUFJLFdBQVc7YUFDbkQsQ0FBQyxDQUFDO1lBRUgsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoQixJQUFBLDRCQUFhLEVBQUM7Z0JBQ1osVUFBVSxFQUFFLFFBQVEsQ0FBQyxPQUFPLElBQUksaUJBQWlCO2dCQUNqRCxXQUFXLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGlCQUFpQjtnQkFDbEcsVUFBVSxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGlCQUFpQjthQUMvRixDQUFDLENBQUM7WUFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLElBQUEsNEJBQWEsRUFBQztnQkFDWixRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUMxQyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJO2dCQUMxQyxZQUFZLEVBQUUsUUFBUSxDQUFDLFNBQVMsSUFBSSxpQkFBaUI7Z0JBQ3JELGFBQWEsRUFBRSxRQUFRLENBQUMsVUFBVSxJQUFJLGlCQUFpQjthQUN4RCxDQUFDLENBQUM7WUFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLElBQUEsNEJBQWEsRUFBQztnQkFDWixjQUFjLEVBQUUsV0FBVztnQkFDM0IsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUc7Z0JBQ3JELFFBQVEsRUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDO2FBQzdCLENBQUMsQ0FBQztZQUVILDRDQUE0QztZQUM1QyxJQUFJLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDdEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEIsSUFBQSx3QkFBUyxFQUFDLDJCQUEyQixFQUFFO29CQUNyQyxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTTtpQkFDNUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELHlDQUF5QztZQUN6QyxNQUFNLElBQUksR0FBRyxRQUE4QyxDQUFDO1lBQzVELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3pELElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEIsSUFBQSx3QkFBUyxFQUFDLDJCQUEyQixFQUFFO29CQUNyQyxTQUFTO29CQUNULEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxTQUFTLFNBQVMsRUFBRTtpQkFDL0MsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELGFBQWE7WUFDYixPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLElBQUEsd0JBQVMsRUFBQyxZQUFZLEVBQUU7Z0JBQ3RCLElBQUksRUFBRSx3QkFBd0IsUUFBUSxDQUFDLEVBQUUsMEJBQTBCO2dCQUNuRSxJQUFJLEVBQUUsdUNBQXVDO2FBQzlDLENBQUMsQ0FBQztRQUVMLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBQSwyQkFBVyxFQUFDLEtBQUssRUFBRSwyQkFBVyxDQUFDLFdBQVcsRUFBRTtnQkFDMUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLO2dCQUMzQixJQUFJLEVBQUUsSUFBSTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsT0FBTyxFQUFFLGVBQWU7b0JBQ3hCLFdBQVc7b0JBQ1gsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO29CQUNsQixZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVk7b0JBQ2xDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtvQkFDbEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO29CQUN4QixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07b0JBQ3RCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtvQkFDdEIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO2lCQUM3QjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IEZvcm1EYXRhIGZyb20gJ2Zvcm0tZGF0YSc7XG5pbXBvcnQgb3JhIGZyb20gJ29yYSc7XG5pbXBvcnQgcGljbyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCB7IEZJTEVfU0laRV9MSU1JVFMsIGZvcm1hdEZpbGVTaXplIH0gZnJvbSAnLi4vY29uZmlnL2NsaS5jb25zdGFudHMnO1xuaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5SZXNwb25zZSB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB7IHByaW50Q29tbWFuZEhlYWRlciwgcHJpbnRTc2xXYXJuaW5nLCBjcmVhdGVBdXRoZW50aWNhdGVkQ2xpZW50IH0gZnJvbSAnLi4vdXRpbHMvY29tbWFuZC11dGlscyc7XG5pbXBvcnQgeyBFUlJPUl9DT0RFUywgaGFuZGxlRXJyb3IsIFZhbGlkYXRpb25FcnJvciB9IGZyb20gJy4uL3V0aWxzL2Vycm9yLWhhbmRsZXInO1xuaW1wb3J0IHsgZXh0cmFjdFNpbmdsZVJlc3BvbnNlLCBmaWxlRXhpc3RzLCBwcmludEVycm9yLCBwcmludEluZm8sIHByaW50S2V5VmFsdWUsIHByaW50U2VjdGlvbiwgcHJpbnRTdWNjZXNzLCBwcmludFdhcm5pbmcgfSBmcm9tICcuLi91dGlscy9vdXRwdXQtdXRpbHMnO1xuXG5jb25zdCB7IGJvbGQsIGdyZWVuIH0gPSBwaWNvO1xuXG4vKipcbiAqIFJlZ2lzdGVycyB0aGUgYHVwbG9hZC1wbHVnaW5gIGNvbW1hbmQgd2l0aCB0aGUgQ0xJIHByb2dyYW0uXG4gKlxuICogVmFsaWRhdGVzIGEgbG9jYWwgcGx1Z2luIFpJUCBmaWxlIChzaXplLCBleHRlbnNpb24sIHJlYWRhYmlsaXR5KSxcbiAqIGJ1aWxkcyBhIG11bHRpcGFydCBmb3JtLCBhbmQgdXBsb2FkcyBpdCB0byB0aGUgcGxhdGZvcm0gQVBJLlxuICogUGx1Z2luIG5hbWUgYW5kIHZlcnNpb24gY2FuIGJlIGF1dG8tZGV0ZWN0ZWQgZnJvbSB0aGUgcGFja2FnZVxuICogb3Igb3ZlcnJpZGRlbiB2aWEgQ0xJIGZsYWdzLlxuICpcbiAqIEBwYXJhbSBwcm9ncmFtIC0gVGhlIHJvb3QgQ29tbWFuZGVyIHByb2dyYW0gaW5zdGFuY2UgdG8gYXR0YWNoIHRoZSBjb21tYW5kIHRvLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBiYXNoXG4gKiBjbGkgdXBsb2FkLXBsdWdpbiAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lXG4gKiBjbGkgdXBsb2FkLXBsdWdpbiAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lIC0tcHVibGljXG4gKiBjbGkgdXBsb2FkLXBsdWdpbiAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lIC0tbmFtZSBteS1wbHVnaW4gLS12ZXJzaW9uIDEuMC4wXG4gKiBjbGkgdXBsb2FkLXBsdWdpbiAtLWZpbGUgcGx1Z2luLnppcCAtLW9yZ2FuaXphdGlvbiBhY21lIC0tbm8tdmVyaWZ5LXNzbFxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGxvYWRQbHVnaW4ocHJvZ3JhbTogQ29tbWFuZCk6IHZvaWQge1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoJ3VwbG9hZC1wbHVnaW4nKVxuICAgIC5kZXNjcmlwdGlvbignVXBsb2FkIGFuZCBkZXBsb3kgYSBwbHVnaW4gcGFja2FnZScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctZiwgLS1maWxlIDxmaWxlPicsICdQYXRoIHRvIHBsdWdpbiBaSVAgZmlsZScpXG4gICAgLnJlcXVpcmVkT3B0aW9uKCctbywgLS1vcmdhbml6YXRpb24gPG9yZ2FuaXphdGlvbj4nLCAnT3JnYW5pemF0aW9uIG5hbWUnKVxuICAgIC5vcHRpb24oJy1uLCAtLW5hbWUgPG5hbWU+JywgJ1BsdWdpbiBuYW1lIChvcHRpb25hbCwgZXh0cmFjdGVkIGZyb20gcGFja2FnZSBpZiBub3QgcHJvdmlkZWQpJylcbiAgICAub3B0aW9uKCctdiwgLS12ZXJzaW9uIDx2ZXJzaW9uPicsICdQbHVnaW4gdmVyc2lvbiAob3B0aW9uYWwsIGV4dHJhY3RlZCBmcm9tIHBhY2thZ2UgaWYgbm90IHByb3ZpZGVkKScpXG4gICAgLm9wdGlvbignLS1wdWJsaWMnLCAnTWFrZSBwbHVnaW4gcHVibGljbHkgYWNjZXNzaWJsZScsIGZhbHNlKVxuICAgIC5vcHRpb24oJy0tYWN0aXZlJywgJ1NldCBwbHVnaW4gYXMgYWN0aXZlJywgdHJ1ZSlcbiAgICAub3B0aW9uKCctLXZlcmlmeS1zc2wnLCAnRW5hYmxlIFNTTCBjZXJ0aWZpY2F0ZSB2ZXJpZmljYXRpb24nKVxuICAgIC5vcHRpb24oJy0tbm8tdmVyaWZ5LXNzbCcsICdEaXNhYmxlIFNTTCBjZXJ0aWZpY2F0ZSB2ZXJpZmljYXRpb24nKVxuICAgIC5vcHRpb24oJy0tZHJ5LXJ1bicsICdWYWxpZGF0ZSBmaWxlIHdpdGhvdXQgdXBsb2FkaW5nJywgZmFsc2UpXG4gICAgLmFjdGlvbihhc3luYyAob3B0aW9ucykgPT4ge1xuICAgICAgY29uc3QgZXhlY3V0aW9uSWQgPSBwcmludENvbW1hbmRIZWFkZXIoJ1VwbG9hZCBQbHVnaW4nKTtcblxuICAgICAgdHJ5IHtcblxuICAgICAgICAvLyBEaXNwbGF5IHBhcmFtZXRlcnNcbiAgICAgICAgcHJpbnRJbmZvKCdVcGxvYWQgcGFyYW1ldGVycycsIHtcbiAgICAgICAgICBmaWxlOiBvcHRpb25zLmZpbGUsXG4gICAgICAgICAgb3JnYW5pemF0aW9uOiBvcHRpb25zLm9yZ2FuaXphdGlvbixcbiAgICAgICAgICBuYW1lOiBvcHRpb25zLm5hbWUgfHwgJyhhdXRvLWRldGVjdCknLFxuICAgICAgICAgIHZlcnNpb246IG9wdGlvbnMudmVyc2lvbiB8fCAnKGF1dG8tZGV0ZWN0KScsXG4gICAgICAgICAgcHVibGljOiBvcHRpb25zLnB1YmxpYyA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgICBhY3RpdmU6IG9wdGlvbnMuYWN0aXZlID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgIGRyeVJ1bjogb3B0aW9ucy5kcnlSdW4sXG4gICAgICAgICAgdmVyaWZ5U3NsOiBvcHRpb25zLnZlcmlmeVNzbCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2VjdXJpdHkgd2FybmluZyBmb3IgU1NMIHZlcmlmaWNhdGlvbiBkaXNhYmxlZFxuICAgICAgICBwcmludFNzbFdhcm5pbmcob3B0aW9ucy52ZXJpZnlTc2wpO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIG9yZ2FuaXphdGlvblxuICAgICAgICBpZiAoIW9wdGlvbnMub3JnYW5pemF0aW9uIHx8IHR5cGVvZiBvcHRpb25zLm9yZ2FuaXphdGlvbiAhPT0gJ3N0cmluZycgfHwgb3B0aW9ucy5vcmdhbml6YXRpb24udHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHByaW50RXJyb3IoJ0ludmFsaWQgb3JnYW5pemF0aW9uIG5hbWUnLCB7IHByb3ZpZGVkOiBvcHRpb25zLm9yZ2FuaXphdGlvbiB9KTtcbiAgICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdPcmdhbml6YXRpb24gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmcnLCAnb3JnYW5pemF0aW9uJywgb3B0aW9ucy5vcmdhbml6YXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgZmlsZSBwYXRoXG4gICAgICAgIGlmICghb3B0aW9ucy5maWxlIHx8IHR5cGVvZiBvcHRpb25zLmZpbGUgIT09ICdzdHJpbmcnIHx8IG9wdGlvbnMuZmlsZS50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignSW52YWxpZCBmaWxlIHBhdGgnLCB7IHByb3ZpZGVkOiBvcHRpb25zLmZpbGUgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcignRmlsZSBwYXRoIG11c3QgYmUgYSBub24tZW1wdHkgc3RyaW5nJywgJ2ZpbGUnLCBvcHRpb25zLmZpbGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLnJlc29sdmUob3B0aW9ucy5maWxlKTtcblxuICAgICAgICAvLyBWYWxpZGF0ZSBmaWxlIGV4aXN0c1xuICAgICAgICBwcmludEluZm8oJ1ZhbGlkYXRpbmcgcGx1Z2luIGZpbGUnLCB7IHBhdGg6IGZpbGVQYXRoIH0pO1xuXG4gICAgICAgIGlmICghZmlsZUV4aXN0cyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICBwcmludEVycm9yKCdQbHVnaW4gZmlsZSBub3QgZm91bmQnLCB7IHBhdGg6IGZpbGVQYXRoIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYFBsdWdpbiBmaWxlIG5vdCBmb3VuZDogJHtmaWxlUGF0aH1gLCAnZmlsZScsIGZpbGVQYXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGUgZXh0ZW5zaW9uXG4gICAgICAgIGNvbnN0IGZpbGVFeHQgPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChmaWxlRXh0ICE9PSAnLnppcCcpIHtcbiAgICAgICAgICBwcmludFdhcm5pbmcoJ0ZpbGUgZXh0ZW5zaW9uIGlzIG5vdCAuemlwJywge1xuICAgICAgICAgICAgcHJvdmlkZWQ6IGZpbGVFeHQsXG4gICAgICAgICAgICBleHBlY3RlZDogJy56aXAnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1BsdWdpbiBmaWxlIG11c3QgYmUgYSBaSVAgYXJjaGl2ZScsICdmaWxlJywgZmlsZVBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IGZpbGUgc3RhdHNcbiAgICAgICAgY29uc3Qgc3RhdHMgPSBmcy5zdGF0U3luYyhmaWxlUGF0aCk7XG4gICAgICAgIGNvbnN0IHNpemVCeXRlcyA9IHN0YXRzLnNpemU7XG4gICAgICAgIGNvbnN0IHNpemVGb3JtYXR0ZWQgPSBmb3JtYXRGaWxlU2l6ZShzaXplQnl0ZXMpO1xuXG4gICAgICAgIHByaW50U3VjY2VzcygnUGx1Z2luIGZpbGUgZm91bmQnLCB7XG4gICAgICAgICAgcGF0aDogZmlsZVBhdGgsXG4gICAgICAgICAgc2l6ZTogc2l6ZUZvcm1hdHRlZCxcbiAgICAgICAgICBtb2RpZmllZDogbmV3IERhdGUoc3RhdHMubXRpbWUpLnRvTG9jYWxlU3RyaW5nKCksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENoZWNrIGZpbGUgc2l6ZVxuICAgICAgICBpZiAoc2l6ZUJ5dGVzID4gRklMRV9TSVpFX0xJTUlUUy5QTFVHSU4pIHtcbiAgICAgICAgICBwcmludEVycm9yKCdQbHVnaW4gZmlsZSB0b28gbGFyZ2UnLCB7XG4gICAgICAgICAgICBzaXplOiBzaXplRm9ybWF0dGVkLFxuICAgICAgICAgICAgbWF4aW11bTogZm9ybWF0RmlsZVNpemUoRklMRV9TSVpFX0xJTUlUUy5QTFVHSU4pLFxuICAgICAgICAgICAgZXhjZWVkZWRCeTogZm9ybWF0RmlsZVNpemUoc2l6ZUJ5dGVzIC0gRklMRV9TSVpFX0xJTUlUUy5QTFVHSU4pLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgICBgUGx1Z2luIGZpbGUgZXhjZWVkcyBtYXhpbXVtIHNpemUgb2YgJHtmb3JtYXRGaWxlU2l6ZShGSUxFX1NJWkVfTElNSVRTLlBMVUdJTil9IChhY3R1YWw6ICR7c2l6ZUZvcm1hdHRlZH0pYCxcbiAgICAgICAgICAgICdmaWxlLnNpemUnLFxuICAgICAgICAgICAgc2l6ZUJ5dGVzLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiBmaWxlIGlzIHJlYWRhYmxlXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZnMuYWNjZXNzU3luYyhmaWxlUGF0aCwgZnMuY29uc3RhbnRzLlJfT0spO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHByaW50RXJyb3IoJ0Nhbm5vdCByZWFkIHBsdWdpbiBmaWxlJywge1xuICAgICAgICAgICAgcGF0aDogZmlsZVBhdGgsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1BsdWdpbiBmaWxlIGlzIG5vdCByZWFkYWJsZScsICdmaWxlJywgZmlsZVBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJpbnRTdWNjZXNzKCdQbHVnaW4gZmlsZSB2YWxpZGF0ZWQnKTtcblxuICAgICAgICAvLyBWYWxpZGF0ZSB2ZXJzaW9uIGZvcm1hdCBpZiBwcm92aWRlZFxuICAgICAgICBpZiAob3B0aW9ucy52ZXJzaW9uKSB7XG4gICAgICAgICAgY29uc3QgdmVyc2lvblJlZ2V4ID0gL15cXGQrXFwuXFxkK1xcLlxcZCsoLVthLXpBLVowLTkuLV0rKT8kLztcbiAgICAgICAgICBpZiAoIXZlcnNpb25SZWdleC50ZXN0KG9wdGlvbnMudmVyc2lvbikpIHtcbiAgICAgICAgICAgIHByaW50V2FybmluZygnVmVyc2lvbiBmb3JtYXQgbWF5IGJlIGludmFsaWQnLCB7XG4gICAgICAgICAgICAgIHByb3ZpZGVkOiBvcHRpb25zLnZlcnNpb24sXG4gICAgICAgICAgICAgIGV4cGVjdGVkOiAnc2VtYW50aWMgdmVyc2lvbiAoZS5nLiwgMS4wLjAsIDEuMi4zLWJldGEuMSknLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgbmFtZSBmb3JtYXQgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKG9wdGlvbnMubmFtZSkge1xuICAgICAgICAgIGNvbnN0IG5hbWVSZWdleCA9IC9eW2EtejAtOS1dKyQvO1xuICAgICAgICAgIGlmICghbmFtZVJlZ2V4LnRlc3Qob3B0aW9ucy5uYW1lKSkge1xuICAgICAgICAgICAgcHJpbnRXYXJuaW5nKCdQbHVnaW4gbmFtZSBmb3JtYXQgbWF5IGJlIGludmFsaWQnLCB7XG4gICAgICAgICAgICAgIHByb3ZpZGVkOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgICAgIGV4cGVjdGVkOiAnbG93ZXJjYXNlIGFscGhhbnVtZXJpYyB3aXRoIGRhc2hlcyAoZS5nLiwgbXktcGx1Z2luLW5hbWUpJyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERyeSBydW4gbW9kZVxuICAgICAgICBpZiAob3B0aW9ucy5kcnlSdW4pIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgICAgcHJpbnRTZWN0aW9uKCdEcnkgUnVuIC0gVmFsaWRhdGlvbiBDb21wbGV0ZScpO1xuICAgICAgICAgIHByaW50U3VjY2VzcygnRmlsZSB2YWxpZGF0aW9uIHBhc3NlZCAtIG5vIHVwbG9hZCBwZXJmb3JtZWQnKTtcblxuICAgICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICAgRmlsZTogZmlsZVBhdGgsXG4gICAgICAgICAgICBTaXplOiBzaXplRm9ybWF0dGVkLFxuICAgICAgICAgICAgT3JnYW5pemF0aW9uOiBvcHRpb25zLm9yZ2FuaXphdGlvbixcbiAgICAgICAgICAgIE5hbWU6IG9wdGlvbnMubmFtZSB8fCAnKHdpbGwgYmUgYXV0by1kZXRlY3RlZCknLFxuICAgICAgICAgICAgVmVyc2lvbjogb3B0aW9ucy52ZXJzaW9uIHx8ICcod2lsbCBiZSBhdXRvLWRldGVjdGVkKScsXG4gICAgICAgICAgICBQdWJsaWM6IG9wdGlvbnMucHVibGljID8gJ1llcycgOiAnTm8nLFxuICAgICAgICAgICAgQWN0aXZlOiBvcHRpb25zLmFjdGl2ZSA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBhdXRoZW50aWNhdGVkIEFQSSBjbGllbnRcbiAgICAgICAgY29uc3QgY2xpZW50ID0gY3JlYXRlQXV0aGVudGljYXRlZENsaWVudChvcHRpb25zKTtcbiAgICAgICAgY29uc3QgY29uZmlnID0gY2xpZW50LmdldENvbmZpZygpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBmb3JtIGRhdGFcbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludFNlY3Rpb24oJ1VwbG9hZGluZyBQbHVnaW4nKTtcbiAgICAgICAgcHJpbnRJbmZvKCdQcmVwYXJpbmcgdXBsb2FkJywge1xuICAgICAgICAgIGZpbGU6IHBhdGguYmFzZW5hbWUoZmlsZVBhdGgpLFxuICAgICAgICAgIHNpemU6IHNpemVGb3JtYXR0ZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgncGx1Z2luJywgZnMuY3JlYXRlUmVhZFN0cmVhbShmaWxlUGF0aCksIHtcbiAgICAgICAgICBmaWxlbmFtZTogcGF0aC5iYXNlbmFtZShmaWxlUGF0aCksXG4gICAgICAgICAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi96aXAnLFxuICAgICAgICB9KTtcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdvcmdhbml6YXRpb24nLCBvcHRpb25zLm9yZ2FuaXphdGlvbik7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubmFtZSkgZm9ybURhdGEuYXBwZW5kKCduYW1lJywgb3B0aW9ucy5uYW1lKTtcbiAgICAgICAgaWYgKG9wdGlvbnMudmVyc2lvbikgZm9ybURhdGEuYXBwZW5kKCd2ZXJzaW9uJywgb3B0aW9ucy52ZXJzaW9uKTtcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdpc1B1YmxpYycsIG9wdGlvbnMucHVibGljID8gJ3RydWUnIDogJ2ZhbHNlJyk7XG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnaXNBY3RpdmUnLCBvcHRpb25zLmFjdGl2ZSA/ICd0cnVlJyA6ICdmYWxzZScpO1xuXG4gICAgICAgIC8vIE1ha2UgQVBJIHJlcXVlc3RcbiAgICAgICAgY29uc3QgZW5kcG9pbnQgPSBjb25maWcuYXBpLnBsdWdpblVwbG9hZFVybDtcbiAgICAgICAgcHJpbnRJbmZvKCdVcGxvYWRpbmcgdG8gQVBJJywge1xuICAgICAgICAgIGVuZHBvaW50OiBgJHtjb25maWcuYXBpLmJhc2VVcmx9JHtlbmRwb2ludH1gLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG5cbiAgICAgICAgY29uc3Qgc3Bpbm5lciA9IG9yYSgnVXBsb2FkaW5nIHBsdWdpbi4uLicpLnN0YXJ0KCk7XG4gICAgICAgIGxldCByYXdSZXNwb25zZTogUGx1Z2luUmVzcG9uc2U7XG4gICAgICAgIGxldCBkdXJhdGlvbjogbnVtYmVyO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgcmF3UmVzcG9uc2UgPSBhd2FpdCBjbGllbnQucG9zdEZvcm08UGx1Z2luUmVzcG9uc2U+KGVuZHBvaW50LCBmb3JtRGF0YSk7XG4gICAgICAgICAgZHVyYXRpb24gPSBEYXRlLm5vdygpIC0gc3RhcnRUaW1lO1xuICAgICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnUGx1Z2luIHVwbG9hZGVkJyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgc3Bpbm5lci5mYWlsKCdVcGxvYWQgZmFpbGVkJyk7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGV4dHJhY3RTaW5nbGVSZXNwb25zZTxQbHVnaW4+KHJhd1Jlc3BvbnNlLCAncGx1Z2luJywgJ25hbWUnKTtcblxuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgcHJpbnRFcnJvcignTm8gdmFsaWQgcGx1Z2luIGRhdGEgaW4gcmVzcG9uc2UnLCB7XG4gICAgICAgICAgICByZXNwb25zZUtleXM6IHJhd1Jlc3BvbnNlID8gT2JqZWN0LmtleXMocmF3UmVzcG9uc2UpIDogJyhudWxsKScsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVcGxvYWQgZmFpbGVkIC0gbm8gdmFsaWQgcGx1Z2luIGRhdGEgcmVjZWl2ZWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRTZWN0aW9uKCdQbHVnaW4gVXBsb2FkZWQgU3VjY2Vzc2Z1bGx5Jyk7XG5cbiAgICAgICAgLy8gRGlzcGxheSBwbHVnaW4gaW5mb3JtYXRpb25cbiAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgJ1BsdWdpbiBJRCc6IGdyZWVuKGJvbGQocmVzcG9uc2UuaWQpKSxcbiAgICAgICAgICAnTmFtZSc6IHJlc3BvbnNlLm5hbWUsXG4gICAgICAgICAgJ1ZlcnNpb24nOiByZXNwb25zZS52ZXJzaW9uLFxuICAgICAgICAgICdPcmdhbml6YXRpb24nOiByZXNwb25zZS5vcmdhbml6YXRpb24sXG4gICAgICAgICAgJ0Rlc2NyaXB0aW9uJzogcmVzcG9uc2UuZGVzY3JpcHRpb24gfHwgJyhub3Qgc2V0KScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgJ0ZpbGUgVVJMJzogcmVzcG9uc2UuZmlsZVVybCB8fCAnKG5vdCBhdmFpbGFibGUpJyxcbiAgICAgICAgICAnRmlsZSBTaXplJzogcmVzcG9uc2UuZmlsZVNpemUgPyBgJHsocmVzcG9uc2UuZmlsZVNpemUgLyAxMDI0KS50b0ZpeGVkKDIpfSBLQmAgOiAnKG5vdCBhdmFpbGFibGUpJyxcbiAgICAgICAgICAnQ2hlY2tzdW0nOiByZXNwb25zZS5jaGVja3N1bSA/IGAke3Jlc3BvbnNlLmNoZWNrc3VtLnN1YnN0cmluZygwLCAxNil9Li4uYCA6ICcobm90IGF2YWlsYWJsZSknLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdQdWJsaWMnOiByZXNwb25zZS5pc1B1YmxpYyA/ICdZZXMnIDogJ05vJyxcbiAgICAgICAgICAnQWN0aXZlJzogcmVzcG9uc2UuaXNBY3RpdmUgPyAnWWVzJyA6ICdObycsXG4gICAgICAgICAgJ0NyZWF0ZWQgQXQnOiByZXNwb25zZS5jcmVhdGVkQXQgfHwgJyhub3QgYXZhaWxhYmxlKScsXG4gICAgICAgICAgJ1VwbG9hZGVkIEJ5JzogcmVzcG9uc2UudXBsb2FkZWRCeSB8fCAnKG5vdCBhdmFpbGFibGUpJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICBwcmludEtleVZhbHVlKHtcbiAgICAgICAgICAnRXhlY3V0aW9uIElEJzogZXhlY3V0aW9uSWQsXG4gICAgICAgICAgJ1VwbG9hZCBEdXJhdGlvbic6IGAkeyhkdXJhdGlvbiAvIDEwMDApLnRvRml4ZWQoMil9c2AsXG4gICAgICAgICAgJ1N0YXR1cyc6IGdyZWVuKCfinJMgU3VjY2VzcycpLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBQcmludCBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIGlmIGF2YWlsYWJsZVxuICAgICAgICBpZiAocmVzcG9uc2UubWV0YWRhdGEpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgICAgcHJpbnRJbmZvKCdQbHVnaW4gbWV0YWRhdGEgYXZhaWxhYmxlJywge1xuICAgICAgICAgICAga2V5czogT2JqZWN0LmtleXMocmVzcG9uc2UubWV0YWRhdGEpLmxlbmd0aCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByaW50IGRlcGxveW1lbnQgbG9ncyBVUkwgaWYgYXZhaWxhYmxlXG4gICAgICAgIGNvbnN0IHJlc3AgPSByZXNwb25zZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICBjb25zdCByZXF1ZXN0SWQgPSByZXNwWydYLVJlcXVlc3QtSWQnXSB8fCByZXNwLnJlcXVlc3RJZDtcbiAgICAgICAgaWYgKHJlcXVlc3RJZCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgICBwcmludEluZm8oJ0RlcGxveW1lbnQgbG9ncyBhdmFpbGFibGUnLCB7XG4gICAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgICB1cmw6IGAke2NvbmZpZy5hcGkuYmFzZVVybH0vbG9ncy8ke3JlcXVlc3RJZH1gLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTmV4dCBzdGVwc1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50SW5mbygnTmV4dCBzdGVwcycsIHtcbiAgICAgICAgICB2aWV3OiBgVXNlIFwiZ2V0LXBsdWdpbiAtLWlkICR7cmVzcG9uc2UuaWR9XCIgdG8gdmlldyBwbHVnaW4gZGV0YWlsc2AsXG4gICAgICAgICAgbGlzdDogJ1VzZSBcImxpc3QtcGx1Z2luc1wiIHRvIHNlZSBhbGwgcGx1Z2lucycsXG4gICAgICAgIH0pO1xuXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBoYW5kbGVFcnJvcihlcnJvciwgRVJST1JfQ09ERVMuQVBJX1JFUVVFU1QsIHtcbiAgICAgICAgICBkZWJ1ZzogcHJvZ3JhbS5vcHRzKCkuZGVidWcsXG4gICAgICAgICAgZXhpdDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICBjb21tYW5kOiAndXBsb2FkLXBsdWdpbicsXG4gICAgICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgICAgIGZpbGU6IG9wdGlvbnMuZmlsZSxcbiAgICAgICAgICAgIG9yZ2FuaXphdGlvbjogb3B0aW9ucy5vcmdhbml6YXRpb24sXG4gICAgICAgICAgICBuYW1lOiBvcHRpb25zLm5hbWUsXG4gICAgICAgICAgICB2ZXJzaW9uOiBvcHRpb25zLnZlcnNpb24sXG4gICAgICAgICAgICBwdWJsaWM6IG9wdGlvbnMucHVibGljLFxuICAgICAgICAgICAgYWN0aXZlOiBvcHRpb25zLmFjdGl2ZSxcbiAgICAgICAgICAgIHZlcmlmeVNzbDogb3B0aW9ucy52ZXJpZnlTc2wsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG59XG4iXX0=
@@ -0,0 +1,12 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Registers the `version` command with the CLI program.
4
+ *
5
+ * Displays the CLI name/version, AWS CDK status, and optionally
6
+ * full system diagnostics (`--verbose`) or configuration validation
7
+ * (`--check-config`). Supports `--json` for machine-readable output.
8
+ *
9
+ * @param program - The root Commander program instance to attach the command to.
10
+ */
11
+ export declare function version(program: Command): void;
12
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/commands/version.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoFpC;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0J9C"}
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ // Copyright 2026 Pipeline Builder Contributors
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.version = version;
9
+ const child_process_1 = require("child_process");
10
+ const picocolors_1 = __importDefault(require("picocolors"));
11
+ const cli_constants_1 = require("../config/cli.constants");
12
+ const cdk_utils_1 = require("../utils/cdk-utils");
13
+ const config_loader_1 = require("../utils/config-loader");
14
+ const error_handler_1 = require("../utils/error-handler");
15
+ const output_utils_1 = require("../utils/output-utils");
16
+ const { bold, cyan, dim, green, magenta, red, yellow } = picocolors_1.default;
17
+ /**
18
+ * Collects runtime system information including Node.js/npm versions,
19
+ * platform, architecture, heap memory usage, and process uptime.
20
+ */
21
+ function getSystemInfo() {
22
+ const mem = process.memoryUsage();
23
+ const totalMem = (mem.heapTotal / 1024 / 1024).toFixed(2);
24
+ const availableHeap = ((mem.heapTotal - mem.heapUsed) / 1024 / 1024).toFixed(2);
25
+ const uptime = process.uptime();
26
+ let npm;
27
+ try {
28
+ npm = (0, child_process_1.execSync)('npm --version', { encoding: 'utf-8', stdio: 'pipe' }).trim();
29
+ }
30
+ catch {
31
+ npm = null;
32
+ }
33
+ return {
34
+ nodejs: process.version,
35
+ npm,
36
+ platform: process.platform,
37
+ architecture: process.arch,
38
+ memory: { total: `${totalMem} MB`, availableHeap: `${availableHeap} MB` },
39
+ uptime: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m ${Math.floor(uptime % 60)}s`,
40
+ };
41
+ }
42
+ /**
43
+ * Attempts to load the CLI configuration and reports whether it is valid.
44
+ * @returns An object with `valid: true` on success, or `valid: false` with an error message.
45
+ */
46
+ function checkConfiguration() {
47
+ try {
48
+ (0, config_loader_1.getConfig)();
49
+ return { valid: true };
50
+ }
51
+ catch (error) {
52
+ return {
53
+ valid: false,
54
+ error: error instanceof Error ? error.message : String(error),
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Checks which key environment variables are currently set.
60
+ * @returns Presence flags for `PLATFORM_TOKEN`, `PLATFORM_BASE_URL`, and `CLI_CONFIG_PATH`.
61
+ */
62
+ function getEnvironmentStatus() {
63
+ return {
64
+ token: !!process.env.PLATFORM_TOKEN,
65
+ url: !!process.env.PLATFORM_BASE_URL,
66
+ configPath: !!process.env.CLI_CONFIG_PATH,
67
+ };
68
+ }
69
+ /**
70
+ * Registers the `version` command with the CLI program.
71
+ *
72
+ * Displays the CLI name/version, AWS CDK status, and optionally
73
+ * full system diagnostics (`--verbose`) or configuration validation
74
+ * (`--check-config`). Supports `--json` for machine-readable output.
75
+ *
76
+ * @param program - The root Commander program instance to attach the command to.
77
+ */
78
+ function version(program) {
79
+ program
80
+ .command('version')
81
+ .description('Display CLI version and environment information')
82
+ .option('--verbose', 'Show detailed environment information', false)
83
+ .option('--check-config', 'Verify configuration status', false)
84
+ .option('--json', 'Output in JSON format', false)
85
+ .action((options) => {
86
+ try {
87
+ const executionId = (0, cli_constants_1.generateExecutionId)();
88
+ const cdkInfo = (0, cdk_utils_1.getCdkInfo)();
89
+ // JSON output
90
+ if (options.json) {
91
+ const systemInfo = getSystemInfo();
92
+ const configStatus = options.checkConfig ? checkConfiguration() : { valid: true };
93
+ const envStatus = getEnvironmentStatus();
94
+ console.log(JSON.stringify({
95
+ cli: { name: cli_constants_1.APP_NAME, version: cli_constants_1.APP_VERSION },
96
+ system: systemInfo,
97
+ cdk: { available: cdkInfo.available, version: cdkInfo.version },
98
+ configuration: { valid: configStatus.valid, error: configStatus.error },
99
+ environment: envStatus,
100
+ executionId,
101
+ timestamp: new Date().toISOString(),
102
+ }, null, 2));
103
+ return;
104
+ }
105
+ // Standard output
106
+ (0, output_utils_1.printSection)('Version Information');
107
+ console.log(`${magenta(`[EXE-${executionId}]`)} ${cyan(bold('CLI Version Check'))}`);
108
+ console.log('');
109
+ (0, output_utils_1.printKeyValue)({
110
+ 'CLI Name': bold(cli_constants_1.APP_NAME),
111
+ 'CLI Version': green(bold(cli_constants_1.APP_VERSION)),
112
+ });
113
+ (0, output_utils_1.printDivider)();
114
+ // Verbose: system environment
115
+ if (options.verbose) {
116
+ (0, output_utils_1.printSection)('System Environment');
117
+ const systemInfo = getSystemInfo();
118
+ (0, output_utils_1.printKeyValue)({
119
+ 'Node.js': systemInfo.nodejs,
120
+ 'npm': systemInfo.npm || yellow('(not available)'),
121
+ 'Platform': systemInfo.platform,
122
+ 'Architecture': systemInfo.architecture,
123
+ 'Memory (Heap)': `${systemInfo.memory.total} total, ${systemInfo.memory.availableHeap} available`,
124
+ 'Process Uptime': systemInfo.uptime,
125
+ });
126
+ (0, output_utils_1.printDivider)();
127
+ (0, output_utils_1.printSection)('AWS CDK');
128
+ }
129
+ // CDK information
130
+ if (cdkInfo.available && cdkInfo.version) {
131
+ if (options.verbose)
132
+ (0, output_utils_1.printSuccess)('AWS CDK is installed');
133
+ (0, output_utils_1.printKeyValue)({
134
+ 'CDK Version': green(cdkInfo.version),
135
+ 'Status': green('✓ Available'),
136
+ });
137
+ }
138
+ else {
139
+ if (options.verbose) {
140
+ (0, output_utils_1.printWarning)('AWS CDK is not installed');
141
+ console.log(dim(' Install CDK with: npm install -g aws-cdk'));
142
+ if (cdkInfo.error)
143
+ console.log(dim(` Error: ${cdkInfo.error}`));
144
+ }
145
+ (0, output_utils_1.printKeyValue)({
146
+ 'AWS CDK': red('✗ Not installed'),
147
+ 'Status': red('✗ Not Available'),
148
+ });
149
+ }
150
+ if (!options.verbose) {
151
+ console.log(dim('\n Run with --verbose for detailed environment information'));
152
+ }
153
+ // Configuration check
154
+ if (options.checkConfig) {
155
+ (0, output_utils_1.printDivider)();
156
+ (0, output_utils_1.printSection)('Configuration Status');
157
+ const configStatus = checkConfiguration();
158
+ const envStatus = getEnvironmentStatus();
159
+ if (configStatus.valid) {
160
+ (0, output_utils_1.printSuccess)('Configuration is valid');
161
+ try {
162
+ const config = (0, config_loader_1.getConfig)();
163
+ (0, output_utils_1.printKeyValue)({
164
+ 'API Base URL': config.api.baseUrl,
165
+ 'SSL Verification': config.api.rejectUnauthorized ? green('Enabled') : yellow('Disabled'),
166
+ 'Timeout': `${config.api.timeout}ms`,
167
+ 'Authenticated': config.auth.token ? green('Yes') : red('No'),
168
+ });
169
+ }
170
+ catch (error) {
171
+ (0, output_utils_1.printWarning)('Could not load full configuration');
172
+ }
173
+ }
174
+ else {
175
+ (0, output_utils_1.printError)('Configuration is invalid');
176
+ if (configStatus.error) {
177
+ console.log(red(` Error: ${configStatus.error}`));
178
+ }
179
+ }
180
+ console.log('');
181
+ (0, output_utils_1.printInfo)('Environment Variables');
182
+ (0, output_utils_1.printKeyValue)({
183
+ PLATFORM_TOKEN: envStatus.token ? green('✓ Set') : red('✗ Not set'),
184
+ PLATFORM_BASE_URL: envStatus.url ? green('✓ Set') : dim('(not set - using default)'),
185
+ CLI_CONFIG_PATH: envStatus.configPath ? green('✓ Set') : dim('(not set - using default)'),
186
+ });
187
+ if (!envStatus.token) {
188
+ console.log('');
189
+ (0, output_utils_1.printWarning)('PLATFORM_TOKEN is required for API operations');
190
+ console.log(dim(' Set it with: export PLATFORM_TOKEN="your-token-here"'));
191
+ }
192
+ }
193
+ else {
194
+ console.log(dim('\n 💡 Tip: Run with --check-config to verify configuration'));
195
+ }
196
+ // Footer
197
+ (0, output_utils_1.printDivider)();
198
+ console.log(dim(` Execution ID: ${executionId}`));
199
+ console.log(dim(` Timestamp: ${new Date().toISOString()}`));
200
+ console.log('');
201
+ }
202
+ catch (error) {
203
+ (0, error_handler_1.handleError)(error, error_handler_1.ERROR_CODES.GENERAL, {
204
+ debug: program.opts().debug,
205
+ exit: true,
206
+ context: {
207
+ command: 'version',
208
+ options: {
209
+ verbose: options.verbose,
210
+ checkConfig: options.checkConfig,
211
+ json: options.json,
212
+ },
213
+ },
214
+ });
215
+ }
216
+ });
217
+ // Also support -v and --version flags at root level
218
+ program.on('option:version', () => {
219
+ console.log(`${cli_constants_1.APP_NAME} v${cli_constants_1.APP_VERSION}`);
220
+ process.exit(0);
221
+ });
222
+ }
223
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOzs7OztBQWdHdEMsMEJBMEpDO0FBeFBELGlEQUF5QztBQUV6Qyw0REFBOEI7QUFDOUIsMkRBQXFGO0FBQ3JGLGtEQUFnRDtBQUNoRCwwREFBbUQ7QUFDbkQsMERBQWtFO0FBQ2xFLHdEQUFxSTtBQUVySSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEdBQUcsb0JBQUksQ0FBQztBQWlCOUQ7OztHQUdHO0FBQ0gsU0FBUyxhQUFhO0lBQ3BCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNsQyxNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRCxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNoRixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFaEMsSUFBSSxHQUFrQixDQUFDO0lBQ3ZCLElBQUksQ0FBQztRQUNILEdBQUcsR0FBRyxJQUFBLHdCQUFRLEVBQUMsZUFBZSxFQUFFLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMvRSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsR0FBRyxHQUFHLElBQUksQ0FBQztJQUNi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QUMsQ0FBQztZQUNuRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM3RCxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWxCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBQSwyQkFBVyxFQUFDLEtBQUssRUFBRSwyQkFBVyxDQUFDLE9BQU8sRUFBRTtnQkFDdEMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLO2dCQUMzQixJQUFJLEVBQUUsSUFBSTtnQkFDVixPQUFPLEVBQUU7b0JBQ1AsT0FBTyxFQUFFLFNBQVM7b0JBQ2xCLE9BQU8sRUFBRTt3QkFDUCxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87d0JBQ3hCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVzt3QkFDaEMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJO3FCQUNuQjtpQkFDRjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVMLG9EQUFvRDtJQUNwRCxPQUFPLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtRQUNoQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsd0JBQVEsS0FBSywyQkFBVyxFQUFFLENBQUMsQ0FBQztRQUMzQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBleGVjU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgcGljbyBmcm9tICdwaWNvY29sb3JzJztcbmltcG9ydCB7IEFQUF9OQU1FLCBBUFBfVkVSU0lPTiwgZ2VuZXJhdGVFeGVjdXRpb25JZCB9IGZyb20gJy4uL2NvbmZpZy9jbGkuY29uc3RhbnRzJztcbmltcG9ydCB7IGdldENka0luZm8gfSBmcm9tICcuLi91dGlscy9jZGstdXRpbHMnO1xuaW1wb3J0IHsgZ2V0Q29uZmlnIH0gZnJvbSAnLi4vdXRpbHMvY29uZmlnLWxvYWRlcic7XG5pbXBvcnQgeyBFUlJPUl9DT0RFUywgaGFuZGxlRXJyb3IgfSBmcm9tICcuLi91dGlscy9lcnJvci1oYW5kbGVyJztcbmltcG9ydCB7IHByaW50RGl2aWRlciwgcHJpbnRFcnJvciwgcHJpbnRJbmZvLCBwcmludEtleVZhbHVlLCBwcmludFNlY3Rpb24sIHByaW50U3VjY2VzcywgcHJpbnRXYXJuaW5nIH0gZnJvbSAnLi4vdXRpbHMvb3V0cHV0LXV0aWxzJztcblxuY29uc3QgeyBib2xkLCBjeWFuLCBkaW0sIGdyZWVuLCBtYWdlbnRhLCByZWQsIHllbGxvdyB9ID0gcGljbztcblxuLyoqXG4gKiBSdW50aW1lIHN5c3RlbSBpbmZvcm1hdGlvbiBjb2xsZWN0ZWQgZm9yIHRoZSBgdmVyc2lvbiAtLXZlcmJvc2VgIG91dHB1dC5cbiAqL1xuaW50ZXJmYWNlIFN5c3RlbUluZm8ge1xuICBub2RlanM6IHN0cmluZztcbiAgbnBtOiBzdHJpbmcgfCBudWxsO1xuICBwbGF0Zm9ybTogc3RyaW5nO1xuICBhcmNoaXRlY3R1cmU6IHN0cmluZztcbiAgbWVtb3J5OiB7XG4gICAgdG90YWw6IHN0cmluZztcbiAgICBhdmFpbGFibGVIZWFwOiBzdHJpbmc7XG4gIH07XG4gIHVwdGltZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbGxlY3RzIHJ1bnRpbWUgc3lzdGVtIGluZm9ybWF0aW9uIGluY2x1ZGluZyBOb2RlLmpzL25wbSB2ZXJzaW9ucyxcbiAqIHBsYXRmb3JtLCBhcmNoaXRlY3R1cmUsIGhlYXAgbWVtb3J5IHVzYWdlLCBhbmQgcHJvY2VzcyB1cHRpbWUuXG4gKi9cbmZ1bmN0aW9uIGdldFN5c3RlbUluZm8oKTogU3lzdGVtSW5mbyB7XG4gIGNvbnN0IG1lbSA9IHByb2Nlc3MubWVtb3J5VXNhZ2UoKTtcbiAgY29uc3QgdG90YWxNZW0gPSAobWVtLmhlYXBUb3RhbCAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpO1xuICBjb25zdCBhdmFpbGFibGVIZWFwID0gKChtZW0uaGVhcFRvdGFsIC0gbWVtLmhlYXBVc2VkKSAvIDEwMjQgLyAxMDI0KS50b0ZpeGVkKDIpO1xuICBjb25zdCB1cHRpbWUgPSBwcm9jZXNzLnVwdGltZSgpO1xuXG4gIGxldCBucG06IHN0cmluZyB8IG51bGw7XG4gIHRyeSB7XG4gICAgbnBtID0gZXhlY1N5bmMoJ25wbSAtLXZlcnNpb24nLCB7IGVuY29kaW5nOiAndXRmLTgnLCBzdGRpbzogJ3BpcGUnIH0pLnRyaW0oKTtcbiAgfSBjYXRjaCB7XG4gICAgbnBtID0gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbm9kZWpzOiBwcm9jZXNzLnZlcnNpb24sXG4gICAgbnBtLFxuICAgIHBsYXRmb3JtOiBwcm9jZXNzLnBsYXRmb3JtLFxuICAgIGFyY2hpdGVjdHVyZTogcHJvY2Vzcy5hcmNoLFxuICAgIG1lbW9yeTogeyB0b3RhbDogYCR7dG90YWxNZW19IE1CYCwgYXZhaWxhYmxlSGVhcDogYCR7YXZhaWxhYmxlSGVhcH0gTUJgIH0sXG4gICAgdXB0aW1lOiBgJHtNYXRoLmZsb29yKHVwdGltZSAvIDM2MDApfWggJHtNYXRoLmZsb29yKCh1cHRpbWUgJSAzNjAwKSAvIDYwKX1tICR7TWF0aC5mbG9vcih1cHRpbWUgJSA2MCl9c2AsXG4gIH07XG59XG5cbi8qKlxuICogQXR0ZW1wdHMgdG8gbG9hZCB0aGUgQ0xJIGNvbmZpZ3VyYXRpb24gYW5kIHJlcG9ydHMgd2hldGhlciBpdCBpcyB2YWxpZC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGB2YWxpZDogdHJ1ZWAgb24gc3VjY2Vzcywgb3IgYHZhbGlkOiBmYWxzZWAgd2l0aCBhbiBlcnJvciBtZXNzYWdlLlxuICovXG5mdW5jdGlvbiBjaGVja0NvbmZpZ3VyYXRpb24oKTogeyB2YWxpZDogYm9vbGVhbjsgZXJyb3I/OiBzdHJpbmcgfSB7XG4gIHRyeSB7XG4gICAgZ2V0Q29uZmlnKCk7XG4gICAgcmV0dXJuIHsgdmFsaWQ6IHRydWUgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoaWNoIGtleSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgYXJlIGN1cnJlbnRseSBzZXQuXG4gKiBAcmV0dXJucyBQcmVzZW5jZSBmbGFncyBmb3IgYFBMQVRGT1JNX1RPS0VOYCwgYFBMQVRGT1JNX0JBU0VfVVJMYCwgYW5kIGBDTElfQ09ORklHX1BBVEhgLlxuICovXG5mdW5jdGlvbiBnZXRFbnZpcm9ubWVudFN0YXR1cygpOiB7XG4gIHRva2VuOiBib29sZWFuO1xuICB1cmw6IGJvb2xlYW47XG4gIGNvbmZpZ1BhdGg6IGJvb2xlYW47XG59IHtcbiAgcmV0dXJuIHtcbiAgICB0b2tlbjogISFwcm9jZXNzLmVudi5QTEFURk9STV9UT0tFTixcbiAgICB1cmw6ICEhcHJvY2Vzcy5lbnYuUExBVEZPUk1fQkFTRV9VUkwsXG4gICAgY29uZmlnUGF0aDogISFwcm9jZXNzLmVudi5DTElfQ09ORklHX1BBVEgsXG4gIH07XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIHRoZSBgdmVyc2lvbmAgY29tbWFuZCB3aXRoIHRoZSBDTEkgcHJvZ3JhbS5cbiAqXG4gKiBEaXNwbGF5cyB0aGUgQ0xJIG5hbWUvdmVyc2lvbiwgQVdTIENESyBzdGF0dXMsIGFuZCBvcHRpb25hbGx5XG4gKiBmdWxsIHN5c3RlbSBkaWFnbm9zdGljcyAoYC0tdmVyYm9zZWApIG9yIGNvbmZpZ3VyYXRpb24gdmFsaWRhdGlvblxuICogKGAtLWNoZWNrLWNvbmZpZ2ApLiAgU3VwcG9ydHMgYC0tanNvbmAgZm9yIG1hY2hpbmUtcmVhZGFibGUgb3V0cHV0LlxuICpcbiAqIEBwYXJhbSBwcm9ncmFtIC0gVGhlIHJvb3QgQ29tbWFuZGVyIHByb2dyYW0gaW5zdGFuY2UgdG8gYXR0YWNoIHRoZSBjb21tYW5kIHRvLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyc2lvbihwcm9ncmFtOiBDb21tYW5kKTogdm9pZCB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZCgndmVyc2lvbicpXG4gICAgLmRlc2NyaXB0aW9uKCdEaXNwbGF5IENMSSB2ZXJzaW9uIGFuZCBlbnZpcm9ubWVudCBpbmZvcm1hdGlvbicpXG4gICAgLm9wdGlvbignLS12ZXJib3NlJywgJ1Nob3cgZGV0YWlsZWQgZW52aXJvbm1lbnQgaW5mb3JtYXRpb24nLCBmYWxzZSlcbiAgICAub3B0aW9uKCctLWNoZWNrLWNvbmZpZycsICdWZXJpZnkgY29uZmlndXJhdGlvbiBzdGF0dXMnLCBmYWxzZSlcbiAgICAub3B0aW9uKCctLWpzb24nLCAnT3V0cHV0IGluIEpTT04gZm9ybWF0JywgZmFsc2UpXG4gICAgLmFjdGlvbigob3B0aW9ucykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZXhlY3V0aW9uSWQgPSBnZW5lcmF0ZUV4ZWN1dGlvbklkKCk7XG4gICAgICAgIGNvbnN0IGNka0luZm8gPSBnZXRDZGtJbmZvKCk7XG5cbiAgICAgICAgLy8gSlNPTiBvdXRwdXRcbiAgICAgICAgaWYgKG9wdGlvbnMuanNvbikge1xuICAgICAgICAgIGNvbnN0IHN5c3RlbUluZm8gPSBnZXRTeXN0ZW1JbmZvKCk7XG4gICAgICAgICAgY29uc3QgY29uZmlnU3RhdHVzID0gb3B0aW9ucy5jaGVja0NvbmZpZyA/IGNoZWNrQ29uZmlndXJhdGlvbigpIDogeyB2YWxpZDogdHJ1ZSB9O1xuICAgICAgICAgIGNvbnN0IGVudlN0YXR1cyA9IGdldEVudmlyb25tZW50U3RhdHVzKCk7XG5cbiAgICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBjbGk6IHsgbmFtZTogQVBQX05BTUUsIHZlcnNpb246IEFQUF9WRVJTSU9OIH0sXG4gICAgICAgICAgICBzeXN0ZW06IHN5c3RlbUluZm8sXG4gICAgICAgICAgICBjZGs6IHsgYXZhaWxhYmxlOiBjZGtJbmZvLmF2YWlsYWJsZSwgdmVyc2lvbjogY2RrSW5mby52ZXJzaW9uIH0sXG4gICAgICAgICAgICBjb25maWd1cmF0aW9uOiB7IHZhbGlkOiBjb25maWdTdGF0dXMudmFsaWQsIGVycm9yOiBjb25maWdTdGF0dXMuZXJyb3IgfSxcbiAgICAgICAgICAgIGVudmlyb25tZW50OiBlbnZTdGF0dXMsXG4gICAgICAgICAgICBleGVjdXRpb25JZCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIH0sIG51bGwsIDIpKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdGFuZGFyZCBvdXRwdXRcbiAgICAgICAgcHJpbnRTZWN0aW9uKCdWZXJzaW9uIEluZm9ybWF0aW9uJyk7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke21hZ2VudGEoYFtFWEUtJHtleGVjdXRpb25JZH1dYCl9ICR7Y3lhbihib2xkKCdDTEkgVmVyc2lvbiBDaGVjaycpKX1gKTtcbiAgICAgICAgY29uc29sZS5sb2coJycpO1xuXG4gICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICdDTEkgTmFtZSc6IGJvbGQoQVBQX05BTUUpLFxuICAgICAgICAgICdDTEkgVmVyc2lvbic6IGdyZWVuKGJvbGQoQVBQX1ZFUlNJT04pKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcHJpbnREaXZpZGVyKCk7XG5cbiAgICAgICAgLy8gVmVyYm9zZTogc3lzdGVtIGVudmlyb25tZW50XG4gICAgICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgICBwcmludFNlY3Rpb24oJ1N5c3RlbSBFbnZpcm9ubWVudCcpO1xuICAgICAgICAgIGNvbnN0IHN5c3RlbUluZm8gPSBnZXRTeXN0ZW1JbmZvKCk7XG4gICAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgICAnTm9kZS5qcyc6IHN5c3RlbUluZm8ubm9kZWpzLFxuICAgICAgICAgICAgJ25wbSc6IHN5c3RlbUluZm8ubnBtIHx8IHllbGxvdygnKG5vdCBhdmFpbGFibGUpJyksXG4gICAgICAgICAgICAnUGxhdGZvcm0nOiBzeXN0ZW1JbmZvLnBsYXRmb3JtLFxuICAgICAgICAgICAgJ0FyY2hpdGVjdHVyZSc6IHN5c3RlbUluZm8uYXJjaGl0ZWN0dXJlLFxuICAgICAgICAgICAgJ01lbW9yeSAoSGVhcCknOiBgJHtzeXN0ZW1JbmZvLm1lbW9yeS50b3RhbH0gdG90YWwsICR7c3lzdGVtSW5mby5tZW1vcnkuYXZhaWxhYmxlSGVhcH0gYXZhaWxhYmxlYCxcbiAgICAgICAgICAgICdQcm9jZXNzIFVwdGltZSc6IHN5c3RlbUluZm8udXB0aW1lLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHByaW50RGl2aWRlcigpO1xuICAgICAgICAgIHByaW50U2VjdGlvbignQVdTIENESycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ0RLIGluZm9ybWF0aW9uXG4gICAgICAgIGlmIChjZGtJbmZvLmF2YWlsYWJsZSAmJiBjZGtJbmZvLnZlcnNpb24pIHtcbiAgICAgICAgICBpZiAob3B0aW9ucy52ZXJib3NlKSBwcmludFN1Y2Nlc3MoJ0FXUyBDREsgaXMgaW5zdGFsbGVkJyk7XG4gICAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgICAnQ0RLIFZlcnNpb24nOiBncmVlbihjZGtJbmZvLnZlcnNpb24pLFxuICAgICAgICAgICAgJ1N0YXR1cyc6IGdyZWVuKCfinJMgQXZhaWxhYmxlJyksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgICAgcHJpbnRXYXJuaW5nKCdBV1MgQ0RLIGlzIG5vdCBpbnN0YWxsZWQnKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGRpbSgnICBJbnN0YWxsIENESyB3aXRoOiBucG0gaW5zdGFsbCAtZyBhd3MtY2RrJykpO1xuICAgICAgICAgICAgaWYgKGNka0luZm8uZXJyb3IpIGNvbnNvbGUubG9nKGRpbShgICBFcnJvcjogJHtjZGtJbmZvLmVycm9yfWApKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgICAgICAgICAnQVdTIENESyc6IHJlZCgn4pyXIE5vdCBpbnN0YWxsZWQnKSxcbiAgICAgICAgICAgICdTdGF0dXMnOiByZWQoJ+KclyBOb3QgQXZhaWxhYmxlJyksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGRpbSgnXFxuICBSdW4gd2l0aCAtLXZlcmJvc2UgZm9yIGRldGFpbGVkIGVudmlyb25tZW50IGluZm9ybWF0aW9uJykpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29uZmlndXJhdGlvbiBjaGVja1xuICAgICAgICBpZiAob3B0aW9ucy5jaGVja0NvbmZpZykge1xuICAgICAgICAgIHByaW50RGl2aWRlcigpO1xuICAgICAgICAgIHByaW50U2VjdGlvbignQ29uZmlndXJhdGlvbiBTdGF0dXMnKTtcblxuICAgICAgICAgIGNvbnN0IGNvbmZpZ1N0YXR1cyA9IGNoZWNrQ29uZmlndXJhdGlvbigpO1xuICAgICAgICAgIGNvbnN0IGVudlN0YXR1cyA9IGdldEVudmlyb25tZW50U3RhdHVzKCk7XG5cbiAgICAgICAgICBpZiAoY29uZmlnU3RhdHVzLnZhbGlkKSB7XG4gICAgICAgICAgICBwcmludFN1Y2Nlc3MoJ0NvbmZpZ3VyYXRpb24gaXMgdmFsaWQnKTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgY29uZmlnID0gZ2V0Q29uZmlnKCk7XG4gICAgICAgICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICAgICAgICdBUEkgQmFzZSBVUkwnOiBjb25maWcuYXBpLmJhc2VVcmwsXG4gICAgICAgICAgICAgICAgJ1NTTCBWZXJpZmljYXRpb24nOiBjb25maWcuYXBpLnJlamVjdFVuYXV0aG9yaXplZCA/IGdyZWVuKCdFbmFibGVkJykgOiB5ZWxsb3coJ0Rpc2FibGVkJyksXG4gICAgICAgICAgICAgICAgJ1RpbWVvdXQnOiBgJHtjb25maWcuYXBpLnRpbWVvdXR9bXNgLFxuICAgICAgICAgICAgICAgICdBdXRoZW50aWNhdGVkJzogY29uZmlnLmF1dGgudG9rZW4gPyBncmVlbignWWVzJykgOiByZWQoJ05vJyksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgcHJpbnRXYXJuaW5nKCdDb3VsZCBub3QgbG9hZCBmdWxsIGNvbmZpZ3VyYXRpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcHJpbnRFcnJvcignQ29uZmlndXJhdGlvbiBpcyBpbnZhbGlkJyk7XG4gICAgICAgICAgICBpZiAoY29uZmlnU3RhdHVzLmVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlZChgICBFcnJvcjogJHtjb25maWdTdGF0dXMuZXJyb3J9YCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgICBwcmludEluZm8oJ0Vudmlyb25tZW50IFZhcmlhYmxlcycpO1xuICAgICAgICAgIHByaW50S2V5VmFsdWUoe1xuICAgICAgICAgICAgUExBVEZPUk1fVE9LRU46IGVudlN0YXR1cy50b2tlbiA/IGdyZWVuKCfinJMgU2V0JykgOiByZWQoJ+KclyBOb3Qgc2V0JyksXG4gICAgICAgICAgICBQTEFURk9STV9CQVNFX1VSTDogZW52U3RhdHVzLnVybCA/IGdyZWVuKCfinJMgU2V0JykgOiBkaW0oJyhub3Qgc2V0IC0gdXNpbmcgZGVmYXVsdCknKSxcbiAgICAgICAgICAgIENMSV9DT05GSUdfUEFUSDogZW52U3RhdHVzLmNvbmZpZ1BhdGggPyBncmVlbign4pyTIFNldCcpIDogZGltKCcobm90IHNldCAtIHVzaW5nIGRlZmF1bHQpJyksXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoIWVudlN0YXR1cy50b2tlbikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJycpO1xuICAgICAgICAgICAgcHJpbnRXYXJuaW5nKCdQTEFURk9STV9UT0tFTiBpcyByZXF1aXJlZCBmb3IgQVBJIG9wZXJhdGlvbnMnKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGRpbSgnICBTZXQgaXQgd2l0aDogZXhwb3J0IFBMQVRGT1JNX1RPS0VOPVwieW91ci10b2tlbi1oZXJlXCInKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGRpbSgnXFxuICDwn5KhIFRpcDogUnVuIHdpdGggLS1jaGVjay1jb25maWcgdG8gdmVyaWZ5IGNvbmZpZ3VyYXRpb24nKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb290ZXJcbiAgICAgICAgcHJpbnREaXZpZGVyKCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGRpbShgICBFeGVjdXRpb24gSUQ6ICR7ZXhlY3V0aW9uSWR9YCkpO1xuICAgICAgICBjb25zb2xlLmxvZyhkaW0oYCAgVGltZXN0YW1wOiAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX1gKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKCcnKTtcblxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IsIEVSUk9SX0NPREVTLkdFTkVSQUwsIHtcbiAgICAgICAgICBkZWJ1ZzogcHJvZ3JhbS5vcHRzKCkuZGVidWcsXG4gICAgICAgICAgZXhpdDogdHJ1ZSxcbiAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICBjb21tYW5kOiAndmVyc2lvbicsXG4gICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgIHZlcmJvc2U6IG9wdGlvbnMudmVyYm9zZSxcbiAgICAgICAgICAgICAgY2hlY2tDb25maWc6IG9wdGlvbnMuY2hlY2tDb25maWcsXG4gICAgICAgICAgICAgIGpzb246IG9wdGlvbnMuanNvbixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgLy8gQWxzbyBzdXBwb3J0IC12IGFuZCAtLXZlcnNpb24gZmxhZ3MgYXQgcm9vdCBsZXZlbFxuICBwcm9ncmFtLm9uKCdvcHRpb246dmVyc2lvbicsICgpID0+IHtcbiAgICBjb25zb2xlLmxvZyhgJHtBUFBfTkFNRX0gdiR7QVBQX1ZFUlNJT059YCk7XG4gICAgcHJvY2Vzcy5leGl0KDApO1xuICB9KTtcbn1cbiJdfQ==