@nlabs/arkhamjs 3.25.0 → 3.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nlabs/arkhamjs",
3
- "version": "3.25.0",
3
+ "version": "3.26.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -36,7 +36,11 @@
36
36
  "build": "lex compile -r",
37
37
  "clean": "lex clean",
38
38
  "lint": "eslint ./src --ext .ts,.tsx",
39
- "pretest": "yarn lint",
39
+ "prepublishOnly": "npm run build",
40
+ "pretest": "npm run lint",
41
+ "publish:major": "npm version major && npm publish",
42
+ "publish:minor": "npm version minor && npm publish",
43
+ "publish:patch": "npm version patch && npm publish",
40
44
  "test": "lex test",
41
45
  "update": "lex update -i"
42
46
  },
@@ -47,12 +51,12 @@
47
51
  },
48
52
  "devDependencies": {
49
53
  "@types/events": "^3.0.0",
50
- "@types/jest": "^29.2.4",
54
+ "@types/jest": "^29.5.0",
51
55
  "@types/lodash": "^4.14.191",
52
- "@types/node": "^18.11.17",
53
- "eslint": "^8.30.0",
54
- "eslint-config-styleguidejs": "^3.1.0",
55
- "typescript": "^4.9.4"
56
+ "@types/node": "^18.15.5",
57
+ "eslint": "^8.36.0",
58
+ "eslint-config-styleguidejs": "^3.2.1",
59
+ "typescript": "^5.0.2"
56
60
  },
57
- "gitHead": "7a0926a9d3e5660cfdde3c1b78de45674aafea25"
61
+ "gitHead": "fc371e1e28fe0ae35d40d29a217d5f0e990ec32a"
58
62
  }
@@ -1,38 +0,0 @@
1
- /// <reference types="node" />
2
- import { EventEmitter } from 'events';
3
- import { FluxAction, FluxMiddlewareType, FluxOptions, FluxStore } from './Flux.types';
4
- export declare class FluxFramework extends EventEmitter {
5
- static initFlux: boolean;
6
- isInit: boolean;
7
- pluginTypes: string[];
8
- private state;
9
- private storeActions;
10
- private defaultOptions;
11
- private middleware;
12
- private options;
13
- constructor();
14
- addMiddleware(middleware: FluxMiddlewareType[]): void;
15
- clearAppData(): Promise<boolean>;
16
- clearMiddleware(): boolean;
17
- removeStores(storeNames: string[]): void;
18
- dispatch(action: FluxAction, silent?: boolean): Promise<FluxAction>;
19
- getOptions(): FluxOptions;
20
- getState(path?: string | string[], defaultValue?: any): any;
21
- getStore(name?: string): FluxStore;
22
- init(options?: FluxOptions, reset?: boolean): Promise<FluxFramework>;
23
- onInit(listener: (...args: any[]) => void): void;
24
- offInit(listener: (...args: any[]) => void): void;
25
- off(eventType: string, listener: (...args: any[]) => void): this;
26
- on(eventType: string, listener: (...args: any[]) => void): this;
27
- addStores(stores: any[]): Promise<object[]>;
28
- removeMiddleware(names: string[]): void;
29
- reset(clearStorage?: boolean): Promise<void>;
30
- setState(path: string | string[], value: any): Promise<boolean>;
31
- private addPlugin;
32
- private deregister;
33
- private register;
34
- private removePlugin;
35
- private updateStorage;
36
- private useStorage;
37
- }
38
- export declare const Flux: FluxFramework;
package/lib/Flux/Flux.js DELETED
@@ -1,372 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
- mod
22
- ));
23
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
- var Flux_exports = {};
25
- __export(Flux_exports, {
26
- Flux: () => Flux,
27
- FluxFramework: () => FluxFramework
28
- });
29
- module.exports = __toCommonJS(Flux_exports);
30
- var import_error_stack_parser = __toESM(require("error-stack-parser"));
31
- var import_events = require("events");
32
- var import_debounce = __toESM(require("lodash/debounce"));
33
- var import_cloneDeep = __toESM(require("lodash/fp/cloneDeep"));
34
- var import_get = __toESM(require("lodash/fp/get"));
35
- var import_isEmpty = __toESM(require("lodash/fp/isEmpty"));
36
- var import_merge = __toESM(require("lodash/fp/merge"));
37
- var import_set = __toESM(require("lodash/fp/set"));
38
- var import_ArkhamConstants = require("../constants/ArkhamConstants");
39
- class FluxFramework extends import_events.EventEmitter {
40
- constructor() {
41
- super();
42
- this.isInit = false;
43
- this.pluginTypes = ["preDispatch", "postDispatch"];
44
- this.state = {};
45
- this.storeActions = {};
46
- this.defaultOptions = {
47
- name: "arkhamjs",
48
- routerType: "browser",
49
- scrollToTop: true,
50
- state: null,
51
- storage: null,
52
- storageWait: 300,
53
- stores: [],
54
- title: "ArkhamJS"
55
- };
56
- this.middleware = {};
57
- this.options = this.defaultOptions;
58
- this.updateStorage = () => Promise.resolve(false);
59
- this.addMiddleware = this.addMiddleware.bind(this);
60
- this.addStores = this.addStores.bind(this);
61
- this.clearAppData = this.clearAppData.bind(this);
62
- this.clearMiddleware = this.clearMiddleware.bind(this);
63
- this.deregister = this.deregister.bind(this);
64
- this.dispatch = this.dispatch.bind(this);
65
- this.getOptions = this.getOptions.bind(this);
66
- this.getState = this.getState.bind(this);
67
- this.getStore = this.getStore.bind(this);
68
- this.init = this.init.bind(this);
69
- this.off = this.off.bind(this);
70
- this.register = this.register.bind(this);
71
- this.removeMiddleware = this.removeMiddleware.bind(this);
72
- this.removeStores = this.removeStores.bind(this);
73
- this.reset = this.reset.bind(this);
74
- this.setState = this.setState.bind(this);
75
- this.pluginTypes.forEach((type) => this.middleware[`${type}List`] = []);
76
- }
77
- addMiddleware(middleware) {
78
- middleware.forEach((middleObj) => {
79
- if (!!middleObj && (typeof middleObj === "function" || typeof middleObj === "object")) {
80
- const middleName = middleObj.name || "";
81
- if (!middleName) {
82
- throw Error("Unknown middleware is not configured properly. Requires name property. Cannot add to Flux.");
83
- }
84
- this.pluginTypes.forEach((type) => {
85
- const method = middleObj[type];
86
- const plugin = { method, name: middleName };
87
- this.middleware[`${type}List`] = this.addPlugin(type, plugin);
88
- });
89
- } else {
90
- throw Error("Unknown middleware is not configured properly. Cannot add to Flux.");
91
- }
92
- });
93
- }
94
- clearAppData() {
95
- Object.keys(this.storeActions).forEach((storeName) => {
96
- const storeFn = this.storeActions[storeName];
97
- this.state[storeFn.name] = (0, import_cloneDeep.default)(storeFn.initialState);
98
- });
99
- const { name, storage } = this.options;
100
- if (storage) {
101
- return storage.setStorageData(name, this.state);
102
- }
103
- return Promise.resolve(true);
104
- }
105
- clearMiddleware() {
106
- Object.keys(this.middleware).forEach((pluginType) => {
107
- this.middleware[pluginType] = [];
108
- });
109
- return true;
110
- }
111
- removeStores(storeNames) {
112
- storeNames.forEach((name) => this.deregister(name));
113
- }
114
- async dispatch(action, silent = false) {
115
- if (!action) {
116
- throw new Error("ArkhamJS Error: Flux.dispatch requires an action.");
117
- }
118
- let clonedAction = (0, import_cloneDeep.default)(action);
119
- const startTime = Date.now();
120
- let stack = [];
121
- try {
122
- const stackProperty = "stackTraceLimit";
123
- const { stackTraceLimit } = Error;
124
- Error[stackProperty] = Infinity;
125
- stack = import_error_stack_parser.default.parse(new Error());
126
- Error[stackProperty] = stackTraceLimit;
127
- } catch (error) {
128
- }
129
- const options = (0, import_cloneDeep.default)(this.options);
130
- const appInfo = { duration: 0, options, stack };
131
- const { postDispatchList = [], preDispatchList = [] } = this.middleware;
132
- if (preDispatchList.length) {
133
- clonedAction = await Promise.all(
134
- preDispatchList.map(
135
- (plugin) => plugin.method(
136
- (0, import_cloneDeep.default)(clonedAction),
137
- (0, import_cloneDeep.default)(this.state),
138
- appInfo
139
- )
140
- )
141
- ).then(
142
- (actions) => actions.reduce((updatedAction, action2) => (0, import_merge.default)(updatedAction, action2), clonedAction)
143
- ).catch((error) => {
144
- throw error;
145
- });
146
- }
147
- const { type, ...data } = clonedAction;
148
- if (!type || type === "") {
149
- console.warn("ArkhamJS Warning: Flux.dispatch is missing an action type for the payload:", data);
150
- return Promise.resolve(clonedAction);
151
- }
152
- Object.keys(this.storeActions).forEach((storeName) => {
153
- const storeFn = this.storeActions[storeName];
154
- const state = (0, import_cloneDeep.default)(this.state[storeName]) || (0, import_cloneDeep.default)(storeFn.initialState) || {};
155
- this.state[storeName] = (0, import_cloneDeep.default)(storeFn.action(type, data, state)) || state;
156
- });
157
- const { storage } = this.options;
158
- if (storage) {
159
- try {
160
- await this.updateStorage();
161
- } catch (error) {
162
- }
163
- }
164
- const endTime = +new Date();
165
- const duration = endTime - startTime;
166
- appInfo.duration = duration;
167
- if (postDispatchList.length) {
168
- clonedAction = await Promise.all(
169
- postDispatchList.map(
170
- async (plugin) => plugin.method((0, import_cloneDeep.default)(clonedAction), (0, import_cloneDeep.default)(this.state), appInfo)
171
- )
172
- ).then(
173
- (actions) => actions.reduce((updatedAction, action2) => (0, import_merge.default)(updatedAction, action2), clonedAction)
174
- ).catch((error) => {
175
- throw error;
176
- });
177
- }
178
- if (!silent) {
179
- this.emit(type, clonedAction);
180
- this.emit("arkhamjs", this.state);
181
- }
182
- return Promise.resolve(clonedAction);
183
- }
184
- getOptions() {
185
- return this.options;
186
- }
187
- getState(path = "", defaultValue) {
188
- let storeValue;
189
- if (!path) {
190
- storeValue = this.state || {};
191
- } else {
192
- storeValue = (0, import_get.default)(path, this.state);
193
- }
194
- const value = storeValue ? (0, import_cloneDeep.default)(storeValue) : storeValue;
195
- return value === void 0 ? defaultValue : value;
196
- }
197
- getStore(name = "") {
198
- return this.storeActions[name];
199
- }
200
- async init(options = {}, reset = false) {
201
- if (reset) {
202
- this.isInit = false;
203
- this.reset(false);
204
- }
205
- const updatedOptions = { ...options };
206
- if (this.isInit) {
207
- updatedOptions.name = this.options.name;
208
- }
209
- this.options = { ...this.defaultOptions, ...updatedOptions };
210
- const { debug, middleware, name, stores } = this.options;
211
- try {
212
- await this.useStorage(name);
213
- } catch (error) {
214
- console.error("Arkham Error: There was an error while using storage.", name);
215
- throw error;
216
- }
217
- if (!!stores && stores.length) {
218
- try {
219
- await this.addStores(stores);
220
- } catch (error) {
221
- console.error("Arkham Error: There was an error while adding stores.", stores);
222
- throw error;
223
- }
224
- }
225
- if (!!middleware && middleware.length) {
226
- this.addMiddleware(middleware);
227
- }
228
- const windowProperty = "arkhamjs";
229
- if (debug) {
230
- window[windowProperty] = this;
231
- } else {
232
- delete window[windowProperty];
233
- }
234
- this.isInit = true;
235
- this.emit(import_ArkhamConstants.ArkhamConstants.INIT);
236
- return this;
237
- }
238
- onInit(listener) {
239
- this.on(import_ArkhamConstants.ArkhamConstants.INIT, listener);
240
- if (this.isInit) {
241
- listener();
242
- }
243
- }
244
- offInit(listener) {
245
- this.off(import_ArkhamConstants.ArkhamConstants.INIT, listener);
246
- }
247
- off(eventType, listener) {
248
- return this.removeListener(eventType, listener);
249
- }
250
- on(eventType, listener) {
251
- return this.addListener(eventType, listener);
252
- }
253
- async addStores(stores) {
254
- const registeredStores = stores.map((store) => this.register(store));
255
- const { name, storage } = this.options;
256
- if (storage) {
257
- try {
258
- await storage.setStorageData(name, this.state);
259
- } catch (error) {
260
- throw error;
261
- }
262
- }
263
- return registeredStores;
264
- }
265
- removeMiddleware(names) {
266
- names.forEach((name) => {
267
- this.pluginTypes.forEach((type) => {
268
- this.middleware[`${type}List`] = this.removePlugin(type, name);
269
- });
270
- });
271
- }
272
- async reset(clearStorage = true) {
273
- const { name, storage } = this.options;
274
- if (storage && clearStorage) {
275
- try {
276
- await storage.setStorageData(name, {});
277
- } catch (error) {
278
- throw error;
279
- }
280
- }
281
- this.middleware = {};
282
- this.options = { ...this.defaultOptions };
283
- this.state = {};
284
- this.storeActions = {};
285
- this.isInit = false;
286
- }
287
- setState(path = "", value) {
288
- if (!!path) {
289
- this.state = (0, import_set.default)(path, (0, import_cloneDeep.default)(value), this.state);
290
- }
291
- const { storage } = this.options;
292
- if (storage) {
293
- return this.updateStorage();
294
- }
295
- return Promise.resolve(false);
296
- }
297
- addPlugin(type, plugin) {
298
- const list = this.middleware[`${type}List`] || [];
299
- const { method, name } = plugin;
300
- if (method && typeof method === "function") {
301
- const exists = !!list.filter((obj) => obj.name === name).length;
302
- if (!exists) {
303
- list.push({ method, name });
304
- }
305
- } else if (method !== void 0) {
306
- throw Error(`${plugin.name} middleware is not configured properly. Method is not a function.`);
307
- }
308
- return list;
309
- }
310
- deregister(name = "") {
311
- delete this.storeActions[name];
312
- delete this.state[name];
313
- }
314
- register(storeFn) {
315
- if (!storeFn) {
316
- throw Error("Store is undefined. Cannot register with Flux.");
317
- }
318
- const isFnc = typeof storeFn === "function";
319
- if (!isFnc) {
320
- throw Error(`${storeFn} is not a store function. Cannot register with Flux.`);
321
- }
322
- const { name } = storeFn;
323
- const initialState = storeFn();
324
- const storeAction = {
325
- action: storeFn,
326
- initialState: storeFn(),
327
- name
328
- };
329
- if (!(0, import_isEmpty.default)(name) && !this.storeActions[name]) {
330
- this.storeActions[name] = storeAction;
331
- if (!this.state[name]) {
332
- if (initialState) {
333
- this.state[name] = (0, import_cloneDeep.default)(initialState);
334
- } else {
335
- this.state[name] = {};
336
- }
337
- }
338
- }
339
- return this.storeActions[name];
340
- }
341
- removePlugin(type, name) {
342
- const list = this.middleware[`${type}List`] || [];
343
- return list.filter((obj) => obj.name !== name);
344
- }
345
- async useStorage(name) {
346
- const { storage, state, storageWait } = this.options;
347
- if (storage) {
348
- try {
349
- this.state = state || await storage.getStorageData(name) || {};
350
- this.updateStorage = (0, import_debounce.default)(
351
- () => storage.setStorageData(name, this.state),
352
- storageWait,
353
- { leading: true, trailing: true }
354
- );
355
- } catch (error) {
356
- console.error(`ArkhamJS Error: Using storage, "${name}".`);
357
- throw error;
358
- }
359
- } else {
360
- this.state = state || {};
361
- }
362
- return null;
363
- }
364
- }
365
- FluxFramework.initFlux = false;
366
- const Flux = new FluxFramework();
367
- // Annotate the CommonJS export names for ESM import in node:
368
- 0 && (module.exports = {
369
- Flux,
370
- FluxFramework
371
- });
372
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL0ZsdXgvRmx1eC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCBFcnJvclN0YWNrUGFyc2VyIGZyb20gJ2Vycm9yLXN0YWNrLXBhcnNlcic7XG5pbXBvcnQge0V2ZW50RW1pdHRlcn0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCBkZWJvdW5jZSBmcm9tICdsb2Rhc2gvZGVib3VuY2UnO1xuaW1wb3J0IGNsb25lRGVlcCBmcm9tICdsb2Rhc2gvZnAvY2xvbmVEZWVwJztcbmltcG9ydCBnZXQgZnJvbSAnbG9kYXNoL2ZwL2dldCc7XG5pbXBvcnQgaXNFbXB0eSBmcm9tICdsb2Rhc2gvZnAvaXNFbXB0eSc7XG5pbXBvcnQgbWVyZ2UgZnJvbSAnbG9kYXNoL2ZwL21lcmdlJztcbmltcG9ydCBzZXQgZnJvbSAnbG9kYXNoL2ZwL3NldCc7XG5cbmltcG9ydCB7QXJraGFtQ29uc3RhbnRzfSBmcm9tICcuLi9jb25zdGFudHMvQXJraGFtQ29uc3RhbnRzJztcbmltcG9ydCB7Rmx1eEFjdGlvbiwgRmx1eE1pZGRsZXdhcmVUeXBlLCBGbHV4T3B0aW9ucywgRmx1eFBsdWdpblR5cGUsIEZsdXhTdG9yZX0gZnJvbSAnLi9GbHV4LnR5cGVzJztcblxuLyoqXG4gKiBGbHV4RnJhbWV3b3JrXG4gKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuICovXG5leHBvcnQgY2xhc3MgRmx1eEZyYW1ld29yayBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gIHN0YXRpYyBpbml0Rmx1eDogYm9vbGVhbiA9IGZhbHNlO1xuICBpc0luaXQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgLy8gUHVibGljIHByb3BlcnRpZXNcbiAgcGx1Z2luVHlwZXM6IHN0cmluZ1tdID0gWydwcmVEaXNwYXRjaCcsICdwb3N0RGlzcGF0Y2gnXTtcbiAgLy8gUHJpdmF0ZSBwcm9wZXJ0aWVzXG4gIHByaXZhdGUgc3RhdGU6IGFueSA9IHt9O1xuICBwcml2YXRlIHN0b3JlQWN0aW9uczogYW55ID0ge307XG4gIHByaXZhdGUgZGVmYXVsdE9wdGlvbnM6IEZsdXhPcHRpb25zID0ge1xuICAgIG5hbWU6ICdhcmtoYW1qcycsXG4gICAgcm91dGVyVHlwZTogJ2Jyb3dzZXInLFxuICAgIHNjcm9sbFRvVG9wOiB0cnVlLFxuICAgIHN0YXRlOiBudWxsLFxuICAgIHN0b3JhZ2U6IG51bGwsXG4gICAgc3RvcmFnZVdhaXQ6IDMwMCxcbiAgICBzdG9yZXM6IFtdLFxuICAgIHRpdGxlOiAnQXJraGFtSlMnXG4gIH07XG4gIHByaXZhdGUgbWlkZGxld2FyZTogYW55ID0ge307XG4gIHByaXZhdGUgb3B0aW9uczogRmx1eE9wdGlvbnMgPSB0aGlzLmRlZmF1bHRPcHRpb25zO1xuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGluc3RhbmNlIG9mIEZsdXguICBOb3RlIHRoYXQgdGhlIEZsdXggb2JqZWN0XG4gICAqIGlzIGEgU2luZ2xldG9uIHBhdHRlcm4sIHNvIG9ubHkgb25lIHNob3VsZCBldmVyIGV4aXN0LlxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHRoaXMge0ZsdXhGcmFtZXdvcmt9XG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgLy8gTWV0aG9kc1xuICAgIHRoaXMuYWRkTWlkZGxld2FyZSA9IHRoaXMuYWRkTWlkZGxld2FyZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuYWRkU3RvcmVzID0gdGhpcy5hZGRTdG9yZXMuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNsZWFyQXBwRGF0YSA9IHRoaXMuY2xlYXJBcHBEYXRhLmJpbmQodGhpcyk7XG4gICAgdGhpcy5jbGVhck1pZGRsZXdhcmUgPSB0aGlzLmNsZWFyTWlkZGxld2FyZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuZGVyZWdpc3RlciA9IHRoaXMuZGVyZWdpc3Rlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuZGlzcGF0Y2ggPSB0aGlzLmRpc3BhdGNoLmJpbmQodGhpcyk7XG4gICAgdGhpcy5nZXRPcHRpb25zID0gdGhpcy5nZXRPcHRpb25zLmJpbmQodGhpcyk7XG4gICAgdGhpcy5nZXRTdGF0ZSA9IHRoaXMuZ2V0U3RhdGUuYmluZCh0aGlzKTtcbiAgICB0aGlzLmdldFN0b3JlID0gdGhpcy5nZXRTdG9yZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaW5pdCA9IHRoaXMuaW5pdC5iaW5kKHRoaXMpO1xuICAgIHRoaXMub2ZmID0gdGhpcy5vZmYuYmluZCh0aGlzKTtcbiAgICB0aGlzLnJlZ2lzdGVyID0gdGhpcy5yZWdpc3Rlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMucmVtb3ZlTWlkZGxld2FyZSA9IHRoaXMucmVtb3ZlTWlkZGxld2FyZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMucmVtb3ZlU3RvcmVzID0gdGhpcy5yZW1vdmVTdG9yZXMuYmluZCh0aGlzKTtcbiAgICB0aGlzLnJlc2V0ID0gdGhpcy5yZXNldC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc2V0U3RhdGUgPSB0aGlzLnNldFN0YXRlLmJpbmQodGhpcyk7XG5cbiAgICAvLyBBZGQgbWlkZGxld2FyZSBwbHVnaW4gdHlwZXNcbiAgICB0aGlzLnBsdWdpblR5cGVzLmZvckVhY2goKHR5cGU6IHN0cmluZykgPT4gdGhpcy5taWRkbGV3YXJlW2Ake3R5cGV9TGlzdGBdID0gW10pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBtaWRkbGV3YXJlIHRvIGZyYW1ld29yay5cbiAgICpcbiAgICogQHBhcmFtIHthcnJheX0gbWlkZGxld2FyZSBBbiBhcnJheSBvZiBtaWRkbGV3YXJlIHRvIGFkZCB0byB0aGUgZnJhbWV3b3JrLlxuICAgKi9cbiAgYWRkTWlkZGxld2FyZShtaWRkbGV3YXJlOiBGbHV4TWlkZGxld2FyZVR5cGVbXSk6IHZvaWQge1xuICAgIG1pZGRsZXdhcmUuZm9yRWFjaCgobWlkZGxlT2JqOiBGbHV4TWlkZGxld2FyZVR5cGUpID0+IHtcbiAgICAgIC8vIE1ha2Ugc3VyZSBtaWRkbGV3YXJlIGlzIGVpdGhlciBhIGNsYXNzIG9yIG9iamVjdC5cbiAgICAgIGlmKCEhbWlkZGxlT2JqICYmICgodHlwZW9mIG1pZGRsZU9iaiA9PT0gJ2Z1bmN0aW9uJykgfHwgKHR5cGVvZiBtaWRkbGVPYmogPT09ICdvYmplY3QnKSkpIHtcbiAgICAgICAgY29uc3QgbWlkZGxlTmFtZTogc3RyaW5nID0gbWlkZGxlT2JqLm5hbWUgfHwgJyc7XG5cbiAgICAgICAgaWYoIW1pZGRsZU5hbWUpIHtcbiAgICAgICAgICB0aHJvdyBFcnJvcignVW5rbm93biBtaWRkbGV3YXJlIGlzIG5vdCBjb25maWd1cmVkIHByb3Blcmx5LiBSZXF1aXJlcyBuYW1lIHByb3BlcnR5LiBDYW5ub3QgYWRkIHRvIEZsdXguJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb3J0IG1pZGRsZXdhcmUgcGx1Z2lucyBmb3IgZWZmaWNpZW5jeVxuICAgICAgICB0aGlzLnBsdWdpblR5cGVzLmZvckVhY2goKHR5cGU6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGNvbnN0IG1ldGhvZCA9IG1pZGRsZU9ialt0eXBlXTtcbiAgICAgICAgICBjb25zdCBwbHVnaW46IEZsdXhQbHVnaW5UeXBlID0ge21ldGhvZCwgbmFtZTogbWlkZGxlTmFtZX07XG4gICAgICAgICAgdGhpcy5taWRkbGV3YXJlW2Ake3R5cGV9TGlzdGBdID0gdGhpcy5hZGRQbHVnaW4odHlwZSwgcGx1Z2luKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBFcnJvcignVW5rbm93biBtaWRkbGV3YXJlIGlzIG5vdCBjb25maWd1cmVkIHByb3Blcmx5LiBDYW5ub3QgYWRkIHRvIEZsdXguJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBhcHAgZGF0YSBmcm9tIHN0b3JhZ2UuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSBXaGV0aGVyIGFwcCBkYXRhIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZC5cbiAgICovXG4gIGNsZWFyQXBwRGF0YSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAvLyBTZXQgYWxsIHN0b3JlIGRhdGEgdG8gaW5pdGlhbCBzdGF0ZVxuICAgIE9iamVjdFxuICAgICAgLmtleXModGhpcy5zdG9yZUFjdGlvbnMpXG4gICAgICAuZm9yRWFjaCgoc3RvcmVOYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3Qgc3RvcmVGbiA9IHRoaXMuc3RvcmVBY3Rpb25zW3N0b3JlTmFtZV07XG4gICAgICAgIHRoaXMuc3RhdGVbc3RvcmVGbi5uYW1lXSA9IGNsb25lRGVlcChzdG9yZUZuLmluaXRpYWxTdGF0ZSk7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHtuYW1lLCBzdG9yYWdlfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmKHN0b3JhZ2UpIHtcbiAgICAgIHJldHVybiBzdG9yYWdlLnNldFN0b3JhZ2VEYXRhKG5hbWUsIHRoaXMuc3RhdGUpO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBtaWRkbGV3YXJlLlxuICAgKlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBtaWRkbGV3YXJlIHdhcyBzdWNjZXNzZnVsbHkgcmVtb3ZlZC5cbiAgICovXG4gIGNsZWFyTWlkZGxld2FyZSgpOiBib29sZWFuIHtcbiAgICAvLyBTZXQgYWxsIHN0b3JlIGRhdGEgdG8gaW5pdGlhbCBzdGF0ZVxuICAgIE9iamVjdFxuICAgICAgLmtleXModGhpcy5taWRkbGV3YXJlKVxuICAgICAgLmZvckVhY2goKHBsdWdpblR5cGU6IHN0cmluZykgPT4ge1xuICAgICAgICB0aGlzLm1pZGRsZXdhcmVbcGx1Z2luVHlwZV0gPSBbXTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogRGUtcmVnaXN0ZXJzIG5hbWVkIHN0b3Jlcy5cbiAgICpcbiAgICogQHBhcmFtIHthcnJheX0gc3RvcmVOYW1lcyBBbiBhcnJheSBvZiBzdG9yZSBuYW1lcyB0byByZW1vdmUgZnJvbSB0aGUgZnJhbWV3b3JrLlxuICAgKi9cbiAgcmVtb3ZlU3RvcmVzKHN0b3JlTmFtZXM6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgc3RvcmVOYW1lcy5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHRoaXMuZGVyZWdpc3RlcihuYW1lKSk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhbiBhY3Rpb24gdG8gYWxsIHN0b3Jlcy5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IGFjdGlvbiB0byBkaXNwYXRjaCB0byBhbGwgdGhlIHN0b3Jlcy5cbiAgICogQHBhcmFtIHtib29sZWFufSBzaWxlbnQgVG8gc2lsZW5jZSBhbnkgZXZlbnRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gVGhlIHByb21pc2UgaXMgcmVzb2x2ZWQgd2hlbiBhbmQgaWYgdGhlIGFwcCBzYXZlcyBkYXRhIHRvIHN0b3JhZ2UsIHJldHVybmluZ1xuICAgKiB0aGUgYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgZGlzcGF0Y2goYWN0aW9uOiBGbHV4QWN0aW9uLCBzaWxlbnQ6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8Rmx1eEFjdGlvbj4ge1xuICAgIGlmKCFhY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQXJraGFtSlMgRXJyb3I6IEZsdXguZGlzcGF0Y2ggcmVxdWlyZXMgYW4gYWN0aW9uLicpO1xuICAgIH1cblxuICAgIGxldCBjbG9uZWRBY3Rpb246IEZsdXhBY3Rpb24gPSBjbG9uZURlZXAoYWN0aW9uKTtcblxuICAgIC8vIExvZyBkdXJhdGlvbiBvZiBkaXNwYXRjaFxuICAgIGNvbnN0IHN0YXJ0VGltZTogbnVtYmVyID0gRGF0ZS5ub3coKTtcblxuICAgIC8vIEdldCBzdGFja1xuICAgIGxldCBzdGFjayA9IFtdO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0YWNrUHJvcGVydHk6IHN0cmluZyA9ICdzdGFja1RyYWNlTGltaXQnO1xuICAgICAgY29uc3Qge3N0YWNrVHJhY2VMaW1pdH06IGFueSA9IEVycm9yO1xuICAgICAgRXJyb3Jbc3RhY2tQcm9wZXJ0eV0gPSBJbmZpbml0eTtcbiAgICAgIHN0YWNrID0gRXJyb3JTdGFja1BhcnNlci5wYXJzZShuZXcgRXJyb3IoKSk7XG4gICAgICBFcnJvcltzdGFja1Byb3BlcnR5XSA9IHN0YWNrVHJhY2VMaW1pdDtcbiAgICB9IGNhdGNoKGVycm9yKSB7fVxuXG4gICAgLy8gR2V0IG9wdGlvbnNcbiAgICBjb25zdCBvcHRpb25zID0gY2xvbmVEZWVwKHRoaXMub3B0aW9ucyk7XG5cbiAgICAvLyBBcHAgaW5mb1xuICAgIGNvbnN0IGFwcEluZm8gPSB7ZHVyYXRpb246IDAsIG9wdGlvbnMsIHN0YWNrfTtcblxuICAgIC8vIEFwcGx5IG1pZGRsZXdhcmUgYmVmb3JlIHRoZSBhY3Rpb24gaXMgcHJvY2Vzc2VkXG4gICAgY29uc3Qge3Bvc3REaXNwYXRjaExpc3QgPSBbXSwgcHJlRGlzcGF0Y2hMaXN0ID0gW119ID0gdGhpcy5taWRkbGV3YXJlO1xuXG4gICAgaWYocHJlRGlzcGF0Y2hMaXN0Lmxlbmd0aCkge1xuICAgICAgY2xvbmVkQWN0aW9uID0gYXdhaXQgUHJvbWlzZVxuICAgICAgICAuYWxsKFxuICAgICAgICAgIHByZURpc3BhdGNoTGlzdC5tYXAoKHBsdWdpbjogRmx1eFBsdWdpblR5cGUpID0+IHBsdWdpbi5tZXRob2QoXG4gICAgICAgICAgICBjbG9uZURlZXAoY2xvbmVkQWN0aW9uKSwgY2xvbmVEZWVwKHRoaXMuc3RhdGUpLCBhcHBJbmZvKVxuICAgICAgICAgIClcbiAgICAgICAgKVxuICAgICAgICAudGhlbihcbiAgICAgICAgICAoYWN0aW9ucykgPT4gYWN0aW9ucy5yZWR1Y2UoKHVwZGF0ZWRBY3Rpb24sIGFjdGlvbikgPT5cbiAgICAgICAgICAgIG1lcmdlKHVwZGF0ZWRBY3Rpb24sIGFjdGlvbiksIGNsb25lZEFjdGlvbikgYXMgRmx1eEFjdGlvblxuICAgICAgICApXG4gICAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY29uc3Qge3R5cGUsIC4uLmRhdGF9ID0gY2xvbmVkQWN0aW9uO1xuXG4gICAgLy8gUmVxdWlyZSBhIHR5cGVcbiAgICBpZighdHlwZSB8fCB0eXBlID09PSAnJykge1xuICAgICAgY29uc29sZS53YXJuKCdBcmtoYW1KUyBXYXJuaW5nOiBGbHV4LmRpc3BhdGNoIGlzIG1pc3NpbmcgYW4gYWN0aW9uIHR5cGUgZm9yIHRoZSBwYXlsb2FkOicsIGRhdGEpO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjbG9uZWRBY3Rpb24pO1xuICAgIH1cblxuICAgIC8vIFdoZW4gYW4gYWN0aW9uIGNvbWVzIGluLCBpdCBtdXN0IGJlIGNvbXBsZXRlbHkgaGFuZGxlZCBieSBhbGwgc3RvcmVzXG4gICAgT2JqZWN0XG4gICAgICAua2V5cyh0aGlzLnN0b3JlQWN0aW9ucylcbiAgICAgIC5mb3JFYWNoKChzdG9yZU5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICBjb25zdCBzdG9yZUZuID0gdGhpcy5zdG9yZUFjdGlvbnNbc3RvcmVOYW1lXTtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBjbG9uZURlZXAodGhpcy5zdGF0ZVtzdG9yZU5hbWVdKSB8fCBjbG9uZURlZXAoc3RvcmVGbi5pbml0aWFsU3RhdGUpIHx8IHt9O1xuICAgICAgICB0aGlzLnN0YXRlW3N0b3JlTmFtZV0gPSBjbG9uZURlZXAoc3RvcmVGbi5hY3Rpb24odHlwZSwgZGF0YSwgc3RhdGUpKSB8fCBzdGF0ZTtcbiAgICAgIH0pO1xuXG4gICAgLy8gU2F2ZSBjYWNoZSBpbiBzdG9yYWdlXG4gICAgY29uc3Qge3N0b3JhZ2V9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgaWYoc3RvcmFnZSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy51cGRhdGVTdG9yYWdlKCk7XG4gICAgICB9IGNhdGNoKGVycm9yKSB7fVxuICAgIH1cblxuICAgIGNvbnN0IGVuZFRpbWU6IG51bWJlciA9ICsobmV3IERhdGUoKSk7XG4gICAgY29uc3QgZHVyYXRpb246IG51bWJlciA9IGVuZFRpbWUgLSBzdGFydFRpbWU7XG4gICAgYXBwSW5mby5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuXG4gICAgaWYocG9zdERpc3BhdGNoTGlzdC5sZW5ndGgpIHtcbiAgICAgIGNsb25lZEFjdGlvbiA9IGF3YWl0IFByb21pc2VcbiAgICAgICAgLmFsbChcbiAgICAgICAgICBwb3N0RGlzcGF0Y2hMaXN0Lm1hcChcbiAgICAgICAgICAgIGFzeW5jIChwbHVnaW46IEZsdXhQbHVnaW5UeXBlKSA9PiBwbHVnaW4ubWV0aG9kKGNsb25lRGVlcChjbG9uZWRBY3Rpb24pLCBjbG9uZURlZXAodGhpcy5zdGF0ZSksIGFwcEluZm8pXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIChhY3Rpb25zKSA9PiBhY3Rpb25zLnJlZHVjZSgodXBkYXRlZEFjdGlvbiwgYWN0aW9uKSA9PlxuICAgICAgICAgICAgbWVyZ2UodXBkYXRlZEFjdGlvbiwgYWN0aW9uKSwgY2xvbmVkQWN0aW9uKSBhcyBGbHV4QWN0aW9uXG4gICAgICAgIClcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpZighc2lsZW50KSB7XG4gICAgICB0aGlzLmVtaXQodHlwZSwgY2xvbmVkQWN0aW9uKTtcbiAgICAgIHRoaXMuZW1pdCgnYXJraGFtanMnLCB0aGlzLnN0YXRlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNsb25lZEFjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50IEZsdXggb3B0aW9ucy5cbiAgICpcbiAgICogQHJldHVybnMge0ZsdXhPcHRpb25zfSB0aGUgRmx1eCBvcHRpb25zIG9iamVjdC5cbiAgICovXG4gIGdldE9wdGlvbnMoKTogRmx1eE9wdGlvbnMge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50IHN0YXRlIG9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd8YXJyYXl9IFtuYW1lXSAob3B0aW9uYWwpIFRoZSBuYW1lIG9mIHRoZSBzdG9yZSBmb3IgYW4gb2JqZWN0LCBvdGhlcndpc2UgaXQgd2lsbCByZXR1cm4gYWxsIHN0b3JlXG4gICAqICAgb2JqZWN0cy4gWW91IGNhbiBhbHNvIHVzZSBhbiBhcnJheSB0byBzcGVjaWZ5IGEgcHJvcGVydHkgcGF0aCB3aXRoaW4gdGhlIG9iamVjdC5cbiAgICogQHBhcmFtIHthbnl9IFtkZWZhdWx0VmFsdWVdIChvcHRpb25hbCkgQSBkZWZhdWx0IHZhbHVlIHRvIHJldHVybiBpZiBudWxsLlxuICAgKiBAcmV0dXJucyB7YW55fSB0aGUgc3RhdGUgb2JqZWN0IG9yIGEgcHJvcGVydHkgdmFsdWUgd2l0aGluLlxuICAgKi9cbiAgZ2V0U3RhdGUocGF0aDogc3RyaW5nIHwgc3RyaW5nW10gPSAnJywgZGVmYXVsdFZhbHVlPyk6IGFueSB7XG4gICAgbGV0IHN0b3JlVmFsdWU7XG5cbiAgICBpZighcGF0aCkge1xuICAgICAgc3RvcmVWYWx1ZSA9IHRoaXMuc3RhdGUgfHwge307XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0b3JlVmFsdWUgPSBnZXQocGF0aCwgdGhpcy5zdGF0ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSBzdG9yZVZhbHVlID8gY2xvbmVEZWVwKHN0b3JlVmFsdWUpIDogc3RvcmVWYWx1ZTtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWx1ZSA6IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHN0b3JlIG9iamVjdCByZWdpc3RlcmVkIHdpdGggRmx1eC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgVGhlIG5hbWUgb2YgdGhlIHN0b3JlLlxuICAgKiBAcmV0dXJucyB7Rmx1eFN0b3JlfSB0aGUgc3RvcmUgb2JqZWN0LlxuICAgKi9cbiAgZ2V0U3RvcmUobmFtZTogc3RyaW5nID0gJycpOiBGbHV4U3RvcmUge1xuICAgIHJldHVybiB0aGlzLnN0b3JlQWN0aW9uc1tuYW1lXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGFuZCBzZXQgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyBDb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gICAqL1xuICBhc3luYyBpbml0KG9wdGlvbnM6IEZsdXhPcHRpb25zID0ge30sIHJlc2V0OiBib29sZWFuID0gZmFsc2UpOiBQcm9taXNlPEZsdXhGcmFtZXdvcms+IHtcbiAgICAvLyBTaG91bGQgcmVzZXQgcHJldmlvdXMgcGFyYW1zXG4gICAgaWYocmVzZXQpIHtcbiAgICAgIHRoaXMuaXNJbml0ID0gZmFsc2U7XG4gICAgICB0aGlzLnJlc2V0KGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyBTZXQgb3B0aW9uc1xuICAgIGNvbnN0IHVwZGF0ZWRPcHRpb25zID0gey4uLm9wdGlvbnN9O1xuXG4gICAgaWYodGhpcy5pc0luaXQpIHtcbiAgICAgIC8vIFJlbW92ZSB0aGUgbmFtZSBmcm9tIG9wdGlvbnMgaWYgYWxyZWFkeSBpbml0aWFsaXplZCwgb3RoZXJ3aXNlIHRoZSByb290IGFwcCB3aWxsIG5vdCBiZSBhYmxlIHRvIGFjY2Vzc1xuICAgICAgLy8gdGhlIHN0YXRlIHRyZWVcbiAgICAgIHVwZGF0ZWRPcHRpb25zLm5hbWUgPSB0aGlzLm9wdGlvbnMubmFtZTtcbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSB7Li4udGhpcy5kZWZhdWx0T3B0aW9ucywgLi4udXBkYXRlZE9wdGlvbnN9O1xuICAgIGNvbnN0IHtkZWJ1ZywgbWlkZGxld2FyZSwgbmFtZSwgc3RvcmVzfSA9IHRoaXMub3B0aW9ucztcblxuICAgIC8vIFVwZGF0ZSBkZWZhdWx0IHN0b3JlXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMudXNlU3RvcmFnZShuYW1lKTtcbiAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdBcmtoYW0gRXJyb3I6IFRoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSB1c2luZyBzdG9yYWdlLicsIG5hbWUpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgaWYoISFzdG9yZXMgJiYgc3RvcmVzLmxlbmd0aCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5hZGRTdG9yZXMoc3RvcmVzKTtcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignQXJraGFtIEVycm9yOiBUaGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgYWRkaW5nIHN0b3Jlcy4nLCBzdG9yZXMpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZighIW1pZGRsZXdhcmUgJiYgbWlkZGxld2FyZS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuYWRkTWlkZGxld2FyZShtaWRkbGV3YXJlKTtcbiAgICB9XG5cbiAgICBjb25zdCB3aW5kb3dQcm9wZXJ0eTogc3RyaW5nID0gJ2Fya2hhbWpzJztcblxuICAgIGlmKGRlYnVnKSB7XG4gICAgICB3aW5kb3dbd2luZG93UHJvcGVydHldID0gdGhpcztcbiAgICB9IGVsc2Uge1xuICAgICAgZGVsZXRlIHdpbmRvd1t3aW5kb3dQcm9wZXJ0eV07XG4gICAgfVxuXG4gICAgdGhpcy5pc0luaXQgPSB0cnVlO1xuICAgIHRoaXMuZW1pdChBcmtoYW1Db25zdGFudHMuSU5JVCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGFuIGluaXRpYWxpemF0aW9uIGxpc3RlbmVyLlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBbbGlzdGVuZXJdIFRoZSBjYWxsYmFjayBhc3NvY2lhdGVkIHdpdGggdGhlIHN1YnNjcmliZWQgZXZlbnQuXG4gICAqL1xuICBvbkluaXQobGlzdGVuZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub24oQXJraGFtQ29uc3RhbnRzLklOSVQsIGxpc3RlbmVyKTtcblxuICAgIGlmKHRoaXMuaXNJbml0KSB7XG4gICAgICBsaXN0ZW5lcigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHRoZSBpbml0aWFsaXphdGlvbiBsaXN0ZW5lci5cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gW2xpc3RlbmVyXSBUaGUgY2FsbGJhY2sgYXNzb2NpYXRlZCB3aXRoIHRoZSBzdWJzY3JpYmVkIGV2ZW50LlxuICAgKi9cbiAgb2ZmSW5pdChsaXN0ZW5lcjogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5vZmYoQXJraGFtQ29uc3RhbnRzLklOSVQsIGxpc3RlbmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFuIGV2ZW50IGxpc3RlbmVyLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2V2ZW50VHlwZV0gRXZlbnQgdG8gdW5zdWJzY3JpYmUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtsaXN0ZW5lcl0gVGhlIGNhbGxiYWNrIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3Vic2NyaWJlZCBldmVudC5cbiAgICovXG4gIG9mZihldmVudFR5cGU6IHN0cmluZywgbGlzdGVuZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCk6IHRoaXMge1xuICAgIHJldHVybiB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2ZW50VHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gZXZlbnQgbGlzdGVuZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZXZlbnRUeXBlXSBFdmVudCB0byBzdWJzY3JpYmUuXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IFtsaXN0ZW5lcl0gVGhlIGNhbGxiYWNrIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3Vic2NyaWJlZCBldmVudC5cbiAgICovXG4gIG9uKGV2ZW50VHlwZTogc3RyaW5nLCBsaXN0ZW5lcjogKC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkKTogdGhpcyB7XG4gICAgcmV0dXJuIHRoaXMuYWRkTGlzdGVuZXIoZXZlbnRUeXBlLCBsaXN0ZW5lcik7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIG5ldyBTdG9yZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7YXJyYXl9IHN0b3JlcyBTdG9yZSBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0W10+fSB0aGUgY2xhc3Mgb2JqZWN0KHMpLlxuICAgKi9cbiAgYXN5bmMgYWRkU3RvcmVzKHN0b3JlczogYW55W10pOiBQcm9taXNlPG9iamVjdFtdPiB7XG4gICAgY29uc3QgcmVnaXN0ZXJlZFN0b3JlczogRmx1eFN0b3JlW10gPSBzdG9yZXMubWFwKChzdG9yZTogRmx1eFN0b3JlKSA9PiB0aGlzLnJlZ2lzdGVyKHN0b3JlKSk7XG5cbiAgICAvLyBTYXZlIGNhY2hlIGluIHNlc3Npb24gc3RvcmFnZVxuICAgIGNvbnN0IHtuYW1lLCBzdG9yYWdlfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmKHN0b3JhZ2UpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2V0U3RvcmFnZURhdGEobmFtZSwgdGhpcy5zdGF0ZSk7XG4gICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiBjbGFzc2VzXG4gICAgcmV0dXJuIHJlZ2lzdGVyZWRTdG9yZXM7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIG1pZGRsZXdhcmUgZnJvbSBmcmFtZXdvcmsuXG4gICAqXG4gICAqIEBwYXJhbSB7YXJyYXl9IHN0cmluZyBtaWRkbGV3YXJlIG5hbWVzIHRvIHJlbW92ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8b2JqZWN0W10+fSB0aGUgY2xhc3Mgb2JqZWN0KHMpLlxuICAgKi9cbiAgcmVtb3ZlTWlkZGxld2FyZShuYW1lczogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBuYW1lcy5mb3JFYWNoKChuYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIFJlbW92ZSBtaWRkbGV3YXJlIHBsdWdpbnNcbiAgICAgIHRoaXMucGx1Z2luVHlwZXMuZm9yRWFjaCgodHlwZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRoaXMubWlkZGxld2FyZVtgJHt0eXBlfUxpc3RgXSA9IHRoaXMucmVtb3ZlUGx1Z2luKHR5cGUsIG5hbWUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXQgZnJhbWV3b3JrLlxuICAgKlxuICAgKiBAcGFyYW0ge2FycmF5fSBzdHJpbmcgbWlkZGxld2FyZSBuYW1lcyB0byByZW1vdmUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG9iamVjdFtdPn0gdGhlIGNsYXNzIG9iamVjdChzKS5cbiAgICovXG4gIGFzeW5jIHJlc2V0KGNsZWFyU3RvcmFnZTogYm9vbGVhbiA9IHRydWUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7bmFtZSwgc3RvcmFnZX0gPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAvLyBDbGVhciBwZXJzaXN0ZW50IGNhY2hlXG4gICAgaWYoc3RvcmFnZSAmJiBjbGVhclN0b3JhZ2UpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2V0U3RvcmFnZURhdGEobmFtZSwge30pO1xuICAgICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDbGVhciBhbGwgcHJvcGVydGllc1xuICAgIHRoaXMubWlkZGxld2FyZSA9IHt9O1xuICAgIHRoaXMub3B0aW9ucyA9IHsuLi50aGlzLmRlZmF1bHRPcHRpb25zfTtcbiAgICB0aGlzLnN0YXRlID0ge307XG4gICAgdGhpcy5zdG9yZUFjdGlvbnMgPSB7fTtcbiAgICB0aGlzLmlzSW5pdCA9IGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGN1cnJlbnQgc3RhdGUgb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ3xhcnJheX0gW25hbWVdIFRoZSBuYW1lIG9mIHRoZSBzdG9yZSB0byBzZXQuIFlvdSBjYW4gYWxzbyB1c2UgYW4gYXJyYXkgdG8gc3BlY2lmeSBhIHByb3BlcnR5IHBhdGhcbiAgICogd2l0aGluIHRoZSBvYmplY3QuXG4gICAqIEBwYXJhbSB7YW55fSBbdmFsdWVdIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAqL1xuICBzZXRTdGF0ZShwYXRoOiBzdHJpbmcgfCBzdHJpbmdbXSA9ICcnLCB2YWx1ZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmKCEhcGF0aCkge1xuICAgICAgdGhpcy5zdGF0ZSA9IHNldChwYXRoLCBjbG9uZURlZXAodmFsdWUpLCB0aGlzLnN0YXRlKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgcGVyc2lzdGVudCBjYWNoZVxuICAgIGNvbnN0IHtzdG9yYWdlfSA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmKHN0b3JhZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLnVwZGF0ZVN0b3JhZ2UoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkUGx1Z2luKHR5cGU6IHN0cmluZywgcGx1Z2luOiBGbHV4UGx1Z2luVHlwZSk6IEZsdXhQbHVnaW5UeXBlW10ge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLm1pZGRsZXdhcmVbYCR7dHlwZX1MaXN0YF0gfHwgW107XG4gICAgY29uc3Qge21ldGhvZCwgbmFtZX0gPSBwbHVnaW47XG5cbiAgICBpZihtZXRob2QgJiYgdHlwZW9mIG1ldGhvZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQ2hlY2sgaWYgcGx1Z2luIGFscmVhZHkgZXhpc3RzXG4gICAgICBjb25zdCBleGlzdHM6IGJvb2xlYW4gPSAhIWxpc3QuZmlsdGVyKChvYmo6IEZsdXhQbHVnaW5UeXBlKSA9PiBvYmoubmFtZSA9PT0gbmFtZSkubGVuZ3RoO1xuXG4gICAgICAvLyBEbyBub3QgYWRkIGR1cGxpY2F0ZSBwbHVnaW5zXG4gICAgICBpZighZXhpc3RzKSB7XG4gICAgICAgIGxpc3QucHVzaCh7bWV0aG9kLCBuYW1lfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmKG1ldGhvZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBFcnJvcihgJHtwbHVnaW4ubmFtZX0gbWlkZGxld2FyZSBpcyBub3QgY29uZmlndXJlZCBwcm9wZXJseS4gTWV0aG9kIGlzIG5vdCBhIGZ1bmN0aW9uLmApO1xuICAgIH1cblxuICAgIHJldHVybiBsaXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBkZXJlZ2lzdGVyKG5hbWU6IHN0cmluZyA9ICcnKTogdm9pZCB7XG4gICAgZGVsZXRlIHRoaXMuc3RvcmVBY3Rpb25zW25hbWVdO1xuICAgIGRlbGV0ZSB0aGlzLnN0YXRlW25hbWVdO1xuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlcihzdG9yZUZuKTogRmx1eFN0b3JlIHtcbiAgICBpZighc3RvcmVGbikge1xuICAgICAgdGhyb3cgRXJyb3IoJ1N0b3JlIGlzIHVuZGVmaW5lZC4gQ2Fubm90IHJlZ2lzdGVyIHdpdGggRmx1eC4nKTtcbiAgICB9XG5cbiAgICBjb25zdCBpc0ZuYzogYm9vbGVhbiA9IHR5cGVvZiBzdG9yZUZuID09PSAnZnVuY3Rpb24nO1xuXG4gICAgaWYoIWlzRm5jKSB7XG4gICAgICB0aHJvdyBFcnJvcihgJHtzdG9yZUZufSBpcyBub3QgYSBzdG9yZSBmdW5jdGlvbi4gQ2Fubm90IHJlZ2lzdGVyIHdpdGggRmx1eC5gKTtcbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgc3RvcmUgb2JqZWN0XG4gICAgY29uc3Qge25hbWV9ID0gc3RvcmVGbjtcbiAgICBjb25zdCBpbml0aWFsU3RhdGU6IGFueSA9IHN0b3JlRm4oKTtcbiAgICBjb25zdCBzdG9yZUFjdGlvbiA9IHtcbiAgICAgIGFjdGlvbjogc3RvcmVGbixcbiAgICAgIGluaXRpYWxTdGF0ZTogc3RvcmVGbigpLFxuICAgICAgbmFtZVxuICAgIH07XG5cbiAgICBpZighaXNFbXB0eShuYW1lKSAmJiAhdGhpcy5zdG9yZUFjdGlvbnNbbmFtZV0pIHtcbiAgICAgIC8vIFNhdmUgc3RvcmUgb2JqZWN0XG4gICAgICB0aGlzLnN0b3JlQWN0aW9uc1tuYW1lXSA9IHN0b3JlQWN0aW9uO1xuXG4gICAgICAvLyBHZXQgZGVmYXVsdCB2YWx1ZXNcbiAgICAgIGlmKCF0aGlzLnN0YXRlW25hbWVdKSB7XG4gICAgICAgIGlmKGluaXRpYWxTdGF0ZSkge1xuICAgICAgICAgIHRoaXMuc3RhdGVbbmFtZV0gPSBjbG9uZURlZXAoaW5pdGlhbFN0YXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnN0YXRlW25hbWVdID0ge307XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gc3RvcmUgY2xhc3NcbiAgICByZXR1cm4gdGhpcy5zdG9yZUFjdGlvbnNbbmFtZV07XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVBsdWdpbih0eXBlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IEZsdXhQbHVnaW5UeXBlW10ge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLm1pZGRsZXdhcmVbYCR7dHlwZX1MaXN0YF0gfHwgW107XG5cbiAgICAvLyByZW1vdmUgYWxsIG9jY3VycmVuY2VzIG9mIHRoZSBwbHVnaW5cbiAgICByZXR1cm4gbGlzdC5maWx0ZXIoKG9iajogRmx1eFBsdWdpblR5cGUpID0+IG9iai5uYW1lICE9PSBuYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU3RvcmFnZSA9ICgpID0+IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG5cbiAgcHJpdmF0ZSBhc3luYyB1c2VTdG9yYWdlKG5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHtzdG9yYWdlLCBzdGF0ZSwgc3RvcmFnZVdhaXR9ID0gdGhpcy5vcHRpb25zO1xuXG4gICAgLy8gQ2FjaGVcbiAgICBpZihzdG9yYWdlKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN0YXRlID0gc3RhdGUgfHwgYXdhaXQgc3RvcmFnZS5nZXRTdG9yYWdlRGF0YShuYW1lKSB8fCB7fTtcbiAgICAgICAgdGhpcy51cGRhdGVTdG9yYWdlID0gZGVib3VuY2UoXG4gICAgICAgICAgKCkgPT4gc3RvcmFnZS5zZXRTdG9yYWdlRGF0YShuYW1lLCB0aGlzLnN0YXRlKSxcbiAgICAgICAgICBzdG9yYWdlV2FpdCxcbiAgICAgICAgICB7bGVhZGluZzogdHJ1ZSwgdHJhaWxpbmc6IHRydWV9XG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEFya2hhbUpTIEVycm9yOiBVc2luZyBzdG9yYWdlLCBcIiR7bmFtZX1cIi5gKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZSB8fCB7fTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgRmx1eDogRmx1eEZyYW1ld29yayA9IG5ldyBGbHV4RnJhbWV3b3JrKCk7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7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ZUFBSyxNQUFNLFFBQVEsQ0FBQztBQUFBLFFBQ3RCO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFHQSxXQUFPLEtBQUssYUFBYTtBQUFBLEVBQzNCO0FBQUEsRUFFUSxhQUFhLE1BQWMsTUFBZ0M7QUFDakUsVUFBTSxPQUFPLEtBQUssV0FBVyxHQUFHLGVBQWUsQ0FBQztBQUdoRCxXQUFPLEtBQUssT0FBTyxDQUFDLFFBQXdCLElBQUksU0FBUyxJQUFJO0FBQUEsRUFDL0Q7QUFBQSxFQUlBLE1BQWMsV0FBVyxNQUE2QjtBQUNwRCxVQUFNLEVBQUMsU0FBUyxPQUFPLFlBQVcsSUFBSSxLQUFLO0FBRzNDLFFBQUcsU0FBUztBQUNWLFVBQUk7QUFDRixhQUFLLFFBQVEsU0FBUyxNQUFNLFFBQVEsZUFBZSxJQUFJLEtBQUssQ0FBQztBQUM3RCxhQUFLLG9CQUFnQixnQkFBQU87QUFBQSxVQUNuQixNQUFNLFFBQVEsZUFBZSxNQUFNLEtBQUssS0FBSztBQUFBLFVBQzdDO0FBQUEsVUFDQSxFQUFDLFNBQVMsTUFBTSxVQUFVLEtBQUk7QUFBQSxRQUNoQztBQUFBLE1BQ0YsU0FBUSxPQUFOO0FBQ0EsZ0JBQVEsTUFBTSxtQ0FBbUMsUUFBUTtBQUN6RCxjQUFNO0FBQUEsTUFDUjtBQUFBLElBQ0YsT0FBTztBQUNMLFdBQUssUUFBUSxTQUFTLENBQUM7QUFBQSxJQUN6QjtBQUVBLFdBQU87QUFBQSxFQUNUO0FBQ0Y7QUE1aUJhLGNBQ0osV0FBb0I7QUE2aUJ0QixNQUFNLE9BQXNCLElBQUksY0FBYzsiLAogICJuYW1lcyI6IFsiY2xvbmVEZWVwIiwgIkVycm9yU3RhY2tQYXJzZXIiLCAiYWN0aW9uIiwgIm1lcmdlIiwgImdldCIsICJzZXQiLCAiaXNFbXB0eSIsICJkZWJvdW5jZSJdCn0K