@nikovirtala/projen-constructs 0.1.4 → 0.1.6

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 (35) hide show
  1. package/.jsii +223 -203
  2. package/API.md +52 -28
  3. package/lib/components/mise.js +4 -2
  4. package/lib/components/vitest.js +1 -1
  5. package/lib/config.d.ts +20 -7
  6. package/lib/config.js +28 -16
  7. package/lib/errors.d.ts +20 -0
  8. package/lib/errors.js +36 -0
  9. package/lib/projects/awscdk-construct-library-options.generated.d.ts +7 -7
  10. package/lib/projects/awscdk-construct-library-options.generated.js +1 -1
  11. package/lib/projects/{awscdk-construct-library.d.ts → awscdk-construct-library.generated.d.ts} +8 -0
  12. package/lib/projects/awscdk-construct-library.generated.js +33 -0
  13. package/lib/projects/awscdk-typescript-app-options.generated.d.ts +31 -31
  14. package/lib/projects/awscdk-typescript-app-options.generated.js +1 -1
  15. package/lib/projects/{awscdk-typescript-app.d.ts → awscdk-typescript-app.generated.d.ts} +8 -0
  16. package/lib/projects/awscdk-typescript-app.generated.js +33 -0
  17. package/lib/projects/index.d.ts +4 -4
  18. package/lib/projects/index.js +5 -5
  19. package/lib/projects/jsii-options.generated.d.ts +7 -7
  20. package/lib/projects/jsii-options.generated.js +1 -1
  21. package/lib/projects/{jsii.d.ts → jsii.generated.d.ts} +8 -0
  22. package/lib/projects/jsii.generated.js +33 -0
  23. package/lib/projects/typescript-options.generated.d.ts +7 -7
  24. package/lib/projects/typescript-options.generated.js +1 -1
  25. package/lib/projects/{typescript.d.ts → typescript.generated.d.ts} +8 -0
  26. package/lib/projects/typescript.generated.js +33 -0
  27. package/lib/projen-project-generator.d.ts +173 -0
  28. package/lib/projen-project-generator.js +509 -0
  29. package/package.json +1 -1
  30. package/lib/projects/awscdk-app-options.generated.d.ts +0 -1098
  31. package/lib/projects/awscdk-app-options.generated.js +0 -3
  32. package/lib/projects/awscdk-construct-library.js +0 -19
  33. package/lib/projects/awscdk-typescript-app.js +0 -19
  34. package/lib/projects/jsii.js +0 -19
  35. package/lib/projects/typescript.js +0 -19
@@ -0,0 +1,509 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProjenProjectGenerator = void 0;
4
+ const jsii_struct_builder_1 = require("@mrgrain/jsii-struct-builder");
5
+ const projen_1 = require("projen");
6
+ const errors_1 = require("./errors");
7
+ /**
8
+ * Default components applied to all generated projects
9
+ */
10
+ const DEFAULT_COMPONENTS = [
11
+ { component: require("./components/mise").Mise },
12
+ {
13
+ component: require("./components/vitest").Vitest,
14
+ optionsProperty: {
15
+ name: "vitestOptions",
16
+ type: "@nikovirtala/projen-constructs.VitestOptions",
17
+ docs: "Vitest configuration",
18
+ },
19
+ },
20
+ ];
21
+ /**
22
+ * Buffer for building indented code with automatic line management
23
+ *
24
+ * Maintains indentation level and provides methods for adding lines,
25
+ * opening/closing blocks, and flushing accumulated content.
26
+ */
27
+ class CodeBuffer {
28
+ /**
29
+ * @param indent - String to use for each indentation level (default: single space)
30
+ */
31
+ constructor(indent = " ") {
32
+ this.indent = indent;
33
+ this.lines = [];
34
+ this.indentLevel = 0;
35
+ }
36
+ /**
37
+ * Returns all accumulated lines and resets the buffer
38
+ *
39
+ * @returns Array of code lines with proper indentation
40
+ */
41
+ flush() {
42
+ const current = this.lines;
43
+ this.reset();
44
+ return current;
45
+ }
46
+ /**
47
+ * Adds a line of code at the current indentation level
48
+ *
49
+ * @param code - Code to add (optional, adds blank line if omitted)
50
+ */
51
+ line(code) {
52
+ const prefix = this.indent.repeat(this.indentLevel);
53
+ this.lines.push((prefix + (code ?? "")).trimEnd());
54
+ }
55
+ /**
56
+ * Opens a new indentation block
57
+ *
58
+ * @param code - Optional code to add before increasing indent (e.g., opening brace)
59
+ */
60
+ open(code) {
61
+ if (code) {
62
+ this.line(code);
63
+ }
64
+ this.indentLevel++;
65
+ }
66
+ /**
67
+ * Closes the current indentation block
68
+ *
69
+ * @param code - Optional code to add after decreasing indent (e.g., closing brace)
70
+ * @throws {InvalidIndentLevelError} When attempting to decrease indent below zero
71
+ */
72
+ close(code) {
73
+ if (this.indentLevel === 0) {
74
+ throw new errors_1.InvalidIndentLevelError();
75
+ }
76
+ this.indentLevel--;
77
+ if (code) {
78
+ this.line(code);
79
+ }
80
+ }
81
+ /**
82
+ * Resets the buffer to initial state
83
+ */
84
+ reset() {
85
+ this.lines = [];
86
+ this.indentLevel = 0;
87
+ }
88
+ }
89
+ /**
90
+ * Renders TypeScript class code from ProjenProjectGenerator options
91
+ *
92
+ * Generates a complete TypeScript class file including imports, options interface export,
93
+ * class declaration, and constructor with component integration.
94
+ */
95
+ class TypeScriptClassRenderer {
96
+ /**
97
+ * @param indent - Number of spaces per indentation level (default: 4)
98
+ */
99
+ constructor(indent = 4) {
100
+ this.buffer = new CodeBuffer(" ".repeat(indent));
101
+ }
102
+ /**
103
+ * Renders complete TypeScript class code from options
104
+ *
105
+ * Orchestrates the rendering process: derives names, extracts component configuration,
106
+ * builds import statements, and renders the class structure.
107
+ *
108
+ * @param options - Generator configuration
109
+ * @returns Complete TypeScript class code as a string
110
+ */
111
+ render(options) {
112
+ this.buffer.flush();
113
+ /* Derive interface and type names from the class name */
114
+ const optionsInterface = `${options.name}Options`;
115
+ const baseOptionsFqn = this.getBaseOptionsFqn(options.baseClass);
116
+ const baseOptionsType = baseOptionsFqn.replace(/^projen\./, "");
117
+ /* Use provided components or fall back to defaults (Mise + Vitest) */
118
+ const components = options.components ?? DEFAULT_COMPONENTS;
119
+ /* Extract component configuration for constructor generation */
120
+ const { destructure, componentArray } = this.extractComponentOptions(components);
121
+ const imports = this.extractImports(options, optionsInterface);
122
+ /* Render all sections of the class file */
123
+ this.renderImports(imports);
124
+ this.buffer.line();
125
+ this.renderExport(optionsInterface);
126
+ this.buffer.line();
127
+ this.renderClass(options, optionsInterface, baseOptionsType, destructure, componentArray);
128
+ this.buffer.line();
129
+ return this.buffer.flush().join("\n");
130
+ }
131
+ /**
132
+ * Derives the fully qualified options interface name from base class
133
+ *
134
+ * Transforms base class reference into the corresponding Projen options interface name
135
+ * by appending "Options" suffix and prefixing with "projen." namespace.
136
+ *
137
+ * @param baseClass - Base class in format "module.ClassName"
138
+ * @returns Fully qualified options interface name
139
+ * @throws {InvalidBaseClassFormatError} When baseClass format is invalid
140
+ *
141
+ * @example
142
+ * getBaseOptionsFqn("typescript.TypeScriptProject") // "projen.typescript.TypeScriptProjectOptions"
143
+ * getBaseOptionsFqn("cdk.JsiiProject") // "projen.cdk.JsiiProjectOptions"
144
+ */
145
+ getBaseOptionsFqn(baseClass) {
146
+ /* Validate base class format: must contain module.ClassName structure */
147
+ if (!baseClass.includes(".")) {
148
+ throw new errors_1.InvalidBaseClassFormatError(baseClass);
149
+ }
150
+ return `projen.${baseClass}Options`;
151
+ }
152
+ /**
153
+ * Extracts component configuration for constructor code generation
154
+ *
155
+ * Transforms component configurations into:
156
+ * 1. Destructure list: variable names to extract from options
157
+ * 2. Component array: code string for applyDefaults() call
158
+ *
159
+ * @param components - Component configurations
160
+ * @returns Object with destructure array and componentArray code string
161
+ *
162
+ * @example
163
+ * Input: [{ component: Vitest, optionsProperty: { name: "vitestOptions", ... } }]
164
+ * Output: {
165
+ * destructure: ["vitest", "vitestOptions"],
166
+ * componentArray: "[{ component: Vitest, enabled: vitest, options: vitestOptions }]"
167
+ * }
168
+ */
169
+ extractComponentOptions(components) {
170
+ const destructure = [];
171
+ const componentParts = [];
172
+ for (const c of components) {
173
+ /* Convert component class name to camelCase variable name (e.g., Vitest -> vitest) */
174
+ const name = c.component.name.charAt(0).toLowerCase() + c.component.name.slice(1);
175
+ destructure.push(name);
176
+ /* Build component config object for applyDefaults() call */
177
+ const parts = [`component: ${c.component.name}`];
178
+ if (c.optionsProperty) {
179
+ /* Component has configurable options - include both enabled flag and options */
180
+ destructure.push(c.optionsProperty.name);
181
+ parts.push(`enabled: ${name}`, `options: ${c.optionsProperty.name}`);
182
+ }
183
+ else {
184
+ /* Component has no options - only include enabled flag */
185
+ parts.push(`enabled: ${name}`);
186
+ }
187
+ componentParts.push(`{ ${parts.join(", ")} }`);
188
+ }
189
+ return { destructure, componentArray: `[${componentParts.join(", ")}]` };
190
+ }
191
+ /**
192
+ * Builds import statements map for the generated class
193
+ *
194
+ * Collects all required imports:
195
+ * - Projen base module (typescript, cdk, awscdk)
196
+ * - Config utilities (applyDefaults, defaultOptions)
197
+ * - Component classes
198
+ * - Utility functions (deepMerge)
199
+ * - Generated options interface (type-only import)
200
+ *
201
+ * @param options - Generator configuration
202
+ * @param optionsInterface - Name of the generated options interface
203
+ * @returns Map of module paths to sets of imported names
204
+ */
205
+ extractImports(options, optionsInterface) {
206
+ const imports = new Map();
207
+ /* Extract base module name from baseClass (e.g., "typescript" from "typescript.TypeScriptProject") */
208
+ const baseModule = options.baseClass.split(".")[0];
209
+ const optionsFileName = this.getOptionsFileName(optionsInterface);
210
+ /* Projen base module import */
211
+ imports.set("projen", new Set([baseModule]));
212
+ /* Configuration utilities import */
213
+ imports.set("../config", new Set(["applyDefaults", "defaultOptions"]));
214
+ /* Component class imports - derive module path from component class name */
215
+ const components = options.components ?? DEFAULT_COMPONENTS;
216
+ for (const c of components) {
217
+ const componentName = c.component.name;
218
+ const modulePath = `../components/${componentName.toLowerCase()}`;
219
+ if (!imports.has(modulePath)) {
220
+ imports.set(modulePath, new Set());
221
+ }
222
+ const moduleImports = imports.get(modulePath);
223
+ if (moduleImports) {
224
+ moduleImports.add(componentName);
225
+ }
226
+ }
227
+ /* Utility functions import */
228
+ imports.set("../utils", new Set(["deepMerge"]));
229
+ /* Generated options interface import (type-only to avoid circular dependencies) */
230
+ imports.set(`./${optionsFileName}.generated`, new Set([optionsInterface]));
231
+ return imports;
232
+ }
233
+ /**
234
+ * Derives the config path for accessing default options
235
+ *
236
+ * Transforms base class reference into the corresponding path in the defaultOptions
237
+ * configuration object exported from config.ts.
238
+ *
239
+ * @param baseClass - Base class in format "module.ClassName"
240
+ * @returns Config path for accessing default options
241
+ *
242
+ * @example
243
+ * getConfigPath("typescript.TypeScriptProject") // "defaultOptions.typescript.TypeScriptProject"
244
+ */
245
+ getConfigPath(baseClass) {
246
+ return `defaultOptions.${baseClass}`;
247
+ }
248
+ /**
249
+ * Renders import statements in sorted order
250
+ *
251
+ * Sorts imports with external packages first, then relative imports.
252
+ * Uses type-only imports for generated files to avoid circular dependencies.
253
+ *
254
+ * @param imports - Map of module paths to imported names
255
+ */
256
+ renderImports(imports) {
257
+ /* Sort modules: external packages first, then relative imports alphabetically */
258
+ const sortedModules = Array.from(imports.keys()).sort((a, b) => {
259
+ const aIsRelative = a.startsWith(".");
260
+ const bIsRelative = b.startsWith(".");
261
+ if (aIsRelative !== bIsRelative) {
262
+ return aIsRelative ? 1 : -1;
263
+ }
264
+ return a.localeCompare(b);
265
+ });
266
+ for (const mod of sortedModules) {
267
+ const names = Array.from(imports.get(mod) || []).sort();
268
+ /* Use type-only import for generated files to prevent circular dependencies */
269
+ const isTypeOnly = mod.includes(".generated");
270
+ const importStmt = isTypeOnly ? "import type" : "import";
271
+ this.buffer.line(`${importStmt} { ${names.join(", ")} } from "${mod}";`);
272
+ }
273
+ }
274
+ /**
275
+ * Renders re-export statement for the generated options interface
276
+ *
277
+ * @param optionsInterface - Name of the options interface to export
278
+ */
279
+ renderExport(optionsInterface) {
280
+ const optionsFileName = this.getOptionsFileName(optionsInterface);
281
+ this.buffer.line();
282
+ this.buffer.line(`export { ${optionsInterface} } from "./${optionsFileName}.generated";`);
283
+ }
284
+ /**
285
+ * Renders the class declaration and constructor
286
+ *
287
+ * @param options - Generator configuration
288
+ * @param optionsInterface - Name of the options interface
289
+ * @param baseOptionsType - Base options type without "projen." prefix
290
+ * @param destructure - Variable names to destructure from options
291
+ * @param componentArray - Code string for component array
292
+ */
293
+ renderClass(options, optionsInterface, baseOptionsType, destructure, componentArray) {
294
+ this.buffer.line();
295
+ this.buffer.line("/**");
296
+ this.buffer.line(` * ${options.name} with standard configuration and component integration`);
297
+ this.buffer.line(" *");
298
+ this.buffer.line(" * Extends Projen's base class with opinionated defaults and automatic component setup.");
299
+ this.buffer.line(" */");
300
+ this.buffer.open(`export class ${options.name} extends ${options.baseClass} {`);
301
+ this.renderConstructor(options, optionsInterface, baseOptionsType, destructure, componentArray);
302
+ this.buffer.close("}");
303
+ }
304
+ /**
305
+ * Renders the constructor implementation
306
+ *
307
+ * The constructor:
308
+ * 1. Destructures component flags and options from the options parameter
309
+ * 2. Merges default configuration with user-provided options
310
+ * 3. Calls super() with merged options
311
+ * 4. Applies component defaults via applyDefaults()
312
+ *
313
+ * @param options - Generator configuration
314
+ * @param optionsInterface - Name of the options interface
315
+ * @param baseOptionsType - Base options type without "projen." prefix
316
+ * @param destructure - Variable names to destructure from options
317
+ * @param componentArray - Code string for component array
318
+ */
319
+ renderConstructor(options, optionsInterface, baseOptionsType, destructure, componentArray) {
320
+ const configPath = this.getConfigPath(options.baseClass);
321
+ this.buffer.line("/**");
322
+ this.buffer.line(" * @param options - Project configuration");
323
+ this.buffer.line(" */");
324
+ this.buffer.open(`constructor(options: ${optionsInterface}) {`);
325
+ this.buffer.line("/* Separate component configuration from base Projen options */");
326
+ this.buffer.line(`const { ${destructure.join(", ")}, ...baseOptions } = options;`);
327
+ this.buffer.line();
328
+ this.buffer.line("/* Merge default configuration with user options and initialize base class */");
329
+ this.buffer.line(`super(deepMerge<${baseOptionsType}>(${configPath}, baseOptions));`);
330
+ this.buffer.line();
331
+ this.buffer.line("/* Apply component defaults and instantiate enabled components */");
332
+ this.buffer.line(`applyDefaults(this, ${componentArray});`);
333
+ this.buffer.close("}");
334
+ }
335
+ /**
336
+ * Maps options interface name to file name
337
+ *
338
+ * Converts PascalCase interface names to kebab-case file names.
339
+ * Falls back to lowercase conversion for unmapped interfaces.
340
+ *
341
+ * @param optionsInterface - Options interface name
342
+ * @returns Kebab-case file name without extension
343
+ *
344
+ * @example
345
+ * getOptionsFileName("TypeScriptProjectOptions") // "typescript-options"
346
+ */
347
+ getOptionsFileName(optionsInterface) {
348
+ const mapping = {
349
+ TypeScriptProjectOptions: "typescript-options",
350
+ JsiiProjectOptions: "jsii-options",
351
+ AwsCdkTypeScriptAppProjectOptions: "awscdk-typescript-app-options",
352
+ AwsCdkConstructLibraryProjectOptions: "awscdk-construct-library-options",
353
+ };
354
+ return mapping[optionsInterface] || optionsInterface.toLowerCase();
355
+ }
356
+ }
357
+ /**
358
+ * Projen component that generates TypeScript project classes with standard configuration
359
+ *
360
+ * This component automates the creation of project classes that extend Projen base classes
361
+ * with opinionated defaults and component integration. It generates both:
362
+ * 1. An options interface (via ProjenStruct) that extends the base Projen options
363
+ * 2. A project class that applies default configuration and instantiates components
364
+ *
365
+ * The generated code follows a consistent pattern:
366
+ * - Imports required modules and components
367
+ * - Re-exports the generated options interface
368
+ * - Defines a class extending the Projen base class
369
+ * - Constructor merges defaults with user options and applies components
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * new ProjenProjectGenerator(project, {
374
+ * name: "TypeScriptProject",
375
+ * baseClass: "typescript.TypeScriptProject",
376
+ * filePath: "src/projects/typescript.generated.ts",
377
+ * components: [{ component: Vitest, optionsProperty: "vitestOptions" }]
378
+ * });
379
+ * ```
380
+ */
381
+ class ProjenProjectGenerator extends projen_1.Component {
382
+ /**
383
+ * @param project - Projen project instance
384
+ * @param options - Generator configuration
385
+ */
386
+ constructor(project, options) {
387
+ super(project);
388
+ this.options = options;
389
+ this.renderer = new TypeScriptClassRenderer();
390
+ /* Generate the options interface using ProjenStruct for JSII compatibility */
391
+ const optionsInterface = `${options.name}Options`;
392
+ const baseOptionsFqn = this.renderer.getBaseOptionsFqn(options.baseClass);
393
+ const optionsFilePath = this.getOptionsFilePath(optionsInterface);
394
+ /* ProjenStruct generates a concrete TypeScript interface from Projen's options
395
+ * This is necessary because JSII doesn't support TypeScript utility types like Omit<>
396
+ * The generated interface can be consumed by other languages (Python, Java, C#, Go) */
397
+ const struct = new jsii_struct_builder_1.ProjenStruct(this.asTypeScriptProject(project), {
398
+ name: optionsInterface,
399
+ filePath: optionsFilePath,
400
+ outputFileOptions: { readonly: true },
401
+ })
402
+ .mixin(jsii_struct_builder_1.Struct.fromFqn(baseOptionsFqn))
403
+ .withoutDeprecated();
404
+ /* Remove specified options from the base interface */
405
+ if (options.omitOptions) {
406
+ struct.omit(...options.omitOptions);
407
+ }
408
+ /* Add component-derived options to the interface */
409
+ const components = options.components ?? DEFAULT_COMPONENTS;
410
+ const { PrimitiveType } = require("@jsii/spec");
411
+ for (const c of components) {
412
+ const name = c.component.name.charAt(0).toLowerCase() + c.component.name.slice(1);
413
+ /* Add enabled flag for the component */
414
+ struct.add({
415
+ name,
416
+ type: { primitive: PrimitiveType.Boolean },
417
+ optional: true,
418
+ docs: {
419
+ summary: `Enable ${c.component.name} component`,
420
+ default: "true",
421
+ },
422
+ });
423
+ /* Add options property if component is configurable */
424
+ if (c.optionsProperty) {
425
+ struct.add({
426
+ name: c.optionsProperty.name,
427
+ type: { fqn: c.optionsProperty.type },
428
+ optional: true,
429
+ docs: {
430
+ summary: c.optionsProperty.docs ?? `${c.component.name} configuration`,
431
+ default: `- default ${c.component.name} configuration`,
432
+ },
433
+ });
434
+ }
435
+ }
436
+ /* Add custom options to the interface */
437
+ if (options.additionalOptions) {
438
+ struct.add(...options.additionalOptions);
439
+ }
440
+ }
441
+ /**
442
+ * Casts project to TypeScript project type
443
+ *
444
+ * ProjenStruct requires a TypeScriptProject instance. This generator is only used
445
+ * within TypeScript projects, so the cast is safe in practice.
446
+ *
447
+ * Note: Type assertion is necessary here because Projen's type system doesn't provide
448
+ * a runtime type guard for TypeScriptProject.
449
+ *
450
+ * @param project - Projen project instance
451
+ * @returns TypeScript project instance
452
+ */
453
+ asTypeScriptProject(project) {
454
+ return project;
455
+ }
456
+ /**
457
+ * Derives the file path for the generated options interface
458
+ *
459
+ * Places the options interface file in the same directory as the class file
460
+ * with a ".generated.ts" suffix.
461
+ *
462
+ * @param optionsInterface - Name of the options interface
463
+ * @returns File path for the options interface
464
+ * @throws {InvalidFilePathError} When filePath doesn't contain a directory separator
465
+ */
466
+ getOptionsFilePath(optionsInterface) {
467
+ const lastSlash = this.options.filePath.lastIndexOf("/");
468
+ if (lastSlash === -1) {
469
+ throw new errors_1.InvalidFilePathError(this.options.filePath);
470
+ }
471
+ const dir = this.options.filePath.substring(0, lastSlash);
472
+ const optionsFileName = this.renderer.getOptionsFileName(optionsInterface);
473
+ return `${dir}/${optionsFileName}.generated.ts`;
474
+ }
475
+ /**
476
+ * Generates the TypeScript class file during Projen synthesis
477
+ *
478
+ * Called by Projen during the synthesis phase to generate the project class file.
479
+ * The file is marked as readonly to prevent manual editing.
480
+ */
481
+ preSynthesize() {
482
+ const content = this.renderer.render(this.options);
483
+ new TypeScriptClassFile(this.project, this.options.filePath, content, {
484
+ readonly: this.options.readonly ?? true,
485
+ });
486
+ }
487
+ }
488
+ exports.ProjenProjectGenerator = ProjenProjectGenerator;
489
+ /**
490
+ * Text file for generated TypeScript class code
491
+ *
492
+ * Extends Projen's TextFile to add the generated file marker comment
493
+ * at the beginning of the file.
494
+ */
495
+ class TypeScriptClassFile extends projen_1.TextFile {
496
+ /**
497
+ * @param project - Projen project instance
498
+ * @param filePath - Output file path
499
+ * @param content - TypeScript class code
500
+ * @param options - Source code options (readonly, etc.)
501
+ */
502
+ constructor(project, filePath, content, options = {}) {
503
+ super(project, filePath, options);
504
+ /* Add generated file marker to prevent manual editing */
505
+ this.addLine(`// ${this.marker}`);
506
+ this.addLine(content);
507
+ }
508
+ }
509
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvamVuLXByb2plY3QtZ2VuZXJhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Byb2plbi1wcm9qZWN0LWdlbmVyYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxzRUFBb0U7QUFFcEUsbUNBQTZDO0FBQzdDLHFDQUFzRztBQUt0Rzs7R0FFRztBQUNILE1BQU0sa0JBQWtCLEdBQXNCO0lBQzFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLElBQUksRUFBRTtJQUNoRDtRQUNJLFNBQVMsRUFBRSxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQyxNQUFNO1FBQ2hELGVBQWUsRUFBRTtZQUNiLElBQUksRUFBRSxlQUFlO1lBQ3JCLElBQUksRUFBRSw4Q0FBOEM7WUFDcEQsSUFBSSxFQUFFLHNCQUFzQjtTQUMvQjtLQUNKO0NBQ0osQ0FBQztBQW9IRjs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVTtJQUlaOztPQUVHO0lBQ0gsWUFBNkIsU0FBUyxHQUFHO1FBQVosV0FBTSxHQUFOLE1BQU0sQ0FBTTtRQU5qQyxVQUFLLEdBQWEsRUFBRSxDQUFDO1FBQ3JCLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO0lBS29CLENBQUM7SUFFN0M7Ozs7T0FJRztJQUNILEtBQUs7UUFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQzNCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNiLE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsSUFBSSxDQUFDLElBQWE7UUFDZCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxP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QUFRLENBQUMsQ0FBQztRQUMxRCxDQUFDO1FBRUQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMxRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDM0UsT0FBTyxHQUFHLEdBQUcsSUFBSSxlQUFlLGVBQWUsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxhQUFhO1FBQ1QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRW5ELElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUU7WUFDbEUsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLElBQUk7U0FDMUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztDQUNKO0FBM0hELHdEQTJIQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxtQkFBb0IsU0FBUSxpQkFBUTtJQUN0Qzs7Ozs7T0FLRztJQUNILFlBQVksT0FBZ0IsRUFBRSxRQUFnQixFQUFFLE9BQWUsRUFBRSxVQUE2QixFQUFFO1FBQzVGLEtBQUssQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLHlEQUF5RDtRQUN6RCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxQixDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFByb3BlcnR5IH0gZnJvbSBcIkBqc2lpL3NwZWNcIjtcbmltcG9ydCB7IFByb2plblN0cnVjdCwgU3RydWN0IH0gZnJvbSBcIkBtcmdyYWluL2pzaWktc3RydWN0LWJ1aWxkZXJcIjtcbmltcG9ydCB0eXBlIHsgUHJvamVjdCwgU291cmNlQ29kZU9wdGlvbnMsIHR5cGVzY3JpcHQgfSBmcm9tIFwicHJvamVuXCI7XG5pbXBvcnQgeyBDb21wb25lbnQsIFRleHRGaWxlIH0gZnJvbSBcInByb2plblwiO1xuaW1wb3J0IHsgSW52YWxpZEJhc2VDbGFzc0Zvcm1hdEVycm9yLCBJbnZhbGlkRmlsZVBhdGhFcnJvciwgSW52YWxpZEluZGVudExldmVsRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxudHlwZSBQcm9qZW5Nb2R1bGUgPSBcInR5cGVzY3JpcHRcIiB8IFwiY2RrXCIgfCBcImF3c2Nka1wiO1xudHlwZSBQcm9qZW5CYXNlQ2xhc3M8TSBleHRlbmRzIFByb2plbk1vZHVsZT4gPSBgJHtNfS4ke3N0cmluZ31gO1xuXG4vKipcbiAqIERlZmF1bHQgY29tcG9uZW50cyBhcHBsaWVkIHRvIGFsbCBnZW5lcmF0ZWQgcHJvamVjdHNcbiAqL1xuY29uc3QgREVGQVVMVF9DT01QT05FTlRTOiBDb21wb25lbnRDb25maWdbXSA9IFtcbiAgICB7IGNvbXBvbmVudDogcmVxdWlyZShcIi4vY29tcG9uZW50cy9taXNlXCIpLk1pc2UgfSxcbiAgICB7XG4gICAgICAgIGNvbXBvbmVudDogcmVxdWlyZShcIi4vY29tcG9uZW50cy92aXRlc3RcIikuVml0ZXN0LFxuICAgICAgICBvcHRpb25zUHJvcGVydHk6IHtcbiAgICAgICAgICAgIG5hbWU6IFwidml0ZXN0T3B0aW9uc1wiLFxuICAgICAgICAgICAgdHlwZTogXCJAbmlrb3ZpcnRhbGEvcHJvamVuLWNvbnN0cnVjdHMuVml0ZXN0T3B0aW9uc1wiLFxuICAgICAgICAgICAgZG9jczogXCJWaXRlc3QgY29uZmlndXJhdGlvblwiLFxuICAgICAgICB9LFxuICAgIH0sXG5dO1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIGEgY29tcG9uZW50IHRvIGJlIGludGVncmF0ZWQgaW50byBhIGdlbmVyYXRlZCBwcm9qZWN0XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IGNvbmZpZzogQ29tcG9uZW50Q29uZmlnID0ge1xuICogICBjb21wb25lbnQ6IFZpdGVzdCxcbiAqICAgb3B0aW9uc1Byb3BlcnR5OiBcInZpdGVzdE9wdGlvbnNcIlxuICogfTtcbiAqIGBgYFxuICovXG5pbnRlcmZhY2UgQ29tcG9uZW50Q29uZmlnPFQgZXh0ZW5kcyBDb21wb25lbnQgPSBDb21wb25lbnQ+IHtcbiAgICAvKipcbiAgICAgKiBDb21wb25lbnQgY2xhc3MgY29uc3RydWN0b3JcbiAgICAgKi9cbiAgICByZWFkb25seSBjb21wb25lbnQ6IG5ldyAoXG4gICAgICAgIHByb2plY3Q6IG5ldmVyLFxuICAgICAgICBvcHRpb25zPzogbmV2ZXIsXG4gICAgKSA9PiBUO1xuXG4gICAgLyoqXG4gICAgICogT3B0aW9ucyBwcm9wZXJ0eSBjb25maWd1cmF0aW9uIGZvciB0aGUgZ2VuZXJhdGVkIG9wdGlvbnMgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBXaGVuIHNwZWNpZmllZCwgYWRkcyBhbiBvcHRpb25zIHByb3BlcnR5IHRvIHRoZSBpbnRlcmZhY2UgYWxsb3dpbmdcbiAgICAgKiB1c2VycyB0byBjb25maWd1cmUgdGhlIGNvbXBvbmVudC5cbiAgICAgKi9cbiAgICByZWFkb25seSBvcHRpb25zUHJvcGVydHk/OiB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOYW1lIG9mIHRoZSBvcHRpb25zIHByb3BlcnR5IChlLmcuLCBcInZpdGVzdE9wdGlvbnNcIilcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZ1bGx5IHF1YWxpZmllZCB0eXBlIG5hbWUgKGUuZy4sIFwiQG5pa292aXJ0YWxhL3Byb2plbi1jb25zdHJ1Y3RzLlZpdGVzdE9wdGlvbnNcIilcbiAgICAgICAgICovXG4gICAgICAgIHJlYWRvbmx5IHR5cGU6IHN0cmluZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERvY3VtZW50YXRpb24gc3VtbWFyeVxuICAgICAgICAgKi9cbiAgICAgICAgcmVhZG9ubHkgZG9jcz86IHN0cmluZztcbiAgICB9O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIFByb2plblByb2plY3RHZW5lcmF0b3IgY29tcG9uZW50XG4gKlxuICogQ29uZmlndXJlcyB0aGUgZ2VuZXJhdGlvbiBvZiBhIFR5cGVTY3JpcHQgcHJvamVjdCBjbGFzcyB0aGF0IGV4dGVuZHMgYSBQcm9qZW4gYmFzZSBjbGFzc1xuICogd2l0aCBzdGFuZGFyZCBjb25maWd1cmF0aW9uIGFuZCBjb21wb25lbnQgaW50ZWdyYXRpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIG5ldyBQcm9qZW5Qcm9qZWN0R2VuZXJhdG9yKHByb2plY3QsIHtcbiAqICAgbmFtZTogXCJUeXBlU2NyaXB0UHJvamVjdFwiLFxuICogICBiYXNlQ2xhc3M6IFwidHlwZXNjcmlwdC5UeXBlU2NyaXB0UHJvamVjdFwiLFxuICogICBmaWxlUGF0aDogXCJzcmMvcHJvamVjdHMvdHlwZXNjcmlwdC5nZW5lcmF0ZWQudHNcIixcbiAqICAgY29tcG9uZW50czogW3sgY29tcG9uZW50OiBWaXRlc3QsIG9wdGlvbnNQcm9wZXJ0eTogXCJ2aXRlc3RPcHRpb25zXCIgfV1cbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvamVuUHJvamVjdEdlbmVyYXRvck9wdGlvbnM8TSBleHRlbmRzIFByb2plbk1vZHVsZSA9IFByb2plbk1vZHVsZT4gZXh0ZW5kcyBTb3VyY2VDb2RlT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogTmFtZSBvZiB0aGUgZ2VuZXJhdGVkIGNsYXNzIChlLmcuLCBcIlR5cGVTY3JpcHRQcm9qZWN0XCIpXG4gICAgICpcbiAgICAgKiBUaGUgb3B0aW9ucyBpbnRlcmZhY2Ugd2lsbCBiZSBuYW1lZCBgJHtuYW1lfU9wdGlvbnNgLlxuICAgICAqL1xuICAgIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEZ1bGx5IHF1YWxpZmllZCBiYXNlIGNsYXNzIHRvIGV4dGVuZCBpbiBmb3JtYXQgXCJtb2R1bGUuQ2xhc3NOYW1lXCJcbiAgICAgKlxuICAgICAqIE11c3QgYmUgYSB2YWxpZCBQcm9qZW4gY2xhc3MgcmVmZXJlbmNlIGxpa2UgXCJ0eXBlc2NyaXB0LlR5cGVTY3JpcHRQcm9qZWN0XCIsXG4gICAgICogXCJjZGsuSnNpaVByb2plY3RcIiwgb3IgXCJhd3NjZGsuQXdzQ2RrVHlwZVNjcmlwdEFwcFwiLlxuICAgICAqXG4gICAgICogQGV4YW1wbGUgXCJ0eXBlc2NyaXB0LlR5cGVTY3JpcHRQcm9qZWN0XCJcbiAgICAgKiBAZXhhbXBsZSBcImNkay5Kc2lpUHJvamVjdFwiXG4gICAgICovXG4gICAgcmVhZG9ubHkgYmFzZUNsYXNzOiBQcm9qZW5CYXNlQ2xhc3M8TT47XG5cbiAgICAvKipcbiAgICAgKiBPdXRwdXQgZmlsZSBwYXRoIGZvciB0aGUgZ2VuZXJhdGVkIGNsYXNzXG4gICAgICpcbiAgICAgKiBNdXN0IGNvbnRhaW4gYSBkaXJlY3Rvcnkgc2VwYXJhdG9yLiBUaGUgb3B0aW9ucyBpbnRlcmZhY2Ugd2lsbCBiZSBnZW5lcmF0ZWRcbiAgICAgKiBpbiB0aGUgc2FtZSBkaXJlY3Rvcnkgd2l0aCBhIFwiLmdlbmVyYXRlZC50c1wiIHN1ZmZpeC5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlIFwic3JjL3Byb2plY3RzL3R5cGVzY3JpcHQuZ2VuZXJhdGVkLnRzXCJcbiAgICAgKi9cbiAgICByZWFkb25seSBmaWxlUGF0aDogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQ29tcG9uZW50cyB0byBpbnRlZ3JhdGUgaW50byB0aGUgcHJvamVjdFxuICAgICAqXG4gICAgICogRWFjaCBjb21wb25lbnQgd2lsbCBiZSBpbnN0YW50aWF0ZWQgZHVyaW5nIHByb2plY3QgY29uc3RydWN0aW9uIGFuZCBjYW4gYmVcbiAgICAgKiBjb25maWd1cmVkIHZpYSBhbiBvcHRpb25hbCBvcHRpb25zIHByb3BlcnR5IGluIHRoZSBnZW5lcmF0ZWQgaW50ZXJmYWNlLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgW3sgY29tcG9uZW50OiBNaXNlIH0sIHsgY29tcG9uZW50OiBWaXRlc3QsIG9wdGlvbnNQcm9wZXJ0eTogeyBuYW1lOiBcInZpdGVzdE9wdGlvbnNcIiwgdHlwZTogXCIuLi5cIiwgZG9jczogXCIuLi5cIiB9IH1dXG4gICAgICovXG4gICAgcmVhZG9ubHkgY29tcG9uZW50cz86IENvbXBvbmVudENvbmZpZ1tdO1xuXG4gICAgLyoqXG4gICAgICogQWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIGFkZCB0byB0aGUgZ2VuZXJhdGVkIG9wdGlvbnMgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBVc2UgdGhpcyB0byBleHRlbmQgdGhlIGJhc2Ugb3B0aW9ucyB3aXRoIGN1c3RvbSBwcm9wZXJ0aWVzIHNwZWNpZmljIHRvXG4gICAgICogeW91ciBwcm9qZWN0IHR5cGUuXG4gICAgICovXG4gICAgcmVhZG9ubHkgYWRkaXRpb25hbE9wdGlvbnM/OiBQcm9wZXJ0eVtdO1xuXG4gICAgLyoqXG4gICAgICogUHJvcGVydHkgbmFtZXMgdG8gb21pdCBmcm9tIHRoZSBiYXNlIG9wdGlvbnMgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBVc2UgdGhpcyB0byBoaWRlIGJhc2UgY2xhc3Mgb3B0aW9ucyB0aGF0IHNob3VsZCBub3QgYmUgY29uZmlndXJhYmxlXG4gICAgICogaW4gdGhlIGdlbmVyYXRlZCBwcm9qZWN0IHR5cGUuXG4gICAgICovXG4gICAgcmVhZG9ubHkgb21pdE9wdGlvbnM/OiBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBCdWZmZXIgZm9yIGJ1aWxkaW5nIGluZGVudGVkIGNvZGUgd2l0aCBhdXRvbWF0aWMgbGluZSBtYW5hZ2VtZW50XG4gKlxuICogTWFpbnRhaW5zIGluZGVudGF0aW9uIGxldmVsIGFuZCBwcm92aWRlcyBtZXRob2RzIGZvciBhZGRpbmcgbGluZXMsXG4gKiBvcGVuaW5nL2Nsb3NpbmcgYmxvY2tzLCBhbmQgZmx1c2hpbmcgYWNjdW11bGF0ZWQgY29udGVudC5cbiAqL1xuY2xhc3MgQ29kZUJ1ZmZlciB7XG4gICAgcHJpdmF0ZSBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgICBwcml2YXRlIGluZGVudExldmVsID0gMDtcblxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBpbmRlbnQgLSBTdHJpbmcgdG8gdXNlIGZvciBlYWNoIGluZGVudGF0aW9uIGxldmVsIChkZWZhdWx0OiBzaW5nbGUgc3BhY2UpXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBpbmRlbnQgPSBcIiBcIikge31cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYWxsIGFjY3VtdWxhdGVkIGxpbmVzIGFuZCByZXNldHMgdGhlIGJ1ZmZlclxuICAgICAqXG4gICAgICogQHJldHVybnMgQXJyYXkgb2YgY29kZSBsaW5lcyB3aXRoIHByb3BlciBpbmRlbnRhdGlvblxuICAgICAqL1xuICAgIGZsdXNoKCk6IHN0cmluZ1tdIHtcbiAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMubGluZXM7XG4gICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQWRkcyBhIGxpbmUgb2YgY29kZSBhdCB0aGUgY3VycmVudCBpbmRlbnRhdGlvbiBsZXZlbFxuICAgICAqXG4gICAgICogQHBhcmFtIGNvZGUgLSBDb2RlIHRvIGFkZCAob3B0aW9uYWwsIGFkZHMgYmxhbmsgbGluZSBpZiBvbWl0dGVkKVxuICAgICAqL1xuICAgIGxpbmUoY29kZT86IHN0cmluZykge1xuICAgICAgICBjb25zdCBwcmVmaXggPSB0aGlzLmluZGVudC5yZXBlYXQodGhpcy5pbmRlbnRMZXZlbCk7XG4gICAgICAgIHRoaXMubGluZXMucHVzaCgocHJlZml4ICsgKGNvZGUgPz8gXCJcIikpLnRyaW1FbmQoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3BlbnMgYSBuZXcgaW5kZW50YXRpb24gYmxvY2tcbiAgICAgKlxuICAgICAqIEBwYXJhbSBjb2RlIC0gT3B0aW9uYWwgY29kZSB0byBhZGQgYmVmb3JlIGluY3JlYXNpbmcgaW5kZW50IChlLmcuLCBvcGVuaW5nIGJyYWNlKVxuICAgICAqL1xuICAgIG9wZW4oY29kZT86IHN0cmluZykge1xuICAgICAgICBpZiAoY29kZSkge1xuICAgICAgICAgICAgdGhpcy5saW5lKGNvZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5kZW50TGV2ZWwrKztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIGN1cnJlbnQgaW5kZW50YXRpb24gYmxvY2tcbiAgICAgKlxuICAgICAqIEBwYXJhbSBjb2RlIC0gT3B0aW9uYWwgY29kZSB0byBhZGQgYWZ0ZXIgZGVjcmVhc2luZyBpbmRlbnQgKGUuZy4sIGNsb3NpbmcgYnJhY2UpXG4gICAgICogQHRocm93cyB7SW52YWxpZEluZGVudExldmVsRXJyb3J9IFdoZW4gYXR0ZW1wdGluZyB0byBkZWNyZWFzZSBpbmRlbnQgYmVsb3cgemVyb1xuICAgICAqL1xuICAgIGNsb3NlKGNvZGU/OiBzdHJpbmcpIHtcbiAgICAgICAgaWYgKHRoaXMuaW5kZW50TGV2ZWwgPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkSW5kZW50TGV2ZWxFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5kZW50TGV2ZWwtLTtcbiAgICAgICAgaWYgKGNvZGUpIHtcbiAgICAgICAgICAgIHRoaXMubGluZShjb2RlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2V0cyB0aGUgYnVmZmVyIHRvIGluaXRpYWwgc3RhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlc2V0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmxpbmVzID0gW107XG4gICAgICAgIHRoaXMuaW5kZW50TGV2ZWwgPSAwO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZW5kZXJzIFR5cGVTY3JpcHQgY2xhc3MgY29kZSBmcm9tIFByb2plblByb2plY3RHZW5lcmF0b3Igb3B0aW9uc1xuICpcbiAqIEdlbmVyYXRlcyBhIGNvbXBsZXRlIFR5cGVTY3JpcHQgY2xhc3MgZmlsZSBpbmNsdWRpbmcgaW1wb3J0cywgb3B0aW9ucyBpbnRlcmZhY2UgZXhwb3J0LFxuICogY2xhc3MgZGVjbGFyYXRpb24sIGFuZCBjb25zdHJ1Y3RvciB3aXRoIGNvbXBvbmVudCBpbnRlZ3JhdGlvbi5cbiAqL1xuY2xhc3MgVHlwZVNjcmlwdENsYXNzUmVuZGVyZXIge1xuICAgIHByaXZhdGUgYnVmZmVyOiBDb2RlQnVmZmVyO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIGluZGVudCAtIE51bWJlciBvZiBzcGFjZXMgcGVyIGluZGVudGF0aW9uIGxldmVsIChkZWZhdWx0OiA0KVxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGluZGVudCA9IDQpIHtcbiAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgQ29kZUJ1ZmZlcihcIiBcIi5yZXBlYXQoaW5kZW50KSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVuZGVycyBjb21wbGV0ZSBUeXBlU2NyaXB0IGNsYXNzIGNvZGUgZnJvbSBvcHRpb25zXG4gICAgICpcbiAgICAgKiBPcmNoZXN0cmF0ZXMgdGhlIHJlbmRlcmluZyBwcm9jZXNzOiBkZXJpdmVzIG5hbWVzLCBleHRyYWN0cyBjb21wb25lbnQgY29uZmlndXJhdGlvbixcbiAgICAgKiBidWlsZHMgaW1wb3J0IHN0YXRlbWVudHMsIGFuZCByZW5kZXJzIHRoZSBjbGFzcyBzdHJ1Y3R1cmUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIEdlbmVyYXRvciBjb25maWd1cmF0aW9uXG4gICAgICogQHJldHVybnMgQ29tcGxldGUgVHlwZVNjcmlwdCBjbGFzcyBjb2RlIGFzIGEgc3RyaW5nXG4gICAgICovXG4gICAgcmVuZGVyKG9wdGlvbnM6IFByb2plblByb2plY3RHZW5lcmF0b3JPcHRpb25zPFByb2plbk1vZHVsZT4pOiBzdHJpbmcge1xuICAgICAgICB0aGlzLmJ1ZmZlci5mbHVzaCgpO1xuXG4gICAgICAgIC8qIERlcml2ZSBpbnRlcmZhY2UgYW5kIHR5cGUgbmFtZXMgZnJvbSB0aGUgY2xhc3MgbmFtZSAqL1xuICAgICAgICBjb25zdCBvcHRpb25zSW50ZXJmYWNlID0gYCR7b3B0aW9ucy5uYW1lfU9wdGlvbnNgO1xuICAgICAgICBjb25zdCBiYXNlT3B0aW9uc0ZxbiA9IHRoaXMuZ2V0QmFzZU9wdGlvbnNGcW4ob3B0aW9ucy5iYXNlQ2xhc3MpO1xuICAgICAgICBjb25zdCBiYXNlT3B0aW9uc1R5cGUgPSBiYXNlT3B0aW9uc0Zxbi5yZXBsYWNlKC9ecHJvamVuXFwuLywgXCJcIik7XG5cbiAgICAgICAgLyogVXNlIHByb3ZpZGVkIGNvbXBvbmVudHMgb3IgZmFsbCBiYWNrIHRvIGRlZmF1bHRzIChNaXNlICsgVml0ZXN0KSAqL1xuICAgICAgICBjb25zdCBjb21wb25lbnRzID0gb3B0aW9ucy5jb21wb25lbnRzID8/IERFRkFVTFRfQ09NUE9ORU5UUztcblxuICAgICAgICAvKiBFeHRyYWN0IGNvbXBvbmVudCBjb25maWd1cmF0aW9uIGZvciBjb25zdHJ1Y3RvciBnZW5lcmF0aW9uICovXG4gICAgICAgIGNvbnN0IHsgZGVzdHJ1Y3R1cmUsIGNvbXBvbmVudEFycmF5IH0gPSB0aGlzLmV4dHJhY3RDb21wb25lbnRPcHRpb25zKGNvbXBvbmVudHMpO1xuICAgICAgICBjb25zdCBpbXBvcnRzID0gdGhpcy5leHRyYWN0SW1wb3J0cyhvcHRpb25zLCBvcHRpb25zSW50ZXJmYWNlKTtcblxuICAgICAgICAvKiBSZW5kZXIgYWxsIHNlY3Rpb25zIG9mIHRoZSBjbGFzcyBmaWxlICovXG4gICAgICAgIHRoaXMucmVuZGVySW1wb3J0cyhpbXBvcnRzKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZSgpO1xuICAgICAgICB0aGlzLnJlbmRlckV4cG9ydChvcHRpb25zSW50ZXJmYWNlKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZSgpO1xuICAgICAgICB0aGlzLnJlbmRlckNsYXNzKG9wdGlvbnMsIG9wdGlvbnNJbnRlcmZhY2UsIGJhc2VPcHRpb25zVHlwZSwgZGVzdHJ1Y3R1cmUsIGNvbXBvbmVudEFycmF5KTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZSgpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5mbHVzaCgpLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVyaXZlcyB0aGUgZnVsbHkgcXVhbGlmaWVkIG9wdGlvbnMgaW50ZXJmYWNlIG5hbWUgZnJvbSBiYXNlIGNsYXNzXG4gICAgICpcbiAgICAgKiBUcmFuc2Zvcm1zIGJhc2UgY2xhc3MgcmVmZXJlbmNlIGludG8gdGhlIGNvcnJlc3BvbmRpbmcgUHJvamVuIG9wdGlvbnMgaW50ZXJmYWNlIG5hbWVcbiAgICAgKiBieSBhcHBlbmRpbmcgXCJPcHRpb25zXCIgc3VmZml4IGFuZCBwcmVmaXhpbmcgd2l0aCBcInByb2plbi5cIiBuYW1lc3BhY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gYmFzZUNsYXNzIC0gQmFzZSBjbGFzcyBpbiBmb3JtYXQgXCJtb2R1bGUuQ2xhc3NOYW1lXCJcbiAgICAgKiBAcmV0dXJucyBGdWxseSBxdWFsaWZpZWQgb3B0aW9ucyBpbnRlcmZhY2UgbmFtZVxuICAgICAqIEB0aHJvd3Mge0ludmFsaWRCYXNlQ2xhc3NGb3JtYXRFcnJvcn0gV2hlbiBiYXNlQ2xhc3MgZm9ybWF0IGlzIGludmFsaWRcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogZ2V0QmFzZU9wdGlvbnNGcW4oXCJ0eXBlc2NyaXB0LlR5cGVTY3JpcHRQcm9qZWN0XCIpIC8vIFwicHJvamVuLnR5cGVzY3JpcHQuVHlwZVNjcmlwdFByb2plY3RPcHRpb25zXCJcbiAgICAgKiBnZXRCYXNlT3B0aW9uc0ZxbihcImNkay5Kc2lpUHJvamVjdFwiKSAvLyBcInByb2plbi5jZGsuSnNpaVByb2plY3RPcHRpb25zXCJcbiAgICAgKi9cbiAgICBnZXRCYXNlT3B0aW9uc0ZxbihiYXNlQ2xhc3M6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgICAgIC8qIFZhbGlkYXRlIGJhc2UgY2xhc3MgZm9ybWF0OiBtdXN0IGNvbnRhaW4gbW9kdWxlLkNsYXNzTmFtZSBzdHJ1Y3R1cmUgKi9cbiAgICAgICAgaWYgKCFiYXNlQ2xhc3MuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZEJhc2VDbGFzc0Zvcm1hdEVycm9yKGJhc2VDbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYHByb2plbi4ke2Jhc2VDbGFzc31PcHRpb25zYDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0cyBjb21wb25lbnQgY29uZmlndXJhdGlvbiBmb3IgY29uc3RydWN0b3IgY29kZSBnZW5lcmF0aW9uXG4gICAgICpcbiAgICAgKiBUcmFuc2Zvcm1zIGNvbXBvbmVudCBjb25maWd1cmF0aW9ucyBpbnRvOlxuICAgICAqIDEuIERlc3RydWN0dXJlIGxpc3Q6IHZhcmlhYmxlIG5hbWVzIHRvIGV4dHJhY3QgZnJvbSBvcHRpb25zXG4gICAgICogMi4gQ29tcG9uZW50IGFycmF5OiBjb2RlIHN0cmluZyBmb3IgYXBwbHlEZWZhdWx0cygpIGNhbGxcbiAgICAgKlxuICAgICAqIEBwYXJhbSBjb21wb25lbnRzIC0gQ29tcG9uZW50IGNvbmZpZ3VyYXRpb25zXG4gICAgICogQHJldHVybnMgT2JqZWN0IHdpdGggZGVzdHJ1Y3R1cmUgYXJyYXkgYW5kIGNvbXBvbmVudEFycmF5IGNvZGUgc3RyaW5nXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIElucHV0OiBbeyBjb21wb25lbnQ6IFZpdGVzdCwgb3B0aW9uc1Byb3BlcnR5OiB7IG5hbWU6IFwidml0ZXN0T3B0aW9uc1wiLCAuLi4gfSB9XVxuICAgICAqIE91dHB1dDoge1xuICAgICAqICAgZGVzdHJ1Y3R1cmU6IFtcInZpdGVzdFwiLCBcInZpdGVzdE9wdGlvbnNcIl0sXG4gICAgICogICBjb21wb25lbnRBcnJheTogXCJbeyBjb21wb25lbnQ6IFZpdGVzdCwgZW5hYmxlZDogdml0ZXN0LCBvcHRpb25zOiB2aXRlc3RPcHRpb25zIH1dXCJcbiAgICAgKiB9XG4gICAgICovXG4gICAgcHJpdmF0ZSBleHRyYWN0Q29tcG9uZW50T3B0aW9ucyhjb21wb25lbnRzOiBDb21wb25lbnRDb25maWdbXSk6IHsgZGVzdHJ1Y3R1cmU6IHN0cmluZ1tdOyBjb21wb25lbnRBcnJheTogc3RyaW5nIH0ge1xuICAgICAgICBjb25zdCBkZXN0cnVjdHVyZTogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgY29tcG9uZW50UGFydHM6IHN0cmluZ1tdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBjIG9mIGNvbXBvbmVudHMpIHtcbiAgICAgICAgICAgIC8qIENvbnZlcnQgY29tcG9uZW50IGNsYXNzIG5hbWUgdG8gY2FtZWxDYXNlIHZhcmlhYmxlIG5hbWUgKGUuZy4sIFZpdGVzdCAtPiB2aXRlc3QpICovXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gYy5jb21wb25lbnQubmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGMuY29tcG9uZW50Lm5hbWUuc2xpY2UoMSk7XG4gICAgICAgICAgICBkZXN0cnVjdHVyZS5wdXNoKG5hbWUpO1xuXG4gICAgICAgICAgICAvKiBCdWlsZCBjb21wb25lbnQgY29uZmlnIG9iamVjdCBmb3IgYXBwbHlEZWZhdWx0cygpIGNhbGwgKi9cbiAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gW2Bjb21wb25lbnQ6ICR7Yy5jb21wb25lbnQubmFtZX1gXTtcbiAgICAgICAgICAgIGlmIChjLm9wdGlvbnNQcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgIC8qIENvbXBvbmVudCBoYXMgY29uZmlndXJhYmxlIG9wdGlvbnMgLSBpbmNsdWRlIGJvdGggZW5hYmxlZCBmbGFnIGFuZCBvcHRpb25zICovXG4gICAgICAgICAgICAgICAgZGVzdHJ1Y3R1cmUucHVzaChjLm9wdGlvbnNQcm9wZXJ0eS5uYW1lKTtcbiAgICAgICAgICAgICAgICBwYXJ0cy5wdXNoKGBlbmFibGVkOiAke25hbWV9YCwgYG9wdGlvbnM6ICR7Yy5vcHRpb25zUHJvcGVydHkubmFtZX1gKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLyogQ29tcG9uZW50IGhhcyBubyBvcHRpb25zIC0gb25seSBpbmNsdWRlIGVuYWJsZWQgZmxhZyAqL1xuICAgICAgICAgICAgICAgIHBhcnRzLnB1c2goYGVuYWJsZWQ6ICR7bmFtZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbXBvbmVudFBhcnRzLnB1c2goYHsgJHtwYXJ0cy5qb2luKFwiLCBcIil9IH1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7IGRlc3RydWN0dXJlLCBjb21wb25lbnRBcnJheTogYFske2NvbXBvbmVudFBhcnRzLmpvaW4oXCIsIFwiKX1dYCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ1aWxkcyBpbXBvcnQgc3RhdGVtZW50cyBtYXAgZm9yIHRoZSBnZW5lcmF0ZWQgY2xhc3NcbiAgICAgKlxuICAgICAqIENvbGxlY3RzIGFsbCByZXF1aXJlZCBpbXBvcnRzOlxuICAgICAqIC0gUHJvamVuIGJhc2UgbW9kdWxlICh0eXBlc2NyaXB0LCBjZGssIGF3c2NkaylcbiAgICAgKiAtIENvbmZpZyB1dGlsaXRpZXMgKGFwcGx5RGVmYXVsdHMsIGRlZmF1bHRPcHRpb25zKVxuICAgICAqIC0gQ29tcG9uZW50IGNsYXNzZXNcbiAgICAgKiAtIFV0aWxpdHkgZnVuY3Rpb25zIChkZWVwTWVyZ2UpXG4gICAgICogLSBHZW5lcmF0ZWQgb3B0aW9ucyBpbnRlcmZhY2UgKHR5cGUtb25seSBpbXBvcnQpXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIEdlbmVyYXRvciBjb25maWd1cmF0aW9uXG4gICAgICogQHBhcmFtIG9wdGlvbnNJbnRlcmZhY2UgLSBOYW1lIG9mIHRoZSBnZW5lcmF0ZWQgb3B0aW9ucyBpbnRlcmZhY2VcbiAgICAgKiBAcmV0dXJucyBNYXAgb2YgbW9kdWxlIHBhdGhzIHRvIHNldHMgb2YgaW1wb3J0ZWQgbmFtZXNcbiAgICAgKi9cbiAgICBwcml2YXRlIGV4dHJhY3RJbXBvcnRzKFxuICAgICAgICBvcHRpb25zOiBQcm9qZW5Qcm9qZWN0R2VuZXJhdG9yT3B0aW9uczxQcm9qZW5Nb2R1bGU+LFxuICAgICAgICBvcHRpb25zSW50ZXJmYWNlOiBzdHJpbmcsXG4gICAgKTogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+IHtcbiAgICAgICAgY29uc3QgaW1wb3J0cyA9IG5ldyBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj4oKTtcblxuICAgICAgICAvKiBFeHRyYWN0IGJhc2UgbW9kdWxlIG5hbWUgZnJvbSBiYXNlQ2xhc3MgKGUuZy4sIFwidHlwZXNjcmlwdFwiIGZyb20gXCJ0eXBlc2NyaXB0LlR5cGVTY3JpcHRQcm9qZWN0XCIpICovXG4gICAgICAgIGNvbnN0IGJhc2VNb2R1bGUgPSBvcHRpb25zLmJhc2VDbGFzcy5zcGxpdChcIi5cIilbMF07XG4gICAgICAgIGNvbnN0IG9wdGlvbnNGaWxlTmFtZSA9IHRoaXMuZ2V0T3B0aW9uc0ZpbGVOYW1lKG9wdGlvbnNJbnRlcmZhY2UpO1xuXG4gICAgICAgIC8qIFByb2plbiBiYXNlIG1vZHVsZSBpbXBvcnQgKi9cbiAgICAgICAgaW1wb3J0cy5zZXQoXCJwcm9qZW5cIiwgbmV3IFNldChbYmFzZU1vZHVsZV0pKTtcblxuICAgICAgICAvKiBDb25maWd1cmF0aW9uIHV0aWxpdGllcyBpbXBvcnQgKi9cbiAgICAgICAgaW1wb3J0cy5zZXQoXCIuLi9jb25maWdcIiwgbmV3IFNldChbXCJhcHBseURlZmF1bHRzXCIsIFwiZGVmYXVsdE9wdGlvbnNcIl0pKTtcblxuICAgICAgICAvKiBDb21wb25lbnQgY2xhc3MgaW1wb3J0cyAtIGRlcml2ZSBtb2R1bGUgcGF0aCBmcm9tIGNvbXBvbmVudCBjbGFzcyBuYW1lICovXG4gICAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBvcHRpb25zLmNvbXBvbmVudHMgPz8gREVGQVVMVF9DT01QT05FTlRTO1xuICAgICAgICBmb3IgKGNvbnN0IGMgb2YgY29tcG9uZW50cykge1xuICAgICAgICAgICAgY29uc3QgY29tcG9uZW50TmFtZSA9IGMuY29tcG9uZW50Lm5hbWU7XG4gICAgICAgICAgICBjb25zdCBtb2R1bGVQYXRoID0gYC4uL2NvbXBvbmVudHMvJHtjb21wb25lbnROYW1lLnRvTG93ZXJDYXNlKCl9YDtcbiAgICAgICAgICAgIGlmICghaW1wb3J0cy5oYXMobW9kdWxlUGF0aCkpIHtcbiAgICAgICAgICAgICAgICBpbXBvcnRzLnNldChtb2R1bGVQYXRoLCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbW9kdWxlSW1wb3J0cyA9IGltcG9ydHMuZ2V0KG1vZHVsZVBhdGgpO1xuICAgICAgICAgICAgaWYgKG1vZHVsZUltcG9ydHMpIHtcbiAgICAgICAgICAgICAgICBtb2R1bGVJbXBvcnRzLmFkZChjb21wb25lbnROYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qIFV0aWxpdHkgZnVuY3Rpb25zIGltcG9ydCAqL1xuICAgICAgICBpbXBvcnRzLnNldChcIi4uL3V0aWxzXCIsIG5ldyBTZXQoW1wiZGVlcE1lcmdlXCJdKSk7XG5cbiAgICAgICAgLyogR2VuZXJhdGVkIG9wdGlvbnMgaW50ZXJmYWNlIGltcG9ydCAodHlwZS1vbmx5IHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY2llcykgKi9cbiAgICAgICAgaW1wb3J0cy5zZXQoYC4vJHtvcHRpb25zRmlsZU5hbWV9LmdlbmVyYXRlZGAsIG5ldyBTZXQoW29wdGlvbnNJbnRlcmZhY2VdKSk7XG5cbiAgICAgICAgcmV0dXJuIGltcG9ydHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVyaXZlcyB0aGUgY29uZmlnIHBhdGggZm9yIGFjY2Vzc2luZyBkZWZhdWx0IG9wdGlvbnNcbiAgICAgKlxuICAgICAqIFRyYW5zZm9ybXMgYmFzZSBjbGFzcyByZWZlcmVuY2UgaW50byB0aGUgY29ycmVzcG9uZGluZyBwYXRoIGluIHRoZSBkZWZhdWx0T3B0aW9uc1xuICAgICAqIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGV4cG9ydGVkIGZyb20gY29uZmlnLnRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIGJhc2VDbGFzcyAtIEJhc2UgY2xhc3MgaW4gZm9ybWF0IFwibW9kdWxlLkNsYXNzTmFtZVwiXG4gICAgICogQHJldHVybnMgQ29uZmlnIHBhdGggZm9yIGFjY2Vzc2luZyBkZWZhdWx0IG9wdGlvbnNcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogZ2V0Q29uZmlnUGF0aChcInR5cGVzY3JpcHQuVHlwZVNjcmlwdFByb2plY3RcIikgLy8gXCJkZWZhdWx0T3B0aW9ucy50eXBlc2NyaXB0LlR5cGVTY3JpcHRQcm9qZWN0XCJcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldENvbmZpZ1BhdGgoYmFzZUNsYXNzOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYGRlZmF1bHRPcHRpb25zLiR7YmFzZUNsYXNzfWA7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVuZGVycyBpbXBvcnQgc3RhdGVtZW50cyBpbiBzb3J0ZWQgb3JkZXJcbiAgICAgKlxuICAgICAqIFNvcnRzIGltcG9ydHMgd2l0aCBleHRlcm5hbCBwYWNrYWdlcyBmaXJzdCwgdGhlbiByZWxhdGl2ZSBpbXBvcnRzLlxuICAgICAqIFVzZXMgdHlwZS1vbmx5IGltcG9ydHMgZm9yIGdlbmVyYXRlZCBmaWxlcyB0byBhdm9pZCBjaXJjdWxhciBkZXBlbmRlbmNpZXMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gaW1wb3J0cyAtIE1hcCBvZiBtb2R1bGUgcGF0aHMgdG8gaW1wb3J0ZWQgbmFtZXNcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlbmRlckltcG9ydHMoaW1wb3J0czogTWFwPHN0cmluZywgU2V0PHN0cmluZz4+KSB7XG4gICAgICAgIC8qIFNvcnQgbW9kdWxlczogZXh0ZXJuYWwgcGFja2FnZXMgZmlyc3QsIHRoZW4gcmVsYXRpdmUgaW1wb3J0cyBhbHBoYWJldGljYWxseSAqL1xuICAgICAgICBjb25zdCBzb3J0ZWRNb2R1bGVzID0gQXJyYXkuZnJvbShpbXBvcnRzLmtleXMoKSkuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgY29uc3QgYUlzUmVsYXRpdmUgPSBhLnN0YXJ0c1dpdGgoXCIuXCIpO1xuICAgICAgICAgICAgY29uc3QgYklzUmVsYXRpdmUgPSBiLnN0YXJ0c1dpdGgoXCIuXCIpO1xuICAgICAgICAgICAgaWYgKGFJc1JlbGF0aXZlICE9PSBiSXNSZWxhdGl2ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhSXNSZWxhdGl2ZSA/IDEgOiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhLmxvY2FsZUNvbXBhcmUoYik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgbW9kIG9mIHNvcnRlZE1vZHVsZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hbWVzID0gQXJyYXkuZnJvbShpbXBvcnRzLmdldChtb2QpIHx8IFtdKS5zb3J0KCk7XG4gICAgICAgICAgICAvKiBVc2UgdHlwZS1vbmx5IGltcG9ydCBmb3IgZ2VuZXJhdGVkIGZpbGVzIHRvIHByZXZlbnQgY2lyY3VsYXIgZGVwZW5kZW5jaWVzICovXG4gICAgICAgICAgICBjb25zdCBpc1R5cGVPbmx5ID0gbW9kLmluY2x1ZGVzKFwiLmdlbmVyYXRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IGltcG9ydFN0bXQgPSBpc1R5cGVPbmx5ID8gXCJpbXBvcnQgdHlwZVwiIDogXCJpbXBvcnRcIjtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoYCR7aW1wb3J0U3RtdH0geyAke25hbWVzLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwiJHttb2R9XCI7YCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW5kZXJzIHJlLWV4cG9ydCBzdGF0ZW1lbnQgZm9yIHRoZSBnZW5lcmF0ZWQgb3B0aW9ucyBpbnRlcmZhY2VcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb25zSW50ZXJmYWNlIC0gTmFtZSBvZiB0aGUgb3B0aW9ucyBpbnRlcmZhY2UgdG8gZXhwb3J0XG4gICAgICovXG4gICAgcHJpdmF0ZSByZW5kZXJFeHBvcnQob3B0aW9uc0ludGVyZmFjZTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnNGaWxlTmFtZSA9IHRoaXMuZ2V0T3B0aW9uc0ZpbGVOYW1lKG9wdGlvbnNJbnRlcmZhY2UpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5saW5lKCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoYGV4cG9ydCB7ICR7b3B0aW9uc0ludGVyZmFjZX0gfSBmcm9tIFwiLi8ke29wdGlvbnNGaWxlTmFtZX0uZ2VuZXJhdGVkXCI7YCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVuZGVycyB0aGUgY2xhc3MgZGVjbGFyYXRpb24gYW5kIGNvbnN0cnVjdG9yXG4gICAgICpcbiAgICAgKiBAcGFyYW0gb3B0aW9ucyAtIEdlbmVyYXRvciBjb25maWd1cmF0aW9uXG4gICAgICogQHBhcmFtIG9wdGlvbnNJbnRlcmZhY2UgLSBOYW1lIG9mIHRoZSBvcHRpb25zIGludGVyZmFjZVxuICAgICAqIEBwYXJhbSBiYXNlT3B0aW9uc1R5cGUgLSBCYXNlIG9wdGlvbnMgdHlwZSB3aXRob3V0IFwicHJvamVuLlwiIHByZWZpeFxuICAgICAqIEBwYXJhbSBkZXN0cnVjdHVyZSAtIFZhcmlhYmxlIG5hbWVzIHRvIGRlc3RydWN0dXJlIGZyb20gb3B0aW9uc1xuICAgICAqIEBwYXJhbSBjb21wb25lbnRBcnJheSAtIENvZGUgc3RyaW5nIGZvciBjb21wb25lbnQgYXJyYXlcbiAgICAgKi9cbiAgICBwcml2YXRlIHJlbmRlckNsYXNzKFxuICAgICAgICBvcHRpb25zOiBQcm9qZW5Qcm9qZWN0R2VuZXJhdG9yT3B0aW9uczxQcm9qZW5Nb2R1bGU+LFxuICAgICAgICBvcHRpb25zSW50ZXJmYWNlOiBzdHJpbmcsXG4gICAgICAgIGJhc2VPcHRpb25zVHlwZTogc3RyaW5nLFxuICAgICAgICBkZXN0cnVjdHVyZTogc3RyaW5nW10sXG4gICAgICAgIGNvbXBvbmVudEFycmF5OiBzdHJpbmcsXG4gICAgKSB7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShcIi8qKlwiKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShgICogJHtvcHRpb25zLm5hbWV9IHdpdGggc3RhbmRhcmQgY29uZmlndXJhdGlvbiBhbmQgY29tcG9uZW50IGludGVncmF0aW9uYCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoXCIgKlwiKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShcIiAqIEV4dGVuZHMgUHJvamVuJ3MgYmFzZSBjbGFzcyB3aXRoIG9waW5pb25hdGVkIGRlZmF1bHRzIGFuZCBhdXRvbWF0aWMgY29tcG9uZW50IHNldHVwLlwiKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShcIiAqL1wiKTtcbiAgICAgICAgdGhpcy5idWZmZXIub3BlbihgZXhwb3J0IGNsYXNzICR7b3B0aW9ucy5uYW1lfSBleHRlbmRzICR7b3B0aW9ucy5iYXNlQ2xhc3N9IHtgKTtcbiAgICAgICAgdGhpcy5yZW5kZXJDb25zdHJ1Y3RvcihvcHRpb25zLCBvcHRpb25zSW50ZXJmYWNlLCBiYXNlT3B0aW9uc1R5cGUsIGRlc3RydWN0dXJlLCBjb21wb25lbnRBcnJheSk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmNsb3NlKFwifVwiKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW5kZXJzIHRoZSBjb25zdHJ1Y3RvciBpbXBsZW1lbnRhdGlvblxuICAgICAqXG4gICAgICogVGhlIGNvbnN0cnVjdG9yOlxuICAgICAqIDEuIERlc3RydWN0dXJlcyBjb21wb25lbnQgZmxhZ3MgYW5kIG9wdGlvbnMgZnJvbSB0aGUgb3B0aW9ucyBwYXJhbWV0ZXJcbiAgICAgKiAyLiBNZXJnZXMgZGVmYXVsdCBjb25maWd1cmF0aW9uIHdpdGggdXNlci1wcm92aWRlZCBvcHRpb25zXG4gICAgICogMy4gQ2FsbHMgc3VwZXIoKSB3aXRoIG1lcmdlZCBvcHRpb25zXG4gICAgICogNC4gQXBwbGllcyBjb21wb25lbnQgZGVmYXVsdHMgdmlhIGFwcGx5RGVmYXVsdHMoKVxuICAgICAqXG4gICAgICogQHBhcmFtIG9wdGlvbnMgLSBHZW5lcmF0b3IgY29uZmlndXJhdGlvblxuICAgICAqIEBwYXJhbSBvcHRpb25zSW50ZXJmYWNlIC0gTmFtZSBvZiB0aGUgb3B0aW9ucyBpbnRlcmZhY2VcbiAgICAgKiBAcGFyYW0gYmFzZU9wdGlvbnNUeXBlIC0gQmFzZSBvcHRpb25zIHR5cGUgd2l0aG91dCBcInByb2plbi5cIiBwcmVmaXhcbiAgICAgKiBAcGFyYW0gZGVzdHJ1Y3R1cmUgLSBWYXJpYWJsZSBuYW1lcyB0byBkZXN0cnVjdHVyZSBmcm9tIG9wdGlvbnNcbiAgICAgKiBAcGFyYW0gY29tcG9uZW50QXJyYXkgLSBDb2RlIHN0cmluZyBmb3IgY29tcG9uZW50IGFycmF5XG4gICAgICovXG4gICAgcHJpdmF0ZSByZW5kZXJDb25zdHJ1Y3RvcihcbiAgICAgICAgb3B0aW9uczogUHJvamVuUHJvamVjdEdlbmVyYXRvck9wdGlvbnM8UHJvamVuTW9kdWxlPixcbiAgICAgICAgb3B0aW9uc0ludGVyZmFjZTogc3RyaW5nLFxuICAgICAgICBiYXNlT3B0aW9uc1R5cGU6IHN0cmluZyxcbiAgICAgICAgZGVzdHJ1Y3R1cmU6IHN0cmluZ1tdLFxuICAgICAgICBjb21wb25lbnRBcnJheTogc3RyaW5nLFxuICAgICkge1xuICAgICAgICBjb25zdCBjb25maWdQYXRoID0gdGhpcy5nZXRDb25maWdQYXRoKG9wdGlvbnMuYmFzZUNsYXNzKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShcIi8qKlwiKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShcIiAqIEBwYXJhbSBvcHRpb25zIC0gUHJvamVjdCBjb25maWd1cmF0aW9uXCIpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5saW5lKFwiICovXCIpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5vcGVuKGBjb25zdHJ1Y3RvcihvcHRpb25zOiAke29wdGlvbnNJbnRlcmZhY2V9KSB7YCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoXCIvKiBTZXBhcmF0ZSBjb21wb25lbnQgY29uZmlndXJhdGlvbiBmcm9tIGJhc2UgUHJvamVuIG9wdGlvbnMgKi9cIik7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoYGNvbnN0IHsgJHtkZXN0cnVjdHVyZS5qb2luKFwiLCBcIil9LCAuLi5iYXNlT3B0aW9ucyB9ID0gb3B0aW9ucztgKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZSgpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5saW5lKFwiLyogTWVyZ2UgZGVmYXVsdCBjb25maWd1cmF0aW9uIHdpdGggdXNlciBvcHRpb25zIGFuZCBpbml0aWFsaXplIGJhc2UgY2xhc3MgKi9cIik7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoYHN1cGVyKGRlZXBNZXJnZTwke2Jhc2VPcHRpb25zVHlwZX0+KCR7Y29uZmlnUGF0aH0sIGJhc2VPcHRpb25zKSk7YCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmxpbmUoKTtcbiAgICAgICAgdGhpcy5idWZmZXIubGluZShcIi8qIEFwcGx5IGNvbXBvbmVudCBkZWZhdWx0cyBhbmQgaW5zdGFudGlhdGUgZW5hYmxlZCBjb21wb25lbnRzICovXCIpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5saW5lKGBhcHBseURlZmF1bHRzKHRoaXMsICR7Y29tcG9uZW50QXJyYXl9KTtgKTtcbiAgICAgICAgdGhpcy5idWZmZXIuY2xvc2UoXCJ9XCIpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1hcHMgb3B0aW9ucyBpbnRlcmZhY2UgbmFtZSB0byBmaWxlIG5hbWVcbiAgICAgKlxuICAgICAqIENvbnZlcnRzIFBhc2NhbENhc2UgaW50ZXJmYWNlIG5hbWVzIHRvIGtlYmFiLWNhc2UgZmlsZSBuYW1lcy5cbiAgICAgKiBGYWxscyBiYWNrIHRvIGxvd2VyY2FzZSBjb252ZXJzaW9uIGZvciB1bm1hcHBlZCBpbnRlcmZhY2VzLlxuICAgICAqXG4gICAgICogQHBhcmFtIG9wdGlvbnNJbnRlcmZhY2UgLSBPcHRpb25zIGludGVyZmFjZSBuYW1lXG4gICAgICogQHJldHVybnMgS2ViYWItY2FzZSBmaWxlIG5hbWUgd2l0aG91dCBleHRlbnNpb25cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogZ2V0T3B0aW9uc0ZpbGVOYW1lKFwiVHlwZVNjcmlwdFByb2plY3RPcHRpb25zXCIpIC8vIFwidHlwZXNjcmlwdC1vcHRpb25zXCJcbiAgICAgKi9cbiAgICBnZXRPcHRpb25zRmlsZU5hbWUob3B0aW9uc0ludGVyZmFjZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgbWFwcGluZzogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgICAgIFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9uczogXCJ0eXBlc2NyaXB0LW9wdGlvbnNcIixcbiAgICAgICAgICAgIEpzaWlQcm9qZWN0T3B0aW9uczogXCJqc2lpLW9wdGlvbnNcIixcbiAgICAgICAgICAgIEF3c0Nka1R5cGVTY3JpcHRBcHBQcm9qZWN0T3B0aW9uczogXCJhd3NjZGstdHlwZXNjcmlwdC1hcHAtb3B0aW9uc1wiLFxuICAgICAgICAgICAgQXdzQ2RrQ29uc3RydWN0TGlicmFyeVByb2plY3RPcHRpb25zOiBcImF3c2Nkay1jb25zdHJ1Y3QtbGlicmFyeS1vcHRpb25zXCIsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtYXBwaW5nW29wdGlvbnNJbnRlcmZhY2VdIHx8IG9wdGlvbnNJbnRlcmZhY2UudG9Mb3dlckNhc2UoKTtcbiAgICB9XG59XG5cbi8qKlxuICogUHJvamVuIGNvbXBvbmVudCB0aGF0IGdlbmVyYXRlcyBUeXBlU2NyaXB0IHByb2plY3QgY2xhc3NlcyB3aXRoIHN0YW5kYXJkIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBUaGlzIGNvbXBvbmVudCBhdXRvbWF0ZXMgdGhlIGNyZWF0aW9uIG9mIHByb2plY3QgY2xhc3NlcyB0aGF0IGV4dGVuZCBQcm9qZW4gYmFzZSBjbGFzc2VzXG4gKiB3aXRoIG9waW5pb25hdGVkIGRlZmF1bHRzIGFuZCBjb21wb25lbnQgaW50ZWdyYXRpb24uIEl0IGdlbmVyYXRlcyBib3RoOlxuICogMS4gQW4gb3B0aW9ucyBpbnRlcmZhY2UgKHZpYSBQcm9qZW5TdHJ1Y3QpIHRoYXQgZXh0ZW5kcyB0aGUgYmFzZSBQcm9qZW4gb3B0aW9uc1xuICogMi4gQSBwcm9qZWN0IGNsYXNzIHRoYXQgYXBwbGllcyBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gYW5kIGluc3RhbnRpYXRlcyBjb21wb25lbnRzXG4gKlxuICogVGhlIGdlbmVyYXRlZCBjb2RlIGZvbGxvd3MgYSBjb25zaXN0ZW50IHBhdHRlcm46XG4gKiAtIEltcG9ydHMgcmVxdWlyZWQgbW9kdWxlcyBhbmQgY29tcG9uZW50c1xuICogLSBSZS1leHBvcnRzIHRoZSBnZW5lcmF0ZWQgb3B0aW9ucyBpbnRlcmZhY2VcbiAqIC0gRGVmaW5lcyBhIGNsYXNzIGV4dGVuZGluZyB0aGUgUHJvamVuIGJhc2UgY2xhc3NcbiAqIC0gQ29uc3RydWN0b3IgbWVyZ2VzIGRlZmF1bHRzIHdpdGggdXNlciBvcHRpb25zIGFuZCBhcHBsaWVzIGNvbXBvbmVudHNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogbmV3IFByb2plblByb2plY3RHZW5lcmF0b3IocHJvamVjdCwge1xuICogICBuYW1lOiBcIlR5cGVTY3JpcHRQcm9qZWN0XCIsXG4gKiAgIGJhc2VDbGFzczogXCJ0eXBlc2NyaXB0LlR5cGVTY3JpcHRQcm9qZWN0XCIsXG4gKiAgIGZpbGVQYXRoOiBcInNyYy9wcm9qZWN0cy90eXBlc2NyaXB0LmdlbmVyYXRlZC50c1wiLFxuICogICBjb21wb25lbnRzOiBbeyBjb21wb25lbnQ6IFZpdGVzdCwgb3B0aW9uc1Byb3BlcnR5OiBcInZpdGVzdE9wdGlvbnNcIiB9XVxuICogfSk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFByb2plblByb2plY3RHZW5lcmF0b3IgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIHByaXZhdGUgcmVuZGVyZXI6IFR5cGVTY3JpcHRDbGFzc1JlbmRlcmVyO1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHByb2plY3QgLSBQcm9qZW4gcHJvamVjdCBpbnN0YW5jZVxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gR2VuZXJhdG9yIGNvbmZpZ3VyYXRpb25cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJvamVjdDogUHJvamVjdCxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBQcm9qZW5Qcm9qZWN0R2VuZXJhdG9yT3B0aW9uczxQcm9qZW5Nb2R1bGU+LFxuICAgICkge1xuICAgICAgICBzdXBlcihwcm9qZWN0KTtcbiAgICAgICAgdGhpcy5yZW5kZXJlciA9IG5ldyBUeXBlU2NyaXB0Q2xhc3NSZW5kZXJlcigpO1xuXG4gICAgICAgIC8qIEdlbmVyYXRlIHRoZSBvcHRpb25zIGludGVyZmFjZSB1c2luZyBQcm9qZW5TdHJ1Y3QgZm9yIEpTSUkgY29tcGF0aWJpbGl0eSAqL1xuICAgICAgICBjb25zdCBvcHRpb25zSW50ZXJmYWNlID0gYCR7b3B0aW9ucy5uYW1lfU9wdGlvbnNgO1xuICAgICAgICBjb25zdCBiYXNlT3B0aW9uc0ZxbiA9IHRoaXMucmVuZGVyZXIuZ2V0QmFzZU9wdGlvbnNGcW4ob3B0aW9ucy5iYXNlQ2xhc3MpO1xuICAgICAgICBjb25zdCBvcHRpb25zRmlsZVBhdGggPSB0aGlzLmdldE9wdGlvbnNGaWxlUGF0aChvcHRpb25zSW50ZXJmYWNlKTtcblxuICAgICAgICAvKiBQcm9qZW5TdHJ1Y3QgZ2VuZXJhdGVzIGEgY29uY3JldGUgVHlwZVNjcmlwdCBpbnRlcmZhY2UgZnJvbSBQcm9qZW4ncyBvcHRpb25zXG4gICAgICAgICAqIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgSlNJSSBkb2Vzbid0IHN1cHBvcnQgVHlwZVNjcmlwdCB1dGlsaXR5IHR5cGVzIGxpa2UgT21pdDw+XG4gICAgICAgICAqIFRoZSBnZW5lcmF0ZWQgaW50ZXJmYWNlIGNhbiBiZSBjb25zdW1lZCBieSBvdGhlciBsYW5ndWFnZXMgKFB5dGhvbiwgSmF2YSwgQyMsIEdvKSAqL1xuICAgICAgICBjb25zdCBzdHJ1Y3QgPSBuZXcgUHJvamVuU3RydWN0KHRoaXMuYXNUeXBlU2NyaXB0UHJvamVjdChwcm9qZWN0KSwge1xuICAgICAgICAgICAgbmFtZTogb3B0aW9uc0ludGVyZmFjZSxcbiAgICAgICAgICAgIGZpbGVQYXRoOiBvcHRpb25zRmlsZVBhdGgsXG4gICAgICAgICAgICBvdXRwdXRGaWxlT3B0aW9uczogeyByZWFkb25seTogdHJ1ZSB9LFxuICAgICAgICB9KVxuICAgICAgICAgICAgLm1peGluKFN0cnVjdC5mcm9tRnFuKGJhc2VPcHRpb25zRnFuKSlcbiAgICAgICAgICAgIC53aXRob3V0RGVwcmVjYXRlZCgpO1xuXG4gICAgICAgIC8qIFJlbW92ZSBzcGVjaWZpZWQgb3B0aW9ucyBmcm9tIHRoZSBiYXNlIGludGVyZmFjZSAqL1xuICAgICAgICBpZiAob3B0aW9ucy5vbWl0T3B0aW9ucykge1xuICAgICAgICAgICAgc3RydWN0Lm9taXQoLi4ub3B0aW9ucy5vbWl0T3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvKiBBZGQgY29tcG9uZW50LWRlcml2ZWQgb3B0aW9ucyB0byB0aGUgaW50ZXJmYWNlICovXG4gICAgICAgIGNvbnN0IGNvbXBvbmVudHMgPSBvcHRpb25zLmNvbXBvbmVudHMgPz8gREVGQVVMVF9DT01QT05FTlRTO1xuICAgICAgICBjb25zdCB7IFByaW1pdGl2ZVR5cGUgfSA9IHJlcXVpcmUoXCJAanNpaS9zcGVjXCIpO1xuXG4gICAgICAgIGZvciAoY29uc3QgYyBvZiBjb21wb25lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gYy5jb21wb25lbnQubmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGMuY29tcG9uZW50Lm5hbWUuc2xpY2UoMSk7XG5cbiAgICAgICAgICAgIC8qIEFkZCBlbmFibGVkIGZsYWcgZm9yIHRoZSBjb21wb25lbnQgKi9cbiAgICAgICAgICAgIHN0cnVjdC5hZGQoe1xuICAgICAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICAgICAgdHlwZTogeyBwcmltaXRpdmU6IFByaW1pdGl2ZVR5cGUuQm9vbGVhbiB9LFxuICAgICAgICAgICAgICAgIG9wdGlvbmFsOiB0cnVlLFxuICAgICAgICAgICAgICAgIGRvY3M6IHtcbiAgICAgICAgICAgICAgICAgICAgc3VtbWFyeTogYEVuYWJsZSAke2MuY29tcG9uZW50Lm5hbWV9IGNvbXBvbmVudGAsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IFwidHJ1ZVwiLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLyogQWRkIG9wdGlvbnMgcHJvcGVydHkgaWYgY29tcG9uZW50IGlzIGNvbmZpZ3VyYWJsZSAqL1xuICAgICAgICAgICAgaWYgKGMub3B0aW9uc1Byb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgc3RydWN0LmFkZCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGMub3B0aW9uc1Byb3BlcnR5Lm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHsgZnFuOiBjLm9wdGlvbnNQcm9wZXJ0eS50eXBlIH0sXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBkb2NzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdW1tYXJ5OiBjLm9wdGlvbnNQcm9wZXJ0eS5kb2NzID8/IGAke2MuY29tcG9uZW50Lm5hbWV9IGNvbmZpZ3VyYXRpb25gLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogYC0gZGVmYXVsdCAke2MuY29tcG9uZW50Lm5hbWV9IGNvbmZpZ3VyYXRpb25gLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyogQWRkIGN1c3RvbSBvcHRpb25zIHRvIHRoZSBpbnRlcmZhY2UgKi9cbiAgICAgICAgaWYgKG9wdGlvbnMuYWRkaXRpb25hbE9wdGlvbnMpIHtcbiAgICAgICAgICAgIHN0cnVjdC5hZGQoLi4ub3B0aW9ucy5hZGRpdGlvbmFsT3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYXN0cyBwcm9qZWN0IHRvIFR5cGVTY3JpcHQgcHJvamVjdCB0eXBlXG4gICAgICpcbiAgICAgKiBQcm9qZW5TdHJ1Y3QgcmVxdWlyZXMgYSBUeXBlU2NyaXB0UHJvamVjdCBpbnN0YW5jZS4gVGhpcyBnZW5lcmF0b3IgaXMgb25seSB1c2VkXG4gICAgICogd2l0aGluIFR5cGVTY3JpcHQgcHJvamVjdHMsIHNvIHRoZSBjYXN0IGlzIHNhZmUgaW4gcHJhY3RpY2UuXG4gICAgICpcbiAgICAgKiBOb3RlOiBUeXBlIGFzc2VydGlvbiBpcyBuZWNlc3NhcnkgaGVyZSBiZWNhdXNlIFByb2plbidzIHR5cGUgc3lzdGVtIGRvZXNuJ3QgcHJvdmlkZVxuICAgICAqIGEgcnVudGltZSB0eXBlIGd1YXJkIGZvciBUeXBlU2NyaXB0UHJvamVjdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcm9qZWN0IC0gUHJvamVuIHByb2plY3QgaW5zdGFuY2VcbiAgICAgKiBAcmV0dXJucyBUeXBlU2NyaXB0IHByb2plY3QgaW5zdGFuY2VcbiAgICAgKi9cbiAgICBwcml2YXRlIGFzVHlwZVNjcmlwdFByb2plY3QocHJvamVjdDogUHJvamVjdCk6IHR5cGVzY3JpcHQuVHlwZVNjcmlwdFByb2plY3Qge1xuICAgICAgICByZXR1cm4gcHJvamVjdCBhcyB1bmtub3duIGFzIHR5cGVzY3JpcHQuVHlwZVNjcmlwdFByb2plY3Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVyaXZlcyB0aGUgZmlsZSBwYXRoIGZvciB0aGUgZ2VuZXJhdGVkIG9wdGlvbnMgaW50ZXJmYWNlXG4gICAgICpcbiAgICAgKiBQbGFjZXMgdGhlIG9wdGlvbnMgaW50ZXJmYWNlIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBjbGFzcyBmaWxlXG4gICAgICogd2l0aCBhIFwiLmdlbmVyYXRlZC50c1wiIHN1ZmZpeC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRpb25zSW50ZXJmYWNlIC0gTmFtZSBvZiB0aGUgb3B0aW9ucyBpbnRlcmZhY2VcbiAgICAgKiBAcmV0dXJucyBGaWxlIHBhdGggZm9yIHRoZSBvcHRpb25zIGludGVyZmFjZVxuICAgICAqIEB0aHJvd3Mge0ludmFsaWRGaWxlUGF0aEVycm9yfSBXaGVuIGZpbGVQYXRoIGRvZXNuJ3QgY29udGFpbiBhIGRpcmVjdG9yeSBzZXBhcmF0b3JcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldE9wdGlvbnNGaWxlUGF0aChvcHRpb25zSW50ZXJmYWNlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBsYXN0U2xhc2ggPSB0aGlzLm9wdGlvbnMuZmlsZVBhdGgubGFzdEluZGV4T2YoXCIvXCIpO1xuICAgICAgICBpZiAobGFzdFNsYXNoID09PSAtMSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRGaWxlUGF0aEVycm9yKHRoaXMub3B0aW9ucy5maWxlUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkaXIgPSB0aGlzLm9wdGlvbnMuZmlsZVBhdGguc3Vic3RyaW5nKDAsIGxhc3RTbGFzaCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnNGaWxlTmFtZSA9IHRoaXMucmVuZGVyZXIuZ2V0T3B0aW9uc0ZpbGVOYW1lKG9wdGlvbnNJbnRlcmZhY2UpO1xuICAgICAgICByZXR1cm4gYCR7ZGlyfS8ke29wdGlvbnNGaWxlTmFtZX0uZ2VuZXJhdGVkLnRzYDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZXMgdGhlIFR5cGVTY3JpcHQgY2xhc3MgZmlsZSBkdXJpbmcgUHJvamVuIHN5bnRoZXNpc1xuICAgICAqXG4gICAgICogQ2FsbGVkIGJ5IFByb2plbiBkdXJpbmcgdGhlIHN5bnRoZXNpcyBwaGFzZSB0byBnZW5lcmF0ZSB0aGUgcHJvamVjdCBjbGFzcyBmaWxlLlxuICAgICAqIFRoZSBmaWxlIGlzIG1hcmtlZCBhcyByZWFkb25seSB0byBwcmV2ZW50IG1hbnVhbCBlZGl0aW5nLlxuICAgICAqL1xuICAgIHByZVN5bnRoZXNpemUoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnJlbmRlcmVyLnJlbmRlcih0aGlzLm9wdGlvbnMpO1xuXG4gICAgICAgIG5ldyBUeXBlU2NyaXB0Q2xhc3NGaWxlKHRoaXMucHJvamVjdCwgdGhpcy5vcHRpb25zLmZpbGVQYXRoLCBjb250ZW50LCB7XG4gICAgICAgICAgICByZWFkb25seTogdGhpcy5vcHRpb25zLnJlYWRvbmx5ID8/IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUZXh0IGZpbGUgZm9yIGdlbmVyYXRlZCBUeXBlU2NyaXB0IGNsYXNzIGNvZGVcbiAqXG4gKiBFeHRlbmRzIFByb2plbidzIFRleHRGaWxlIHRvIGFkZCB0aGUgZ2VuZXJhdGVkIGZpbGUgbWFya2VyIGNvbW1lbnRcbiAqIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUuXG4gKi9cbmNsYXNzIFR5cGVTY3JpcHRDbGFzc0ZpbGUgZXh0ZW5kcyBUZXh0RmlsZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHByb2plY3QgLSBQcm9qZW4gcHJvamVjdCBpbnN0YW5jZVxuICAgICAqIEBwYXJhbSBmaWxlUGF0aCAtIE91dHB1dCBmaWxlIHBhdGhcbiAgICAgKiBAcGFyYW0gY29udGVudCAtIFR5cGVTY3JpcHQgY2xhc3MgY29kZVxuICAgICAqIEBwYXJhbSBvcHRpb25zIC0gU291cmNlIGNvZGUgb3B0aW9ucyAocmVhZG9ubHksIGV0Yy4pXG4gICAgICovXG4gICAgY29uc3RydWN0b3IocHJvamVjdDogUHJvamVjdCwgZmlsZVBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nLCBvcHRpb25zOiBTb3VyY2VDb2RlT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHN1cGVyKHByb2plY3QsIGZpbGVQYXRoLCBvcHRpb25zKTtcbiAgICAgICAgLyogQWRkIGdlbmVyYXRlZCBmaWxlIG1hcmtlciB0byBwcmV2ZW50IG1hbnVhbCBlZGl0aW5nICovXG4gICAgICAgIHRoaXMuYWRkTGluZShgLy8gJHt0aGlzLm1hcmtlcn1gKTtcbiAgICAgICAgdGhpcy5hZGRMaW5lKGNvbnRlbnQpO1xuICAgIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -50,7 +50,7 @@
50
50
  "publishConfig": {
51
51
  "access": "public"
52
52
  },
53
- "version": "0.1.4",
53
+ "version": "0.1.6",
54
54
  "types": "lib/index.d.ts",
55
55
  "stability": "stable",
56
56
  "jsii": {