@decaf-ts/cli 0.3.5 → 0.3.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.
package/dist/cli.esm.cjs CHANGED
@@ -3,25 +3,35 @@ import fs from 'fs';
3
3
  import path from 'path';
4
4
 
5
5
  /**
6
- * @description The name for decaf cli modules where each library must export
7
- * a single {@link CliModule}
6
+ * @description The filename that identifies Decaf CLI modules
7
+ * @summary The standard filename for CLI module files where each library must export a single CliModule function
8
8
  *
9
- * @constant
10
- * @memberOf module:CLI.cli
9
+ * @const CLI_FILE_NAME
10
+ * @memberOf module:CLI
11
11
  */
12
12
  const CLI_FILE_NAME = "cli-module";
13
13
 
14
14
  /**
15
- * @description util class to retrieve versions and other information
15
+ * @description Utility class for CLI operations
16
+ * @summary A static utility class that provides methods for loading modules, retrieving package information, and initializing CLI commands
17
+ *
18
+ * @example
19
+ * // Initialize a Command object with package information
20
+ * const command = new Command();
21
+ * CLIUtils.initialize(command, './path/to/package');
22
+ *
23
+ * // Load a CLI module from a file
24
+ * const module = await CLIUtils.loadFromFile('./path/to/cli-module.js');
16
25
  *
17
26
  * @class CLIUtils
18
- * @static
19
27
  */
20
28
  class CLIUtils {
21
29
  /**
22
- * @description Dynamically imports a cjs file into a decaf module
23
- * @param {string} path
24
- * @static
30
+ * @description Dynamically imports a module file
31
+ * @summary Loads a JavaScript file and returns it as a CliModule, handling both ESM and CommonJS formats
32
+ *
33
+ * @param {string} path The file path to the module to load
34
+ * @return {Promise<CliModule>} A promise that resolves to the loaded CliModule
25
35
  */
26
36
  static async loadFromFile(path) {
27
37
  try {
@@ -32,11 +42,12 @@ class CLIUtils {
32
42
  }
33
43
  }
34
44
  /**
35
- * @description allows safe dynamic imports
36
- * @summary property imports JS files regardless of esm status
45
+ * @description Normalizes module imports to handle both ESM and CommonJS formats
46
+ * @summary Properly imports JavaScript files regardless of their module format by handling the ESM wrapper for CommonJS modules
37
47
  *
38
- * @typeParam T
39
- * @param {Promise} importPromise
48
+ * @template T The type of the imported module
49
+ * @param {Promise<T>} importPromise The promise returned by the dynamic import
50
+ * @return {Promise<T>} A promise that resolves to the normalized module
40
51
  * @private
41
52
  */
42
53
  static async normalizeImport(importPromise) {
@@ -44,10 +55,12 @@ class CLIUtils {
44
55
  return importPromise.then((m) => (m.default || m));
45
56
  }
46
57
  /**
47
- * @description initializes the Cli object
58
+ * @description Initializes a Command object with package information
59
+ * @summary Sets up a Commander Command object with the package name, description, and version from the package.json file
48
60
  *
49
- * @param {Command} command
50
- * @param {string} [basePath] defaults to the current working directory
61
+ * @param {Command} command The Command object to initialize
62
+ * @param {string} [basePath] The base path where the package.json file is located, defaults to the current working directory
63
+ * @return {void}
51
64
  */
52
65
  static initialize(command, basePath) {
53
66
  const name = CLIUtils.packageName(basePath);
@@ -57,9 +70,11 @@ class CLIUtils {
57
70
  .version(CLIUtils.packageVersion(basePath));
58
71
  }
59
72
  /**
60
- * @description retrieves and parses the package.json file
73
+ * @description Retrieves and parses the package.json file
74
+ * @summary Reads the package.json file from the specified path and parses it into a JavaScript object
61
75
  *
62
- * @param {string} basePath
76
+ * @param {string} basePath The base path where the package.json file is located
77
+ * @return {Record<string, unknown>} The parsed package.json content as an object
63
78
  * @private
64
79
  */
65
80
  static getPackage(basePath) {
@@ -71,27 +86,42 @@ class CLIUtils {
71
86
  }
72
87
  }
73
88
  /**
74
- * @description returns the package version
75
- * @param {string} [basePath] defaults to current working dir
89
+ * @description Returns the version from package.json
90
+ * @summary Retrieves the version field from the package.json file at the specified path
91
+ *
92
+ * @param {string} basePath The base path where the package.json file is located
93
+ * @return {string} The package version string
76
94
  */
77
95
  static packageVersion(basePath) {
78
96
  return CLIUtils.getPackage(basePath)["version"];
79
97
  }
80
98
  /**
81
- * @description returns the package name
82
- * @param {string} [basePath] defaults to current working dir
99
+ * @description Returns the name from package.json
100
+ * @summary Retrieves the name field from the package.json file at the specified path and extracts the package name without the scope
101
+ *
102
+ * @param {string} basePath The base path where the package.json file is located
103
+ * @return {string} The package name without the scope (e.g., "cli" from "@decaf-ts/cli")
83
104
  */
84
105
  static packageName(basePath) {
85
- return CLIUtils.getPackage(basePath)["name"].split("/")[1];
106
+ const name = CLIUtils.getPackage(basePath)["name"].split("/");
107
+ return name[name.length - 1];
86
108
  }
87
109
  }
88
110
 
89
111
  /**
90
- * @summary Util class to handle CLI functionality from all Decaf modules
91
- * @description CLI handler class
112
+ * @description Utility class to handle CLI functionality from all Decaf modules
113
+ * @summary This class provides a wrapper around Commander.js to handle CLI commands from different Decaf modules.
114
+ * It crawls the filesystem to find CLI modules, loads them, and registers their commands.
92
115
  *
93
- * @param {string} [basepath] the base path to look for modules in. defaults to `./`
94
- * @param {string} [crawlLevels] folders to crawl to find modules from the basePath. defaults to 4
116
+ * @param {string} [basePath] The base path to look for modules in. Defaults to `./`
117
+ * @param {number} [crawlLevels] Number of folder levels to crawl to find modules from the basePath. Defaults to 4
118
+ *
119
+ * @example
120
+ * // Create a new CLI wrapper and run it with custom options
121
+ * const cli = new CliWrapper('./src', 2);
122
+ * cli.run(process.argv).then(() => {
123
+ * console.log('CLI commands executed successfully');
124
+ * });
95
125
  *
96
126
  * @class CliWrapper
97
127
  */
@@ -100,26 +130,47 @@ class CliWrapper {
100
130
  this.basePath = basePath;
101
131
  this.crawlLevels = crawlLevels;
102
132
  this.modules = {};
133
+ this.rootPath = path.resolve(__dirname, "..");
103
134
  }
104
135
  /**
105
- * @description Retrieves and initializes the {@link Command} object
136
+ * @description Retrieves and initializes the Commander Command object
137
+ * @summary Lazy-loads the Command object, initializing it with the package name, description, and version
138
+ * @return {Command} The initialized Command object
106
139
  * @private
107
140
  */
108
141
  get command() {
109
142
  if (!this._command) {
110
143
  this._command = new Command();
111
- CLIUtils.initialize(this._command, this.basePath);
144
+ CLIUtils.initialize(this._command, this.rootPath);
112
145
  }
113
146
  return this._command;
114
147
  }
115
148
  /**
116
- * @description loads and registers module from a file
149
+ * @description Loads and registers a module from a file
150
+ * @summary Dynamically imports a CLI module from the specified file path, initializes it, and registers it in the modules collection
117
151
  *
118
- * @param {string} filePath path to look for modules
119
- * @param {string} rootPath repo root to find the package.json
120
- * @return {string} the module name
152
+ * @param {string} filePath Path to the module file to load
153
+ * @param {string} rootPath Repository root path to find the package.json
154
+ * @return {Promise<string>} A promise that resolves to the module name
121
155
  *
122
156
  * @private
157
+ * @mermaid
158
+ * sequenceDiagram
159
+ * participant CliWrapper
160
+ * participant CLIUtils
161
+ * participant Module
162
+ *
163
+ * CliWrapper->>CLIUtils: loadFromFile(filePath)
164
+ * CLIUtils-->>CliWrapper: module
165
+ * CliWrapper->>CliWrapper: Get module name
166
+ * CliWrapper->>Command: new Command()
167
+ * Command-->>CliWrapper: cmd
168
+ * CliWrapper->>CLIUtils: initialize(cmd, path.dirname(rootPath))
169
+ * CliWrapper->>Module: module()
170
+ * Note over CliWrapper,Module: Handle Promise if needed
171
+ * Module-->>CliWrapper: Command instance
172
+ * CliWrapper->>CliWrapper: Store in modules[name]
173
+ * CliWrapper-->>CliWrapper: Return name
123
174
  */
124
175
  async load(filePath, rootPath) {
125
176
  let name;
@@ -127,7 +178,7 @@ class CliWrapper {
127
178
  const module = await CLIUtils.loadFromFile(filePath);
128
179
  name = module.name;
129
180
  const cmd = new Command();
130
- CLIUtils.initialize(cmd, path.dirname(rootPath));
181
+ CLIUtils.initialize(cmd, rootPath);
131
182
  let m = module();
132
183
  if (m instanceof Promise)
133
184
  m = await m;
@@ -139,12 +190,36 @@ class CliWrapper {
139
190
  return name;
140
191
  }
141
192
  /**
142
- * @description finds all the cli modules in the basePath via {@link CliWrapper.crawl}
143
- * and loads them
193
+ * @description Finds and loads all CLI modules in the basePath
194
+ * @summary Uses the crawl method to find all CLI modules in the specified base path,
195
+ * then loads and registers each module as a subcommand
196
+ *
197
+ * @return {Promise<void>} A promise that resolves when all modules are loaded
198
+ *
144
199
  * @private
200
+ * @mermaid
201
+ * sequenceDiagram
202
+ * participant CliWrapper
203
+ * participant Filesystem
204
+ * participant Module
205
+ *
206
+ * CliWrapper->>Filesystem: Join basePath with cwd
207
+ * CliWrapper->>CliWrapper: crawl(basePath, crawlLevels)
208
+ * CliWrapper-->>CliWrapper: modules[]
209
+ * loop For each module
210
+ * alt Not @decaf-ts/cli
211
+ * CliWrapper->>CliWrapper: load(module, cwd)
212
+ * CliWrapper-->>CliWrapper: name
213
+ * CliWrapper->>CliWrapper: Check if command exists
214
+ * alt Command doesn't exist
215
+ * CliWrapper->>Command: command(name).addCommand(modules[name])
216
+ * end
217
+ * end
218
+ * end
219
+ * CliWrapper->>Console: Log loaded modules
145
220
  */
146
221
  async boot() {
147
- const basePath = path.join(process.cwd(), this.basePath);
222
+ const basePath = path.resolve(this.rootPath, this.basePath);
148
223
  const modules = this.crawl(basePath, this.crawlLevels);
149
224
  for (const module of modules) {
150
225
  if (module.includes("@decaf-ts/cli")) {
@@ -152,7 +227,7 @@ class CliWrapper {
152
227
  }
153
228
  let name;
154
229
  try {
155
- name = await this.load(module, process.cwd());
230
+ name = await this.load(module, this.rootPath);
156
231
  }
157
232
  catch (e) {
158
233
  console.error(e);
@@ -171,9 +246,13 @@ class CliWrapper {
171
246
  .join("\n")}`);
172
247
  }
173
248
  /**
174
- * @description crawls the basePath up for 'levels' folders to find a module,eg a {@link CLI_FILE_NAME} named file
175
- * @param {string} basePath the relative base batch to start searching in
176
- * @param {number} [levels] the max number of levels to crawl. defaults to 2
249
+ * @description Recursively searches for CLI module files in the directory structure
250
+ * @summary Crawls the basePath up to the specified number of folder levels to find files named according to CLI_FILE_NAME
251
+ *
252
+ * @param {string} basePath The absolute base path to start searching in
253
+ * @param {number} [levels=2] The maximum number of directory levels to crawl
254
+ * @return {string[]} An array of file paths to CLI modules
255
+ *
177
256
  * @private
178
257
  */
179
258
  crawl(basePath, levels = 2) {
@@ -191,9 +270,24 @@ class CliWrapper {
191
270
  }, []);
192
271
  }
193
272
  /**
194
- * @description runs the given command
273
+ * @description Executes the CLI with the provided arguments
274
+ * @summary Boots the CLI by loading all modules, then parses and executes the command specified in the arguments
275
+ *
276
+ * @param {string[]} [args=process.argv] Command line arguments to parse and execute
277
+ * @return {Promise<void>} A promise that resolves when the command execution is complete
195
278
  *
196
- * @param {string[]} [args] args to run. defaults to process.argv
279
+ * @mermaid
280
+ * sequenceDiagram
281
+ * participant Client
282
+ * participant CliWrapper
283
+ * participant Command
284
+ *
285
+ * Client->>CliWrapper: run(args)
286
+ * CliWrapper->>CliWrapper: boot()
287
+ * Note over CliWrapper: Loads all modules
288
+ * CliWrapper->>Command: parseAsync(args)
289
+ * Command-->>CliWrapper: result
290
+ * CliWrapper-->>Client: result
197
291
  */
198
292
  async run(args = process.argv) {
199
293
  await this.boot();
@@ -204,7 +298,8 @@ class CliWrapper {
204
298
  /**
205
299
  * @description Decaf-ts' CLI module
206
300
  * @summary This file will crawl the current working directory for files called {@link CLI_FILE_NAME}
207
- * within the @decaf-ts namespace and load then as subcommands
301
+ * within the @decaf-ts namespace and load them as subcommands. It serves as the main entry point
302
+ * for the CLI functionality, exporting the CliWrapper class and VERSION constant.
208
303
  *
209
304
  * @example
210
305
  * run module command - $ npx decaf <module name> <module command> ...<module command options>
@@ -215,26 +310,12 @@ class CliWrapper {
215
310
  * @module CLI
216
311
  */
217
312
  /**
218
- * @description Decaf-ts' CLI namespace
219
- * @summary This file will crawl the current working directory for files called {@link CLI_FILE_NAME}
220
- * within the @decaf-ts namespace and load then as subcommands
221
- *
222
- * @example
223
- * run module command - $ npx decaf <module name> <module command> ...<module command options>
224
- * get module help - $ npx decaf help <module name>;
225
- * list imported modules - $ npx decaf list;
226
- * get cli help - $ npx decaf help;
227
- *
228
- * @namespace cli
229
- * @memberOf module:CLI
230
- */
231
- /**
232
- * @summary stores the current package version
233
- * @description this is how you should document a constant
313
+ * @description Stores the current package version
314
+ * @summary A constant that holds the version string of the package, which is replaced during build
234
315
  * @const VERSION
235
316
  * @memberOf module:CLI
236
317
  */
237
- const VERSION = "0.3.4";
318
+ const VERSION = "0.3.6";
238
319
 
239
320
  export { CliWrapper, VERSION };
240
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmVzbS5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvQ2xpV3JhcHBlci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5pbXBvcnQgeyBDbGlNb2R1bGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUaGUgbmFtZSBmb3IgZGVjYWYgY2xpIG1vZHVsZXMgd2hlcmUgZWFjaCBsaWJyYXJ5IG11c3QgZXhwb3J0XG4gKiBhIHNpbmdsZSB7QGxpbmsgQ2xpTW9kdWxlfVxuICpcbiAqIEBjb25zdGFudFxuICogQG1lbWJlck9mIG1vZHVsZTpDTEkuY2xpXG4gKi9cbmV4cG9ydCBjb25zdCBDTElfRklMRV9OQU1FID0gXCJjbGktbW9kdWxlXCI7XG4iLCJpbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIjtcbmltcG9ydCB7IENsaU1vZHVsZSB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIHV0aWwgY2xhc3MgdG8gcmV0cmlldmUgdmVyc2lvbnMgYW5kIG90aGVyIGluZm9ybWF0aW9uXG4gKlxuICogQGNsYXNzIENMSVV0aWxzXG4gKiBAc3RhdGljXG4gKi9cbmV4cG9ydCBjbGFzcyBDTElVdGlscyB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRHluYW1pY2FsbHkgaW1wb3J0cyBhIGNqcyBmaWxlIGludG8gYSBkZWNhZiBtb2R1bGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhdGhcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIGFzeW5jIGxvYWRGcm9tRmlsZShwYXRoOiBzdHJpbmcpOiBQcm9taXNlPENsaU1vZHVsZT4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gQ0xJVXRpbHMubm9ybWFsaXplSW1wb3J0KGltcG9ydChwYXRoKSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxvYWQgZnJvbSAke3BhdGh9OiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IGV9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIGFsbG93cyBzYWZlIGR5bmFtaWMgaW1wb3J0c1xuICAgKiBAc3VtbWFyeSBwcm9wZXJ0eSBpbXBvcnRzIEpTIGZpbGVzIHJlZ2FyZGxlc3Mgb2YgZXNtIHN0YXR1c1xuICAgKlxuICAgKiBAdHlwZVBhcmFtIFRcbiAgICogQHBhcmFtIHtQcm9taXNlfSBpbXBvcnRQcm9taXNlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgbm9ybWFsaXplSW1wb3J0PFQ+KGltcG9ydFByb21pc2U6IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAvLyBDb21tb25KUydzIGBtb2R1bGUuZXhwb3J0c2AgaXMgd3JhcHBlZCBhcyBgZGVmYXVsdGAgaW4gRVNNb2R1bGUuXG4gICAgcmV0dXJuIGltcG9ydFByb21pc2UudGhlbihcbiAgICAgIChtOiB1bmtub3duKSA9PiAoKG0gYXMgeyBkZWZhdWx0OiBUIH0pLmRlZmF1bHQgfHwgbSkgYXMgVFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIGluaXRpYWxpemVzIHRoZSBDbGkgb2JqZWN0XG4gICAqXG4gICAqIEBwYXJhbSB7Q29tbWFuZH0gY29tbWFuZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Jhc2VQYXRoXSBkZWZhdWx0cyB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICAgKi9cbiAgc3RhdGljIGluaXRpYWxpemUoY29tbWFuZDogQ29tbWFuZCwgYmFzZVBhdGg6IHN0cmluZykge1xuICAgIGNvbnN0IG5hbWUgPSBDTElVdGlscy5wYWNrYWdlTmFtZShiYXNlUGF0aCk7XG4gICAgY29tbWFuZFxuICAgICAgLm5hbWUobmFtZSlcbiAgICAgIC5kZXNjcmlwdGlvbihgUnVucyAke25hbWV9IHJlbGF0ZWQgY29tbWFuZHNgKVxuICAgICAgLnZlcnNpb24oQ0xJVXRpbHMucGFja2FnZVZlcnNpb24oYmFzZVBhdGgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gcmV0cmlldmVzIGFuZCBwYXJzZXMgdGhlIHBhY2thZ2UuanNvbiBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0UGFja2FnZShiYXNlUGF0aDogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShcbiAgICAgICAgZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihiYXNlUGF0aCwgXCJwYWNrYWdlLmpzb25cIiksIFwidXRmOFwiKVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byByZWFkIHZlcnNpb24gZnJvbSAke2Jhc2VQYXRofTogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gcmV0dXJucyB0aGUgcGFja2FnZSB2ZXJzaW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYmFzZVBhdGhdIGRlZmF1bHRzIHRvIGN1cnJlbnQgd29ya2luZyBkaXJcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlVmVyc2lvbihiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gQ0xJVXRpbHMuZ2V0UGFja2FnZShiYXNlUGF0aClbXCJ2ZXJzaW9uXCJdIGFzIHN0cmluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gcmV0dXJucyB0aGUgcGFja2FnZSBuYW1lXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYmFzZVBhdGhdIGRlZmF1bHRzIHRvIGN1cnJlbnQgd29ya2luZyBkaXJcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlTmFtZShiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gKENMSVV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1wibmFtZVwiXSBhcyBzdHJpbmcpLnNwbGl0KFwiL1wiKVsxXTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDTElfRklMRV9OQU1FIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDTElVdGlscyB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBjbGFzcyB0byBoYW5kbGUgQ0xJIGZ1bmN0aW9uYWxpdHkgZnJvbSBhbGwgRGVjYWYgbW9kdWxlc1xuICogQGRlc2NyaXB0aW9uIENMSSBoYW5kbGVyIGNsYXNzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtiYXNlcGF0aF0gdGhlIGJhc2UgcGF0aCB0byBsb29rIGZvciBtb2R1bGVzIGluLiBkZWZhdWx0cyB0byBgLi9gXG4gKiBAcGFyYW0ge3N0cmluZ30gW2NyYXdsTGV2ZWxzXSBmb2xkZXJzIHRvIGNyYXdsIHRvIGZpbmQgbW9kdWxlcyBmcm9tIHRoZSBiYXNlUGF0aC4gZGVmYXVsdHMgdG8gNFxuICpcbiAqIEBjbGFzcyBDbGlXcmFwcGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBDbGlXcmFwcGVyIHtcbiAgcHJpdmF0ZSBfY29tbWFuZD86IENvbW1hbmQ7XG4gIHByaXZhdGUgbW9kdWxlczogUmVjb3JkPHN0cmluZywgQ29tbWFuZD4gPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGJhc2VQYXRoOiBzdHJpbmcgPSBcIi4vXCIsXG4gICAgcHJpdmF0ZSBjcmF3bExldmVscyA9IDRcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBpbml0aWFsaXplcyB0aGUge0BsaW5rIENvbW1hbmR9IG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgY29tbWFuZCgpIHtcbiAgICBpZiAoIXRoaXMuX2NvbW1hbmQpIHtcbiAgICAgIHRoaXMuX2NvbW1hbmQgPSBuZXcgQ29tbWFuZCgpO1xuICAgICAgQ0xJVXRpbHMuaW5pdGlhbGl6ZSh0aGlzLl9jb21tYW5kLCB0aGlzLmJhc2VQYXRoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NvbW1hbmQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIGxvYWRzIGFuZCByZWdpc3RlcnMgbW9kdWxlIGZyb20gYSBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCBwYXRoIHRvIGxvb2sgZm9yIG1vZHVsZXNcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb3RQYXRoIHJlcG8gcm9vdCB0byBmaW5kIHRoZSBwYWNrYWdlLmpzb25cbiAgICogQHJldHVybiB7c3RyaW5nfSB0aGUgbW9kdWxlIG5hbWVcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgbG9hZChmaWxlUGF0aDogc3RyaW5nLCByb290UGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBsZXQgbmFtZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgQ0xJVXRpbHMubG9hZEZyb21GaWxlKGZpbGVQYXRoKTtcbiAgICAgIG5hbWUgPSBtb2R1bGUubmFtZTtcbiAgICAgIGNvbnN0IGNtZCA9IG5ldyBDb21tYW5kKCk7XG4gICAgICBDTElVdGlscy5pbml0aWFsaXplKGNtZCwgcGF0aC5kaXJuYW1lKHJvb3RQYXRoKSk7XG4gICAgICBsZXQgbSA9IG1vZHVsZSgpO1xuICAgICAgaWYgKG0gaW5zdGFuY2VvZiBQcm9taXNlKSBtID0gYXdhaXQgbTtcbiAgICAgIHRoaXMubW9kdWxlc1tuYW1lXSA9IG07XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGxvYWQgbW9kdWxlICR7bmFtZSB8fCBcInVubmFtZWRcIn0gdW5kZXIgJHtmaWxlUGF0aH06ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogZX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gZmluZHMgYWxsIHRoZSBjbGkgbW9kdWxlcyBpbiB0aGUgYmFzZVBhdGggdmlhIHtAbGluayBDbGlXcmFwcGVyLmNyYXdsfVxuICAgKiBhbmQgbG9hZHMgdGhlbVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBib290KCkge1xuICAgIGNvbnN0IGJhc2VQYXRoID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksIHRoaXMuYmFzZVBhdGgpO1xuICAgIGNvbnN0IG1vZHVsZXMgPSB0aGlzLmNyYXdsKGJhc2VQYXRoLCB0aGlzLmNyYXdsTGV2ZWxzKTtcbiAgICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzKSB7XG4gICAgICBpZiAobW9kdWxlLmluY2x1ZGVzKFwiQGRlY2FmLXRzL2NsaVwiKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGxldCBuYW1lOiBzdHJpbmc7XG4gICAgICB0cnkge1xuICAgICAgICBuYW1lID0gYXdhaXQgdGhpcy5sb2FkKG1vZHVsZSwgcHJvY2Vzcy5jd2QoKSk7XG4gICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLmNvbW1hbmQuY29tbWFuZHMuZmluZChcbiAgICAgICAgICAoYykgPT4gKGMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KVtcIl9uYW1lXCJdID09PSBuYW1lXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLmNvbW1hbmQuY29tbWFuZChuYW1lKS5hZGRDb21tYW5kKHRoaXMubW9kdWxlc1tuYW1lXSk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYGxvYWRlZCBtb2R1bGVzOlxcbiR7T2JqZWN0LmtleXModGhpcy5tb2R1bGVzKVxuICAgICAgICAubWFwKChrKSA9PiBgLSAke2t9YClcbiAgICAgICAgLmpvaW4oXCJcXG5cIil9YFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIGNyYXdscyB0aGUgYmFzZVBhdGggdXAgZm9yICdsZXZlbHMnIGZvbGRlcnMgdG8gZmluZCBhIG1vZHVsZSxlZyBhIHtAbGluayBDTElfRklMRV9OQU1FfSBuYW1lZCBmaWxlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCB0aGUgcmVsYXRpdmUgYmFzZSBiYXRjaCB0byBzdGFydCBzZWFyY2hpbmcgaW5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtsZXZlbHNdIHRoZSBtYXggbnVtYmVyIG9mIGxldmVscyB0byBjcmF3bC4gZGVmYXVsdHMgdG8gMlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBjcmF3bChiYXNlUGF0aDogc3RyaW5nLCBsZXZlbHM6IG51bWJlciA9IDIpIHtcbiAgICBpZiAobGV2ZWxzIDw9IDApIHJldHVybiBbXTtcbiAgICByZXR1cm4gZnMucmVhZGRpclN5bmMoYmFzZVBhdGgpLnJlZHVjZSgoYWNjdW06IHN0cmluZ1tdLCBmaWxlKSA9PiB7XG4gICAgICBmaWxlID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlKTtcbiAgICAgIGlmIChmcy5zdGF0U3luYyhmaWxlKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goLi4udGhpcy5jcmF3bChmaWxlLCBsZXZlbHMgLSAxKSk7XG4gICAgICB9IGVsc2UgaWYgKGZpbGUubWF0Y2gobmV3IFJlZ0V4cChgJHtDTElfRklMRV9OQU1FfS5bY21dP2pzJGAsIFwiZ21cIikpKSB7XG4gICAgICAgIGFjY3VtLnB1c2goZmlsZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSwgW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBydW5zIHRoZSBnaXZlbiBjb21tYW5kXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFthcmdzXSBhcmdzIHRvIHJ1bi4gZGVmYXVsdHMgdG8gcHJvY2Vzcy5hcmd2XG4gICAqL1xuICBhc3luYyBydW4oYXJnczogc3RyaW5nW10gPSBwcm9jZXNzLmFyZ3YpIHtcbiAgICBhd2FpdCB0aGlzLmJvb3QoKTtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kLnBhcnNlQXN5bmMoYXJncyk7XG4gIH1cbn1cbiIsImV4cG9ydCAqIGZyb20gXCIuL0NsaVdyYXBwZXJcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjYWYtdHMnIENMSSBtb2R1bGVcbiAqIEBzdW1tYXJ5IFRoaXMgZmlsZSB3aWxsIGNyYXdsIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5IGZvciBmaWxlcyBjYWxsZWQge0BsaW5rIENMSV9GSUxFX05BTUV9XG4gKiB3aXRoaW4gdGhlIEBkZWNhZi10cyBuYW1lc3BhY2UgYW5kIGxvYWQgdGhlbiBhcyBzdWJjb21tYW5kc1xuICpcbiAqIEBleGFtcGxlXG4gKiBydW4gbW9kdWxlIGNvbW1hbmQgICAgIC0gJCBucHggZGVjYWYgPG1vZHVsZSBuYW1lPiA8bW9kdWxlIGNvbW1hbmQ+IC4uLjxtb2R1bGUgY29tbWFuZCBvcHRpb25zPlxuICogZ2V0IG1vZHVsZSBoZWxwICAgICAgICAtICQgbnB4IGRlY2FmIGhlbHAgPG1vZHVsZSBuYW1lPjtcbiAqIGxpc3QgaW1wb3J0ZWQgbW9kdWxlcyAgLSAkIG5weCBkZWNhZiBsaXN0O1xuICogZ2V0IGNsaSBoZWxwICAgICAgICAgICAtICQgbnB4IGRlY2FmIGhlbHA7XG4gKlxuICogQG1vZHVsZSBDTElcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNhZi10cycgQ0xJIG5hbWVzcGFjZVxuICogQHN1bW1hcnkgVGhpcyBmaWxlIHdpbGwgY3Jhd2wgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkgZm9yIGZpbGVzIGNhbGxlZCB7QGxpbmsgQ0xJX0ZJTEVfTkFNRX1cbiAqIHdpdGhpbiB0aGUgQGRlY2FmLXRzIG5hbWVzcGFjZSBhbmQgbG9hZCB0aGVuIGFzIHN1YmNvbW1hbmRzXG4gKlxuICogQGV4YW1wbGVcbiAqIHJ1biBtb2R1bGUgY29tbWFuZCAgICAgLSAkIG5weCBkZWNhZiA8bW9kdWxlIG5hbWU+IDxtb2R1bGUgY29tbWFuZD4gLi4uPG1vZHVsZSBjb21tYW5kIG9wdGlvbnM+XG4gKiBnZXQgbW9kdWxlIGhlbHAgICAgICAgIC0gJCBucHggZGVjYWYgaGVscCA8bW9kdWxlIG5hbWU+O1xuICogbGlzdCBpbXBvcnRlZCBtb2R1bGVzICAtICQgbnB4IGRlY2FmIGxpc3Q7XG4gKiBnZXQgY2xpIGhlbHAgICAgICAgICAgIC0gJCBucHggZGVjYWYgaGVscDtcbiAqXG4gKiBAbmFtZXNwYWNlIGNsaVxuICogQG1lbWJlck9mIG1vZHVsZTpDTElcbiAqL1xuXG4vKipcbiAqIEBzdW1tYXJ5IHN0b3JlcyB0aGUgY3VycmVudCBwYWNrYWdlIHZlcnNpb25cbiAqIEBkZXNjcmlwdGlvbiB0aGlzIGlzIGhvdyB5b3Ugc2hvdWxkIGRvY3VtZW50IGEgY29uc3RhbnRcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNMSVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBR0E7Ozs7OztBQU1HO0FBQ0ksTUFBTSxhQUFhLEdBQUcsWUFBWTs7QUNMekM7Ozs7O0FBS0c7TUFDVSxRQUFRLENBQUE7QUFDbkI7Ozs7QUFJRztBQUNILElBQUEsYUFBYSxZQUFZLENBQUMsSUFBWSxFQUFBO0FBQ3BDLFFBQUEsSUFBSTtZQUNGLE9BQU8sUUFBUSxDQUFDLGVBQWUsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDOztRQUM3QyxPQUFPLENBQVUsRUFBRTtZQUNuQixNQUFNLElBQUksS0FBSyxDQUNiLENBQUEsb0JBQUEsRUFBdUIsSUFBSSxDQUFLLEVBQUEsRUFBQSxDQUFDLFlBQVksS0FBSyxHQUFHLENBQUMsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFFLENBQUEsQ0FDckU7OztBQUlMOzs7Ozs7O0FBT0c7QUFDSCxJQUFBLGFBQWEsZUFBZSxDQUFJLGFBQXlCLEVBQUE7O0FBRXZELFFBQUEsT0FBTyxhQUFhLENBQUMsSUFBSSxDQUN2QixDQUFDLENBQVUsTUFBTyxDQUFvQixDQUFDLE9BQU8sSUFBSSxDQUFDLENBQU0sQ0FDMUQ7O0FBR0g7Ozs7O0FBS0c7QUFDSCxJQUFBLE9BQU8sVUFBVSxDQUFDLE9BQWdCLEVBQUUsUUFBZ0IsRUFBQTtRQUNsRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQztRQUMzQzthQUNHLElBQUksQ0FBQyxJQUFJO0FBQ1QsYUFBQSxXQUFXLENBQUMsQ0FBQSxLQUFBLEVBQVEsSUFBSSxDQUFBLGlCQUFBLENBQW1CO2FBQzNDLE9BQU8sQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDOztBQUcvQzs7Ozs7QUFLRztJQUNLLE9BQU8sVUFBVSxDQUFD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
321
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmVzbS5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb25zdGFudHMudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvQ2xpV3JhcHBlci50cyIsIi4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG5pbXBvcnQgeyBDbGlNb2R1bGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUaGUgZmlsZW5hbWUgdGhhdCBpZGVudGlmaWVzIERlY2FmIENMSSBtb2R1bGVzXG4gKiBAc3VtbWFyeSBUaGUgc3RhbmRhcmQgZmlsZW5hbWUgZm9yIENMSSBtb2R1bGUgZmlsZXMgd2hlcmUgZWFjaCBsaWJyYXJ5IG11c3QgZXhwb3J0IGEgc2luZ2xlIENsaU1vZHVsZSBmdW5jdGlvblxuICpcbiAqIEBjb25zdCBDTElfRklMRV9OQU1FXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNMSVxuICovXG5leHBvcnQgY29uc3QgQ0xJX0ZJTEVfTkFNRSA9IFwiY2xpLW1vZHVsZVwiO1xuIiwiaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyBDbGlNb2R1bGUgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGNsYXNzIGZvciBDTEkgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgQSBzdGF0aWMgdXRpbGl0eSBjbGFzcyB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgZm9yIGxvYWRpbmcgbW9kdWxlcywgcmV0cmlldmluZyBwYWNrYWdlIGluZm9ybWF0aW9uLCBhbmQgaW5pdGlhbGl6aW5nIENMSSBjb21tYW5kc1xuICogXG4gKiBAZXhhbXBsZVxuICogLy8gSW5pdGlhbGl6ZSBhIENvbW1hbmQgb2JqZWN0IHdpdGggcGFja2FnZSBpbmZvcm1hdGlvblxuICogY29uc3QgY29tbWFuZCA9IG5ldyBDb21tYW5kKCk7XG4gKiBDTElVdGlscy5pbml0aWFsaXplKGNvbW1hbmQsICcuL3BhdGgvdG8vcGFja2FnZScpO1xuICogXG4gKiAvLyBMb2FkIGEgQ0xJIG1vZHVsZSBmcm9tIGEgZmlsZVxuICogY29uc3QgbW9kdWxlID0gYXdhaXQgQ0xJVXRpbHMubG9hZEZyb21GaWxlKCcuL3BhdGgvdG8vY2xpLW1vZHVsZS5qcycpO1xuICogXG4gKiBAY2xhc3MgQ0xJVXRpbHNcbiAqL1xuZXhwb3J0IGNsYXNzIENMSVV0aWxzIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEeW5hbWljYWxseSBpbXBvcnRzIGEgbW9kdWxlIGZpbGVcbiAgICogQHN1bW1hcnkgTG9hZHMgYSBKYXZhU2NyaXB0IGZpbGUgYW5kIHJldHVybnMgaXQgYXMgYSBDbGlNb2R1bGUsIGhhbmRsaW5nIGJvdGggRVNNIGFuZCBDb21tb25KUyBmb3JtYXRzXG4gICAqIFxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgZmlsZSBwYXRoIHRvIHRoZSBtb2R1bGUgdG8gbG9hZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPENsaU1vZHVsZT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBsb2FkZWQgQ2xpTW9kdWxlXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgbG9hZEZyb21GaWxlKHBhdGg6IHN0cmluZyk6IFByb21pc2U8Q2xpTW9kdWxlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBDTElVdGlscy5ub3JtYWxpemVJbXBvcnQoaW1wb3J0KHBhdGgpKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gbG9hZCBmcm9tICR7cGF0aH06ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogZX1gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTm9ybWFsaXplcyBtb2R1bGUgaW1wb3J0cyB0byBoYW5kbGUgYm90aCBFU00gYW5kIENvbW1vbkpTIGZvcm1hdHNcbiAgICogQHN1bW1hcnkgUHJvcGVybHkgaW1wb3J0cyBKYXZhU2NyaXB0IGZpbGVzIHJlZ2FyZGxlc3Mgb2YgdGhlaXIgbW9kdWxlIGZvcm1hdCBieSBoYW5kbGluZyB0aGUgRVNNIHdyYXBwZXIgZm9yIENvbW1vbkpTIG1vZHVsZXNcbiAgICpcbiAgICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIGltcG9ydGVkIG1vZHVsZVxuICAgKiBAcGFyYW0ge1Byb21pc2U8VD59IGltcG9ydFByb21pc2UgVGhlIHByb21pc2UgcmV0dXJuZWQgYnkgdGhlIGR5bmFtaWMgaW1wb3J0XG4gICAqIEByZXR1cm4ge1Byb21pc2U8VD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBub3JtYWxpemVkIG1vZHVsZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgc3RhdGljIGFzeW5jIG5vcm1hbGl6ZUltcG9ydDxUPihpbXBvcnRQcm9taXNlOiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgLy8gQ29tbW9uSlMncyBgbW9kdWxlLmV4cG9ydHNgIGlzIHdyYXBwZWQgYXMgYGRlZmF1bHRgIGluIEVTTW9kdWxlLlxuICAgIHJldHVybiBpbXBvcnRQcm9taXNlLnRoZW4oXG4gICAgICAobTogdW5rbm93bikgPT4gKChtIGFzIHsgZGVmYXVsdDogVCB9KS5kZWZhdWx0IHx8IG0pIGFzIFRcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyBhIENvbW1hbmQgb2JqZWN0IHdpdGggcGFja2FnZSBpbmZvcm1hdGlvblxuICAgKiBAc3VtbWFyeSBTZXRzIHVwIGEgQ29tbWFuZGVyIENvbW1hbmQgb2JqZWN0IHdpdGggdGhlIHBhY2thZ2UgbmFtZSwgZGVzY3JpcHRpb24sIGFuZCB2ZXJzaW9uIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7Q29tbWFuZH0gY29tbWFuZCBUaGUgQ29tbWFuZCBvYmplY3QgdG8gaW5pdGlhbGl6ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2Jhc2VQYXRoXSBUaGUgYmFzZSBwYXRoIHdoZXJlIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBpcyBsb2NhdGVkLCBkZWZhdWx0cyB0byB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIGluaXRpYWxpemUoY29tbWFuZDogQ29tbWFuZCwgYmFzZVBhdGg6IHN0cmluZykge1xuICAgIGNvbnN0IG5hbWUgPSBDTElVdGlscy5wYWNrYWdlTmFtZShiYXNlUGF0aCk7XG4gICAgY29tbWFuZFxuICAgICAgLm5hbWUobmFtZSlcbiAgICAgIC5kZXNjcmlwdGlvbihgUnVucyAke25hbWV9IHJlbGF0ZWQgY29tbWFuZHNgKVxuICAgICAgLnZlcnNpb24oQ0xJVXRpbHMucGFja2FnZVZlcnNpb24oYmFzZVBhdGgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBwYXJzZXMgdGhlIHBhY2thZ2UuanNvbiBmaWxlXG4gICAqIEBzdW1tYXJ5IFJlYWRzIHRoZSBwYWNrYWdlLmpzb24gZmlsZSBmcm9tIHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgcGFyc2VzIGl0IGludG8gYSBKYXZhU2NyaXB0IG9iamVjdFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gVGhlIHBhcnNlZCBwYWNrYWdlLmpzb24gY29udGVudCBhcyBhbiBvYmplY3RcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGdldFBhY2thZ2UoYmFzZVBhdGg6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgICAgIGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oYmFzZVBhdGgsIFwicGFja2FnZS5qc29uXCIpLCBcInV0ZjhcIilcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcmVhZCB2ZXJzaW9uIGZyb20gJHtiYXNlUGF0aH06ICR7ZX1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIHZlcnNpb24gZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSB2ZXJzaW9uIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aFxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gICAqL1xuICBzdGF0aWMgcGFja2FnZVZlcnNpb24oYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIENMSVV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1widmVyc2lvblwiXSBhcyBzdHJpbmc7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHVybnMgdGhlIG5hbWUgZnJvbSBwYWNrYWdlLmpzb25cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBuYW1lIGZpZWxkIGZyb20gdGhlIHBhY2thZ2UuanNvbiBmaWxlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aCBhbmQgZXh0cmFjdHMgdGhlIHBhY2thZ2UgbmFtZSB3aXRob3V0IHRoZSBzY29wZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYmFzZVBhdGggVGhlIGJhc2UgcGF0aCB3aGVyZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgaXMgbG9jYXRlZFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwYWNrYWdlIG5hbWUgd2l0aG91dCB0aGUgc2NvcGUgKGUuZy4sIFwiY2xpXCIgZnJvbSBcIkBkZWNhZi10cy9jbGlcIilcbiAgICovXG4gIHN0YXRpYyBwYWNrYWdlTmFtZShiYXNlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBuYW1lID0gKENMSVV0aWxzLmdldFBhY2thZ2UoYmFzZVBhdGgpW1wibmFtZVwiXSBhcyBzdHJpbmcpLnNwbGl0KFwiL1wiKTtcbiAgICByZXR1cm4gbmFtZVtuYW1lLmxlbmd0aCAtIDFdO1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IENMSV9GSUxFX05BTUUgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IENMSVV0aWxzIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVXRpbGl0eSBjbGFzcyB0byBoYW5kbGUgQ0xJIGZ1bmN0aW9uYWxpdHkgZnJvbSBhbGwgRGVjYWYgbW9kdWxlc1xuICogQHN1bW1hcnkgVGhpcyBjbGFzcyBwcm92aWRlcyBhIHdyYXBwZXIgYXJvdW5kIENvbW1hbmRlci5qcyB0byBoYW5kbGUgQ0xJIGNvbW1hbmRzIGZyb20gZGlmZmVyZW50IERlY2FmIG1vZHVsZXMuXG4gKiBJdCBjcmF3bHMgdGhlIGZpbGVzeXN0ZW0gdG8gZmluZCBDTEkgbW9kdWxlcywgbG9hZHMgdGhlbSwgYW5kIHJlZ2lzdGVycyB0aGVpciBjb21tYW5kcy5cbiAqIFxuICogQHBhcmFtIHtzdHJpbmd9IFtiYXNlUGF0aF0gVGhlIGJhc2UgcGF0aCB0byBsb29rIGZvciBtb2R1bGVzIGluLiBEZWZhdWx0cyB0byBgLi9gXG4gKiBAcGFyYW0ge251bWJlcn0gW2NyYXdsTGV2ZWxzXSBOdW1iZXIgb2YgZm9sZGVyIGxldmVscyB0byBjcmF3bCB0byBmaW5kIG1vZHVsZXMgZnJvbSB0aGUgYmFzZVBhdGguIERlZmF1bHRzIHRvIDRcbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0ZSBhIG5ldyBDTEkgd3JhcHBlciBhbmQgcnVuIGl0IHdpdGggY3VzdG9tIG9wdGlvbnNcbiAqIGNvbnN0IGNsaSA9IG5ldyBDbGlXcmFwcGVyKCcuL3NyYycsIDIpO1xuICogY2xpLnJ1bihwcm9jZXNzLmFyZ3YpLnRoZW4oKCkgPT4ge1xuICogICBjb25zb2xlLmxvZygnQ0xJIGNvbW1hbmRzIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseScpO1xuICogfSk7XG4gKiBcbiAqIEBjbGFzcyBDbGlXcmFwcGVyXG4gKi9cbmV4cG9ydCBjbGFzcyBDbGlXcmFwcGVyIHtcbiAgcHJpdmF0ZSBfY29tbWFuZD86IENvbW1hbmQ7XG4gIHByaXZhdGUgbW9kdWxlczogUmVjb3JkPHN0cmluZywgQ29tbWFuZD4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSByb290UGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYmFzZVBhdGg6IHN0cmluZyA9IFwiLi9cIixcbiAgICBwcml2YXRlIGNyYXdsTGV2ZWxzID0gNFxuICApIHtcbiAgICB0aGlzLnJvb3RQYXRoID0gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgXCIuLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGFuZCBpbml0aWFsaXplcyB0aGUgQ29tbWFuZGVyIENvbW1hbmQgb2JqZWN0XG4gICAqIEBzdW1tYXJ5IExhenktbG9hZHMgdGhlIENvbW1hbmQgb2JqZWN0LCBpbml0aWFsaXppbmcgaXQgd2l0aCB0aGUgcGFja2FnZSBuYW1lLCBkZXNjcmlwdGlvbiwgYW5kIHZlcnNpb25cbiAgICogQHJldHVybiB7Q29tbWFuZH0gVGhlIGluaXRpYWxpemVkIENvbW1hbmQgb2JqZWN0XG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIGdldCBjb21tYW5kKCkge1xuICAgIGlmICghdGhpcy5fY29tbWFuZCkge1xuICAgICAgdGhpcy5fY29tbWFuZCA9IG5ldyBDb21tYW5kKCk7XG4gICAgICBDTElVdGlscy5pbml0aWFsaXplKHRoaXMuX2NvbW1hbmQsIHRoaXMucm9vdFBhdGgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29tbWFuZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTG9hZHMgYW5kIHJlZ2lzdGVycyBhIG1vZHVsZSBmcm9tIGEgZmlsZVxuICAgKiBAc3VtbWFyeSBEeW5hbWljYWxseSBpbXBvcnRzIGEgQ0xJIG1vZHVsZSBmcm9tIHRoZSBzcGVjaWZpZWQgZmlsZSBwYXRoLCBpbml0aWFsaXplcyBpdCwgYW5kIHJlZ2lzdGVycyBpdCBpbiB0aGUgbW9kdWxlcyBjb2xsZWN0aW9uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlUGF0aCBQYXRoIHRvIHRoZSBtb2R1bGUgZmlsZSB0byBsb2FkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb290UGF0aCBSZXBvc2l0b3J5IHJvb3QgcGF0aCB0byBmaW5kIHRoZSBwYWNrYWdlLmpzb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxzdHJpbmc+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbW9kdWxlIG5hbWVcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2xpV3JhcHBlclxuICAgKiAgIHBhcnRpY2lwYW50IENMSVV0aWxzXG4gICAqICAgcGFydGljaXBhbnQgTW9kdWxlXG4gICAqICAgXG4gICAqICAgQ2xpV3JhcHBlci0+PkNMSVV0aWxzOiBsb2FkRnJvbUZpbGUoZmlsZVBhdGgpXG4gICAqICAgQ0xJVXRpbHMtLT4+Q2xpV3JhcHBlcjogbW9kdWxlXG4gICAqICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IEdldCBtb2R1bGUgbmFtZVxuICAgKiAgIENsaVdyYXBwZXItPj5Db21tYW5kOiBuZXcgQ29tbWFuZCgpXG4gICAqICAgQ29tbWFuZC0tPj5DbGlXcmFwcGVyOiBjbWRcbiAgICogICBDbGlXcmFwcGVyLT4+Q0xJVXRpbHM6IGluaXRpYWxpemUoY21kLCBwYXRoLmRpcm5hbWUocm9vdFBhdGgpKVxuICAgKiAgIENsaVdyYXBwZXItPj5Nb2R1bGU6IG1vZHVsZSgpXG4gICAqICAgTm90ZSBvdmVyIENsaVdyYXBwZXIsTW9kdWxlOiBIYW5kbGUgUHJvbWlzZSBpZiBuZWVkZWRcbiAgICogICBNb2R1bGUtLT4+Q2xpV3JhcHBlcjogQ29tbWFuZCBpbnN0YW5jZVxuICAgKiAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBTdG9yZSBpbiBtb2R1bGVzW25hbWVdXG4gICAqICAgQ2xpV3JhcHBlci0tPj5DbGlXcmFwcGVyOiBSZXR1cm4gbmFtZVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBsb2FkKGZpbGVQYXRoOiBzdHJpbmcsIHJvb3RQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGxldCBuYW1lO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBDTElVdGlscy5sb2FkRnJvbUZpbGUoZmlsZVBhdGgpO1xuICAgICAgbmFtZSA9IG1vZHVsZS5uYW1lO1xuICAgICAgY29uc3QgY21kID0gbmV3IENvbW1hbmQoKTtcbiAgICAgIENMSVV0aWxzLmluaXRpYWxpemUoY21kLCByb290UGF0aCk7XG4gICAgICBsZXQgbSA9IG1vZHVsZSgpO1xuICAgICAgaWYgKG0gaW5zdGFuY2VvZiBQcm9taXNlKSBtID0gYXdhaXQgbTtcbiAgICAgIHRoaXMubW9kdWxlc1tuYW1lXSA9IG07XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgZmFpbGVkIHRvIGxvYWQgbW9kdWxlICR7bmFtZSB8fCBcInVubmFtZWRcIn0gdW5kZXIgJHtmaWxlUGF0aH06ICR7ZSBpbnN0YW5jZW9mIEVycm9yID8gZS5tZXNzYWdlIDogZX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmluZHMgYW5kIGxvYWRzIGFsbCBDTEkgbW9kdWxlcyBpbiB0aGUgYmFzZVBhdGhcbiAgICogQHN1bW1hcnkgVXNlcyB0aGUgY3Jhd2wgbWV0aG9kIHRvIGZpbmQgYWxsIENMSSBtb2R1bGVzIGluIHRoZSBzcGVjaWZpZWQgYmFzZSBwYXRoLCBcbiAgICogdGhlbiBsb2FkcyBhbmQgcmVnaXN0ZXJzIGVhY2ggbW9kdWxlIGFzIGEgc3ViY29tbWFuZFxuICAgKiBcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgbW9kdWxlcyBhcmUgbG9hZGVkXG4gICAqIFxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGlXcmFwcGVyXG4gICAqICAgcGFydGljaXBhbnQgRmlsZXN5c3RlbVxuICAgKiAgIHBhcnRpY2lwYW50IE1vZHVsZVxuICAgKiAgIFxuICAgKiAgIENsaVdyYXBwZXItPj5GaWxlc3lzdGVtOiBKb2luIGJhc2VQYXRoIHdpdGggY3dkXG4gICAqICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGNyYXdsKGJhc2VQYXRoLCBjcmF3bExldmVscylcbiAgICogICBDbGlXcmFwcGVyLS0+PkNsaVdyYXBwZXI6IG1vZHVsZXNbXVxuICAgKiAgIGxvb3AgRm9yIGVhY2ggbW9kdWxlXG4gICAqICAgICBhbHQgTm90IEBkZWNhZi10cy9jbGlcbiAgICogICAgICAgQ2xpV3JhcHBlci0+PkNsaVdyYXBwZXI6IGxvYWQobW9kdWxlLCBjd2QpXG4gICAqICAgICAgIENsaVdyYXBwZXItLT4+Q2xpV3JhcHBlcjogbmFtZVxuICAgKiAgICAgICBDbGlXcmFwcGVyLT4+Q2xpV3JhcHBlcjogQ2hlY2sgaWYgY29tbWFuZCBleGlzdHNcbiAgICogICAgICAgYWx0IENvbW1hbmQgZG9lc24ndCBleGlzdFxuICAgKiAgICAgICAgIENsaVdyYXBwZXItPj5Db21tYW5kOiBjb21tYW5kKG5hbWUpLmFkZENvbW1hbmQobW9kdWxlc1tuYW1lXSlcbiAgICogICAgICAgZW5kXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICogICBDbGlXcmFwcGVyLT4+Q29uc29sZTogTG9nIGxvYWRlZCBtb2R1bGVzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGJvb3QoKSB7XG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXRoLnJlc29sdmUodGhpcy5yb290UGF0aCwgdGhpcy5iYXNlUGF0aCk7XG4gICAgY29uc3QgbW9kdWxlcyA9IHRoaXMuY3Jhd2woYmFzZVBhdGgsIHRoaXMuY3Jhd2xMZXZlbHMpO1xuICAgIGZvciAoY29uc3QgbW9kdWxlIG9mIG1vZHVsZXMpIHtcbiAgICAgIGlmIChtb2R1bGUuaW5jbHVkZXMoXCJAZGVjYWYtdHMvY2xpXCIpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbGV0IG5hbWU6IHN0cmluZztcbiAgICAgIHRyeSB7XG4gICAgICAgIG5hbWUgPSBhd2FpdCB0aGlzLmxvYWQobW9kdWxlLCB0aGlzLnJvb3RQYXRoKTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuY29tbWFuZC5jb21tYW5kcy5maW5kKFxuICAgICAgICAgIChjKSA9PiAoYyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pW1wiX25hbWVcIl0gPT09IG5hbWVcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuY29tbWFuZC5jb21tYW5kKG5hbWUpLmFkZENvbW1hbmQodGhpcy5tb2R1bGVzW25hbWVdKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc29sZS5sb2coXG4gICAgICBgbG9hZGVkIG1vZHVsZXM6XFxuJHtPYmplY3Qua2V5cyh0aGlzLm1vZHVsZXMpXG4gICAgICAgIC5tYXAoKGspID0+IGAtICR7a31gKVxuICAgICAgICAuam9pbihcIlxcblwiKX1gXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVjdXJzaXZlbHkgc2VhcmNoZXMgZm9yIENMSSBtb2R1bGUgZmlsZXMgaW4gdGhlIGRpcmVjdG9yeSBzdHJ1Y3R1cmVcbiAgICogQHN1bW1hcnkgQ3Jhd2xzIHRoZSBiYXNlUGF0aCB1cCB0byB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBmb2xkZXIgbGV2ZWxzIHRvIGZpbmQgZmlsZXMgbmFtZWQgYWNjb3JkaW5nIHRvIENMSV9GSUxFX05BTUVcbiAgICogXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlUGF0aCBUaGUgYWJzb2x1dGUgYmFzZSBwYXRoIHRvIHN0YXJ0IHNlYXJjaGluZyBpblxuICAgKiBAcGFyYW0ge251bWJlcn0gW2xldmVscz0yXSBUaGUgbWF4aW11bSBudW1iZXIgb2YgZGlyZWN0b3J5IGxldmVscyB0byBjcmF3bFxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXX0gQW4gYXJyYXkgb2YgZmlsZSBwYXRocyB0byBDTEkgbW9kdWxlc1xuICAgKiBcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgY3Jhd2woYmFzZVBhdGg6IHN0cmluZywgbGV2ZWxzOiBudW1iZXIgPSAyKSB7XG4gICAgaWYgKGxldmVscyA8PSAwKSByZXR1cm4gW107XG4gICAgcmV0dXJuIGZzLnJlYWRkaXJTeW5jKGJhc2VQYXRoKS5yZWR1Y2UoKGFjY3VtOiBzdHJpbmdbXSwgZmlsZSkgPT4ge1xuICAgICAgZmlsZSA9IHBhdGguam9pbihiYXNlUGF0aCwgZmlsZSk7XG4gICAgICBpZiAoZnMuc3RhdFN5bmMoZmlsZSkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICBhY2N1bS5wdXNoKC4uLnRoaXMuY3Jhd2woZmlsZSwgbGV2ZWxzIC0gMSkpO1xuICAgICAgfSBlbHNlIGlmIChmaWxlLm1hdGNoKG5ldyBSZWdFeHAoYCR7Q0xJX0ZJTEVfTkFNRX0uW2NtXT9qcyRgLCBcImdtXCIpKSkge1xuICAgICAgICBhY2N1bS5wdXNoKGZpbGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgdGhlIENMSSB3aXRoIHRoZSBwcm92aWRlZCBhcmd1bWVudHNcbiAgICogQHN1bW1hcnkgQm9vdHMgdGhlIENMSSBieSBsb2FkaW5nIGFsbCBtb2R1bGVzLCB0aGVuIHBhcnNlcyBhbmQgZXhlY3V0ZXMgdGhlIGNvbW1hbmQgc3BlY2lmaWVkIGluIHRoZSBhcmd1bWVudHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW2FyZ3M9cHJvY2Vzcy5hcmd2XSBDb21tYW5kIGxpbmUgYXJndW1lbnRzIHRvIHBhcnNlIGFuZCBleGVjdXRlXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGNvbW1hbmQgZXhlY3V0aW9uIGlzIGNvbXBsZXRlXG4gICAqIFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBDbGlXcmFwcGVyXG4gICAqICAgcGFydGljaXBhbnQgQ29tbWFuZFxuICAgKiAgIFxuICAgKiAgIENsaWVudC0+PkNsaVdyYXBwZXI6IHJ1bihhcmdzKVxuICAgKiAgIENsaVdyYXBwZXItPj5DbGlXcmFwcGVyOiBib290KClcbiAgICogICBOb3RlIG92ZXIgQ2xpV3JhcHBlcjogTG9hZHMgYWxsIG1vZHVsZXNcbiAgICogICBDbGlXcmFwcGVyLT4+Q29tbWFuZDogcGFyc2VBc3luYyhhcmdzKVxuICAgKiAgIENvbW1hbmQtLT4+Q2xpV3JhcHBlcjogcmVzdWx0XG4gICAqICAgQ2xpV3JhcHBlci0tPj5DbGllbnQ6IHJlc3VsdFxuICAgKi9cbiAgYXN5bmMgcnVuKGFyZ3M6IHN0cmluZ1tdID0gcHJvY2Vzcy5hcmd2KSB7XG4gICAgYXdhaXQgdGhpcy5ib290KCk7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZC5wYXJzZUFzeW5jKGFyZ3MpO1xuICB9XG59XG4iLCJleHBvcnQgKiBmcm9tIFwiLi9DbGlXcmFwcGVyXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY2FmLXRzJyBDTEkgbW9kdWxlXG4gKiBAc3VtbWFyeSBUaGlzIGZpbGUgd2lsbCBjcmF3bCB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBmb3IgZmlsZXMgY2FsbGVkIHtAbGluayBDTElfRklMRV9OQU1FfVxuICogd2l0aGluIHRoZSBAZGVjYWYtdHMgbmFtZXNwYWNlIGFuZCBsb2FkIHRoZW0gYXMgc3ViY29tbWFuZHMuIEl0IHNlcnZlcyBhcyB0aGUgbWFpbiBlbnRyeSBwb2ludFxuICogZm9yIHRoZSBDTEkgZnVuY3Rpb25hbGl0eSwgZXhwb3J0aW5nIHRoZSBDbGlXcmFwcGVyIGNsYXNzIGFuZCBWRVJTSU9OIGNvbnN0YW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBydW4gbW9kdWxlIGNvbW1hbmQgICAgIC0gJCBucHggZGVjYWYgPG1vZHVsZSBuYW1lPiA8bW9kdWxlIGNvbW1hbmQ+IC4uLjxtb2R1bGUgY29tbWFuZCBvcHRpb25zPlxuICogZ2V0IG1vZHVsZSBoZWxwICAgICAgICAtICQgbnB4IGRlY2FmIGhlbHAgPG1vZHVsZSBuYW1lPjtcbiAqIGxpc3QgaW1wb3J0ZWQgbW9kdWxlcyAgLSAkIG5weCBkZWNhZiBsaXN0O1xuICogZ2V0IGNsaSBoZWxwICAgICAgICAgICAtICQgbnB4IGRlY2FmIGhlbHA7XG4gKlxuICogQG1vZHVsZSBDTElcbiAqL1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uXG4gKiBAc3VtbWFyeSBBIGNvbnN0YW50IHRoYXQgaG9sZHMgdGhlIHZlcnNpb24gc3RyaW5nIG9mIHRoZSBwYWNrYWdlLCB3aGljaCBpcyByZXBsYWNlZCBkdXJpbmcgYnVpbGRcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNMSVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBR0E7Ozs7OztBQU1HO0FBQ0ksTUFBTSxhQUFhLEdBQUcsWUFBWTs7QUNMekM7Ozs7Ozs7Ozs7Ozs7QUFhRztNQUNVLFFBQVEsQ0FBQTtBQUNuQjs7Ozs7O0FBTUc7QUFDSCxJQUFBLGFBQWEsWUFBWSxDQUFDLElBQVksRUFBQTtBQUNwQyxRQUFBLElBQUk7WUFDRixPQUFPLFFBQVEsQ0FBQyxlQUFlLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQzs7UUFDN0MsT0FBTyxDQUFVLEVBQUU7WUFDbkIsTUFBTSxJQUFJLEtBQUssQ0FDYixDQUFBLG9CQUFBLEVBQXVCLElBQUksQ0FBSyxFQUFBLEVBQUEsQ0FBQyxZQUFZLEtBQUssR0FBRyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBRSxDQUFBLENBQ3JFOzs7QUFJTDs7Ozs7Ozs7QUFRRztBQUNILElBQUEsYUFBYSxlQUFlLENBQUksYUFBeUIsRUFBQTs7QUFFdkQsUUFBQSxPQUFPLGFBQWEsQ0FBQyxJQUFJLENBQ3ZC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