@nlabs/arkhamjs 3.20.4 → 3.22.1

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.
@@ -0,0 +1,717 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
25
+ var __reExport = (target, module2, copyDefault, desc) => {
26
+ if (module2 && typeof module2 === "object" || typeof module2 === "function") {
27
+ for (let key of __getOwnPropNames(module2))
28
+ if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
29
+ __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
30
+ }
31
+ return target;
32
+ };
33
+ var __toESM = (module2, isNodeMode) => {
34
+ return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
35
+ };
36
+ var import_debounce = __toESM(require("lodash/debounce"));
37
+ var import_cloneDeep = __toESM(require("lodash/fp/cloneDeep"));
38
+ var import_set = __toESM(require("lodash/fp/set"));
39
+ var import_ArkhamConstants = require("../constants/ArkhamConstants");
40
+ var import_Flux = require("./Flux");
41
+ jest.mock("lodash/debounce");
42
+ const initialState = {
43
+ falsy: false,
44
+ item: "default",
45
+ testAction: "default",
46
+ testUpdate: "default",
47
+ zeroValue: 0
48
+ };
49
+ const helloStore = (type, data, state = initialState) => {
50
+ switch (type) {
51
+ case "TEST_EVENT":
52
+ return (0, import_set.default)("testAction", data.testVar, state);
53
+ default:
54
+ return state;
55
+ }
56
+ };
57
+ describe("Flux", () => {
58
+ const consoleError = console.error;
59
+ const consoleWarn = console.warn;
60
+ const cfg = {
61
+ name: "arkhamjsTest",
62
+ stores: [helloStore]
63
+ };
64
+ let Flux;
65
+ beforeAll(() => {
66
+ console.error = jest.fn();
67
+ console.warn = jest.fn();
68
+ });
69
+ beforeEach(async () => {
70
+ Flux = new import_Flux.FluxFramework();
71
+ await Flux.init(cfg, true);
72
+ });
73
+ afterAll(() => {
74
+ console.error = consoleError;
75
+ console.warn = consoleWarn;
76
+ });
77
+ describe("#addMiddleware", () => {
78
+ describe("should apply pre-dispatch middleware", () => {
79
+ const middleTest = "intercept object";
80
+ const objMiddleware = {
81
+ name: "objectMiddleware",
82
+ preDispatch: (action) => __spreadProps(__spreadValues({}, action), { testVar: middleTest })
83
+ };
84
+ afterEach(() => {
85
+ Flux.clearMiddleware();
86
+ });
87
+ it("should alter data before sending to stores", async () => {
88
+ Flux.addMiddleware([objMiddleware]);
89
+ Flux.setState("helloStore.testAction", "default");
90
+ const preAction = await Flux.dispatch({ testVar: "hello world", type: "TEST_EVENT" });
91
+ expect(Flux.getState("helloStore.testAction")).toEqual(middleTest);
92
+ expect(preAction.testVar).toEqual(middleTest);
93
+ });
94
+ it("should handle error for middleware without a name", () => {
95
+ const fn = () => Flux.addMiddleware([{ preDispatch: objMiddleware.preDispatch }]);
96
+ expect(fn).toThrowError();
97
+ });
98
+ it("should handle error for incompatible middleware", () => {
99
+ const fn = () => Flux.addMiddleware(["incorrect"]);
100
+ expect(fn).toThrowError();
101
+ });
102
+ });
103
+ describe("should apply pre-dispatch middleware as promise", () => {
104
+ const middleTest = "intercept promise";
105
+ beforeEach(() => {
106
+ const promiseMiddleware = {
107
+ name: "promiseMiddleware",
108
+ preDispatch: (action) => Promise.resolve(__spreadProps(__spreadValues({}, action), { testVar: middleTest }))
109
+ };
110
+ Flux.addMiddleware([promiseMiddleware]);
111
+ });
112
+ afterEach(() => {
113
+ Flux.clearMiddleware();
114
+ });
115
+ it("should alter data before sending to stores", async () => {
116
+ Flux.setState("helloStore.testAction", "default");
117
+ const preAction = await Flux.dispatch({ testVar: "hello world", type: "TEST_EVENT" });
118
+ expect(Flux.getState("helloStore.testAction")).toEqual(middleTest);
119
+ expect(preAction.testVar).toEqual(middleTest);
120
+ });
121
+ });
122
+ describe("should apply post dispatch middleware", () => {
123
+ const middleTest = "intercept post";
124
+ beforeEach(() => {
125
+ const postMiddleware = {
126
+ name: "postMiddleware",
127
+ postDispatch: (action) => Promise.resolve(__spreadProps(__spreadValues({}, action), { testVar: middleTest }))
128
+ };
129
+ Flux.addMiddleware([postMiddleware]);
130
+ });
131
+ afterEach(() => {
132
+ Flux.clearMiddleware();
133
+ });
134
+ it("should alter store data", async () => {
135
+ Flux.setState("helloStore.testAction", "default");
136
+ const postAction = await Flux.dispatch({ testVar: "hello world", type: "TEST_EVENT" });
137
+ expect(Flux.getState("helloStore.testAction")).toEqual("hello world");
138
+ expect(postAction.testVar).toEqual(middleTest);
139
+ });
140
+ it("should handle no action error", async () => {
141
+ await expect(Flux.dispatch(null)).rejects.toThrowError();
142
+ });
143
+ it("should handle pre dispatch error", async () => {
144
+ const preMiddleware = {
145
+ name: "errorMiddleware",
146
+ preDispatch: () => Promise.reject(new Error("test"))
147
+ };
148
+ Flux.addMiddleware([preMiddleware]);
149
+ await expect(Flux.dispatch({ type: "test" })).rejects.toThrowError();
150
+ });
151
+ it("should handle post dispatch error", async () => {
152
+ const postMiddleware = {
153
+ name: "errorMiddleware",
154
+ postDispatch: () => Promise.reject(new Error("test"))
155
+ };
156
+ Flux.addMiddleware([postMiddleware]);
157
+ await expect(Flux.dispatch({ type: "test" })).rejects.toThrowError();
158
+ });
159
+ });
160
+ });
161
+ describe("#addPlugin", () => {
162
+ it("should add a plugin", () => {
163
+ const addPluginKey = "addPlugin";
164
+ const plugin = { method: () => {
165
+ }, name: "demoPlugin" };
166
+ const results = Flux[addPluginKey]("preDispatch", plugin);
167
+ expect(results).toEqual([plugin]);
168
+ });
169
+ it("should skip plugin if already exists", () => {
170
+ const addPluginKey = "addPlugin";
171
+ const plugin = { method: () => {
172
+ }, name: "demoPlugin" };
173
+ Flux.middleware.preDispatchList = [plugin];
174
+ const results = Flux[addPluginKey]("preDispatch", plugin);
175
+ expect(results).toEqual([plugin]);
176
+ });
177
+ it("should handle undefined function", () => {
178
+ const addPluginKey = "addPlugin";
179
+ const fn = () => Flux[addPluginKey]("preDispatch", { method: "object" });
180
+ expect(fn).toThrowError();
181
+ });
182
+ });
183
+ describe("#clearAppData", () => {
184
+ beforeEach(() => {
185
+ Flux.setState("helloStore.item", "clear");
186
+ });
187
+ it("should reset the store data", async () => {
188
+ await Flux.clearAppData();
189
+ expect(Flux.getState(["helloStore", "item"])).toEqual("default");
190
+ });
191
+ it("should set data in storage", async () => {
192
+ const retrnedValue = { hello: "world" };
193
+ const setStorageData = jest.fn().mockResolvedValue(retrnedValue);
194
+ Flux.options.storage = { setStorageData };
195
+ const results = await Flux.clearAppData();
196
+ expect(setStorageData.mock.calls.length).toEqual(1);
197
+ expect(results).toEqual(retrnedValue);
198
+ });
199
+ });
200
+ describe("#deregister", () => {
201
+ it("should remove a state and store", () => {
202
+ Flux.state = { hello: "world" };
203
+ Flux.storeActions = { hello: "world" };
204
+ Flux.deregister("hello");
205
+ expect(Flux.state).toEqual({});
206
+ expect(Flux.storeActions).toEqual({});
207
+ });
208
+ it("should use empty string as default", () => {
209
+ const originalState = (0, import_cloneDeep.default)(Flux.state);
210
+ Flux.deregister();
211
+ expect(originalState).toEqual(Flux.state);
212
+ });
213
+ });
214
+ describe("#dispatch", () => {
215
+ let eventSpy;
216
+ beforeEach(() => {
217
+ eventSpy = jest.fn();
218
+ Flux.on("TEST_EVENT", eventSpy);
219
+ });
220
+ afterEach(() => {
221
+ Flux.off("TEST_EVENT", eventSpy);
222
+ });
223
+ it("should return an action", async () => {
224
+ Flux.dispatch({ testVar: "test", type: "TEST_EVENT" });
225
+ const action = await Flux.dispatch({ testVar: "test", type: "TEST_EVENT" });
226
+ expect(action).toEqual({ testVar: "test", type: "TEST_EVENT" });
227
+ });
228
+ it("should alter the store data", () => {
229
+ Flux.dispatch({ testVar: "test", type: "TEST_EVENT" });
230
+ const item = Flux.getState("helloStore.testAction");
231
+ expect(item).toEqual("test");
232
+ });
233
+ it("should dispatch an event", () => {
234
+ Flux.dispatch({ testVar: "test", type: "TEST_EVENT" });
235
+ expect(eventSpy.mock.calls.length).toEqual(1);
236
+ });
237
+ it("should not dispatch if no type", () => {
238
+ Flux.dispatch({ testVar: "test" });
239
+ expect(eventSpy.mock.calls.length).toEqual(0);
240
+ });
241
+ it("should not dispatch if silent", () => {
242
+ Flux.dispatch({ testVar: "test", type: "TEST_EVENT" }, true);
243
+ expect(eventSpy.mock.calls.length).toEqual(0);
244
+ });
245
+ it("should update storage", () => {
246
+ Flux.updateStorage = jest.fn().mockResolvedValue({});
247
+ Flux.options.storage = {};
248
+ Flux.dispatch({ testVar: "test", type: "TEST_EVENT" });
249
+ expect(Flux.updateStorage.mock.calls.length).toEqual(1);
250
+ });
251
+ it("should return updated state if action returns null", async () => {
252
+ const nullStore = (type, data, state = initialState) => {
253
+ switch (type) {
254
+ case "TEST_NULL":
255
+ return null;
256
+ default:
257
+ return state;
258
+ }
259
+ };
260
+ await Flux.addStores([nullStore]);
261
+ await Flux.dispatch({ testVar: "test", type: "TEST_NULL" });
262
+ expect(Flux.state.nullStore).toEqual(initialState);
263
+ });
264
+ it("should return empty object if store returns null by default", async () => {
265
+ const nullStore = (type, data, state) => {
266
+ switch (type) {
267
+ case "TEST_NULL":
268
+ return null;
269
+ default:
270
+ return state;
271
+ }
272
+ };
273
+ await Flux.addStores([nullStore]);
274
+ Flux.state.nullStore = null;
275
+ await Flux.dispatch({ testVar: "test", type: "TEST_NULL" });
276
+ expect(Flux.state.nullStore).toEqual({});
277
+ });
278
+ });
279
+ describe("#getOptions", () => {
280
+ it("should get a options object", () => {
281
+ const options = Flux.getOptions();
282
+ const optionsKey = "options";
283
+ expect(options).toEqual(Flux[optionsKey]);
284
+ });
285
+ });
286
+ describe("#getState", () => {
287
+ beforeEach(() => {
288
+ const storeAction = Flux.getStore("helloStore");
289
+ Flux.setState("helloStore", storeAction.initialState);
290
+ });
291
+ it("should get a global store", () => {
292
+ const value = Flux.getState();
293
+ expect(value.helloStore.item).toEqual("default");
294
+ });
295
+ it("should get a specific store returning an object", () => {
296
+ const value = Flux.getState("helloStore");
297
+ expect(value.item).toEqual("default");
298
+ });
299
+ it("should get a specific item within a store using array", () => {
300
+ const value = Flux.getState(["helloStore", "item"]);
301
+ expect(value).toEqual("default");
302
+ });
303
+ it("should get a specific item within a store using dot notation", () => {
304
+ const value = Flux.getState("helloStore.item");
305
+ expect(value).toEqual("default");
306
+ });
307
+ it("should return default value from a null item", () => {
308
+ const value = Flux.getState("helloStore.notDefault", "");
309
+ expect(value).toEqual("");
310
+ });
311
+ it("should return entire store object with empty key", () => {
312
+ const value = Flux.getState("");
313
+ expect(value).toEqual({ helloStore: initialState });
314
+ });
315
+ it("should return entire store object with null key", () => {
316
+ const value = Flux.getState(null);
317
+ expect(value).toEqual({ helloStore: initialState });
318
+ });
319
+ it("should return entire store object with undefined key", () => {
320
+ const value = Flux.getState();
321
+ expect(value).toEqual({ helloStore: initialState });
322
+ });
323
+ it("should return empty object if state is null", () => {
324
+ Flux.state = null;
325
+ const value = Flux.getState();
326
+ expect(value).toEqual({});
327
+ });
328
+ it("should return a false value", () => {
329
+ const value = Flux.getState("helloStore.falsy");
330
+ expect(value).toEqual(false);
331
+ });
332
+ it("should return a zero value", () => {
333
+ const value = Flux.getState("helloStore.zeroValue");
334
+ expect(value).toEqual(0);
335
+ });
336
+ });
337
+ describe("#getStore", () => {
338
+ it("should get a store function", () => {
339
+ const storeAction = Flux.getStore("helloStore");
340
+ expect(storeAction.name).toEqual("helloStore");
341
+ });
342
+ it("should use empty string as default value", () => {
343
+ const storeAction = Flux.getStore();
344
+ expect(storeAction).toBeUndefined();
345
+ });
346
+ });
347
+ describe("#init", () => {
348
+ describe("set app name", () => {
349
+ const opts = {
350
+ name: "demo"
351
+ };
352
+ it("should update app name if initializing for the first time", async () => {
353
+ const privateInit = "isInit";
354
+ Flux[privateInit] = false;
355
+ await Flux.init(opts);
356
+ const optionsKey = "options";
357
+ expect(Flux[optionsKey].name).toEqual("demo");
358
+ });
359
+ it("should not update app name if initializing again", async () => {
360
+ const privateInit = "isInit";
361
+ Flux[privateInit] = true;
362
+ await Flux.init(opts);
363
+ const optionsKey = "options";
364
+ expect(Flux[optionsKey].name).toEqual("arkhamjsTest");
365
+ });
366
+ it("should add windows object for debugging", async () => {
367
+ await Flux.init(__spreadProps(__spreadValues({}, opts), { debug: true }));
368
+ const debugKey = "arkhamjs";
369
+ expect(window[debugKey]).toEqual(Flux);
370
+ });
371
+ it("should use default object if undefined", async () => {
372
+ await Flux.reset();
373
+ await Flux.init();
374
+ const optionsKey = "options";
375
+ const expectedOptions = {
376
+ name: "arkhamjs",
377
+ routerType: "browser",
378
+ scrollToTop: true,
379
+ state: null,
380
+ storage: null,
381
+ storageWait: 300,
382
+ stores: [],
383
+ title: "ArkhamJS"
384
+ };
385
+ expect(Flux[optionsKey]).toEqual(expectedOptions);
386
+ });
387
+ });
388
+ describe("set app name for initialized app", () => {
389
+ const opts = {
390
+ name: "demo"
391
+ };
392
+ it("should set app name", async () => {
393
+ await Flux.init(opts, true);
394
+ const privateProperty = "options";
395
+ expect(Flux[privateProperty].name).toEqual("demo");
396
+ });
397
+ });
398
+ describe("set initial empty state", () => {
399
+ const opts = {
400
+ state: {},
401
+ stores: [helloStore]
402
+ };
403
+ it("should set state", async () => {
404
+ await Flux.init(opts, true);
405
+ const privateProperty = "state";
406
+ expect(Object.keys(Flux[privateProperty]).length).toEqual(1);
407
+ });
408
+ it("should set state branch for store", async () => {
409
+ await Flux.init(opts, true);
410
+ const privateProperty = "state";
411
+ expect(Flux[privateProperty].helloStore.item).toEqual("default");
412
+ });
413
+ });
414
+ describe("set null state", () => {
415
+ const opts = {
416
+ state: null,
417
+ stores: [helloStore]
418
+ };
419
+ it("should set state", async () => {
420
+ await Flux.init(opts, true);
421
+ const privateProperty = "state";
422
+ expect(Object.keys(Flux[privateProperty]).length).toEqual(1);
423
+ });
424
+ it("should set state branch for store", async () => {
425
+ await Flux.init(opts, true);
426
+ const privateProperty = "state";
427
+ expect(Flux[privateProperty].helloStore.item).toEqual("default");
428
+ });
429
+ });
430
+ describe("set defined state", () => {
431
+ const opts = {
432
+ state: { second: "value", test: { hello: "world" } },
433
+ stores: [helloStore]
434
+ };
435
+ it("should set state", async () => {
436
+ await Flux.init(opts, true);
437
+ const privateProperty = "state";
438
+ expect(Object.keys(Flux[privateProperty]).length).toEqual(3);
439
+ });
440
+ it("should set state branch for store", async () => {
441
+ await Flux.init(opts, true);
442
+ const privateProperty = "state";
443
+ expect(Flux[privateProperty].test.hello).toEqual("world");
444
+ });
445
+ });
446
+ describe("middleware", () => {
447
+ const objMiddleware = {
448
+ name: "objectMiddleware",
449
+ preDispatch: (action) => __spreadValues({}, action)
450
+ };
451
+ const opts = {
452
+ middleware: [objMiddleware],
453
+ name: "demo",
454
+ stores: [helloStore]
455
+ };
456
+ it("should add middleware", async () => {
457
+ await Flux.init(opts, true);
458
+ const privateProperty = "middleware";
459
+ expect(Flux[privateProperty].preDispatchList[0].name).toEqual("objectMiddleware");
460
+ });
461
+ });
462
+ describe("error handling", () => {
463
+ it("should handle useStorage error", async () => {
464
+ Flux.useStorage = Promise.reject(new Error("test"));
465
+ await expect(Flux.init(cfg, true)).rejects.toThrowError();
466
+ });
467
+ it("should handle addStores error", async () => {
468
+ Flux.addStores = Promise.reject(new Error("test"));
469
+ await expect(Flux.init(cfg, true)).rejects.toThrowError();
470
+ });
471
+ });
472
+ });
473
+ describe("event listeners", () => {
474
+ let eventSpy;
475
+ beforeEach(() => {
476
+ eventSpy = jest.fn();
477
+ Flux.on("test", eventSpy);
478
+ });
479
+ describe("#on", () => {
480
+ it("should add a listener", async () => {
481
+ await Flux.dispatch({ type: "test" });
482
+ expect(eventSpy.mock.calls.length).toEqual(1);
483
+ });
484
+ });
485
+ describe("#off", () => {
486
+ it("should remove a listener", async () => {
487
+ Flux.off("test", eventSpy);
488
+ await Flux.dispatch({ type: "test" });
489
+ expect(eventSpy.mock.calls.length).toEqual(0);
490
+ });
491
+ });
492
+ });
493
+ describe("#addStores", () => {
494
+ const demo = (type, data, state = { helloStore: "joker" }) => {
495
+ if (type === "DEMO_TEST") {
496
+ state.helloStore = data.helloStore;
497
+ }
498
+ return state;
499
+ };
500
+ it("should create and save a Store class", () => {
501
+ Flux.addStores([demo]);
502
+ const privateProperty = "storeActions";
503
+ const storeAction = Flux[privateProperty].demo;
504
+ expect(storeAction.name).toEqual("demo");
505
+ });
506
+ it("should set initial state", () => {
507
+ Flux.addStores([demo]);
508
+ const privateProperty = "storeActions";
509
+ const storeAction = Flux[privateProperty].demo;
510
+ expect(storeAction.initialState).toEqual({ helloStore: "joker" });
511
+ });
512
+ it("should handle unsupported stores", () => {
513
+ const optionsKey = "options";
514
+ const setStorageData = new Error("test");
515
+ Flux[optionsKey].storage = { setStorageData };
516
+ Flux.addStores([demo]);
517
+ const privateProperty = "storeActions";
518
+ const storeAction = Flux[privateProperty].demo;
519
+ expect(storeAction.initialState).toEqual({ helloStore: "joker" });
520
+ });
521
+ });
522
+ describe("#offInit", () => {
523
+ it("should remove listener after initialization", () => {
524
+ const listener = jest.fn();
525
+ Flux.off = jest.fn();
526
+ Flux.offInit(listener);
527
+ expect(Flux.off.mock.calls.length).toEqual(1);
528
+ expect(Flux.off.mock.calls[0][0]).toEqual(import_ArkhamConstants.ArkhamConstants.INIT);
529
+ });
530
+ });
531
+ describe("#onInit", () => {
532
+ it("should add listener after initialization", () => {
533
+ const listener = jest.fn();
534
+ Flux.isInit = false;
535
+ Flux.on = jest.fn();
536
+ Flux.onInit(listener);
537
+ expect(Flux.on.mock.calls.length).toEqual(1);
538
+ expect(Flux.on.mock.calls[0][0]).toEqual(import_ArkhamConstants.ArkhamConstants.INIT);
539
+ });
540
+ it("should dispatch instantly if already initialized", () => {
541
+ const listener = jest.fn();
542
+ Flux.isInit = true;
543
+ Flux.onInit(listener);
544
+ expect(listener.mock.calls.length).toEqual(1);
545
+ });
546
+ });
547
+ describe("#register", () => {
548
+ it("should register a store function", () => {
549
+ const demoStore = (type, data, state = initialState) => {
550
+ switch (type) {
551
+ case "TEST_EVENT":
552
+ return (0, import_set.default)("testAction", data.testVar, state);
553
+ default:
554
+ return state;
555
+ }
556
+ };
557
+ const registerKey = "register";
558
+ const storeAction = Flux[registerKey](demoStore);
559
+ const expectedAction = {
560
+ action: demoStore,
561
+ initialState,
562
+ name: "demoStore"
563
+ };
564
+ expect(storeAction).toEqual(expectedAction);
565
+ });
566
+ it("should register a store function without an initial value", () => {
567
+ const demoStore = (type, data, state) => {
568
+ switch (type) {
569
+ case "TEST_EVENT":
570
+ return (0, import_set.default)("testAction", data.testVar, state);
571
+ default:
572
+ return state;
573
+ }
574
+ };
575
+ const registerKey = "register";
576
+ const storeAction = Flux[registerKey](demoStore);
577
+ const expectedAction = {
578
+ action: demoStore,
579
+ initialState: void 0,
580
+ name: "demoStore"
581
+ };
582
+ expect(storeAction).toEqual(expectedAction);
583
+ });
584
+ it("should not save a store function without a name", () => {
585
+ const registerKey = "register";
586
+ const storeAction = Flux[registerKey]((type, data, state = initialState) => {
587
+ switch (type) {
588
+ case "TEST_EVENT":
589
+ return (0, import_set.default)("testAction", data.testVar, state);
590
+ default:
591
+ return state;
592
+ }
593
+ });
594
+ expect(storeAction).toBeUndefined();
595
+ });
596
+ it("should handle undefined function", () => {
597
+ const registerKey = "register";
598
+ const fn = () => Flux[registerKey]();
599
+ expect(fn).toThrowError();
600
+ });
601
+ it("should handle argument that is not a function", () => {
602
+ const registerKey = "register";
603
+ const fn = () => Flux[registerKey]({});
604
+ expect(fn).toThrowError();
605
+ });
606
+ });
607
+ describe("#removeMiddleware", () => {
608
+ beforeEach(() => {
609
+ Flux.clearMiddleware();
610
+ const objMiddleware = {
611
+ name: "objectMiddleware",
612
+ preDispatch: (action) => __spreadValues({}, action)
613
+ };
614
+ Flux.addMiddleware([objMiddleware]);
615
+ });
616
+ it("should alter data before sending to stores", () => {
617
+ Flux.removeMiddleware(["objectMiddleware"]);
618
+ const privateProperty = "middleware";
619
+ expect(Flux[privateProperty].preDispatchList.length).toEqual(0);
620
+ });
621
+ });
622
+ describe("#removePlugin", () => {
623
+ it("should remove an existing plugin", () => {
624
+ Flux.middleware.preDispatchList = [{ name: "demoPlugin" }, { name: "noNotRemovePlugin" }];
625
+ expect(Flux.removePlugin("preDispatch", "demoPlugin")).toEqual([{ name: "noNotRemovePlugin" }]);
626
+ });
627
+ it("should get an undefined list", () => {
628
+ Flux.middleware.preDispatchList = null;
629
+ expect(Flux.removePlugin("preDispatch", "demoPlugin")).toEqual([]);
630
+ });
631
+ });
632
+ describe("#removeStores", () => {
633
+ beforeEach(() => {
634
+ Flux.removeStores(["helloStore"]);
635
+ });
636
+ afterEach(() => {
637
+ Flux.addStores([helloStore]);
638
+ });
639
+ it("should remove class", () => {
640
+ const privateProperty = "storeActions";
641
+ expect(!!Flux[privateProperty].helloStore).toEqual(false);
642
+ });
643
+ it("should remove store data", () => {
644
+ const privateProperty = "state";
645
+ expect(!!Flux[privateProperty].helloStore).toEqual(false);
646
+ });
647
+ });
648
+ describe("#reset", () => {
649
+ it("should handle argument that is not a function", async () => {
650
+ const optionsKey = "options";
651
+ const setStorageData = new Error("test");
652
+ Flux[optionsKey].storage = { setStorageData };
653
+ await expect(Flux.reset()).rejects.toThrowError();
654
+ });
655
+ });
656
+ describe("#setState", () => {
657
+ it("should update the property within the store", async () => {
658
+ await Flux.setState("helloStore.testUpdate", "test");
659
+ const newItem = await Flux.getState("helloStore.testUpdate");
660
+ expect(newItem).toEqual("test");
661
+ });
662
+ it("should empty string as default path", async () => {
663
+ await Flux.setState(void 0, "test");
664
+ const newItem = await Flux.getState("helloStore");
665
+ expect(newItem).toEqual(initialState);
666
+ });
667
+ it("should update storage", async () => {
668
+ const optionsKey = "options";
669
+ const updateStorageKey = "updateStorage";
670
+ const updateStorage = jest.fn();
671
+ Flux[optionsKey] = { storage: {} };
672
+ Flux[updateStorageKey] = updateStorage;
673
+ await Flux.setState("helloStore.testUpdate", "test");
674
+ expect(updateStorage.mock.calls.length).toEqual(1);
675
+ });
676
+ });
677
+ describe("#useStorage", () => {
678
+ it("should update storage", async () => {
679
+ const getStorageData = jest.fn();
680
+ const optionsKey = "options";
681
+ Flux[optionsKey].state = null;
682
+ Flux[optionsKey].storage = { getStorageData };
683
+ const useStorageKey = "useStorage";
684
+ await Flux[useStorageKey]("helloStore");
685
+ expect(getStorageData.mock.calls.length).toEqual(1);
686
+ });
687
+ it("without storage", async () => {
688
+ const optionsKey = "options";
689
+ Flux[optionsKey].state = { hello: "world" };
690
+ Flux[optionsKey].storage = null;
691
+ const useStorageKey = "useStorage";
692
+ await Flux[useStorageKey]("helloStore");
693
+ const stateKey = "state";
694
+ expect(Flux[stateKey].hello).toEqual("world");
695
+ });
696
+ it("should handle storage errors", async () => {
697
+ const optionsKey = "options";
698
+ Flux[optionsKey].state = null;
699
+ Flux[optionsKey].storage = new Error("test");
700
+ const useStorageKey = "useStorage";
701
+ await expect(Flux[useStorageKey]("helloStore")).rejects.toThrowError();
702
+ });
703
+ it("should debounce storage", async () => {
704
+ const value = "test";
705
+ const optionsKey = "options";
706
+ Flux[optionsKey].state = { hello: "world" };
707
+ const setStorageData = jest.fn().mockReturnValue(value);
708
+ Flux[optionsKey].storage = { setStorageData };
709
+ const debounceMock = import_debounce.default;
710
+ debounceMock.mockImplementation((fn) => fn());
711
+ const useStorageKey = "useStorage";
712
+ await Flux[useStorageKey]("helloStore");
713
+ expect(setStorageData.mock.calls.length).toEqual(1);
714
+ });
715
+ });
716
+ });
717
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL0ZsdXgvRmx1eC50ZXN0LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAxOC1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IGRlYm91bmNlIGZyb20gJ2xvZGFzaC9kZWJvdW5jZSc7XG5pbXBvcnQgY2xvbmVEZWVwIGZyb20gJ2xvZGFzaC9mcC9jbG9uZURlZXAnO1xuaW1wb3J0IHNldCBmcm9tICdsb2Rhc2gvZnAvc2V0JztcblxuaW1wb3J0IHtBcmtoYW1Db25zdGFudHN9IGZyb20gJy4uL2NvbnN0YW50cy9BcmtoYW1Db25zdGFudHMnO1xuaW1wb3J0IHtGbHV4RnJhbWV3b3JrfSBmcm9tICcuL0ZsdXgnO1xuaW1wb3J0IHtGbHV4QWN0aW9uLCBGbHV4T3B0aW9ucywgRmx1eFN0b3JlfSBmcm9tICcuL0ZsdXgudHlwZXMnO1xuXG5qZXN0Lm1vY2soJ2xvZGFzaC9kZWJvdW5jZScpO1xuXG5jb25zdCBpbml0aWFsU3RhdGUgPSB7XG4gIGZhbHN5OiBmYWxzZSxcbiAgaXRlbTogJ2RlZmF1bHQnLFxuICB0ZXN0QWN0aW9uOiAnZGVmYXVsdCcsXG4gIHRlc3RVcGRhdGU6ICdkZWZhdWx0JyxcbiAgemVyb1ZhbHVlOiAwXG59O1xuXG5jb25zdCBoZWxsb1N0b3JlID0gKHR5cGU6IHN0cmluZywgZGF0YSwgc3RhdGUgPSBpbml0aWFsU3RhdGUpOiBhbnkgPT4ge1xuICBzd2l0Y2godHlwZSkge1xuICAgIGNhc2UgJ1RFU1RfRVZFTlQnOlxuICAgICAgcmV0dXJuIHNldCgndGVzdEFjdGlvbicsIGRhdGEudGVzdFZhciwgc3RhdGUpO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn07XG5cbmRlc2NyaWJlKCdGbHV4JywgKCkgPT4ge1xuICBjb25zdCBjb25zb2xlRXJyb3IgPSBjb25zb2xlLmVycm9yO1xuICBjb25zdCBjb25zb2xlV2FybiA9IGNvbnNvbGUud2FybjtcbiAgY29uc3QgY2ZnOiBGbHV4T3B0aW9ucyA9IHtcbiAgICBuYW1lOiAnYXJraGFtanNUZXN0JyxcbiAgICBzdG9yZXM6IFtoZWxsb1N0b3JlXVxuICB9O1xuICBsZXQgRmx1eDtcblxuICBiZWZvcmVBbGwoKCkgPT4ge1xuICAgIGNvbnNvbGUuZXJyb3IgPSBqZXN0LmZuKCk7XG4gICAgY29uc29sZS53YXJuID0gamVzdC5mbigpO1xuICB9KTtcblxuICBiZWZvcmVFYWNoKGFzeW5jICgpID0+IHtcbiAgICBGbHV4ID0gbmV3IEZsdXhGcmFtZXdvcmsoKTtcblxuICAgIC8vIENvbmZpZ3VyZVxuICAgIGF3YWl0IEZsdXguaW5pdChjZmcsIHRydWUpO1xuICB9KTtcblxuICBhZnRlckFsbCgoKSA9PiB7XG4gICAgY29uc29sZS5lcnJvciA9IGNvbnNvbGVFcnJvcjtcbiAgICBjb25zb2xlLndhcm4gPSBjb25zb2xlV2FybjtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNhZGRNaWRkbGV3YXJlJywgKCkgPT4ge1xuICAgIGRlc2NyaWJlKCdzaG91bGQgYXBwbHkgcHJlLWRpc3BhdGNoIG1pZGRsZXdhcmUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtaWRkbGVUZXN0OiBzdHJpbmcgPSAnaW50ZXJjZXB0IG9iamVjdCc7XG5cbiAgICAgIC8vIEFkZCBvYmplY3QgbWlkZGxld2FyZVxuICAgICAgY29uc3Qgb2JqTWlkZGxld2FyZSA9IHtcbiAgICAgICAgbmFtZTogJ29iamVjdE1pZGRsZXdhcmUnLFxuICAgICAgICBwcmVEaXNwYXRjaDogKGFjdGlvbikgPT4gKHsuLi5hY3Rpb24sIHRlc3RWYXI6IG1pZGRsZVRlc3R9KVxuICAgICAgfTtcblxuICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgRmx1eC5jbGVhck1pZGRsZXdhcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFsdGVyIGRhdGEgYmVmb3JlIHNlbmRpbmcgdG8gc3RvcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBNZXRob2RcbiAgICAgICAgRmx1eC5hZGRNaWRkbGV3YXJlKFtvYmpNaWRkbGV3YXJlXSk7XG5cbiAgICAgICAgLy8gU2V0IHRlc3QgZGF0YVxuICAgICAgICBGbHV4LnNldFN0YXRlKCdoZWxsb1N0b3JlLnRlc3RBY3Rpb24nLCAnZGVmYXVsdCcpO1xuXG4gICAgICAgIC8vIERpc3BhdGNoIGFuIGFjdGlvblxuICAgICAgICBjb25zdCBwcmVBY3Rpb246IEZsdXhBY3Rpb24gPSBhd2FpdCBGbHV4LmRpc3BhdGNoKHt0ZXN0VmFyOiAnaGVsbG8gd29ybGQnLCB0eXBlOiAnVEVTVF9FVkVOVCd9KTtcblxuICAgICAgICBleHBlY3QoRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS50ZXN0QWN0aW9uJykpLnRvRXF1YWwobWlkZGxlVGVzdCk7XG4gICAgICAgIGV4cGVjdChwcmVBY3Rpb24udGVzdFZhcikudG9FcXVhbChtaWRkbGVUZXN0KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlcnJvciBmb3IgbWlkZGxld2FyZSB3aXRob3V0IGEgbmFtZScsICgpID0+IHtcbiAgICAgICAgY29uc3QgZm4gPSAoKSA9PiBGbHV4LmFkZE1pZGRsZXdhcmUoW3twcmVEaXNwYXRjaDogb2JqTWlkZGxld2FyZS5wcmVEaXNwYXRjaH1dKTtcbiAgICAgICAgZXhwZWN0KGZuKS50b1Rocm93RXJyb3IoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlcnJvciBmb3IgaW5jb21wYXRpYmxlIG1pZGRsZXdhcmUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZuID0gKCkgPT4gRmx1eC5hZGRNaWRkbGV3YXJlKFsnaW5jb3JyZWN0J10pO1xuICAgICAgICBleHBlY3QoZm4pLnRvVGhyb3dFcnJvcigpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2hvdWxkIGFwcGx5IHByZS1kaXNwYXRjaCBtaWRkbGV3YXJlIGFzIHByb21pc2UnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtaWRkbGVUZXN0OiBzdHJpbmcgPSAnaW50ZXJjZXB0IHByb21pc2UnO1xuXG4gICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgLy8gQWRkIG9iamVjdCBtaWRkbGV3YXJlXG4gICAgICAgIGNvbnN0IHByb21pc2VNaWRkbGV3YXJlID0ge1xuICAgICAgICAgIG5hbWU6ICdwcm9taXNlTWlkZGxld2FyZScsXG4gICAgICAgICAgcHJlRGlzcGF0Y2g6IChhY3Rpb24pID0+IFByb21pc2UucmVzb2x2ZSh7Li4uYWN0aW9uLCB0ZXN0VmFyOiBtaWRkbGVUZXN0fSlcbiAgICAgICAgfTtcblxuICAgICAgICBGbHV4LmFkZE1pZGRsZXdhcmUoW3Byb21pc2VNaWRkbGV3YXJlXSk7XG4gICAgICB9KTtcblxuICAgICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgRmx1eC5jbGVhck1pZGRsZXdhcmUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFsdGVyIGRhdGEgYmVmb3JlIHNlbmRpbmcgdG8gc3RvcmVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBTZXQgdGVzdCBkYXRhXG4gICAgICAgIEZsdXguc2V0U3RhdGUoJ2hlbGxvU3RvcmUudGVzdEFjdGlvbicsICdkZWZhdWx0Jyk7XG5cbiAgICAgICAgLy8gRGlzcGF0Y2ggYW4gYWN0aW9uXG4gICAgICAgIGNvbnN0IHByZUFjdGlvbjogRmx1eEFjdGlvbiA9IGF3YWl0IEZsdXguZGlzcGF0Y2goe3Rlc3RWYXI6ICdoZWxsbyB3b3JsZCcsIHR5cGU6ICdURVNUX0VWRU5UJ30pO1xuICAgICAgICBleHBlY3QoRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS50ZXN0QWN0aW9uJykpLnRvRXF1YWwobWlkZGxlVGVzdCk7XG4gICAgICAgIGV4cGVjdChwcmVBY3Rpb24udGVzdFZhcikudG9FcXVhbChtaWRkbGVUZXN0KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3Nob3VsZCBhcHBseSBwb3N0IGRpc3BhdGNoIG1pZGRsZXdhcmUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBtaWRkbGVUZXN0OiBzdHJpbmcgPSAnaW50ZXJjZXB0IHBvc3QnO1xuXG4gICAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgLy8gQWRkIG9iamVjdCBtaWRkbGV3YXJlXG4gICAgICAgIGNvbnN0IHBvc3RNaWRkbGV3YXJlID0ge1xuICAgICAgICAgIG5hbWU6ICdwb3N0TWlkZGxld2FyZScsXG4gICAgICAgICAgcG9zdERpc3BhdGNoOiAoYWN0aW9uKSA9PiBQcm9taXNlLnJlc29sdmUoey4uLmFjdGlvbiwgdGVzdFZhcjogbWlkZGxlVGVzdH0pXG4gICAgICAgIH07XG5cbiAgICAgICAgRmx1eC5hZGRNaWRkbGV3YXJlKFtwb3N0TWlkZGxld2FyZV0pO1xuICAgICAgfSk7XG5cbiAgICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIEZsdXguY2xlYXJNaWRkbGV3YXJlKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBhbHRlciBzdG9yZSBkYXRhJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBTZXQgdGVzdCBkYXRhXG4gICAgICAgIEZsdXguc2V0U3RhdGUoJ2hlbGxvU3RvcmUudGVzdEFjdGlvbicsICdkZWZhdWx0Jyk7XG5cbiAgICAgICAgLy8gRGlzcGF0Y2ggYW4gYWN0aW9uXG4gICAgICAgIGNvbnN0IHBvc3RBY3Rpb246IEZsdXhBY3Rpb24gPSBhd2FpdCBGbHV4LmRpc3BhdGNoKHt0ZXN0VmFyOiAnaGVsbG8gd29ybGQnLCB0eXBlOiAnVEVTVF9FVkVOVCd9KTtcblxuICAgICAgICBleHBlY3QoRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS50ZXN0QWN0aW9uJykpLnRvRXF1YWwoJ2hlbGxvIHdvcmxkJyk7XG4gICAgICAgIGV4cGVjdChwb3N0QWN0aW9uLnRlc3RWYXIpLnRvRXF1YWwobWlkZGxlVGVzdCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbm8gYWN0aW9uIGVycm9yJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBleHBlY3QoRmx1eC5kaXNwYXRjaChudWxsKSkucmVqZWN0cy50b1Rocm93RXJyb3IoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBwcmUgZGlzcGF0Y2ggZXJyb3InLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByZU1pZGRsZXdhcmUgPSB7XG4gICAgICAgICAgbmFtZTogJ2Vycm9yTWlkZGxld2FyZScsXG4gICAgICAgICAgcHJlRGlzcGF0Y2g6ICgpID0+IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcigndGVzdCcpKVxuICAgICAgICB9O1xuICAgICAgICBGbHV4LmFkZE1pZGRsZXdhcmUoW3ByZU1pZGRsZXdhcmVdKTtcbiAgICAgICAgYXdhaXQgZXhwZWN0KEZsdXguZGlzcGF0Y2goe3R5cGU6ICd0ZXN0J30pKS5yZWplY3RzLnRvVGhyb3dFcnJvcigpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIHBvc3QgZGlzcGF0Y2ggZXJyb3InLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBvc3RNaWRkbGV3YXJlID0ge1xuICAgICAgICAgIG5hbWU6ICdlcnJvck1pZGRsZXdhcmUnLFxuICAgICAgICAgIHBvc3REaXNwYXRjaDogKCkgPT4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCd0ZXN0JykpXG4gICAgICAgIH07XG4gICAgICAgIEZsdXguYWRkTWlkZGxld2FyZShbcG9zdE1pZGRsZXdhcmVdKTtcbiAgICAgICAgYXdhaXQgZXhwZWN0KEZsdXguZGlzcGF0Y2goe3R5cGU6ICd0ZXN0J30pKS5yZWplY3RzLnRvVGhyb3dFcnJvcigpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjYWRkUGx1Z2luJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYWRkIGEgcGx1Z2luJywgKCkgPT4ge1xuICAgICAgY29uc3QgYWRkUGx1Z2luS2V5OiBzdHJpbmcgPSAnYWRkUGx1Z2luJztcbiAgICAgIGNvbnN0IHBsdWdpbiA9IHttZXRob2Q6ICgpID0+IHt9LCBuYW1lOiAnZGVtb1BsdWdpbid9O1xuICAgICAgY29uc3QgcmVzdWx0cyA9IEZsdXhbYWRkUGx1Z2luS2V5XSgncHJlRGlzcGF0Y2gnLCBwbHVnaW4pO1xuICAgICAgZXhwZWN0KHJlc3VsdHMpLnRvRXF1YWwoW3BsdWdpbl0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBza2lwIHBsdWdpbiBpZiBhbHJlYWR5IGV4aXN0cycsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZFBsdWdpbktleTogc3RyaW5nID0gJ2FkZFBsdWdpbic7XG4gICAgICBjb25zdCBwbHVnaW4gPSB7bWV0aG9kOiAoKSA9PiB7fSwgbmFtZTogJ2RlbW9QbHVnaW4nfTtcbiAgICAgIEZsdXgubWlkZGxld2FyZS5wcmVEaXNwYXRjaExpc3QgPSBbcGx1Z2luXTtcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBGbHV4W2FkZFBsdWdpbktleV0oJ3ByZURpc3BhdGNoJywgcGx1Z2luKTtcbiAgICAgIGV4cGVjdChyZXN1bHRzKS50b0VxdWFsKFtwbHVnaW5dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHVuZGVmaW5lZCBmdW5jdGlvbicsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZFBsdWdpbktleTogc3RyaW5nID0gJ2FkZFBsdWdpbic7XG4gICAgICBjb25zdCBmbiA9ICgpID0+IEZsdXhbYWRkUGx1Z2luS2V5XSgncHJlRGlzcGF0Y2gnLCB7bWV0aG9kOiAnb2JqZWN0J30pO1xuICAgICAgZXhwZWN0KGZuKS50b1Rocm93RXJyb3IoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNjbGVhckFwcERhdGEnLCAoKSA9PiB7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICAvLyBTZXQgdGVzdCBkYXRhXG4gICAgICBGbHV4LnNldFN0YXRlKCdoZWxsb1N0b3JlLml0ZW0nLCAnY2xlYXInKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVzZXQgdGhlIHN0b3JlIGRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBNZXRob2RcbiAgICAgIGF3YWl0IEZsdXguY2xlYXJBcHBEYXRhKCk7XG5cbiAgICAgIGV4cGVjdChGbHV4LmdldFN0YXRlKFsnaGVsbG9TdG9yZScsICdpdGVtJ10pKS50b0VxdWFsKCdkZWZhdWx0Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCBkYXRhIGluIHN0b3JhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXRybmVkVmFsdWUgPSB7aGVsbG86ICd3b3JsZCd9O1xuICAgICAgY29uc3Qgc2V0U3RvcmFnZURhdGEgPSBqZXN0LmZuKCkubW9ja1Jlc29sdmVkVmFsdWUocmV0cm5lZFZhbHVlKTtcbiAgICAgIEZsdXgub3B0aW9ucy5zdG9yYWdlID0ge3NldFN0b3JhZ2VEYXRhfTtcblxuICAgICAgLy8gTWV0aG9kXG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgRmx1eC5jbGVhckFwcERhdGEoKTtcblxuICAgICAgZXhwZWN0KHNldFN0b3JhZ2VEYXRhLm1vY2suY2FsbHMubGVuZ3RoKS50b0VxdWFsKDEpO1xuICAgICAgZXhwZWN0KHJlc3VsdHMpLnRvRXF1YWwocmV0cm5lZFZhbHVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNkZXJlZ2lzdGVyJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmVtb3ZlIGEgc3RhdGUgYW5kIHN0b3JlJywgKCkgPT4ge1xuICAgICAgRmx1eC5zdGF0ZSA9IHtoZWxsbzogJ3dvcmxkJ307XG4gICAgICBGbHV4LnN0b3JlQWN0aW9ucyA9IHtoZWxsbzogJ3dvcmxkJ307XG4gICAgICBGbHV4LmRlcmVnaXN0ZXIoJ2hlbGxvJyk7XG4gICAgICBleHBlY3QoRmx1eC5zdGF0ZSkudG9FcXVhbCh7fSk7XG4gICAgICBleHBlY3QoRmx1eC5zdG9yZUFjdGlvbnMpLnRvRXF1YWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgZW1wdHkgc3RyaW5nIGFzIGRlZmF1bHQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW5hbFN0YXRlID0gY2xvbmVEZWVwKEZsdXguc3RhdGUpO1xuICAgICAgRmx1eC5kZXJlZ2lzdGVyKCk7XG4gICAgICBleHBlY3Qob3JpZ2luYWxTdGF0ZSkudG9FcXVhbChGbHV4LnN0YXRlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNkaXNwYXRjaCcsICgpID0+IHtcbiAgICBsZXQgZXZlbnRTcHk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIC8vIFNweVxuICAgICAgZXZlbnRTcHkgPSBqZXN0LmZuKCk7XG4gICAgICBGbHV4Lm9uKCdURVNUX0VWRU5UJywgZXZlbnRTcHkpO1xuICAgIH0pO1xuXG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgIEZsdXgub2ZmKCdURVNUX0VWRU5UJywgZXZlbnRTcHkpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYW4gYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gTWV0aG9kXG4gICAgICBGbHV4LmRpc3BhdGNoKHt0ZXN0VmFyOiAndGVzdCcsIHR5cGU6ICdURVNUX0VWRU5UJ30pO1xuXG4gICAgICBjb25zdCBhY3Rpb246IGFueSA9IGF3YWl0IEZsdXguZGlzcGF0Y2goe3Rlc3RWYXI6ICd0ZXN0JywgdHlwZTogJ1RFU1RfRVZFTlQnfSk7XG4gICAgICBleHBlY3QoYWN0aW9uKS50b0VxdWFsKHt0ZXN0VmFyOiAndGVzdCcsIHR5cGU6ICdURVNUX0VWRU5UJ30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhbHRlciB0aGUgc3RvcmUgZGF0YScsICgpID0+IHtcbiAgICAgIC8vIE1ldGhvZFxuICAgICAgRmx1eC5kaXNwYXRjaCh7dGVzdFZhcjogJ3Rlc3QnLCB0eXBlOiAnVEVTVF9FVkVOVCd9KTtcblxuICAgICAgY29uc3QgaXRlbTogc3RyaW5nID0gRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS50ZXN0QWN0aW9uJyk7XG4gICAgICBleHBlY3QoaXRlbSkudG9FcXVhbCgndGVzdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBkaXNwYXRjaCBhbiBldmVudCcsICgpID0+IHtcbiAgICAgIC8vIE1ldGhvZFxuICAgICAgRmx1eC5kaXNwYXRjaCh7dGVzdFZhcjogJ3Rlc3QnLCB0eXBlOiAnVEVTVF9FVkVOVCd9KTtcblxuICAgICAgZXhwZWN0KGV2ZW50U3B5Lm1vY2suY2FsbHMubGVuZ3RoKS50b0VxdWFsKDEpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgZGlzcGF0Y2ggaWYgbm8gdHlwZScsICgpID0+IHtcbiAgICAgIC8vIE1ldGhvZFxuICAgICAgRmx1eC5kaXNwYXRjaCh7dGVzdFZhcjogJ3Rlc3QnfSk7XG5cbiAgICAgIGV4cGVjdChldmVudFNweS5tb2NrLmNhbGxzLmxlbmd0aCkudG9FcXVhbCgwKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGRpc3BhdGNoIGlmIHNpbGVudCcsICgpID0+IHtcbiAgICAgIC8vIE1ldGhvZFxuICAgICAgRmx1eC5kaXNwYXRjaCh7dGVzdFZhcjogJ3Rlc3QnLCB0eXBlOiAnVEVTVF9FVkVOVCd9LCB0cnVlKTtcblxuICAgICAgZXhwZWN0KGV2ZW50U3B5Lm1vY2suY2FsbHMubGVuZ3RoKS50b0VxdWFsKDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1cGRhdGUgc3RvcmFnZScsICgpID0+IHtcbiAgICAgIEZsdXgudXBkYXRlU3RvcmFnZSA9IGplc3QuZm4oKS5tb2NrUmVzb2x2ZWRWYWx1ZSh7fSk7XG4gICAgICBGbHV4Lm9wdGlvbnMuc3RvcmFnZSA9IHt9O1xuXG4gICAgICAvLyBNZXRob2RcbiAgICAgIEZsdXguZGlzcGF0Y2goe3Rlc3RWYXI6ICd0ZXN0JywgdHlwZTogJ1RFU1RfRVZFTlQnfSk7XG5cbiAgICAgIGV4cGVjdChGbHV4LnVwZGF0ZVN0b3JhZ2UubW9jay5jYWxscy5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiB1cGRhdGVkIHN0YXRlIGlmIGFjdGlvbiByZXR1cm5zIG51bGwnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBBZGQgbnVsbCBzdG9yZVxuICAgICAgY29uc3QgbnVsbFN0b3JlID0gKHR5cGU6IHN0cmluZywgZGF0YSwgc3RhdGUgPSBpbml0aWFsU3RhdGUpOiBhbnkgPT4ge1xuICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgIGNhc2UgJ1RFU1RfTlVMTCc6XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIHN0YXRlO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgYXdhaXQgRmx1eC5hZGRTdG9yZXMoW251bGxTdG9yZV0pO1xuXG4gICAgICAvLyBNZXRob2RcbiAgICAgIGF3YWl0IEZsdXguZGlzcGF0Y2goe3Rlc3RWYXI6ICd0ZXN0JywgdHlwZTogJ1RFU1RfTlVMTCd9KTtcblxuICAgICAgZXhwZWN0KEZsdXguc3RhdGUubnVsbFN0b3JlKS50b0VxdWFsKGluaXRpYWxTdGF0ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBvYmplY3QgaWYgc3RvcmUgcmV0dXJucyBudWxsIGJ5IGRlZmF1bHQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBBZGQgbnVsbCBzdG9yZVxuICAgICAgY29uc3QgbnVsbFN0b3JlID0gKHR5cGU6IHN0cmluZywgZGF0YSwgc3RhdGUpOiBhbnkgPT4ge1xuICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgIGNhc2UgJ1RFU1RfTlVMTCc6XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIHN0YXRlO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgYXdhaXQgRmx1eC5hZGRTdG9yZXMoW251bGxTdG9yZV0pO1xuICAgICAgRmx1eC5zdGF0ZS5udWxsU3RvcmUgPSBudWxsO1xuXG4gICAgICAvLyBNZXRob2RcbiAgICAgIGF3YWl0IEZsdXguZGlzcGF0Y2goe3Rlc3RWYXI6ICd0ZXN0JywgdHlwZTogJ1RFU1RfTlVMTCd9KTtcblxuICAgICAgZXhwZWN0KEZsdXguc3RhdGUubnVsbFN0b3JlKS50b0VxdWFsKHt9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNnZXRPcHRpb25zJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZ2V0IGEgb3B0aW9ucyBvYmplY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zID0gRmx1eC5nZXRPcHRpb25zKCk7XG4gICAgICBjb25zdCBvcHRpb25zS2V5OiBzdHJpbmcgPSAnb3B0aW9ucyc7XG4gICAgICBleHBlY3Qob3B0aW9ucykudG9FcXVhbChGbHV4W29wdGlvbnNLZXldKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNnZXRTdGF0ZScsICgpID0+IHtcbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIGNvbnN0IHN0b3JlQWN0aW9uID0gRmx1eC5nZXRTdG9yZSgnaGVsbG9TdG9yZScpO1xuICAgICAgRmx1eC5zZXRTdGF0ZSgnaGVsbG9TdG9yZScsIHN0b3JlQWN0aW9uLmluaXRpYWxTdGF0ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGdldCBhIGdsb2JhbCBzdG9yZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gRmx1eC5nZXRTdGF0ZSgpO1xuICAgICAgZXhwZWN0KHZhbHVlLmhlbGxvU3RvcmUuaXRlbSkudG9FcXVhbCgnZGVmYXVsdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgYSBzcGVjaWZpYyBzdG9yZSByZXR1cm5pbmcgYW4gb2JqZWN0JywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBGbHV4LmdldFN0YXRlKCdoZWxsb1N0b3JlJyk7XG4gICAgICBleHBlY3QodmFsdWUuaXRlbSkudG9FcXVhbCgnZGVmYXVsdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBnZXQgYSBzcGVjaWZpYyBpdGVtIHdpdGhpbiBhIHN0b3JlIHVzaW5nIGFycmF5JywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWU6IHN0cmluZyA9IEZsdXguZ2V0U3RhdGUoWydoZWxsb1N0b3JlJywgJ2l0ZW0nXSk7XG4gICAgICBleHBlY3QodmFsdWUpLnRvRXF1YWwoJ2RlZmF1bHQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IGEgc3BlY2lmaWMgaXRlbSB3aXRoaW4gYSBzdG9yZSB1c2luZyBkb3Qgbm90YXRpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZTogc3RyaW5nID0gRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS5pdGVtJyk7XG4gICAgICBleHBlY3QodmFsdWUpLnRvRXF1YWwoJ2RlZmF1bHQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGRlZmF1bHQgdmFsdWUgZnJvbSBhIG51bGwgaXRlbScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgPSBGbHV4LmdldFN0YXRlKCdoZWxsb1N0b3JlLm5vdERlZmF1bHQnLCAnJyk7XG4gICAgICBleHBlY3QodmFsdWUpLnRvRXF1YWwoJycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZW50aXJlIHN0b3JlIG9iamVjdCB3aXRoIGVtcHR5IGtleScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgPSBGbHV4LmdldFN0YXRlKCcnKTtcbiAgICAgIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCh7aGVsbG9TdG9yZTogaW5pdGlhbFN0YXRlfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbnRpcmUgc3RvcmUgb2JqZWN0IHdpdGggbnVsbCBrZXknLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZTogc3RyaW5nID0gRmx1eC5nZXRTdGF0ZShudWxsKTtcbiAgICAgIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCh7aGVsbG9TdG9yZTogaW5pdGlhbFN0YXRlfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBlbnRpcmUgc3RvcmUgb2JqZWN0IHdpdGggdW5kZWZpbmVkIGtleScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgPSBGbHV4LmdldFN0YXRlKCk7XG4gICAgICBleHBlY3QodmFsdWUpLnRvRXF1YWwoe2hlbGxvU3RvcmU6IGluaXRpYWxTdGF0ZX0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gZW1wdHkgb2JqZWN0IGlmIHN0YXRlIGlzIG51bGwnLCAoKSA9PiB7XG4gICAgICBGbHV4LnN0YXRlID0gbnVsbDtcbiAgICAgIGNvbnN0IHZhbHVlOiBzdHJpbmcgPSBGbHV4LmdldFN0YXRlKCk7XG4gICAgICBleHBlY3QodmFsdWUpLnRvRXF1YWwoe30pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBmYWxzZSB2YWx1ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS5mYWxzeScpO1xuICAgICAgZXhwZWN0KHZhbHVlKS50b0VxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIGEgemVybyB2YWx1ZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS56ZXJvVmFsdWUnKTtcbiAgICAgIGV4cGVjdCh2YWx1ZSkudG9FcXVhbCgwKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNnZXRTdG9yZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGdldCBhIHN0b3JlIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc3RvcmVBY3Rpb24gPSBGbHV4LmdldFN0b3JlKCdoZWxsb1N0b3JlJyk7XG4gICAgICBleHBlY3Qoc3RvcmVBY3Rpb24ubmFtZSkudG9FcXVhbCgnaGVsbG9TdG9yZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB1c2UgZW1wdHkgc3RyaW5nIGFzIGRlZmF1bHQgdmFsdWUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBzdG9yZUFjdGlvbiA9IEZsdXguZ2V0U3RvcmUoKTtcbiAgICAgIGV4cGVjdChzdG9yZUFjdGlvbikudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnI2luaXQnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ3NldCBhcHAgbmFtZScsICgpID0+IHtcbiAgICAgIC8vIFZhcnNcbiAgICAgIGNvbnN0IG9wdHM6IEZsdXhPcHRpb25zID0ge1xuICAgICAgICBuYW1lOiAnZGVtbydcbiAgICAgIH07XG5cbiAgICAgIGl0KCdzaG91bGQgdXBkYXRlIGFwcCBuYW1lIGlmIGluaXRpYWxpemluZyBmb3IgdGhlIGZpcnN0IHRpbWUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByaXZhdGVJbml0OiBzdHJpbmcgPSAnaXNJbml0JztcbiAgICAgICAgRmx1eFtwcml2YXRlSW5pdF0gPSBmYWxzZTtcblxuICAgICAgICAvLyBNZXRob2RcbiAgICAgICAgYXdhaXQgRmx1eC5pbml0KG9wdHMpO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnNLZXk6IHN0cmluZyA9ICdvcHRpb25zJztcbiAgICAgICAgZXhwZWN0KEZsdXhbb3B0aW9uc0tleV0ubmFtZSkudG9FcXVhbCgnZGVtbycpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgbm90IHVwZGF0ZSBhcHAgbmFtZSBpZiBpbml0aWFsaXppbmcgYWdhaW4nLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByaXZhdGVJbml0OiBzdHJpbmcgPSAnaXNJbml0JztcbiAgICAgICAgRmx1eFtwcml2YXRlSW5pdF0gPSB0cnVlO1xuXG4gICAgICAgIC8vIE1ldGhvZFxuICAgICAgICBhd2FpdCBGbHV4LmluaXQob3B0cyk7XG5cbiAgICAgICAgY29uc3Qgb3B0aW9uc0tleTogc3RyaW5nID0gJ29wdGlvbnMnO1xuICAgICAgICBleHBlY3QoRmx1eFtvcHRpb25zS2V5XS5uYW1lKS50b0VxdWFsKCdhcmtoYW1qc1Rlc3QnKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGFkZCB3aW5kb3dzIG9iamVjdCBmb3IgZGVidWdnaW5nJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBNZXRob2RcbiAgICAgICAgYXdhaXQgRmx1eC5pbml0KHsuLi5vcHRzLCBkZWJ1ZzogdHJ1ZX0pO1xuXG4gICAgICAgIGNvbnN0IGRlYnVnS2V5OiBzdHJpbmcgPSAnYXJraGFtanMnO1xuICAgICAgICBleHBlY3Qod2luZG93W2RlYnVnS2V5XSkudG9FcXVhbChGbHV4KTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVzZSBkZWZhdWx0IG9iamVjdCBpZiB1bmRlZmluZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIE1ldGhvZFxuICAgICAgICBhd2FpdCBGbHV4LnJlc2V0KCk7XG4gICAgICAgIGF3YWl0IEZsdXguaW5pdCgpO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnNLZXk6IHN0cmluZyA9ICdvcHRpb25zJztcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRPcHRpb25zID0ge1xuICAgICAgICAgIG5hbWU6ICdhcmtoYW1qcycsXG4gICAgICAgICAgcm91dGVyVHlwZTogJ2Jyb3dzZXInLFxuICAgICAgICAgIHNjcm9sbFRvVG9wOiB0cnVlLFxuICAgICAgICAgIHN0YXRlOiBudWxsLFxuICAgICAgICAgIHN0b3JhZ2U6IG51bGwsXG4gICAgICAgICAgc3RvcmFnZVdhaXQ6IDMwMCxcbiAgICAgICAgICBzdG9yZXM6IFtdLFxuICAgICAgICAgIHRpdGxlOiAnQXJraGFtSlMnXG4gICAgICAgIH07XG4gICAgICAgIGV4cGVjdChGbHV4W29wdGlvbnNLZXldKS50b0VxdWFsKGV4cGVjdGVkT3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdzZXQgYXBwIG5hbWUgZm9yIGluaXRpYWxpemVkIGFwcCcsICgpID0+IHtcbiAgICAgIC8vIFZhcnNcbiAgICAgIGNvbnN0IG9wdHM6IEZsdXhPcHRpb25zID0ge1xuICAgICAgICBuYW1lOiAnZGVtbydcbiAgICAgIH07XG5cbiAgICAgIGl0KCdzaG91bGQgc2V0IGFwcCBuYW1lJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBGbHV4LmluaXQob3B0cywgdHJ1ZSk7XG4gICAgICAgIGNvbnN0IHByaXZhdGVQcm9wZXJ0eTogc3RyaW5nID0gJ29wdGlvbnMnO1xuICAgICAgICBleHBlY3QoRmx1eFtwcml2YXRlUHJvcGVydHldLm5hbWUpLnRvRXF1YWwoJ2RlbW8nKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldCBpbml0aWFsIGVtcHR5IHN0YXRlJywgKCkgPT4ge1xuICAgICAgLy8gVmFyc1xuICAgICAgY29uc3Qgb3B0czogRmx1eE9wdGlvbnMgPSB7XG4gICAgICAgIHN0YXRlOiB7fSxcbiAgICAgICAgc3RvcmVzOiBbaGVsbG9TdG9yZV1cbiAgICAgIH07XG5cbiAgICAgIGl0KCdzaG91bGQgc2V0IHN0YXRlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBGbHV4LmluaXQob3B0cywgdHJ1ZSk7XG4gICAgICAgIGNvbnN0IHByaXZhdGVQcm9wZXJ0eTogc3RyaW5nID0gJ3N0YXRlJztcbiAgICAgICAgZXhwZWN0KE9iamVjdC5rZXlzKEZsdXhbcHJpdmF0ZVByb3BlcnR5XSkubGVuZ3RoKS50b0VxdWFsKDEpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc2V0IHN0YXRlIGJyYW5jaCBmb3Igc3RvcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IEZsdXguaW5pdChvcHRzLCB0cnVlKTtcbiAgICAgICAgY29uc3QgcHJpdmF0ZVByb3BlcnR5OiBzdHJpbmcgPSAnc3RhdGUnO1xuICAgICAgICBleHBlY3QoRmx1eFtwcml2YXRlUHJvcGVydHldLmhlbGxvU3RvcmUuaXRlbSkudG9FcXVhbCgnZGVmYXVsdCcpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnc2V0IG51bGwgc3RhdGUnLCAoKSA9PiB7XG4gICAgICAvLyBWYXJzXG4gICAgICBjb25zdCBvcHRzOiBGbHV4T3B0aW9ucyA9IHtcbiAgICAgICAgc3RhdGU6IG51bGwsXG4gICAgICAgIHN0b3JlczogW2hlbGxvU3RvcmVdXG4gICAgICB9O1xuXG4gICAgICBpdCgnc2hvdWxkIHNldCBzdGF0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgRmx1eC5pbml0KG9wdHMsIHRydWUpO1xuICAgICAgICBjb25zdCBwcml2YXRlUHJvcGVydHk6IHN0cmluZyA9ICdzdGF0ZSc7XG4gICAgICAgIGV4cGVjdChPYmplY3Qua2V5cyhGbHV4W3ByaXZhdGVQcm9wZXJ0eV0pLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHNldCBzdGF0ZSBicmFuY2ggZm9yIHN0b3JlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBGbHV4LmluaXQob3B0cywgdHJ1ZSk7XG4gICAgICAgIGNvbnN0IHByaXZhdGVQcm9wZXJ0eTogc3RyaW5nID0gJ3N0YXRlJztcbiAgICAgICAgZXhwZWN0KEZsdXhbcHJpdmF0ZVByb3BlcnR5XS5oZWxsb1N0b3JlLml0ZW0pLnRvRXF1YWwoJ2RlZmF1bHQnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ3NldCBkZWZpbmVkIHN0YXRlJywgKCkgPT4ge1xuICAgICAgLy8gVmFyc1xuICAgICAgY29uc3Qgb3B0czogRmx1eE9wdGlvbnMgPSB7XG4gICAgICAgIHN0YXRlOiB7c2Vjb25kOiAndmFsdWUnLCB0ZXN0OiB7aGVsbG86ICd3b3JsZCd9fSxcbiAgICAgICAgc3RvcmVzOiBbaGVsbG9TdG9yZV1cbiAgICAgIH07XG5cbiAgICAgIGl0KCdzaG91bGQgc2V0IHN0YXRlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBGbHV4LmluaXQob3B0cywgdHJ1ZSk7XG4gICAgICAgIGNvbnN0IHByaXZhdGVQcm9wZXJ0eTogc3RyaW5nID0gJ3N0YXRlJztcbiAgICAgICAgZXhwZWN0KE9iamVjdC5rZXlzKEZsdXhbcHJpdmF0ZVByb3BlcnR5XSkubGVuZ3RoKS50b0VxdWFsKDMpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgc2V0IHN0YXRlIGJyYW5jaCBmb3Igc3RvcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IEZsdXguaW5pdChvcHRzLCB0cnVlKTtcbiAgICAgICAgY29uc3QgcHJpdmF0ZVByb3BlcnR5OiBzdHJpbmcgPSAnc3RhdGUnO1xuICAgICAgICBleHBlY3QoRmx1eFtwcml2YXRlUHJvcGVydHldLnRlc3QuaGVsbG8pLnRvRXF1YWwoJ3dvcmxkJyk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdtaWRkbGV3YXJlJywgKCkgPT4ge1xuICAgICAgLy8gTWlkZGxld2FyZSBvYmplY3RcbiAgICAgIGNvbnN0IG9iak1pZGRsZXdhcmUgPSB7XG4gICAgICAgIG5hbWU6ICdvYmplY3RNaWRkbGV3YXJlJyxcbiAgICAgICAgcHJlRGlzcGF0Y2g6IChhY3Rpb24pID0+ICh7Li4uYWN0aW9ufSlcbiAgICAgIH07XG5cbiAgICAgIC8vIFZhcnNcbiAgICAgIGNvbnN0IG9wdHM6IEZsdXhPcHRpb25zID0ge1xuICAgICAgICBtaWRkbGV3YXJlOiBbb2JqTWlkZGxld2FyZV0sXG4gICAgICAgIG5hbWU6ICdkZW1vJyxcbiAgICAgICAgc3RvcmVzOiBbaGVsbG9TdG9yZV1cbiAgICAgIH07XG5cbiAgICAgIGl0KCdzaG91bGQgYWRkIG1pZGRsZXdhcmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IEZsdXguaW5pdChvcHRzLCB0cnVlKTtcbiAgICAgICAgY29uc3QgcHJpdmF0ZVByb3BlcnR5OiBzdHJpbmcgPSAnbWlkZGxld2FyZSc7XG4gICAgICAgIGV4cGVjdChGbHV4W3ByaXZhdGVQcm9wZXJ0eV0ucHJlRGlzcGF0Y2hMaXN0WzBdLm5hbWUpLnRvRXF1YWwoJ29iamVjdE1pZGRsZXdhcmUnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ2Vycm9yIGhhbmRsaW5nJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgdXNlU3RvcmFnZSBlcnJvcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgRmx1eC51c2VTdG9yYWdlID0gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCd0ZXN0JykpO1xuICAgICAgICBhd2FpdCBleHBlY3QoRmx1eC5pbml0KGNmZywgdHJ1ZSkpLnJlamVjdHMudG9UaHJvd0Vycm9yKCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYWRkU3RvcmVzIGVycm9yJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBGbHV4LmFkZFN0b3JlcyA9IFByb21pc2UucmVqZWN0KG5ldyBFcnJvcigndGVzdCcpKTtcbiAgICAgICAgYXdhaXQgZXhwZWN0KEZsdXguaW5pdChjZmcsIHRydWUpKS5yZWplY3RzLnRvVGhyb3dFcnJvcigpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdldmVudCBsaXN0ZW5lcnMnLCAoKSA9PiB7XG4gICAgbGV0IGV2ZW50U3B5O1xuXG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBldmVudFNweSA9IGplc3QuZm4oKTtcbiAgICAgIEZsdXgub24oJ3Rlc3QnLCBldmVudFNweSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnI29uJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBhZGQgYSBsaXN0ZW5lcicsIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgRmx1eC5kaXNwYXRjaCh7dHlwZTogJ3Rlc3QnfSk7XG4gICAgICAgIGV4cGVjdChldmVudFNweS5tb2NrLmNhbGxzLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJyNvZmYnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIHJlbW92ZSBhIGxpc3RlbmVyJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBGbHV4Lm9mZigndGVzdCcsIGV2ZW50U3B5KTtcbiAgICAgICAgYXdhaXQgRmx1eC5kaXNwYXRjaCh7dHlwZTogJ3Rlc3QnfSk7XG5cbiAgICAgICAgZXhwZWN0KGV2ZW50U3B5Lm1vY2suY2FsbHMubGVuZ3RoKS50b0VxdWFsKDApO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjYWRkU3RvcmVzJywgKCkgPT4ge1xuICAgIGNvbnN0IGRlbW8gPSAodHlwZSwgZGF0YSwgc3RhdGUgPSB7aGVsbG9TdG9yZTogJ2pva2VyJ30pID0+IHtcbiAgICAgIGlmKHR5cGUgPT09ICdERU1PX1RFU1QnKSB7XG4gICAgICAgIHN0YXRlLmhlbGxvU3RvcmUgPSBkYXRhLmhlbGxvU3RvcmU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9O1xuXG4gICAgaXQoJ3Nob3VsZCBjcmVhdGUgYW5kIHNhdmUgYSBTdG9yZSBjbGFzcycsICgpID0+IHtcbiAgICAgIEZsdXguYWRkU3RvcmVzKFtkZW1vXSk7XG4gICAgICBjb25zdCBwcml2YXRlUHJvcGVydHk6IHN0cmluZyA9ICdzdG9yZUFjdGlvbnMnO1xuICAgICAgY29uc3Qgc3RvcmVBY3Rpb246IEZsdXhTdG9yZSA9IEZsdXhbcHJpdmF0ZVByb3BlcnR5XS5kZW1vO1xuICAgICAgZXhwZWN0KHN0b3JlQWN0aW9uLm5hbWUpLnRvRXF1YWwoJ2RlbW8nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2V0IGluaXRpYWwgc3RhdGUnLCAoKSA9PiB7XG4gICAgICBGbHV4LmFkZFN0b3JlcyhbZGVtb10pO1xuICAgICAgY29uc3QgcHJpdmF0ZVByb3BlcnR5OiBzdHJpbmcgPSAnc3RvcmVBY3Rpb25zJztcbiAgICAgIGNvbnN0IHN0b3JlQWN0aW9uOiBGbHV4U3RvcmUgPSBGbHV4W3ByaXZhdGVQcm9wZXJ0eV0uZGVtbztcbiAgICAgIGV4cGVjdChzdG9yZUFjdGlvbi5pbml0aWFsU3RhdGUpLnRvRXF1YWwoe2hlbGxvU3RvcmU6ICdqb2tlcid9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIHVuc3VwcG9ydGVkIHN0b3JlcycsICgpID0+IHtcbiAgICAgIGNvbnN0IG9wdGlvbnNLZXk6IHN0cmluZyA9ICdvcHRpb25zJztcbiAgICAgIGNvbnN0IHNldFN0b3JhZ2VEYXRhID0gbmV3IEVycm9yKCd0ZXN0Jyk7XG4gICAgICBGbHV4W29wdGlvbnNLZXldLnN0b3JhZ2UgPSB7c2V0U3RvcmFnZURhdGF9O1xuXG4gICAgICBGbHV4LmFkZFN0b3JlcyhbZGVtb10pO1xuICAgICAgY29uc3QgcHJpdmF0ZVByb3BlcnR5OiBzdHJpbmcgPSAnc3RvcmVBY3Rpb25zJztcbiAgICAgIGNvbnN0IHN0b3JlQWN0aW9uOiBGbHV4U3RvcmUgPSBGbHV4W3ByaXZhdGVQcm9wZXJ0eV0uZGVtbztcbiAgICAgIGV4cGVjdChzdG9yZUFjdGlvbi5pbml0aWFsU3RhdGUpLnRvRXF1YWwoe2hlbGxvU3RvcmU6ICdqb2tlcid9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNvZmZJbml0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmVtb3ZlIGxpc3RlbmVyIGFmdGVyIGluaXRpYWxpemF0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgbGlzdGVuZXIgPSBqZXN0LmZuKCk7XG4gICAgICBGbHV4Lm9mZiA9IGplc3QuZm4oKTtcbiAgICAgIEZsdXgub2ZmSW5pdChsaXN0ZW5lcik7XG4gICAgICBleHBlY3QoRmx1eC5vZmYubW9jay5jYWxscy5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgICBleHBlY3QoRmx1eC5vZmYubW9jay5jYWxsc1swXVswXSkudG9FcXVhbChBcmtoYW1Db25zdGFudHMuSU5JVCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjb25Jbml0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYWRkIGxpc3RlbmVyIGFmdGVyIGluaXRpYWxpemF0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgbGlzdGVuZXIgPSBqZXN0LmZuKCk7XG4gICAgICBGbHV4LmlzSW5pdCA9IGZhbHNlO1xuICAgICAgRmx1eC5vbiA9IGplc3QuZm4oKTtcbiAgICAgIEZsdXgub25Jbml0KGxpc3RlbmVyKTtcbiAgICAgIGV4cGVjdChGbHV4Lm9uLm1vY2suY2FsbHMubGVuZ3RoKS50b0VxdWFsKDEpO1xuICAgICAgZXhwZWN0KEZsdXgub24ubW9jay5jYWxsc1swXVswXSkudG9FcXVhbChBcmtoYW1Db25zdGFudHMuSU5JVCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGRpc3BhdGNoIGluc3RhbnRseSBpZiBhbHJlYWR5IGluaXRpYWxpemVkJywgKCkgPT4ge1xuICAgICAgY29uc3QgbGlzdGVuZXIgPSBqZXN0LmZuKCk7XG4gICAgICBGbHV4LmlzSW5pdCA9IHRydWU7XG4gICAgICBGbHV4Lm9uSW5pdChsaXN0ZW5lcik7XG4gICAgICBleHBlY3QobGlzdGVuZXIubW9jay5jYWxscy5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjcmVnaXN0ZXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZWdpc3RlciBhIHN0b3JlIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgZGVtb1N0b3JlID0gKHR5cGU6IHN0cmluZywgZGF0YSwgc3RhdGUgPSBpbml0aWFsU3RhdGUpOiBhbnkgPT4ge1xuICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgIGNhc2UgJ1RFU1RfRVZFTlQnOlxuICAgICAgICAgICAgcmV0dXJuIHNldCgndGVzdEFjdGlvbicsIGRhdGEudGVzdFZhciwgc3RhdGUpO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJlZ2lzdGVyS2V5OiBzdHJpbmcgPSAncmVnaXN0ZXInO1xuICAgICAgY29uc3Qgc3RvcmVBY3Rpb24gPSBGbHV4W3JlZ2lzdGVyS2V5XShkZW1vU3RvcmUpO1xuICAgICAgY29uc3QgZXhwZWN0ZWRBY3Rpb24gPSB7XG4gICAgICAgIGFjdGlvbjogZGVtb1N0b3JlLFxuICAgICAgICBpbml0aWFsU3RhdGUsXG4gICAgICAgIG5hbWU6ICdkZW1vU3RvcmUnXG4gICAgICB9O1xuICAgICAgZXhwZWN0KHN0b3JlQWN0aW9uKS50b0VxdWFsKGV4cGVjdGVkQWN0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVnaXN0ZXIgYSBzdG9yZSBmdW5jdGlvbiB3aXRob3V0IGFuIGluaXRpYWwgdmFsdWUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBkZW1vU3RvcmUgPSAodHlwZTogc3RyaW5nLCBkYXRhLCBzdGF0ZSk6IGFueSA9PiB7XG4gICAgICAgIHN3aXRjaCh0eXBlKSB7XG4gICAgICAgICAgY2FzZSAnVEVTVF9FVkVOVCc6XG4gICAgICAgICAgICByZXR1cm4gc2V0KCd0ZXN0QWN0aW9uJywgZGF0YS50ZXN0VmFyLCBzdGF0ZSk7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVnaXN0ZXJLZXk6IHN0cmluZyA9ICdyZWdpc3Rlcic7XG4gICAgICBjb25zdCBzdG9yZUFjdGlvbiA9IEZsdXhbcmVnaXN0ZXJLZXldKGRlbW9TdG9yZSk7XG4gICAgICBjb25zdCBleHBlY3RlZEFjdGlvbiA9IHtcbiAgICAgICAgYWN0aW9uOiBkZW1vU3RvcmUsXG4gICAgICAgIGluaXRpYWxTdGF0ZTogdW5kZWZpbmVkLFxuICAgICAgICBuYW1lOiAnZGVtb1N0b3JlJ1xuICAgICAgfTtcbiAgICAgIGV4cGVjdChzdG9yZUFjdGlvbikudG9FcXVhbChleHBlY3RlZEFjdGlvbik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG5vdCBzYXZlIGEgc3RvcmUgZnVuY3Rpb24gd2l0aG91dCBhIG5hbWUnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZWdpc3RlcktleTogc3RyaW5nID0gJ3JlZ2lzdGVyJztcbiAgICAgIGNvbnN0IHN0b3JlQWN0aW9uID0gRmx1eFtyZWdpc3RlcktleV0oKHR5cGU6IHN0cmluZywgZGF0YSwgc3RhdGUgPSBpbml0aWFsU3RhdGUpOiBhbnkgPT4ge1xuICAgICAgICBzd2l0Y2godHlwZSkge1xuICAgICAgICAgIGNhc2UgJ1RFU1RfRVZFTlQnOlxuICAgICAgICAgICAgcmV0dXJuIHNldCgndGVzdEFjdGlvbicsIGRhdGEudGVzdFZhciwgc3RhdGUpO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KHN0b3JlQWN0aW9uKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSB1bmRlZmluZWQgZnVuY3Rpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCByZWdpc3RlcktleTogc3RyaW5nID0gJ3JlZ2lzdGVyJztcblxuICAgICAgY29uc3QgZm4gPSAoKSA9PiBGbHV4W3JlZ2lzdGVyS2V5XSgpO1xuICAgICAgZXhwZWN0KGZuKS50b1Rocm93RXJyb3IoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIGFyZ3VtZW50IHRoYXQgaXMgbm90IGEgZnVuY3Rpb24nLCAoKSA9PiB7XG4gICAgICBjb25zdCByZWdpc3RlcktleTogc3RyaW5nID0gJ3JlZ2lzdGVyJztcblxuICAgICAgY29uc3QgZm4gPSAoKSA9PiBGbHV4W3JlZ2lzdGVyS2V5XSh7fSk7XG4gICAgICBleHBlY3QoZm4pLnRvVGhyb3dFcnJvcigpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnI3JlbW92ZU1pZGRsZXdhcmUnLCAoKSA9PiB7XG4gICAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgICBGbHV4LmNsZWFyTWlkZGxld2FyZSgpO1xuXG4gICAgICAvLyBBZGQgb2JqZWN0IG1pZGRsZXdhcmVcbiAgICAgIGNvbnN0IG9iak1pZGRsZXdhcmUgPSB7XG4gICAgICAgIG5hbWU6ICdvYmplY3RNaWRkbGV3YXJlJyxcbiAgICAgICAgcHJlRGlzcGF0Y2g6IChhY3Rpb24pID0+ICh7Li4uYWN0aW9ufSlcbiAgICAgIH07XG5cbiAgICAgIEZsdXguYWRkTWlkZGxld2FyZShbb2JqTWlkZGxld2FyZV0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhbHRlciBkYXRhIGJlZm9yZSBzZW5kaW5nIHRvIHN0b3JlcycsICgpID0+IHtcbiAgICAgIEZsdXgucmVtb3ZlTWlkZGxld2FyZShbJ29iamVjdE1pZGRsZXdhcmUnXSk7XG4gICAgICBjb25zdCBwcml2YXRlUHJvcGVydHk6IHN0cmluZyA9ICdtaWRkbGV3YXJlJztcbiAgICAgIGV4cGVjdChGbHV4W3ByaXZhdGVQcm9wZXJ0eV0ucHJlRGlzcGF0Y2hMaXN0Lmxlbmd0aCkudG9FcXVhbCgwKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNyZW1vdmVQbHVnaW4nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZW1vdmUgYW4gZXhpc3RpbmcgcGx1Z2luJywgKCkgPT4ge1xuICAgICAgRmx1eC5taWRkbGV3YXJlLnByZURpc3BhdGNoTGlzdCA9IFt7bmFtZTogJ2RlbW9QbHVnaW4nfSwge25hbWU6ICdub05vdFJlbW92ZVBsdWdpbid9XTtcbiAgICAgIGV4cGVjdChGbHV4LnJlbW92ZVBsdWdpbigncHJlRGlzcGF0Y2gnLCAnZGVtb1BsdWdpbicpKS50b0VxdWFsKFt7bmFtZTogJ25vTm90UmVtb3ZlUGx1Z2luJ31dKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2V0IGFuIHVuZGVmaW5lZCBsaXN0JywgKCkgPT4ge1xuICAgICAgRmx1eC5taWRkbGV3YXJlLnByZURpc3BhdGNoTGlzdCA9IG51bGw7XG4gICAgICBleHBlY3QoRmx1eC5yZW1vdmVQbHVnaW4oJ3ByZURpc3BhdGNoJywgJ2RlbW9QbHVnaW4nKSkudG9FcXVhbChbXSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjcmVtb3ZlU3RvcmVzJywgKCkgPT4ge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgLy8gTWV0aG9kXG4gICAgICBGbHV4LnJlbW92ZVN0b3JlcyhbJ2hlbGxvU3RvcmUnXSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgRmx1eC5hZGRTdG9yZXMoW2hlbGxvU3RvcmVdKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVtb3ZlIGNsYXNzJywgKCkgPT4ge1xuICAgICAgY29uc3QgcHJpdmF0ZVByb3BlcnR5OiBzdHJpbmcgPSAnc3RvcmVBY3Rpb25zJztcbiAgICAgIGV4cGVjdCghIUZsdXhbcHJpdmF0ZVByb3BlcnR5XS5oZWxsb1N0b3JlKS50b0VxdWFsKGZhbHNlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVtb3ZlIHN0b3JlIGRhdGEnLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcml2YXRlUHJvcGVydHk6IHN0cmluZyA9ICdzdGF0ZSc7XG4gICAgICBleHBlY3QoISFGbHV4W3ByaXZhdGVQcm9wZXJ0eV0uaGVsbG9TdG9yZSkudG9FcXVhbChmYWxzZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcjcmVzZXQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgYXJndW1lbnQgdGhhdCBpcyBub3QgYSBmdW5jdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IG9wdGlvbnNLZXk6IHN0cmluZyA9ICdvcHRpb25zJztcbiAgICAgIGNvbnN0IHNldFN0b3JhZ2VEYXRhID0gbmV3IEVycm9yKCd0ZXN0Jyk7XG4gICAgICBGbHV4W29wdGlvbnNLZXldLnN0b3JhZ2UgPSB7c2V0U3RvcmFnZURhdGF9O1xuICAgICAgYXdhaXQgZXhwZWN0KEZsdXgucmVzZXQoKSkucmVqZWN0cy50b1Rocm93RXJyb3IoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyNzZXRTdGF0ZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHVwZGF0ZSB0aGUgcHJvcGVydHkgd2l0aGluIHRoZSBzdG9yZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IEZsdXguc2V0U3RhdGUoJ2hlbGxvU3RvcmUudGVzdFVwZGF0ZScsICd0ZXN0Jyk7XG4gICAgICBjb25zdCBuZXdJdGVtID0gYXdhaXQgRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZS50ZXN0VXBkYXRlJyk7XG4gICAgICBleHBlY3QobmV3SXRlbSkudG9FcXVhbCgndGVzdCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlbXB0eSBzdHJpbmcgYXMgZGVmYXVsdCBwYXRoJywgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgRmx1eC5zZXRTdGF0ZSh1bmRlZmluZWQsICd0ZXN0Jyk7XG4gICAgICBjb25zdCBuZXdJdGVtID0gYXdhaXQgRmx1eC5nZXRTdGF0ZSgnaGVsbG9TdG9yZScpO1xuICAgICAgZXhwZWN0KG5ld0l0ZW0pLnRvRXF1YWwoaW5pdGlhbFN0YXRlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdXBkYXRlIHN0b3JhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zS2V5OiBzdHJpbmcgPSAnb3B0aW9ucyc7XG4gICAgICBjb25zdCB1cGRhdGVTdG9yYWdlS2V5OiBzdHJpbmcgPSAndXBkYXRlU3RvcmFnZSc7XG4gICAgICBjb25zdCB1cGRhdGVTdG9yYWdlID0gamVzdC5mbigpO1xuICAgICAgRmx1eFtvcHRpb25zS2V5XSA9IHtzdG9yYWdlOiB7fX07XG4gICAgICBGbHV4W3VwZGF0ZVN0b3JhZ2VLZXldID0gdXBkYXRlU3RvcmFnZTtcbiAgICAgIGF3YWl0IEZsdXguc2V0U3RhdGUoJ2hlbGxvU3RvcmUudGVzdFVwZGF0ZScsICd0ZXN0Jyk7XG4gICAgICBleHBlY3QodXBkYXRlU3RvcmFnZS5tb2NrLmNhbGxzLmxlbmd0aCkudG9FcXVhbCgxKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJyN1c2VTdG9yYWdlJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgdXBkYXRlIHN0b3JhZ2UnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBnZXRTdG9yYWdlRGF0YSA9IGplc3QuZm4oKTtcbiAgICAgIGNvbnN0IG9wdGlvbnNLZXk6IHN0cmluZyA9ICdvcHRpb25zJztcbiAgICAgIEZsdXhbb3B0aW9uc0tleV0uc3RhdGUgPSBudWxsO1xuICAgICAgRmx1eFtvcHRpb25zS2V5XS5zdG9yYWdlID0ge2dldFN0b3JhZ2VEYXRhfTtcblxuICAgICAgY29uc3QgdXNlU3RvcmFnZUtleTogc3RyaW5nID0gJ3VzZVN0b3JhZ2UnO1xuICAgICAgYXdhaXQgRmx1eFt1c2VTdG9yYWdlS2V5XSgnaGVsbG9TdG9yZScpO1xuXG4gICAgICBleHBlY3QoZ2V0U3RvcmFnZURhdGEubW9jay5jYWxscy5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnd2l0aG91dCBzdG9yYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uc0tleTogc3RyaW5nID0gJ29wdGlvbnMnO1xuICAgICAgRmx1eFtvcHRpb25zS2V5XS5zdGF0ZSA9IHtoZWxsbzogJ3dvcmxkJ307XG4gICAgICBGbHV4W29wdGlvbnNLZXldLnN0b3JhZ2UgPSBudWxsO1xuXG4gICAgICBjb25zdCB1c2VTdG9yYWdlS2V5OiBzdHJpbmcgPSAndXNlU3RvcmFnZSc7XG4gICAgICBhd2FpdCBGbHV4W3VzZVN0b3JhZ2VLZXldKCdoZWxsb1N0b3JlJyk7XG5cbiAgICAgIGNvbnN0IHN0YXRlS2V5OiBzdHJpbmcgPSAnc3RhdGUnO1xuICAgICAgZXhwZWN0KEZsdXhbc3RhdGVLZXldLmhlbGxvKS50b0VxdWFsKCd3b3JsZCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgc3RvcmFnZSBlcnJvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBvcHRpb25zS2V5OiBzdHJpbmcgPSAnb3B0aW9ucyc7XG4gICAgICBGbHV4W29wdGlvbnNLZXldLnN0YXRlID0gbnVsbDtcbiAgICAgIEZsdXhbb3B0aW9uc0tleV0uc3RvcmFnZSA9IG5ldyBFcnJvcigndGVzdCcpO1xuXG4gICAgICBjb25zdCB1c2VTdG9yYWdlS2V5OiBzdHJpbmcgPSAndXNlU3RvcmFnZSc7XG4gICAgICBhd2FpdCBleHBlY3QoRmx1eFt1c2VTdG9yYWdlS2V5XSgnaGVsbG9TdG9yZScpKS5yZWplY3RzLnRvVGhyb3dFcnJvcigpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBkZWJvdW5jZSBzdG9yYWdlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsdWU6IHN0cmluZyA9ICd0ZXN0JztcbiAgICAgIGNvbnN0IG9wdGlvbnNLZXk6IHN0cmluZyA9ICdvcHRpb25zJztcbiAgICAgIEZsdXhbb3B0aW9uc0tleV0uc3RhdGUgPSB7aGVsbG86ICd3b3JsZCd9O1xuXG4gICAgICBjb25zdCBzZXRTdG9yYWdlRGF0YSA9IGplc3QuZm4oKS5tb2NrUmV0dXJuVmFsdWUodmFsdWUpO1xuICAgICAgRmx1eFtvcHRpb25zS2V5XS5zdG9yYWdlID0ge3NldFN0b3JhZ2VEYXRhfTtcblxuICAgICAgY29uc3QgZGVib3VuY2VNb2NrOiBhbnkgPSBkZWJvdW5jZTtcbiAgICAgIGRlYm91bmNlTW9jay5tb2NrSW1wbGVtZW50YXRpb24oKGZuKSA9PiBmbigpKTtcblxuICAgICAgY29uc3QgdXNlU3RvcmFnZUtleTogc3RyaW5nID0gJ3VzZVN0b3JhZ2UnO1xuICAgICAgYXdhaXQgRmx1eFt1c2VTdG9yYWdlS2V5XSgnaGVsbG9TdG9yZScpO1xuXG4gICAgICBleHBlY3Qoc2V0U3RvcmFnZURhdGEubW9jay5jYWxscy5sZW5ndGgpLnRvRXF1YWwoMSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUlBLHNCQUFxQjtBQUNyQix1QkFBc0I7QUFDdEIsaUJBQWdCO0FBRWhCLDZCQUE4QjtBQUM5QixrQkFBNEI7QUFHNUIsS0FBSyxLQUFLO0FBRVYsTUFBTSxlQUFlO0FBQUEsRUFDbkIsT0FBTztBQUFBLEVBQ1AsTUFBTTtBQUFBLEVBQ04sWUFBWTtBQUFBLEVBQ1osWUFBWTtBQUFBLEVBQ1osV0FBVztBQUFBO0FBR2IsTUFBTSxhQUFhLENBQUMsTUFBYyxNQUFNLFFBQVEsaUJBQXNCO0FBQ3BFLFVBQU87QUFBQSxTQUNBO0FBQ0gsYUFBTyx3QkFBSSxjQUFjLEtBQUssU0FBUztBQUFBO0FBRXZDLGFBQU87QUFBQTtBQUFBO0FBSWIsU0FBUyxRQUFRLE1BQU07QUFDckIsUUFBTSxlQUFlLFFBQVE7QUFDN0IsUUFBTSxjQUFjLFFBQVE7QUFDNUIsUUFBTSxNQUFtQjtBQUFBLElBQ3ZCLE1BQU07QUFBQSxJQUNOLFFBQVEsQ0FBQztBQUFBO0FBRVgsTUFBSTtBQUVKLFlBQVUsTUFBTTtBQUNkLFlBQVEsUUFBUSxLQUFLO0FBQ3JCLFlBQVEsT0FBTyxLQUFLO0FB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