@uql/core 0.4.81 → 0.4.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dialect/abstractSqlDialect-spec.d.ts +49 -0
  2. package/dialect/abstractSqlDialect-spec.js +765 -0
  3. package/dialect/mysqlDialect.spec.d.ts +6 -0
  4. package/dialect/mysqlDialect.spec.js +33 -0
  5. package/dialect/postgresDialect.spec.d.ts +1 -0
  6. package/dialect/postgresDialect.spec.js +139 -0
  7. package/dialect/sqliteDialect.spec.d.ts +1 -0
  8. package/dialect/sqliteDialect.spec.js +12 -0
  9. package/entity/decorator/definition.spec.d.ts +1 -0
  10. package/entity/decorator/definition.spec.js +737 -0
  11. package/entity/decorator/relation.spec.d.ts +1 -0
  12. package/entity/decorator/relation.spec.js +55 -0
  13. package/options.spec.d.ts +1 -0
  14. package/options.spec.js +50 -0
  15. package/package.json +3 -3
  16. package/querier/abstractQuerier-it.d.ts +41 -0
  17. package/querier/abstractQuerier-it.js +410 -0
  18. package/querier/abstractSqlQuerier-it.d.ts +9 -0
  19. package/querier/abstractSqlQuerier-it.js +19 -0
  20. package/querier/abstractSqlQuerier-spec.d.ts +53 -0
  21. package/querier/abstractSqlQuerier-spec.js +609 -0
  22. package/querier/decorator/injectQuerier.spec.d.ts +1 -0
  23. package/querier/decorator/injectQuerier.spec.js +108 -0
  24. package/querier/decorator/transactional.spec.d.ts +1 -0
  25. package/querier/decorator/transactional.spec.js +241 -0
  26. package/repository/genericRepository.spec.d.ts +1 -0
  27. package/repository/genericRepository.spec.js +86 -0
  28. package/test/entityMock.d.ts +180 -0
  29. package/test/entityMock.js +451 -0
  30. package/test/index.d.ts +3 -0
  31. package/test/index.js +7 -0
  32. package/test/it.util.d.ts +4 -0
  33. package/test/it.util.js +60 -0
  34. package/test/spec.util.d.ts +13 -0
  35. package/test/spec.util.js +54 -0
  36. package/util/dialect.util.spec.d.ts +1 -0
  37. package/util/dialect.util.spec.js +23 -0
  38. package/util/object.util.spec.d.ts +1 -0
  39. package/util/object.util.spec.js +26 -0
  40. package/util/sql.util.spec.d.ts +1 -0
  41. package/util/sql.util.spec.js +164 -0
  42. package/util/string.util.spec.d.ts +1 -0
  43. package/util/string.util.spec.js +26 -0
@@ -0,0 +1,609 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractSqlQuerierSpec = void 0;
4
+ const raw_1 = require("@uql/core/util/raw");
5
+ const test_1 = require("@uql/core/test");
6
+ class AbstractSqlQuerierSpec {
7
+ constructor(pool, idType) {
8
+ this.pool = pool;
9
+ this.idType = idType;
10
+ }
11
+ async beforeAll() {
12
+ this.querier = await this.pool.getQuerier();
13
+ await (0, test_1.dropTables)(this.querier);
14
+ await (0, test_1.createTables)(this.querier, this.idType);
15
+ await this.querier.release();
16
+ }
17
+ async beforeEach() {
18
+ this.querier = await this.pool.getQuerier();
19
+ await (0, test_1.clearTables)(this.querier);
20
+ jest.spyOn(this.querier, 'all');
21
+ jest.spyOn(this.querier, 'run');
22
+ }
23
+ async afterEach() {
24
+ jest.restoreAllMocks();
25
+ await this.querier.release();
26
+ }
27
+ async afterAll() {
28
+ await this.pool.end();
29
+ }
30
+ async shouldFindOneById() {
31
+ await this.querier.findOneById(test_1.User, 1);
32
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id`, `companyId`, `creatorId`, `createdAt`, `updatedAt`, `name`, `email`, `password` FROM `User` WHERE `id` = 1 LIMIT 1');
33
+ expect(this.querier.all).toBeCalledTimes(1);
34
+ expect(this.querier.run).toBeCalledTimes(0);
35
+ }
36
+ async shouldFindOne() {
37
+ await this.querier.findOne(test_1.User, { $project: ['id', 'name'], $filter: { companyId: 123 } });
38
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id`, `name` FROM `User` WHERE `companyId` = 123 LIMIT 1');
39
+ expect(this.querier.all).toBeCalledTimes(1);
40
+ expect(this.querier.run).toBeCalledTimes(0);
41
+ }
42
+ async shouldFindOneAndProjectOneToMany() {
43
+ await this.querier.insertMany(test_1.InventoryAdjustment, [
44
+ {
45
+ id: 123,
46
+ createdAt: 1,
47
+ },
48
+ { id: 456, createdAt: 1 },
49
+ ]);
50
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `InventoryAdjustment` (`id`, `createdAt`) VALUES (123, 1), (456, 1)');
51
+ await this.querier.findMany(test_1.InventoryAdjustment, {
52
+ $project: ['id', 'itemAdjustments'],
53
+ $filter: { createdAt: 1 },
54
+ });
55
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `InventoryAdjustment`.`id` FROM `InventoryAdjustment` WHERE `InventoryAdjustment`.`createdAt` = 1');
56
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id`, `companyId`, `creatorId`, `createdAt`, `updatedAt`, `itemId`, `number`, `buyPrice`, `storehouseId`' +
57
+ ', `inventoryAdjustmentId` FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` IN (123, 456)');
58
+ expect(this.querier.all).toBeCalledTimes(2);
59
+ expect(this.querier.run).toBeCalledTimes(1);
60
+ }
61
+ async shouldFindAndProjectRaw() {
62
+ await this.querier.findMany(test_1.InventoryAdjustment, {
63
+ $project: {
64
+ creator: ['id', 'name'],
65
+ itemAdjustments: {
66
+ $project: {
67
+ item: {
68
+ $project: {
69
+ companyId: true,
70
+ total: (0, raw_1.raw)(({ escapedPrefix, dialect }) => `SUM(${escapedPrefix}${dialect.escapeId('salePrice')})`),
71
+ },
72
+ },
73
+ },
74
+ $sort: { createdAt: -1 },
75
+ $limit: 100,
76
+ },
77
+ },
78
+ $filter: {
79
+ companyId: 1,
80
+ },
81
+ $sort: { creator: { name: 'asc' } },
82
+ });
83
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `InventoryAdjustment`.`id`, `creator`.`id` `creator.id`, `creator`.`name` `creator.name`' +
84
+ ' FROM `InventoryAdjustment` LEFT JOIN `User` `creator` ON `creator`.`id` = `InventoryAdjustment`.`creatorId`' +
85
+ ' WHERE `InventoryAdjustment`.`companyId` = 1 ORDER BY `creator`.`name`');
86
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `ItemAdjustment`.`id`, `ItemAdjustment`.`inventoryAdjustmentId`' +
87
+ ', `item`.`id` `item.id`, `item`.`companyId` `item.companyId`, SUM(`item`.`salePrice`) `item.total`' +
88
+ ' FROM `ItemAdjustment` LEFT JOIN `Item` `item` ON `item`.`id` = `ItemAdjustment`.`itemId`' +
89
+ ' WHERE `ItemAdjustment`.`inventoryAdjustmentId` IN ()' +
90
+ ' ORDER BY `ItemAdjustment`.`createdAt`' +
91
+ ' DESC LIMIT 100');
92
+ expect(this.querier.all).toBeCalledTimes(2);
93
+ expect(this.querier.run).toBeCalledTimes(0);
94
+ }
95
+ async shouldVirtualField() {
96
+ await this.querier.findMany(test_1.Item, {
97
+ $project: {
98
+ id: 1,
99
+ },
100
+ $filter: {
101
+ tagsCount: { $gte: 10 },
102
+ },
103
+ });
104
+ expect(this.querier.all).toBeCalledWith('SELECT `id` FROM `Item` WHERE (SELECT COUNT(*) `count` FROM `ItemTag` WHERE `ItemTag`.`itemId` = `id`) >= 10');
105
+ expect(this.querier.all).toBeCalledTimes(1);
106
+ expect(this.querier.run).toBeCalledTimes(0);
107
+ jest.clearAllMocks();
108
+ await this.querier.findMany(test_1.Item, {
109
+ $project: {
110
+ id: 1,
111
+ name: 1,
112
+ code: 1,
113
+ tagsCount: 1,
114
+ measureUnit: {
115
+ $project: { id: 1, name: 1, categoryId: 1, category: ['name'] },
116
+ },
117
+ },
118
+ $limit: 100,
119
+ });
120
+ expect(this.querier.all).toBeCalledWith('SELECT `Item`.`id`, `Item`.`name`, `Item`.`code`' +
121
+ ', (SELECT COUNT(*) `count` FROM `ItemTag` WHERE `ItemTag`.`itemId` = `Item`.`id`) `tagsCount`' +
122
+ ', `measureUnit`.`id` `measureUnit.id`, `measureUnit`.`name` `measureUnit.name`, `measureUnit`.`categoryId` `measureUnit.categoryId`' +
123
+ ', `measureUnit.category`.`id` `measureUnit.category.id`, `measureUnit.category`.`name` `measureUnit.category.name`' +
124
+ ' FROM `Item` LEFT JOIN `MeasureUnit` `measureUnit` ON `measureUnit`.`id` = `Item`.`measureUnitId`' +
125
+ ' LEFT JOIN `MeasureUnitCategory` `measureUnit.category` ON `measureUnit.category`.`id` = `measureUnit`.`categoryId`' +
126
+ ' LIMIT 100');
127
+ expect(this.querier.all).toBeCalledTimes(1);
128
+ expect(this.querier.run).toBeCalledTimes(0);
129
+ jest.clearAllMocks();
130
+ await this.querier.findMany(test_1.Tag, {
131
+ $project: {
132
+ id: 1,
133
+ itemsCount: 1,
134
+ },
135
+ });
136
+ expect(this.querier.all).toBeCalledWith('SELECT `id`, (SELECT COUNT(*) `count` FROM `ItemTag` WHERE `ItemTag`.`tagId` = `id`) `itemsCount` FROM `Tag`');
137
+ expect(this.querier.all).toBeCalledTimes(1);
138
+ expect(this.querier.run).toBeCalledTimes(0);
139
+ }
140
+ async shouldFind$exists() {
141
+ await this.querier.findMany(test_1.Item, {
142
+ $project: {
143
+ id: 1,
144
+ },
145
+ $filter: {
146
+ $exists: (0, raw_1.raw)(({ escapedPrefix, dialect }) => dialect.find(test_1.User, {
147
+ $project: ['id'],
148
+ $filter: { companyId: (0, raw_1.raw)(escapedPrefix + dialect.escapeId(`companyId`)) },
149
+ }, { autoPrefix: true })),
150
+ },
151
+ });
152
+ expect(this.querier.all).toBeCalledWith('SELECT `id` FROM `Item` WHERE EXISTS (SELECT `User`.`id` FROM `User` WHERE `User`.`companyId` = `Item`.`companyId`)');
153
+ expect(this.querier.all).toBeCalledTimes(1);
154
+ expect(this.querier.run).toBeCalledTimes(0);
155
+ }
156
+ async shouldFind$nexists() {
157
+ await this.querier.findMany(test_1.Item, {
158
+ $project: {
159
+ id: 1,
160
+ },
161
+ $filter: {
162
+ $nexists: (0, raw_1.raw)(({ escapedPrefix, dialect }) => dialect.find(test_1.User, {
163
+ $project: ['id'],
164
+ $filter: { companyId: (0, raw_1.raw)(escapedPrefix + dialect.escapeId(`companyId`)) },
165
+ }, { autoPrefix: true })),
166
+ },
167
+ });
168
+ expect(this.querier.all).toBeCalledWith('SELECT `id` FROM `Item` WHERE NOT EXISTS (SELECT `User`.`id` FROM `User` WHERE `User`.`companyId` = `Item`.`companyId`)');
169
+ expect(this.querier.all).toBeCalledTimes(1);
170
+ expect(this.querier.run).toBeCalledTimes(0);
171
+ }
172
+ async shouldFindOneAndProjectOneToManyOnly() {
173
+ await this.querier.insertMany(test_1.InventoryAdjustment, [
174
+ {
175
+ id: 123,
176
+ createdAt: 1,
177
+ },
178
+ { id: 456, createdAt: 1 },
179
+ ]);
180
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `InventoryAdjustment` (`id`, `createdAt`) VALUES (123, 1), (456, 1)');
181
+ await this.querier.findMany(test_1.InventoryAdjustment, {
182
+ $project: { itemAdjustments: ['id', 'buyPrice', 'itemId', 'creatorId', 'createdAt'] },
183
+ $filter: { createdAt: 1 },
184
+ });
185
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `InventoryAdjustment`.`id` FROM `InventoryAdjustment` WHERE `InventoryAdjustment`.`createdAt` = 1');
186
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id`, `buyPrice`, `itemId`, `creatorId`, `createdAt`, `inventoryAdjustmentId`' +
187
+ ' FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` IN (123, 456)');
188
+ expect(this.querier.all).toBeCalledTimes(2);
189
+ expect(this.querier.run).toBeCalledTimes(1);
190
+ }
191
+ async shouldFindOneAndProjectOneToManyWithSpecifiedFields() {
192
+ await this.querier.insertMany(test_1.InventoryAdjustment, [
193
+ {
194
+ description: 'something a',
195
+ createdAt: 1,
196
+ itemAdjustments: [
197
+ { buyPrice: 1, createdAt: 1 },
198
+ { buyPrice: 1, createdAt: 1 },
199
+ ],
200
+ },
201
+ {
202
+ description: 'something b',
203
+ createdAt: 1,
204
+ itemAdjustments: [
205
+ { id: 1, buyPrice: 1, updatedAt: 1 },
206
+ { buyPrice: 1, createdAt: 1 },
207
+ ],
208
+ },
209
+ ]);
210
+ expect(this.querier.run).nthCalledWith(1, "INSERT INTO `InventoryAdjustment` (`description`, `createdAt`) VALUES ('something a', 1), ('something b', 1)");
211
+ expect(this.querier.run).nthCalledWith(2, 'INSERT INTO `ItemAdjustment` (`buyPrice`, `createdAt`, `inventoryAdjustmentId`) VALUES (1, 1, 1), (1, 1, 1)');
212
+ expect(this.querier.run).nthCalledWith(3, 'INSERT INTO `ItemAdjustment` (`buyPrice`, `createdAt`, `inventoryAdjustmentId`) VALUES (1, 1, 2)');
213
+ expect(this.querier.run).nthCalledWith(4, 'UPDATE `ItemAdjustment` SET `buyPrice` = 1, `updatedAt` = 1, `inventoryAdjustmentId` = 2 WHERE `id` = 1');
214
+ await this.querier.findMany(test_1.InventoryAdjustment, {
215
+ $project: { id: true, itemAdjustments: ['buyPrice'] },
216
+ $filter: { createdAt: 1 },
217
+ });
218
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `InventoryAdjustment`.`id` FROM `InventoryAdjustment` WHERE `InventoryAdjustment`.`createdAt` = 1');
219
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `buyPrice`, `inventoryAdjustmentId` FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` IN (1, 2)');
220
+ expect(this.querier.all).toBeCalledTimes(2);
221
+ expect(this.querier.run).toBeCalledTimes(4);
222
+ }
223
+ async shouldFindManyAndProjectOneToMany() {
224
+ await this.querier.insertMany(test_1.InventoryAdjustment, [
225
+ { id: 123, description: 'something a', createdAt: 1 },
226
+ { id: 456, description: 'something b', createdAt: 1 },
227
+ ]);
228
+ expect(this.querier.run).nthCalledWith(1, "INSERT INTO `InventoryAdjustment` (`id`, `description`, `createdAt`) VALUES (123, 'something a', 1), (456, 'something b', 1)");
229
+ await this.querier.findMany(test_1.InventoryAdjustment, {
230
+ $project: { id: true, itemAdjustments: true },
231
+ $filter: { createdAt: 1 },
232
+ });
233
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `InventoryAdjustment`.`id` FROM `InventoryAdjustment` WHERE `InventoryAdjustment`.`createdAt` = 1');
234
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id`, `companyId`, `creatorId`, `createdAt`, `updatedAt`, `itemId`, `number`, `buyPrice`, `storehouseId`' +
235
+ ', `inventoryAdjustmentId` FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` IN (123, 456)');
236
+ expect(this.querier.all).toBeCalledTimes(2);
237
+ expect(this.querier.run).toBeCalledTimes(1);
238
+ }
239
+ async shouldFindOneAndProjectManyToMany() {
240
+ await this.querier.insertOne(test_1.Item, { id: 123, createdAt: 1 });
241
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `Item` (`id`, `createdAt`) VALUES (123, 1)');
242
+ await this.querier.findOne(test_1.Item, {
243
+ $project: { id: true, createdAt: true, tags: ['id'] },
244
+ });
245
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `Item`.`id`, `Item`.`createdAt` FROM `Item` LIMIT 1');
246
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `ItemTag`.`id`, `ItemTag`.`itemId`, `tag`.`id` `tag.id`' +
247
+ ' FROM `ItemTag` INNER JOIN `Tag` `tag` ON `tag`.`id` = `ItemTag`.`tagId`' +
248
+ ' WHERE `ItemTag`.`itemId` IN (123)');
249
+ expect(this.querier.all).toBeCalledTimes(2);
250
+ expect(this.querier.run).toBeCalledTimes(1);
251
+ }
252
+ async shouldFindOneByIdAndProjectManyToMany() {
253
+ await this.querier.insertOne(test_1.Item, { id: 123, createdAt: 1 });
254
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `Item` (`id`, `createdAt`) VALUES (123, 1)');
255
+ await this.querier.findOneById(test_1.Item, 123, {
256
+ $project: { id: 1, createdAt: 1, tags: ['id'] },
257
+ });
258
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `Item`.`id`, `Item`.`createdAt` FROM `Item` WHERE `Item`.`id` = 123 LIMIT 1');
259
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `ItemTag`.`id`, `ItemTag`.`itemId`, `tag`.`id` `tag.id`' +
260
+ ' FROM `ItemTag` INNER JOIN `Tag` `tag` ON `tag`.`id` = `ItemTag`.`tagId`' +
261
+ ' WHERE `ItemTag`.`itemId` IN (123)');
262
+ expect(this.querier.all).toBeCalledTimes(2);
263
+ expect(this.querier.run).toBeCalledTimes(1);
264
+ }
265
+ async shouldFindMany() {
266
+ await this.querier.findMany(test_1.User, {
267
+ $project: { id: true, name: true },
268
+ $filter: { companyId: 123 },
269
+ $limit: 100,
270
+ });
271
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id`, `name` FROM `User` WHERE `companyId` = 123 LIMIT 100');
272
+ expect(this.querier.all).toBeCalledTimes(1);
273
+ expect(this.querier.run).toBeCalledTimes(0);
274
+ }
275
+ async shouldFindManyAndCount() {
276
+ await this.querier.findManyAndCount(test_1.User, {
277
+ $project: { id: true, name: true },
278
+ $filter: { companyId: 123 },
279
+ $sort: { createdAt: -1 },
280
+ $skip: 50,
281
+ $limit: 100,
282
+ });
283
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id`, `name` FROM `User` WHERE `companyId` = 123 ORDER BY `createdAt` DESC LIMIT 100 OFFSET 50');
284
+ expect(this.querier.all).nthCalledWith(2, 'SELECT COUNT(*) `count` FROM `User` WHERE `companyId` = 123');
285
+ expect(this.querier.all).toBeCalledTimes(2);
286
+ expect(this.querier.run).toBeCalledTimes(0);
287
+ }
288
+ async shouldInsertOne() {
289
+ await this.querier.insertOne(test_1.User, { companyId: 123, createdAt: 1 });
290
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `User` (`companyId`, `createdAt`) VALUES (123, 1)');
291
+ expect(this.querier.all).toBeCalledTimes(0);
292
+ expect(this.querier.run).toBeCalledTimes(1);
293
+ }
294
+ async shouldInsertOneAndCascadeOneToOne() {
295
+ await this.querier.insertOne(test_1.User, {
296
+ name: 'some name',
297
+ createdAt: 1,
298
+ profile: { picture: 'abc', createdAt: 1 },
299
+ });
300
+ expect(this.querier.run).nthCalledWith(1, "INSERT INTO `User` (`name`, `createdAt`) VALUES ('some name', 1)");
301
+ expect(this.querier.run).nthCalledWith(2, "INSERT INTO `user_profile` (`image`, `createdAt`, `creatorId`) VALUES ('abc', 1, 1)");
302
+ expect(this.querier.all).toBeCalledTimes(0);
303
+ expect(this.querier.run).toBeCalledTimes(2);
304
+ }
305
+ async shouldInsertOneAndCascadeManyToOne() {
306
+ await this.querier.insertOne(test_1.MeasureUnit, {
307
+ name: 'Centimeter',
308
+ createdAt: 123,
309
+ category: { name: 'Metric', createdAt: 123 },
310
+ });
311
+ expect(this.querier.run).nthCalledWith(1, "INSERT INTO `MeasureUnit` (`name`, `createdAt`) VALUES ('Centimeter', 123)");
312
+ expect(this.querier.run).nthCalledWith(2, "INSERT INTO `MeasureUnitCategory` (`name`, `createdAt`) VALUES ('Metric', 123)");
313
+ expect(this.querier.run).nthCalledWith(3, expect.toMatch(/^UPDATE `MeasureUnit` SET `categoryId` = 1, `updatedAt` = \d+ WHERE `id` = 1 AND `deletedAt` IS NULL$/));
314
+ expect(this.querier.all).toBeCalledTimes(0);
315
+ expect(this.querier.run).toBeCalledTimes(3);
316
+ }
317
+ async shouldInsertOneAndCascadeOneToMany() {
318
+ await this.querier.insertOne(test_1.InventoryAdjustment, {
319
+ description: 'some description',
320
+ createdAt: 1,
321
+ itemAdjustments: [
322
+ { buyPrice: 50, createdAt: 1 },
323
+ { buyPrice: 300, createdAt: 1 },
324
+ ],
325
+ });
326
+ expect(this.querier.run).nthCalledWith(1, "INSERT INTO `InventoryAdjustment` (`description`, `createdAt`) VALUES ('some description', 1)");
327
+ expect(this.querier.run).nthCalledWith(2, 'INSERT INTO `ItemAdjustment` (`buyPrice`, `createdAt`, `inventoryAdjustmentId`) VALUES (50, 1, 1), (300, 1, 1)');
328
+ expect(this.querier.all).toBeCalledTimes(0);
329
+ expect(this.querier.run).toBeCalledTimes(2);
330
+ }
331
+ async shouldUpdateMany() {
332
+ await this.querier.updateMany(test_1.User, { $filter: { companyId: 4 } }, { name: 'Hola', updatedAt: 1 });
333
+ expect(this.querier.run).nthCalledWith(1, "UPDATE `User` SET `name` = 'Hola', `updatedAt` = 1 WHERE `companyId` = 4");
334
+ expect(this.querier.all).toBeCalledTimes(0);
335
+ expect(this.querier.run).toBeCalledTimes(1);
336
+ }
337
+ async shouldUpdateOneById() {
338
+ await this.querier.updateOneById(test_1.User, 5, { companyId: 123, updatedAt: 1 });
339
+ expect(this.querier.run).nthCalledWith(1, 'UPDATE `User` SET `companyId` = 123, `updatedAt` = 1 WHERE `id` = 5');
340
+ expect(this.querier.all).toBeCalledTimes(0);
341
+ expect(this.querier.run).toBeCalledTimes(1);
342
+ }
343
+ async shouldUpdateOneByIdAndCascadeOneToOne() {
344
+ await this.querier.insertOne(test_1.User, { createdAt: 1 });
345
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `User` (`createdAt`) VALUES (1)');
346
+ await this.querier.updateOneById(test_1.User, 1, {
347
+ name: 'something',
348
+ updatedAt: 1,
349
+ profile: { picture: 'xyz', createdAt: 1 },
350
+ });
351
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `User` SET `name` = 'something', `updatedAt` = 1 WHERE `id` = 1");
352
+ expect(this.querier.run).nthCalledWith(3, "INSERT INTO `user_profile` (`image`, `createdAt`, `creatorId`) VALUES ('xyz', 1, 1)");
353
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `User` WHERE `id` = 1');
354
+ expect(this.querier.all).toBeCalledTimes(1);
355
+ expect(this.querier.run).toBeCalledTimes(3);
356
+ }
357
+ async shouldUpdateOneByIdAndCascadeOneToOneNull() {
358
+ await this.querier.insertOne(test_1.User, { createdAt: 1 });
359
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `User` (`createdAt`) VALUES (1)');
360
+ await this.querier.updateOneById(test_1.User, 1, {
361
+ name: 'something',
362
+ updatedAt: 1,
363
+ profile: null,
364
+ });
365
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `User` SET `name` = 'something', `updatedAt` = 1 WHERE `id` = 1");
366
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `User` WHERE `id` = 1');
367
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `pk` `id` FROM `user_profile` WHERE `creatorId` = 1');
368
+ expect(this.querier.all).toBeCalledTimes(2);
369
+ expect(this.querier.run).toBeCalledTimes(2);
370
+ }
371
+ async shouldUpdateOneByIdAndCascadeOneToMany() {
372
+ await this.querier.insertOne(test_1.InventoryAdjustment, { createdAt: 1 });
373
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `InventoryAdjustment` (`createdAt`) VALUES (1)');
374
+ await this.querier.updateOneById(test_1.InventoryAdjustment, 1, {
375
+ description: 'some description',
376
+ updatedAt: 1,
377
+ itemAdjustments: [
378
+ { buyPrice: 50, createdAt: 1 },
379
+ { buyPrice: 300, createdAt: 1 },
380
+ ],
381
+ });
382
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `InventoryAdjustment` SET `description` = 'some description', `updatedAt` = 1 WHERE `id` = 1");
383
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `InventoryAdjustment` WHERE `id` = 1');
384
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id` FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` = 1');
385
+ expect(this.querier.run).nthCalledWith(3, 'INSERT INTO `ItemAdjustment` (`buyPrice`, `createdAt`, `inventoryAdjustmentId`) VALUES (50, 1, 1), (300, 1, 1)');
386
+ expect(this.querier.all).toBeCalledTimes(2);
387
+ expect(this.querier.run).toBeCalledTimes(3);
388
+ }
389
+ async shouldUpdateOneByIdAndCascadeOneToManyNull() {
390
+ await this.querier.insertOne(test_1.InventoryAdjustment, { createdAt: 1 });
391
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `InventoryAdjustment` (`createdAt`) VALUES (1)');
392
+ await this.querier.updateOneById(test_1.InventoryAdjustment, 1, {
393
+ description: 'some description',
394
+ updatedAt: 1,
395
+ itemAdjustments: null,
396
+ });
397
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `InventoryAdjustment` SET `description` = 'some description', `updatedAt` = 1 WHERE `id` = 1");
398
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `InventoryAdjustment` WHERE `id` = 1');
399
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id` FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` = 1');
400
+ expect(this.querier.all).toBeCalledTimes(2);
401
+ expect(this.querier.run).toBeCalledTimes(2);
402
+ }
403
+ async shouldUpdateManyAndCascadeOneToManyNull() {
404
+ await this.querier.insertOne(test_1.InventoryAdjustment, { companyId: 1, createdAt: 1 });
405
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `InventoryAdjustment` (`companyId`, `createdAt`) VALUES (1, 1)');
406
+ await this.querier.updateMany(test_1.InventoryAdjustment, { $filter: { companyId: 1 } }, {
407
+ description: 'some description',
408
+ updatedAt: 1,
409
+ itemAdjustments: null,
410
+ });
411
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `InventoryAdjustment` SET `description` = 'some description', `updatedAt` = 1 WHERE `companyId` = 1");
412
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `InventoryAdjustment` WHERE `companyId` = 1');
413
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id` FROM `ItemAdjustment` WHERE `inventoryAdjustmentId` = 1');
414
+ expect(this.querier.all).toBeCalledTimes(2);
415
+ expect(this.querier.run).toBeCalledTimes(2);
416
+ }
417
+ async shouldInsertOneAndCascadeManyToManyInserts() {
418
+ await this.querier.insertOne(test_1.Item, {
419
+ name: 'item one',
420
+ createdAt: 1,
421
+ tags: [
422
+ {
423
+ name: 'tag one',
424
+ createdAt: 1,
425
+ },
426
+ {
427
+ name: 'tag two',
428
+ createdAt: 1,
429
+ },
430
+ ],
431
+ });
432
+ expect(this.querier.run).nthCalledWith(1, "INSERT INTO `Item` (`name`, `createdAt`) VALUES ('item one', 1)");
433
+ expect(this.querier.run).nthCalledWith(2, "INSERT INTO `Tag` (`name`, `createdAt`) VALUES ('tag one', 1), ('tag two', 1)");
434
+ expect(this.querier.run).nthCalledWith(3, 'INSERT INTO `ItemTag` (`itemId`, `tagId`) VALUES (1, 1), (1, 2)');
435
+ expect(this.querier.all).toBeCalledTimes(0);
436
+ expect(this.querier.run).toBeCalledTimes(3);
437
+ }
438
+ async shouldUpdateAndCascadeManyToManyInserts() {
439
+ const id = await this.querier.insertOne(test_1.Item, { createdAt: 1 });
440
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `Item` (`createdAt`) VALUES (1)');
441
+ await this.querier.updateOneById(test_1.Item, id, {
442
+ name: 'item one',
443
+ updatedAt: 1,
444
+ tags: [
445
+ {
446
+ name: 'tag one',
447
+ createdAt: 1,
448
+ },
449
+ {
450
+ name: 'tag two',
451
+ createdAt: 1,
452
+ },
453
+ ],
454
+ });
455
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `Item` SET `name` = 'item one', `updatedAt` = 1 WHERE `id` = 1");
456
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `Item` WHERE `id` = 1');
457
+ expect(this.querier.run).nthCalledWith(3, "INSERT INTO `Tag` (`name`, `createdAt`) VALUES ('tag one', 1), ('tag two', 1)");
458
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id` FROM `ItemTag` WHERE `itemId` = 1');
459
+ expect(this.querier.run).nthCalledWith(4, 'INSERT INTO `ItemTag` (`itemId`, `tagId`) VALUES (1, 1), (1, 2)');
460
+ expect(this.querier.all).toBeCalledTimes(2);
461
+ expect(this.querier.run).toBeCalledTimes(4);
462
+ }
463
+ async shouldUpdateAndCascadeManyToManyLinks() {
464
+ const id = await this.querier.insertOne(test_1.Item, { createdAt: 1 });
465
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `Item` (`createdAt`) VALUES (1)');
466
+ await this.querier.updateOneById(test_1.Item, id, {
467
+ name: 'item one',
468
+ tags: [{ id: 22 }, { id: 33 }],
469
+ updatedAt: 1,
470
+ });
471
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `Item` SET `name` = 'item one', `updatedAt` = 1 WHERE `id` = 1");
472
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `Item` WHERE `id` = 1');
473
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id` FROM `ItemTag` WHERE `itemId` = 1');
474
+ expect(this.querier.run).nthCalledWith(3, 'INSERT INTO `ItemTag` (`itemId`, `tagId`) VALUES (1, 22), (1, 33)');
475
+ expect(this.querier.all).toBeCalledTimes(2);
476
+ expect(this.querier.run).toBeCalledTimes(3);
477
+ }
478
+ async shouldDeleteOneAndCascadeManyToManyDeletes() {
479
+ await this.shouldInsertOneAndCascadeManyToManyInserts();
480
+ jest.clearAllMocks();
481
+ await this.querier.deleteOneById(test_1.Item, 1);
482
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `Item` WHERE `id` = 1');
483
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `id` FROM `ItemTag` WHERE `itemId` IN (1)');
484
+ expect(this.querier.run).nthCalledWith(1, 'DELETE FROM `Item` WHERE `id` IN (1)');
485
+ expect(this.querier.run).nthCalledWith(2, 'DELETE FROM `ItemTag` WHERE `id` IN (1, 2)');
486
+ expect(this.querier.all).toBeCalledTimes(2);
487
+ expect(this.querier.run).toBeCalledTimes(2);
488
+ }
489
+ async shouldDeleteOneAndNoCascadeManyToManyDeletes() {
490
+ await this.shouldInsertOneAndCascadeManyToManyInserts();
491
+ jest.clearAllMocks();
492
+ await this.querier.deleteOneById(test_1.Tag, 1);
493
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `Tag` WHERE `id` = 1');
494
+ expect(this.querier.run).nthCalledWith(1, 'DELETE FROM `Tag` WHERE `id` IN (1)');
495
+ expect(this.querier.all).toBeCalledTimes(1);
496
+ expect(this.querier.run).toBeCalledTimes(1);
497
+ }
498
+ async shouldDeleteOneById() {
499
+ const id = await this.querier.insertOne(test_1.User, { createdAt: 1, profile: { createdAt: 1 } });
500
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `User` (`createdAt`) VALUES (1)');
501
+ expect(this.querier.run).nthCalledWith(2, 'INSERT INTO `user_profile` (`createdAt`, `creatorId`) VALUES (1, 1)');
502
+ await this.querier.deleteOneById(test_1.User, id);
503
+ expect(this.querier.run).nthCalledWith(3, 'DELETE FROM `User` WHERE `id` IN (1)');
504
+ expect(this.querier.run).nthCalledWith(4, 'DELETE FROM `user_profile` WHERE `pk` IN (1)');
505
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `User` WHERE `id` = 1');
506
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `pk` `id` FROM `user_profile`');
507
+ expect(this.querier.all).toBeCalledTimes(2);
508
+ expect(this.querier.run).toBeCalledTimes(4);
509
+ }
510
+ async shouldDeleteMany() {
511
+ await this.querier.insertOne(test_1.User, { createdAt: 123 });
512
+ expect(this.querier.run).nthCalledWith(1, 'INSERT INTO `User` (`createdAt`) VALUES (123)');
513
+ await this.querier.deleteMany(test_1.User, { $filter: { createdAt: 123 } });
514
+ expect(this.querier.all).nthCalledWith(1, 'SELECT `id` FROM `User` WHERE `createdAt` = 123');
515
+ expect(this.querier.all).nthCalledWith(2, 'SELECT `pk` `id` FROM `user_profile`');
516
+ expect(this.querier.run).nthCalledWith(2, 'DELETE FROM `User` WHERE `id` IN (1)');
517
+ expect(this.querier.all).toBeCalledTimes(2);
518
+ expect(this.querier.run).toBeCalledTimes(2);
519
+ }
520
+ async shouldCount() {
521
+ await this.querier.count(test_1.User, { $filter: { companyId: 123 } });
522
+ expect(this.querier.all).nthCalledWith(1, 'SELECT COUNT(*) `count` FROM `User` WHERE `companyId` = 123');
523
+ expect(this.querier.all).toBeCalledTimes(1);
524
+ expect(this.querier.run).toBeCalledTimes(0);
525
+ }
526
+ async shouldUseTransaction() {
527
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
528
+ await this.querier.beginTransaction();
529
+ expect(this.querier.run).toBeCalledWith(this.querier.dialect.beginTransactionCommand);
530
+ expect(this.querier.hasOpenTransaction).toBe(true);
531
+ await this.querier.updateOneById(test_1.User, 5, { name: 'Hola', updatedAt: 1 });
532
+ expect(this.querier.hasOpenTransaction).toBe(true);
533
+ await this.querier.commitTransaction();
534
+ expect(this.querier.run).nthCalledWith(1, this.querier.dialect.beginTransactionCommand);
535
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `User` SET `name` = 'Hola', `updatedAt` = 1 WHERE `id` = 5");
536
+ expect(this.querier.run).nthCalledWith(3, 'COMMIT');
537
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
538
+ await this.querier.release();
539
+ expect(this.querier.run).toBeCalledTimes(3);
540
+ expect(this.querier.all).toBeCalledTimes(0);
541
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
542
+ }
543
+ async shouldUseTransactionCallback() {
544
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
545
+ await this.querier.transaction(async () => {
546
+ expect(this.querier.run).toBeCalledWith(this.querier.dialect.beginTransactionCommand);
547
+ expect(this.querier.hasOpenTransaction).toBe(true);
548
+ await this.querier.updateOneById(test_1.User, 5, { name: 'Hola', updatedAt: 1 });
549
+ });
550
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
551
+ expect(this.querier.run).nthCalledWith(1, this.querier.dialect.beginTransactionCommand);
552
+ expect(this.querier.run).nthCalledWith(2, "UPDATE `User` SET `name` = 'Hola', `updatedAt` = 1 WHERE `id` = 5");
553
+ expect(this.querier.run).nthCalledWith(3, 'COMMIT');
554
+ expect(this.querier.run).toBeCalledTimes(3);
555
+ expect(this.querier.all).toBeCalledTimes(0);
556
+ }
557
+ async shouldThrowIfRollbackIfErrorInCallback() {
558
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
559
+ const prom = this.querier.transaction(async () => {
560
+ expect(this.querier.run).toBeCalledWith(this.querier.dialect.beginTransactionCommand);
561
+ expect(this.querier.hasOpenTransaction).toBe(true);
562
+ throw new Error('some error');
563
+ });
564
+ await expect(prom).rejects.toThrow('some error');
565
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
566
+ expect(this.querier.run).nthCalledWith(1, this.querier.dialect.beginTransactionCommand);
567
+ expect(this.querier.run).nthCalledWith(2, 'ROLLBACK');
568
+ expect(this.querier.run).toBeCalledTimes(2);
569
+ expect(this.querier.all).toBeCalledTimes(0);
570
+ }
571
+ async shouldThrowIfTransactionIsPending() {
572
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
573
+ await this.querier.beginTransaction();
574
+ expect(this.querier.hasOpenTransaction).toBe(true);
575
+ await expect(this.querier.beginTransaction()).rejects.toThrow('pending transaction');
576
+ expect(this.querier.hasOpenTransaction).toBe(true);
577
+ expect(this.querier.run).toBeCalledTimes(1);
578
+ expect(this.querier.all).toBeCalledTimes(0);
579
+ await this.querier.rollbackTransaction();
580
+ }
581
+ async shouldThrowIfCommitWithNoPendingTransaction() {
582
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
583
+ await expect(this.querier.commitTransaction()).rejects.toThrow('pending transaction');
584
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
585
+ expect(this.querier.run).toBeCalledTimes(0);
586
+ expect(this.querier.all).toBeCalledTimes(0);
587
+ }
588
+ async shouldThrowIfRollbackWithNoPendingTransaction() {
589
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
590
+ await expect(this.querier.rollbackTransaction()).rejects.toThrow('not a pending transaction');
591
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
592
+ expect(this.querier.run).toBeCalledTimes(0);
593
+ expect(this.querier.all).toBeCalledTimes(0);
594
+ }
595
+ async shouldThrowIfReleaseWithPendingTransaction() {
596
+ expect(this.querier.hasOpenTransaction).toBeFalsy();
597
+ await this.querier.beginTransaction();
598
+ expect(this.querier.hasOpenTransaction).toBe(true);
599
+ await this.querier.updateOneById(test_1.User, 5, { name: 'some name' });
600
+ expect(this.querier.hasOpenTransaction).toBe(true);
601
+ await expect(this.querier.release()).rejects.toThrow('pending transaction');
602
+ expect(this.querier.hasOpenTransaction).toBe(true);
603
+ expect(this.querier.run).toBeCalledTimes(2);
604
+ expect(this.querier.all).toBeCalledTimes(0);
605
+ await this.querier.rollbackTransaction();
606
+ }
607
+ }
608
+ exports.AbstractSqlQuerierSpec = AbstractSqlQuerierSpec;
609
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWJzdHJhY3RTcWxRdWVyaWVyLXNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcXVlcmllci9hYnN0cmFjdFNxbFF1ZXJpZXItc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw0Q0FBeUM7QUFDekMseUNBQWdJO0FBSWhJLE1BQXNCLHNCQUFzQjtJQUcxQyxZQUFxQixJQUFxQyxFQUFXLE1BQWM7UUFBOUQsU0FBSSxHQUFKLElBQUksQ0FBaUM7UUFBVyxXQUFNLEdBQU4sTUFBTSxDQUFRO0lBQUcsQ0FBQztJQUV2RixLQUFLLENBQUMsU0FBUztRQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzVDLE1BQU0sSUFBQSxpQkFBVSxFQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQixNQUFNLElBQUEsbUJBQVksRUFBQyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUssQ0FBQyxVQUFVO1FBQ2QsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDNUMsTUFBTSxJQUFBLGtCQUFXLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELEtBQUssQ0FBQyxTQUFTO1FBQ2IsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FB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QUMsYUFBYSxDQUFDLFdBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNqRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRCxNQUFNLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzVFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25ELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM1QyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUMsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFDM0MsQ0FBQztDQUNGO0FBdnpCRCx3REF1ekJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmF3IH0gZnJvbSAnQHVxbC9jb3JlL3V0aWwvcmF3JztcbmltcG9ydCB7IFVzZXIsIEludmVudG9yeUFkanVzdG1lbnQsIFNwZWMsIEl0ZW0sIFRhZywgTWVhc3VyZVVuaXQsIGRyb3BUYWJsZXMsIGNyZWF0ZVRhYmxlcywgY2xlYXJUYWJsZXMgfSBmcm9tICdAdXFsL2NvcmUvdGVzdCc7XG5pbXBvcnQgeyBRdWVyaWVyUG9vbCB9IGZyb20gJ0B1cWwvY29yZS90eXBlJztcbmltcG9ydCB7IEFic3RyYWN0U3FsUXVlcmllciB9IGZyb20gJy4vYWJzdHJhY3RTcWxRdWVyaWVyJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEFic3RyYWN0U3FsUXVlcmllclNwZWMgaW1wbGVtZW50cyBTcGVjIHtcbiAgcXVlcmllcjogQWJzdHJhY3RTcWxRdWVyaWVyO1xuXG4gIGNvbnN0cnVjdG9yKHJlYWRvbmx5IHBvb2w6IFF1ZXJpZXJQb29sPEFic3RyYWN0U3FsUXVlcmllcj4sIHJlYWRvbmx5IGlkVHlwZTogc3RyaW5nKSB7fVxuXG4gIGFzeW5jIGJlZm9yZUFsbCgpIHtcbiAgICB0aGlzLnF1ZXJpZXIgPSBhd2FpdCB0aGlzLnBvb2wuZ2V0UXVlcmllcigpO1xuICAgIGF3YWl0IGRyb3BUYWJsZXModGhpcy5xdWVyaWVyKTtcbiAgICBhd2FpdCBjcmVhdGVUYWJsZXModGhpcy5xdWVyaWVyLCB0aGlzLmlkVHlwZSk7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLnJlbGVhc2UoKTtcbiAgfVxuXG4gIGFzeW5jIGJlZm9yZUVhY2goKSB7XG4gICAgdGhpcy5xdWVyaWVyID0gYXdhaXQgdGhpcy5wb29sLmdldFF1ZXJpZXIoKTtcbiAgICBhd2FpdCBjbGVhclRhYmxlcyh0aGlzLnF1ZXJpZXIpO1xuICAgIGplc3Quc3B5T24odGhpcy5xdWVyaWVyLCAnYWxsJyk7XG4gICAgamVzdC5zcHlPbih0aGlzLnF1ZXJpZXIsICdydW4nKTtcbiAgfVxuXG4gIGFzeW5jIGFmdGVyRWFjaCgpIHtcbiAgICBqZXN0LnJlc3RvcmVBbGxNb2NrcygpO1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5yZWxlYXNlKCk7XG4gIH1cblxuICBhc3luYyBhZnRlckFsbCgpIHtcbiAgICBhd2FpdCB0aGlzLnBvb2wuZW5kKCk7XG4gIH1cblxuICBhc3luYyBzaG91bGRGaW5kT25lQnlJZCgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuZmluZE9uZUJ5SWQoVXNlciwgMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoXG4gICAgICAxLFxuICAgICAgJ1NFTEVDVCBgaWRgLCBgY29tcGFueUlkYCwgYGNyZWF0b3JJZGAsIGBjcmVhdGVkQXRgLCBgdXBkYXRlZEF0YCwgYG5hbWVgLCBgZW1haWxgLCBgcGFzc3dvcmRgIEZST00gYFVzZXJgIFdIRVJFIGBpZGAgPSAxIExJTUlUIDEnXG4gICAgKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDEpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gIH1cblxuICBhc3luYyBzaG91bGRGaW5kT25lKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5maW5kT25lKFVzZXIsIHsgJHByb2plY3Q6IFsnaWQnLCAnbmFtZSddLCAkZmlsdGVyOiB7IGNvbXBhbnlJZDogMTIzIH0gfSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMSwgJ1NFTEVDVCBgaWRgLCBgbmFtZWAgRlJPTSBgVXNlcmAgV0hFUkUgYGNvbXBhbnlJZGAgPSAxMjMgTElNSVQgMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEZpbmRPbmVBbmRQcm9qZWN0T25lVG9NYW55KCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5pbnNlcnRNYW55KEludmVudG9yeUFkanVzdG1lbnQsIFtcbiAgICAgIHtcbiAgICAgICAgaWQ6IDEyMyxcbiAgICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgfSxcbiAgICAgIHsgaWQ6IDQ1NiwgY3JlYXRlZEF0OiAxIH0sXG4gICAgXSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnSU5TRVJUIElOVE8gYEludmVudG9yeUFkanVzdG1lbnRgIChgaWRgLCBgY3JlYXRlZEF0YCkgVkFMVUVTICgxMjMsIDEpLCAoNDU2LCAxKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRNYW55KEludmVudG9yeUFkanVzdG1lbnQsIHtcbiAgICAgICRwcm9qZWN0OiBbJ2lkJywgJ2l0ZW1BZGp1c3RtZW50cyddLFxuICAgICAgJGZpbHRlcjogeyBjcmVhdGVkQXQ6IDEgfSxcbiAgICB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKFxuICAgICAgMSxcbiAgICAgICdTRUxFQ1QgYEludmVudG9yeUFkanVzdG1lbnRgLmBpZGAgRlJPTSBgSW52ZW50b3J5QWRqdXN0bWVudGAgV0hFUkUgYEludmVudG9yeUFkanVzdG1lbnRgLmBjcmVhdGVkQXRgID0gMSdcbiAgICApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKFxuICAgICAgMixcbiAgICAgICdTRUxFQ1QgYGlkYCwgYGNvbXBhbnlJZGAsIGBjcmVhdG9ySWRgLCBgY3JlYXRlZEF0YCwgYHVwZGF0ZWRBdGAsIGBpdGVtSWRgLCBgbnVtYmVyYCwgYGJ1eVByaWNlYCwgYHN0b3JlaG91c2VJZGAnICtcbiAgICAgICAgJywgYGludmVudG9yeUFkanVzdG1lbnRJZGAgRlJPTSBgSXRlbUFkanVzdG1lbnRgIFdIRVJFIGBpbnZlbnRvcnlBZGp1c3RtZW50SWRgIElOICgxMjMsIDQ1NiknXG4gICAgKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEZpbmRBbmRQcm9qZWN0UmF3KCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5maW5kTWFueShJbnZlbnRvcnlBZGp1c3RtZW50LCB7XG4gICAgICAkcHJvamVjdDoge1xuICAgICAgICBjcmVhdG9yOiBbJ2lkJywgJ25hbWUnXSxcbiAgICAgICAgaXRlbUFkanVzdG1lbnRzOiB7XG4gICAgICAgICAgJHByb2plY3Q6IHtcbiAgICAgICAgICAgIGl0ZW06IHtcbiAgICAgICAgICAgICAgJHByb2plY3Q6IHtcbiAgICAgICAgICAgICAgICBjb21wYW55SWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgdG90YWw6IHJhdygoeyBlc2NhcGVkUHJlZml4LCBkaWFsZWN0IH0pID0+IGBTVU0oJHtlc2NhcGVkUHJlZml4fSR7ZGlhbGVjdC5lc2NhcGVJZCgnc2FsZVByaWNlJyl9KWApLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgICRzb3J0OiB7IGNyZWF0ZWRBdDogLTEgfSxcbiAgICAgICAgICAkbGltaXQ6IDEwMCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICAkZmlsdGVyOiB7XG4gICAgICAgIGNvbXBhbnlJZDogMSxcbiAgICAgIH0sXG4gICAgICAkc29ydDogeyBjcmVhdG9yOiB7IG5hbWU6ICdhc2MnIH0gfSxcbiAgICB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKFxuICAgICAgMSxcbiAgICAgICdTRUxFQ1QgYEludmVudG9yeUFkanVzdG1lbnRgLmBpZGAsIGBjcmVhdG9yYC5gaWRgIGBjcmVhdG9yLmlkYCwgYGNyZWF0b3JgLmBuYW1lYCBgY3JlYXRvci5uYW1lYCcgK1xuICAgICAgICAnIEZST00gYEludmVudG9yeUFkanVzdG1lbnRgIExFRlQgSk9JTiBgVXNlcmAgYGNyZWF0b3JgIE9OIGBjcmVhdG9yYC5gaWRgID0gYEludmVudG9yeUFkanVzdG1lbnRgLmBjcmVhdG9ySWRgJyArXG4gICAgICAgICcgV0hFUkUgYEludmVudG9yeUFkanVzdG1lbnRgLmBjb21wYW55SWRgID0gMSBPUkRFUiBCWSBgY3JlYXRvcmAuYG5hbWVgJ1xuICAgICk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoXG4gICAgICAyLFxuICAgICAgJ1NFTEVDVCBgSXRlbUFkanVzdG1lbnRgLmBpZGAsIGBJdGVtQWRqdXN0bWVudGAuYGludmVudG9yeUFkanVzdG1lbnRJZGAnICtcbiAgICAgICAgJywgYGl0ZW1gLmBpZGAgYGl0ZW0uaWRgLCBgaXRlbWAuYGNvbXBhbnlJZGAgYGl0ZW0uY29tcGFueUlkYCwgU1VNKGBpdGVtYC5gc2FsZVByaWNlYCkgYGl0ZW0udG90YWxgJyArXG4gICAgICAgICcgRlJPTSBgSXRlbUFkanVzdG1lbnRgIExFRlQgSk9JTiBgSXRlbWAgYGl0ZW1gIE9OIGBpdGVtYC5gaWRgID0gYEl0ZW1BZGp1c3RtZW50YC5gaXRlbUlkYCcgK1xuICAgICAgICAnIFdIRVJFIGBJdGVtQWRqdXN0bWVudGAuYGludmVudG9yeUFkanVzdG1lbnRJZGAgSU4gKCknICtcbiAgICAgICAgJyBPUkRFUiBCWSBgSXRlbUFkanVzdG1lbnRgLmBjcmVhdGVkQXRgJyArXG4gICAgICAgICcgREVTQyBMSU1JVCAxMDAnXG4gICAgKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFZpcnR1YWxGaWVsZCgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuZmluZE1hbnkoSXRlbSwge1xuICAgICAgJHByb2plY3Q6IHtcbiAgICAgICAgaWQ6IDEsXG4gICAgICB9LFxuICAgICAgJGZpbHRlcjoge1xuICAgICAgICB0YWdzQ291bnQ6IHsgJGd0ZTogMTAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFdpdGgoXG4gICAgICAnU0VMRUNUIGBpZGAgRlJPTSBgSXRlbWAgV0hFUkUgKFNFTEVDVCBDT1VOVCgqKSBgY291bnRgIEZST00gYEl0ZW1UYWdgIFdIRVJFIGBJdGVtVGFnYC5gaXRlbUlkYCA9IGBpZGApID49IDEwJ1xuICAgICk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDEpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgamVzdC5jbGVhckFsbE1vY2tzKCk7XG5cbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuZmluZE1hbnkoSXRlbSwge1xuICAgICAgJHByb2plY3Q6IHtcbiAgICAgICAgaWQ6IDEsXG4gICAgICAgIG5hbWU6IDEsXG4gICAgICAgIGNvZGU6IDEsXG4gICAgICAgIHRhZ3NDb3VudDogMSxcbiAgICAgICAgbWVhc3VyZVVuaXQ6IHtcbiAgICAgICAgICAkcHJvamVjdDogeyBpZDogMSwgbmFtZTogMSwgY2F0ZWdvcnlJZDogMSwgY2F0ZWdvcnk6IFsnbmFtZSddIH0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgJGxpbWl0OiAxMDAsXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFdpdGgoXG4gICAgICAnU0VMRUNUIGBJdGVtYC5gaWRgLCBgSXRlbWAuYG5hbWVgLCBgSXRlbWAuYGNvZGVgJyArXG4gICAgICAgICcsIChTRUxFQ1QgQ09VTlQoKikgYGNvdW50YCBGUk9NIGBJdGVtVGFnYCBXSEVSRSBgSXRlbVRhZ2AuYGl0ZW1JZGAgPSBgSXRlbWAuYGlkYCkgYHRhZ3NDb3VudGAnICtcbiAgICAgICAgJywgYG1lYXN1cmVVbml0YC5gaWRgIGBtZWFzdXJlVW5pdC5pZGAsIGBtZWFzdXJlVW5pdGAuYG5hbWVgIGBtZWFzdXJlVW5pdC5uYW1lYCwgYG1lYXN1cmVVbml0YC5gY2F0ZWdvcnlJZGAgYG1lYXN1cmVVbml0LmNhdGVnb3J5SWRgJyArXG4gICAgICAgICcsIGBtZWFzdXJlVW5pdC5jYXRlZ29yeWAuYGlkYCBgbWVhc3VyZVVuaXQuY2F0ZWdvcnkuaWRgLCBgbWVhc3VyZVVuaXQuY2F0ZWdvcnlgLmBuYW1lYCBgbWVhc3VyZVVuaXQuY2F0ZWdvcnkubmFtZWAnICtcbiAgICAgICAgJyBGUk9NIGBJdGVtYCBMRUZUIEpPSU4gYE1lYXN1cmVVbml0YCBgbWVhc3VyZVVuaXRgIE9OIGBtZWFzdXJlVW5pdGAuYGlkYCA9IGBJdGVtYC5gbWVhc3VyZVVuaXRJZGAnICtcbiAgICAgICAgJyBMRUZUIEpPSU4gYE1lYXN1cmVVbml0Q2F0ZWdvcnlgIGBtZWFzdXJlVW5pdC5jYXRlZ29yeWAgT04gYG1lYXN1cmVVbml0LmNhdGVnb3J5YC5gaWRgID0gYG1lYXN1cmVVbml0YC5gY2F0ZWdvcnlJZGAnICtcbiAgICAgICAgJyBMSU1JVCAxMDAnXG4gICAgKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygwKTtcblxuICAgIGplc3QuY2xlYXJBbGxNb2NrcygpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRNYW55KFRhZywge1xuICAgICAgJHByb2plY3Q6IHtcbiAgICAgICAgaWQ6IDEsXG4gICAgICAgIGl0ZW1zQ291bnQ6IDEsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRXaXRoKFxuICAgICAgJ1NFTEVDVCBgaWRgLCAoU0VMRUNUIENPVU5UKCopIGBjb3VudGAgRlJPTSBgSXRlbVRhZ2AgV0hFUkUgYEl0ZW1UYWdgLmB0YWdJZGAgPSBgaWRgKSBgaXRlbXNDb3VudGAgRlJPTSBgVGFnYCdcbiAgICApO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDApO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkRmluZCRleGlzdHMoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRNYW55KEl0ZW0sIHtcbiAgICAgICRwcm9qZWN0OiB7XG4gICAgICAgIGlkOiAxLFxuICAgICAgfSxcbiAgICAgICRmaWx0ZXI6IHtcbiAgICAgICAgJGV4aXN0czogcmF3KCh7IGVzY2FwZWRQcmVmaXgsIGRpYWxlY3QgfSkgPT5cbiAgICAgICAgICBkaWFsZWN0LmZpbmQoXG4gICAgICAgICAgICBVc2VyLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAkcHJvamVjdDogWydpZCddLFxuICAgICAgICAgICAgICAkZmlsdGVyOiB7IGNvbXBhbnlJZDogcmF3KGVzY2FwZWRQcmVmaXggKyBkaWFsZWN0LmVzY2FwZUlkKGBjb21wYW55SWRgKSkgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IGF1dG9QcmVmaXg6IHRydWUgfVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFdpdGgoXG4gICAgICAnU0VMRUNUIGBpZGAgRlJPTSBgSXRlbWAgV0hFUkUgRVhJU1RTIChTRUxFQ1QgYFVzZXJgLmBpZGAgRlJPTSBgVXNlcmAgV0hFUkUgYFVzZXJgLmBjb21wYW55SWRgID0gYEl0ZW1gLmBjb21wYW55SWRgKSdcbiAgICApO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDApO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkRmluZCRuZXhpc3RzKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5maW5kTWFueShJdGVtLCB7XG4gICAgICAkcHJvamVjdDoge1xuICAgICAgICBpZDogMSxcbiAgICAgIH0sXG4gICAgICAkZmlsdGVyOiB7XG4gICAgICAgICRuZXhpc3RzOiByYXcoKHsgZXNjYXBlZFByZWZpeCwgZGlhbGVjdCB9KSA9PlxuICAgICAgICAgIGRpYWxlY3QuZmluZChcbiAgICAgICAgICAgIFVzZXIsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICRwcm9qZWN0OiBbJ2lkJ10sXG4gICAgICAgICAgICAgICRmaWx0ZXI6IHsgY29tcGFueUlkOiByYXcoZXNjYXBlZFByZWZpeCArIGRpYWxlY3QuZXNjYXBlSWQoYGNvbXBhbnlJZGApKSB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgYXV0b1ByZWZpeDogdHJ1ZSB9XG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkV2l0aChcbiAgICAgICdTRUxFQ1QgYGlkYCBGUk9NIGBJdGVtYCBXSEVSRSBOT1QgRVhJU1RTIChTRUxFQ1QgYFVzZXJgLmBpZGAgRlJPTSBgVXNlcmAgV0hFUkUgYFVzZXJgLmBjb21wYW55SWRgID0gYEl0ZW1gLmBjb21wYW55SWRgKSdcbiAgICApO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDApO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkRmluZE9uZUFuZFByb2plY3RPbmVUb01hbnlPbmx5KCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5pbnNlcnRNYW55KEludmVudG9yeUFkanVzdG1lbnQsIFtcbiAgICAgIHtcbiAgICAgICAgaWQ6IDEyMyxcbiAgICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgfSxcbiAgICAgIHsgaWQ6IDQ1NiwgY3JlYXRlZEF0OiAxIH0sXG4gICAgXSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnSU5TRVJUIElOVE8gYEludmVudG9yeUFkanVzdG1lbnRgIChgaWRgLCBgY3JlYXRlZEF0YCkgVkFMVUVTICgxMjMsIDEpLCAoNDU2LCAxKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRNYW55KEludmVudG9yeUFkanVzdG1lbnQsIHtcbiAgICAgICRwcm9qZWN0OiB7IGl0ZW1BZGp1c3RtZW50czogWydpZCcsICdidXlQcmljZScsICdpdGVtSWQnLCAnY3JlYXRvcklkJywgJ2NyZWF0ZWRBdCddIH0sXG4gICAgICAkZmlsdGVyOiB7IGNyZWF0ZWRBdDogMSB9LFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoXG4gICAgICAxLFxuICAgICAgJ1NFTEVDVCBgSW52ZW50b3J5QWRqdXN0bWVudGAuYGlkYCBGUk9NIGBJbnZlbnRvcnlBZGp1c3RtZW50YCBXSEVSRSBgSW52ZW50b3J5QWRqdXN0bWVudGAuYGNyZWF0ZWRBdGAgPSAxJ1xuICAgICk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoXG4gICAgICAyLFxuICAgICAgJ1NFTEVDVCBgaWRgLCBgYnV5UHJpY2VgLCBgaXRlbUlkYCwgYGNyZWF0b3JJZGAsIGBjcmVhdGVkQXRgLCBgaW52ZW50b3J5QWRqdXN0bWVudElkYCcgK1xuICAgICAgICAnIEZST00gYEl0ZW1BZGp1c3RtZW50YCBXSEVSRSBgaW52ZW50b3J5QWRqdXN0bWVudElkYCBJTiAoMTIzLCA0NTYpJ1xuICAgICk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gIH1cblxuICBhc3luYyBzaG91bGRGaW5kT25lQW5kUHJvamVjdE9uZVRvTWFueVdpdGhTcGVjaWZpZWRGaWVsZHMoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmluc2VydE1hbnkoSW52ZW50b3J5QWRqdXN0bWVudCwgW1xuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ3NvbWV0aGluZyBhJyxcbiAgICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgICBpdGVtQWRqdXN0bWVudHM6IFtcbiAgICAgICAgICB7IGJ1eVByaWNlOiAxLCBjcmVhdGVkQXQ6IDEgfSxcbiAgICAgICAgICB7IGJ1eVByaWNlOiAxLCBjcmVhdGVkQXQ6IDEgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnc29tZXRoaW5nIGInLFxuICAgICAgICBjcmVhdGVkQXQ6IDEsXG4gICAgICAgIGl0ZW1BZGp1c3RtZW50czogW1xuICAgICAgICAgIHsgaWQ6IDEsIGJ1eVByaWNlOiAxLCB1cGRhdGVkQXQ6IDEgfSxcbiAgICAgICAgICB7IGJ1eVByaWNlOiAxLCBjcmVhdGVkQXQ6IDEgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aChcbiAgICAgIDEsXG4gICAgICBcIklOU0VSVCBJTlRPIGBJbnZlbnRvcnlBZGp1c3RtZW50YCAoYGRlc2NyaXB0aW9uYCwgYGNyZWF0ZWRBdGApIFZBTFVFUyAoJ3NvbWV0aGluZyBhJywgMSksICgnc29tZXRoaW5nIGInLCAxKVwiXG4gICAgKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aChcbiAgICAgIDIsXG4gICAgICAnSU5TRVJUIElOVE8gYEl0ZW1BZGp1c3RtZW50YCAoYGJ1eVByaWNlYCwgYGNyZWF0ZWRBdGAsIGBpbnZlbnRvcnlBZGp1c3RtZW50SWRgKSBWQUxVRVMgKDEsIDEsIDEpLCAoMSwgMSwgMSknXG4gICAgKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgzLCAnSU5TRVJUIElOVE8gYEl0ZW1BZGp1c3RtZW50YCAoYGJ1eVByaWNlYCwgYGNyZWF0ZWRBdGAsIGBpbnZlbnRvcnlBZGp1c3RtZW50SWRgKSBWQUxVRVMgKDEsIDEsIDIpJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoXG4gICAgICA0LFxuICAgICAgJ1VQREFURSBgSXRlbUFkanVzdG1lbnRgIFNFVCBgYnV5UHJpY2VgID0gMSwgYHVwZGF0ZWRBdGAgPSAxLCBgaW52ZW50b3J5QWRqdXN0bWVudElkYCA9IDIgV0hFUkUgYGlkYCA9IDEnXG4gICAgKTtcblxuICAgIGF3YWl0IHRoaXMucXVlcmllci5maW5kTWFueShJbnZlbnRvcnlBZGp1c3RtZW50LCB7XG4gICAgICAkcHJvamVjdDogeyBpZDogdHJ1ZSwgaXRlbUFkanVzdG1lbnRzOiBbJ2J1eVByaWNlJ10gfSxcbiAgICAgICRmaWx0ZXI6IHsgY3JlYXRlZEF0OiAxIH0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aChcbiAgICAgIDEsXG4gICAgICAnU0VMRUNUIGBJbnZlbnRvcnlBZGp1c3RtZW50YC5gaWRgIEZST00gYEludmVudG9yeUFkanVzdG1lbnRgIFdIRVJFIGBJbnZlbnRvcnlBZGp1c3RtZW50YC5gY3JlYXRlZEF0YCA9IDEnXG4gICAgKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aChcbiAgICAgIDIsXG4gICAgICAnU0VMRUNUIGBidXlQcmljZWAsIGBpbnZlbnRvcnlBZGp1c3RtZW50SWRgIEZST00gYEl0ZW1BZGp1c3RtZW50YCBXSEVSRSBgaW52ZW50b3J5QWRqdXN0bWVudElkYCBJTiAoMSwgMiknXG4gICAgKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcyg0KTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEZpbmRNYW55QW5kUHJvamVjdE9uZVRvTWFueSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0TWFueShJbnZlbnRvcnlBZGp1c3RtZW50LCBbXG4gICAgICB7IGlkOiAxMjMsIGRlc2NyaXB0aW9uOiAnc29tZXRoaW5nIGEnLCBjcmVhdGVkQXQ6IDEgfSxcbiAgICAgIHsgaWQ6IDQ1NiwgZGVzY3JpcHRpb246ICdzb21ldGhpbmcgYicsIGNyZWF0ZWRBdDogMSB9LFxuICAgIF0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoXG4gICAgICAxLFxuICAgICAgXCJJTlNFUlQgSU5UTyBgSW52ZW50b3J5QWRqdXN0bWVudGAgKGBpZGAsIGBkZXNjcmlwdGlvbmAsIGBjcmVhdGVkQXRgKSBWQUxVRVMgKDEyMywgJ3NvbWV0aGluZyBhJywgMSksICg0NTYsICdzb21ldGhpbmcgYicsIDEpXCJcbiAgICApO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRNYW55KEludmVudG9yeUFkanVzdG1lbnQsIHtcbiAgICAgICRwcm9qZWN0OiB7IGlkOiB0cnVlLCBpdGVtQWRqdXN0bWVudHM6IHRydWUgfSxcbiAgICAgICRmaWx0ZXI6IHsgY3JlYXRlZEF0OiAxIH0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aChcbiAgICAgIDEsXG4gICAgICAnU0VMRUNUIGBJbnZlbnRvcnlBZGp1c3RtZW50YC5gaWRgIEZST00gYEludmVudG9yeUFkanVzdG1lbnRgIFdIRVJFIGBJbnZlbnRvcnlBZGp1c3RtZW50YC5gY3JlYXRlZEF0YCA9IDEnXG4gICAgKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aChcbiAgICAgIDIsXG4gICAgICAnU0VMRUNUIGBpZGAsIGBjb21wYW55SWRgLCBgY3JlYXRvcklkYCwgYGNyZWF0ZWRBdGAsIGB1cGRhdGVkQXRgLCBgaXRlbUlkYCwgYG51bWJlcmAsIGBidXlQcmljZWAsIGBzdG9yZWhvdXNlSWRgJyArXG4gICAgICAgICcsIGBpbnZlbnRvcnlBZGp1c3RtZW50SWRgIEZST00gYEl0ZW1BZGp1c3RtZW50YCBXSEVSRSBgaW52ZW50b3J5QWRqdXN0bWVudElkYCBJTiAoMTIzLCA0NTYpJ1xuICAgICk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gIH1cblxuICBhc3luYyBzaG91bGRGaW5kT25lQW5kUHJvamVjdE1hbnlUb01hbnkoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmluc2VydE9uZShJdGVtLCB7IGlkOiAxMjMsIGNyZWF0ZWRBdDogMSB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDEsICdJTlNFUlQgSU5UTyBgSXRlbWAgKGBpZGAsIGBjcmVhdGVkQXRgKSBWQUxVRVMgKDEyMywgMSknKTtcblxuICAgIGF3YWl0IHRoaXMucXVlcmllci5maW5kT25lKEl0ZW0sIHtcbiAgICAgICRwcm9qZWN0OiB7IGlkOiB0cnVlLCBjcmVhdGVkQXQ6IHRydWUsIHRhZ3M6IFsnaWQnXSB9LFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMSwgJ1NFTEVDVCBgSXRlbWAuYGlkYCwgYEl0ZW1gLmBjcmVhdGVkQXRgIEZST00gYEl0ZW1gIExJTUlUIDEnKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aChcbiAgICAgIDIsXG4gICAgICAnU0VMRUNUIGBJdGVtVGFnYC5gaWRgLCBgSXRlbVRhZ2AuYGl0ZW1JZGAsIGB0YWdgLmBpZGAgYHRhZy5pZGAnICtcbiAgICAgICAgJyBGUk9NIGBJdGVtVGFnYCBJTk5FUiBKT0lOIGBUYWdgIGB0YWdgIE9OIGB0YWdgLmBpZGAgPSBgSXRlbVRhZ2AuYHRhZ0lkYCcgK1xuICAgICAgICAnIFdIRVJFIGBJdGVtVGFnYC5gaXRlbUlkYCBJTiAoMTIzKSdcbiAgICApO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDEpO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkRmluZE9uZUJ5SWRBbmRQcm9qZWN0TWFueVRvTWFueSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKEl0ZW0sIHsgaWQ6IDEyMywgY3JlYXRlZEF0OiAxIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgJ0lOU0VSVCBJTlRPIGBJdGVtYCAoYGlkYCwgYGNyZWF0ZWRBdGApIFZBTFVFUyAoMTIzLCAxKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRPbmVCeUlkKEl0ZW0sIDEyMywge1xuICAgICAgJHByb2plY3Q6IHsgaWQ6IDEsIGNyZWF0ZWRBdDogMSwgdGFnczogWydpZCddIH0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aCgxLCAnU0VMRUNUIGBJdGVtYC5gaWRgLCBgSXRlbWAuYGNyZWF0ZWRBdGAgRlJPTSBgSXRlbWAgV0hFUkUgYEl0ZW1gLmBpZGAgPSAxMjMgTElNSVQgMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKFxuICAgICAgMixcbiAgICAgICdTRUxFQ1QgYEl0ZW1UYWdgLmBpZGAsIGBJdGVtVGFnYC5gaXRlbUlkYCwgYHRhZ2AuYGlkYCBgdGFnLmlkYCcgK1xuICAgICAgICAnIEZST00gYEl0ZW1UYWdgIElOTkVSIEpPSU4gYFRhZ2AgYHRhZ2AgT04gYHRhZ2AuYGlkYCA9IGBJdGVtVGFnYC5gdGFnSWRgJyArXG4gICAgICAgICcgV0hFUkUgYEl0ZW1UYWdgLmBpdGVtSWRgIElOICgxMjMpJ1xuICAgICk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gIH1cblxuICBhc3luYyBzaG91bGRGaW5kTWFueSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuZmluZE1hbnkoVXNlciwge1xuICAgICAgJHByb2plY3Q6IHsgaWQ6IHRydWUsIG5hbWU6IHRydWUgfSxcbiAgICAgICRmaWx0ZXI6IHsgY29tcGFueUlkOiAxMjMgfSxcbiAgICAgICRsaW1pdDogMTAwLFxuICAgIH0pO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDEsICdTRUxFQ1QgYGlkYCwgYG5hbWVgIEZST00gYFVzZXJgIFdIRVJFIGBjb21wYW55SWRgID0gMTIzIExJTUlUIDEwMCcpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEZpbmRNYW55QW5kQ291bnQoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmZpbmRNYW55QW5kQ291bnQoVXNlciwge1xuICAgICAgJHByb2plY3Q6IHsgaWQ6IHRydWUsIG5hbWU6IHRydWUgfSxcbiAgICAgICRmaWx0ZXI6IHsgY29tcGFueUlkOiAxMjMgfSxcbiAgICAgICRzb3J0OiB7IGNyZWF0ZWRBdDogLTEgfSxcbiAgICAgICRza2lwOiA1MCxcbiAgICAgICRsaW1pdDogMTAwLFxuICAgIH0pO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKFxuICAgICAgMSxcbiAgICAgICdTRUxFQ1QgYGlkYCwgYG5hbWVgIEZST00gYFVzZXJgIFdIRVJFIGBjb21wYW55SWRgID0gMTIzIE9SREVSIEJZIGBjcmVhdGVkQXRgIERFU0MgTElNSVQgMTAwIE9GRlNFVCA1MCdcbiAgICApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDIsICdTRUxFQ1QgQ09VTlQoKikgYGNvdW50YCBGUk9NIGBVc2VyYCBXSEVSRSBgY29tcGFueUlkYCA9IDEyMycpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEluc2VydE9uZSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKFVzZXIsIHsgY29tcGFueUlkOiAxMjMsIGNyZWF0ZWRBdDogMSB9KTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnSU5TRVJUIElOVE8gYFVzZXJgIChgY29tcGFueUlkYCwgYGNyZWF0ZWRBdGApIFZBTFVFUyAoMTIzLCAxKScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEluc2VydE9uZUFuZENhc2NhZGVPbmVUb09uZSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKFVzZXIsIHtcbiAgICAgIG5hbWU6ICdzb21lIG5hbWUnLFxuICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgcHJvZmlsZTogeyBwaWN0dXJlOiAnYWJjJywgY3JlYXRlZEF0OiAxIH0sXG4gICAgfSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgXCJJTlNFUlQgSU5UTyBgVXNlcmAgKGBuYW1lYCwgYGNyZWF0ZWRBdGApIFZBTFVFUyAoJ3NvbWUgbmFtZScsIDEpXCIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDIsIFwiSU5TRVJUIElOVE8gYHVzZXJfcHJvZmlsZWAgKGBpbWFnZWAsIGBjcmVhdGVkQXRgLCBgY3JlYXRvcklkYCkgVkFMVUVTICgnYWJjJywgMSwgMSlcIik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDIpO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkSW5zZXJ0T25lQW5kQ2FzY2FkZU1hbnlUb09uZSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKE1lYXN1cmVVbml0LCB7XG4gICAgICBuYW1lOiAnQ2VudGltZXRlcicsXG4gICAgICBjcmVhdGVkQXQ6IDEyMyxcbiAgICAgIGNhdGVnb3J5OiB7IG5hbWU6ICdNZXRyaWMnLCBjcmVhdGVkQXQ6IDEyMyB9LFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgXCJJTlNFUlQgSU5UTyBgTWVhc3VyZVVuaXRgIChgbmFtZWAsIGBjcmVhdGVkQXRgKSBWQUxVRVMgKCdDZW50aW1ldGVyJywgMTIzKVwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgyLCBcIklOU0VSVCBJTlRPIGBNZWFzdXJlVW5pdENhdGVnb3J5YCAoYG5hbWVgLCBgY3JlYXRlZEF0YCkgVkFMVUVTICgnTWV0cmljJywgMTIzKVwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aChcbiAgICAgIDMsXG4gICAgICBleHBlY3QudG9NYXRjaCgvXlVQREFURSBgTWVhc3VyZVVuaXRgIFNFVCBgY2F0ZWdvcnlJZGAgPSAxLCBgdXBkYXRlZEF0YCA9IFxcZCsgV0hFUkUgYGlkYCA9IDEgQU5EIGBkZWxldGVkQXRgIElTIE5VTEwkLylcbiAgICApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygzKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZEluc2VydE9uZUFuZENhc2NhZGVPbmVUb01hbnkoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmluc2VydE9uZShJbnZlbnRvcnlBZGp1c3RtZW50LCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ3NvbWUgZGVzY3JpcHRpb24nLFxuICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgaXRlbUFkanVzdG1lbnRzOiBbXG4gICAgICAgIHsgYnV5UHJpY2U6IDUwLCBjcmVhdGVkQXQ6IDEgfSxcbiAgICAgICAgeyBidXlQcmljZTogMzAwLCBjcmVhdGVkQXQ6IDEgfSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgXCJJTlNFUlQgSU5UTyBgSW52ZW50b3J5QWRqdXN0bWVudGAgKGBkZXNjcmlwdGlvbmAsIGBjcmVhdGVkQXRgKSBWQUxVRVMgKCdzb21lIGRlc2NyaXB0aW9uJywgMSlcIik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoXG4gICAgICAyLFxuICAgICAgJ0lOU0VSVCBJTlRPIGBJdGVtQWRqdXN0bWVudGAgKGBidXlQcmljZWAsIGBjcmVhdGVkQXRgLCBgaW52ZW50b3J5QWRqdXN0bWVudElkYCkgVkFMVUVTICg1MCwgMSwgMSksICgzMDAsIDEsIDEpJ1xuICAgICk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDIpO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkVXBkYXRlTWFueSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIudXBkYXRlTWFueShVc2VyLCB7ICRmaWx0ZXI6IHsgY29tcGFueUlkOiA0IH0gfSwgeyBuYW1lOiAnSG9sYScsIHVwZGF0ZWRBdDogMSB9KTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCBcIlVQREFURSBgVXNlcmAgU0VUIGBuYW1lYCA9ICdIb2xhJywgYHVwZGF0ZWRBdGAgPSAxIFdIRVJFIGBjb21wYW55SWRgID0gNFwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gIH1cblxuICBhc3luYyBzaG91bGRVcGRhdGVPbmVCeUlkKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci51cGRhdGVPbmVCeUlkKFVzZXIsIDUsIHsgY29tcGFueUlkOiAxMjMsIHVwZGF0ZWRBdDogMSB9KTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnVVBEQVRFIGBVc2VyYCBTRVQgYGNvbXBhbnlJZGAgPSAxMjMsIGB1cGRhdGVkQXRgID0gMSBXSEVSRSBgaWRgID0gNScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVwZGF0ZU9uZUJ5SWRBbmRDYXNjYWRlT25lVG9PbmUoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmluc2VydE9uZShVc2VyLCB7IGNyZWF0ZWRBdDogMSB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDEsICdJTlNFUlQgSU5UTyBgVXNlcmAgKGBjcmVhdGVkQXRgKSBWQUxVRVMgKDEpJyk7XG5cbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIudXBkYXRlT25lQnlJZChVc2VyLCAxLCB7XG4gICAgICBuYW1lOiAnc29tZXRoaW5nJyxcbiAgICAgIHVwZGF0ZWRBdDogMSxcbiAgICAgIHByb2ZpbGU6IHsgcGljdHVyZTogJ3h5eicsIGNyZWF0ZWRBdDogMSB9LFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgXCJVUERBVEUgYFVzZXJgIFNFVCBgbmFtZWAgPSAnc29tZXRoaW5nJywgYHVwZGF0ZWRBdGAgPSAxIFdIRVJFIGBpZGAgPSAxXCIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDMsIFwiSU5TRVJUIElOVE8gYHVzZXJfcHJvZmlsZWAgKGBpbWFnZWAsIGBjcmVhdGVkQXRgLCBgY3JlYXRvcklkYCkgVkFMVUVTICgneHl6JywgMSwgMSlcIik7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aCgxLCAnU0VMRUNUIGBpZGAgRlJPTSBgVXNlcmAgV0hFUkUgYGlkYCA9IDEnKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygzKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVwZGF0ZU9uZUJ5SWRBbmRDYXNjYWRlT25lVG9PbmVOdWxsKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5pbnNlcnRPbmUoVXNlciwgeyBjcmVhdGVkQXQ6IDEgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnSU5TRVJUIElOVE8gYFVzZXJgIChgY3JlYXRlZEF0YCkgVkFMVUVTICgxKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLnVwZGF0ZU9uZUJ5SWQoVXNlciwgMSwge1xuICAgICAgbmFtZTogJ3NvbWV0aGluZycsXG4gICAgICB1cGRhdGVkQXQ6IDEsXG4gICAgICBwcm9maWxlOiBudWxsLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgXCJVUERBVEUgYFVzZXJgIFNFVCBgbmFtZWAgPSAnc29tZXRoaW5nJywgYHVwZGF0ZWRBdGAgPSAxIFdIRVJFIGBpZGAgPSAxXCIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDEsICdTRUxFQ1QgYGlkYCBGUk9NIGBVc2VyYCBXSEVSRSBgaWRgID0gMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDIsICdTRUxFQ1QgYHBrYCBgaWRgIEZST00gYHVzZXJfcHJvZmlsZWAgV0hFUkUgYGNyZWF0b3JJZGAgPSAxJyk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gIH1cblxuICBhc3luYyBzaG91bGRVcGRhdGVPbmVCeUlkQW5kQ2FzY2FkZU9uZVRvTWFueSgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKEludmVudG9yeUFkanVzdG1lbnQsIHsgY3JlYXRlZEF0OiAxIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgJ0lOU0VSVCBJTlRPIGBJbnZlbnRvcnlBZGp1c3RtZW50YCAoYGNyZWF0ZWRBdGApIFZBTFVFUyAoMSknKTtcblxuICAgIGF3YWl0IHRoaXMucXVlcmllci51cGRhdGVPbmVCeUlkKEludmVudG9yeUFkanVzdG1lbnQsIDEsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnc29tZSBkZXNjcmlwdGlvbicsXG4gICAgICB1cGRhdGVkQXQ6IDEsXG4gICAgICBpdGVtQWRqdXN0bWVudHM6IFtcbiAgICAgICAgeyBidXlQcmljZTogNTAsIGNyZWF0ZWRBdDogMSB9LFxuICAgICAgICB7IGJ1eVByaWNlOiAzMDAsIGNyZWF0ZWRBdDogMSB9LFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDIsIFwiVVBEQVRFIGBJbnZlbnRvcnlBZGp1c3RtZW50YCBTRVQgYGRlc2NyaXB0aW9uYCA9ICdzb21lIGRlc2NyaXB0aW9uJywgYHVwZGF0ZWRBdGAgPSAxIFdIRVJFIGBpZGAgPSAxXCIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDEsICdTRUxFQ1QgYGlkYCBGUk9NIGBJbnZlbnRvcnlBZGp1c3RtZW50YCBXSEVSRSBgaWRgID0gMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDIsICdTRUxFQ1QgYGlkYCBGUk9NIGBJdGVtQWRqdXN0bWVudGAgV0hFUkUgYGludmVudG9yeUFkanVzdG1lbnRJZGAgPSAxJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoXG4gICAgICAzLFxuICAgICAgJ0lOU0VSVCBJTlRPIGBJdGVtQWRqdXN0bWVudGAgKGBidXlQcmljZWAsIGBjcmVhdGVkQXRgLCBgaW52ZW50b3J5QWRqdXN0bWVudElkYCkgVkFMVUVTICg1MCwgMSwgMSksICgzMDAsIDEsIDEpJ1xuICAgICk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMyk7XG4gIH1cblxuICBhc3luYyBzaG91bGRVcGRhdGVPbmVCeUlkQW5kQ2FzY2FkZU9uZVRvTWFueU51bGwoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmluc2VydE9uZShJbnZlbnRvcnlBZGp1c3RtZW50LCB7IGNyZWF0ZWRBdDogMSB9KTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDEsICdJTlNFUlQgSU5UTyBgSW52ZW50b3J5QWRqdXN0bWVudGAgKGBjcmVhdGVkQXRgKSBWQUxVRVMgKDEpJyk7XG5cbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIudXBkYXRlT25lQnlJZChJbnZlbnRvcnlBZGp1c3RtZW50LCAxLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ3NvbWUgZGVzY3JpcHRpb24nLFxuICAgICAgdXBkYXRlZEF0OiAxLFxuICAgICAgaXRlbUFkanVzdG1lbnRzOiBudWxsLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgXCJVUERBVEUgYEludmVudG9yeUFkanVzdG1lbnRgIFNFVCBgZGVzY3JpcHRpb25gID0gJ3NvbWUgZGVzY3JpcHRpb24nLCBgdXBkYXRlZEF0YCA9IDEgV0hFUkUgYGlkYCA9IDFcIik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMSwgJ1NFTEVDVCBgaWRgIEZST00gYEludmVudG9yeUFkanVzdG1lbnRgIFdIRVJFIGBpZGAgPSAxJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMiwgJ1NFTEVDVCBgaWRgIEZST00gYEl0ZW1BZGp1c3RtZW50YCBXSEVSRSBgaW52ZW50b3J5QWRqdXN0bWVudElkYCA9IDEnKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVwZGF0ZU1hbnlBbmRDYXNjYWRlT25lVG9NYW55TnVsbCgpIHtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKEludmVudG9yeUFkanVzdG1lbnQsIHsgY29tcGFueUlkOiAxLCBjcmVhdGVkQXQ6IDEgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnSU5TRVJUIElOVE8gYEludmVudG9yeUFkanVzdG1lbnRgIChgY29tcGFueUlkYCwgYGNyZWF0ZWRBdGApIFZBTFVFUyAoMSwgMSknKTtcblxuICAgIGF3YWl0IHRoaXMucXVlcmllci51cGRhdGVNYW55KFxuICAgICAgSW52ZW50b3J5QWRqdXN0bWVudCxcbiAgICAgIHsgJGZpbHRlcjogeyBjb21wYW55SWQ6IDEgfSB9LFxuICAgICAge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ3NvbWUgZGVzY3JpcHRpb24nLFxuICAgICAgICB1cGRhdGVkQXQ6IDEsXG4gICAgICAgIGl0ZW1BZGp1c3RtZW50czogbnVsbCxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoXG4gICAgICAyLFxuICAgICAgXCJVUERBVEUgYEludmVudG9yeUFkanVzdG1lbnRgIFNFVCBgZGVzY3JpcHRpb25gID0gJ3NvbWUgZGVzY3JpcHRpb24nLCBgdXBkYXRlZEF0YCA9IDEgV0hFUkUgYGNvbXBhbnlJZGAgPSAxXCJcbiAgICApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDEsICdTRUxFQ1QgYGlkYCBGUk9NIGBJbnZlbnRvcnlBZGp1c3RtZW50YCBXSEVSRSBgY29tcGFueUlkYCA9IDEnKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aCgyLCAnU0VMRUNUIGBpZGAgRlJPTSBgSXRlbUFkanVzdG1lbnRgIFdIRVJFIGBpbnZlbnRvcnlBZGp1c3RtZW50SWRgID0gMScpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDIpO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkSW5zZXJ0T25lQW5kQ2FzY2FkZU1hbnlUb01hbnlJbnNlcnRzKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5pbnNlcnRPbmUoSXRlbSwge1xuICAgICAgbmFtZTogJ2l0ZW0gb25lJyxcbiAgICAgIGNyZWF0ZWRBdDogMSxcbiAgICAgIHRhZ3M6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICd0YWcgb25lJyxcbiAgICAgICAgICBjcmVhdGVkQXQ6IDEsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAndGFnIHR3bycsXG4gICAgICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCBcIklOU0VSVCBJTlRPIGBJdGVtYCAoYG5hbWVgLCBgY3JlYXRlZEF0YCkgVkFMVUVTICgnaXRlbSBvbmUnLCAxKVwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgyLCBcIklOU0VSVCBJTlRPIGBUYWdgIChgbmFtZWAsIGBjcmVhdGVkQXRgKSBWQUxVRVMgKCd0YWcgb25lJywgMSksICgndGFnIHR3bycsIDEpXCIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDMsICdJTlNFUlQgSU5UTyBgSXRlbVRhZ2AgKGBpdGVtSWRgLCBgdGFnSWRgKSBWQUxVRVMgKDEsIDEpLCAoMSwgMiknKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygzKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVwZGF0ZUFuZENhc2NhZGVNYW55VG9NYW55SW5zZXJ0cygpIHtcbiAgICBjb25zdCBpZCA9IGF3YWl0IHRoaXMucXVlcmllci5pbnNlcnRPbmUoSXRlbSwgeyBjcmVhdGVkQXQ6IDEgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnSU5TRVJUIElOVE8gYEl0ZW1gIChgY3JlYXRlZEF0YCkgVkFMVUVTICgxKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLnVwZGF0ZU9uZUJ5SWQoSXRlbSwgaWQsIHtcbiAgICAgIG5hbWU6ICdpdGVtIG9uZScsXG4gICAgICB1cGRhdGVkQXQ6IDEsXG4gICAgICB0YWdzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAndGFnIG9uZScsXG4gICAgICAgICAgY3JlYXRlZEF0OiAxLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ3RhZyB0d28nLFxuICAgICAgICAgIGNyZWF0ZWRBdDogMSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgyLCBcIlVQREFURSBgSXRlbWAgU0VUIGBuYW1lYCA9ICdpdGVtIG9uZScsIGB1cGRhdGVkQXRgID0gMSBXSEVSRSBgaWRgID0gMVwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aCgxLCAnU0VMRUNUIGBpZGAgRlJPTSBgSXRlbWAgV0hFUkUgYGlkYCA9IDEnKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgzLCBcIklOU0VSVCBJTlRPIGBUYWdgIChgbmFtZWAsIGBjcmVhdGVkQXRgKSBWQUxVRVMgKCd0YWcgb25lJywgMSksICgndGFnIHR3bycsIDEpXCIpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMiwgJ1NFTEVDVCBgaWRgIEZST00gYEl0ZW1UYWdgIFdIRVJFIGBpdGVtSWRgID0gMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDQsICdJTlNFUlQgSU5UTyBgSXRlbVRhZ2AgKGBpdGVtSWRgLCBgdGFnSWRgKSBWQUxVRVMgKDEsIDEpLCAoMSwgMiknKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcyg0KTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVwZGF0ZUFuZENhc2NhZGVNYW55VG9NYW55TGlua3MoKSB7XG4gICAgY29uc3QgaWQgPSBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKEl0ZW0sIHsgY3JlYXRlZEF0OiAxIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgJ0lOU0VSVCBJTlRPIGBJdGVtYCAoYGNyZWF0ZWRBdGApIFZBTFVFUyAoMSknKTtcblxuICAgIGF3YWl0IHRoaXMucXVlcmllci51cGRhdGVPbmVCeUlkKEl0ZW0sIGlkLCB7XG4gICAgICBuYW1lOiAnaXRlbSBvbmUnLFxuICAgICAgdGFnczogW3sgaWQ6IDIyIH0sIHsgaWQ6IDMzIH1dLFxuICAgICAgdXBkYXRlZEF0OiAxLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgXCJVUERBVEUgYEl0ZW1gIFNFVCBgbmFtZWAgPSAnaXRlbSBvbmUnLCBgdXBkYXRlZEF0YCA9IDEgV0hFUkUgYGlkYCA9IDFcIik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMSwgJ1NFTEVDVCBgaWRgIEZST00gYEl0ZW1gIFdIRVJFIGBpZGAgPSAxJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMiwgJ1NFTEVDVCBgaWRgIEZST00gYEl0ZW1UYWdgIFdIRVJFIGBpdGVtSWRgID0gMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDMsICdJTlNFUlQgSU5UTyBgSXRlbVRhZ2AgKGBpdGVtSWRgLCBgdGFnSWRgKSBWQUxVRVMgKDEsIDIyKSwgKDEsIDMzKScpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDMpO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkRGVsZXRlT25lQW5kQ2FzY2FkZU1hbnlUb01hbnlEZWxldGVzKCkge1xuICAgIGF3YWl0IHRoaXMuc2hvdWxkSW5zZXJ0T25lQW5kQ2FzY2FkZU1hbnlUb01hbnlJbnNlcnRzKCk7XG5cbiAgICBqZXN0LmNsZWFyQWxsTW9ja3MoKTtcblxuICAgIGF3YWl0IHRoaXMucXVlcmllci5kZWxldGVPbmVCeUlkKEl0ZW0sIDEpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMSwgJ1NFTEVDVCBgaWRgIEZST00gYEl0ZW1gIFdIRVJFIGBpZGAgPSAxJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMiwgJ1NFTEVDVCBgaWRgIEZST00gYEl0ZW1UYWdgIFdIRVJFIGBpdGVtSWRgIElOICgxKScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDEsICdERUxFVEUgRlJPTSBgSXRlbWAgV0hFUkUgYGlkYCBJTiAoMSknKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgyLCAnREVMRVRFIEZST00gYEl0ZW1UYWdgIFdIRVJFIGBpZGAgSU4gKDEsIDIpJyk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDIpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gIH1cblxuICBhc3luYyBzaG91bGREZWxldGVPbmVBbmROb0Nhc2NhZGVNYW55VG9NYW55RGVsZXRlcygpIHtcbiAgICBhd2FpdCB0aGlzLnNob3VsZEluc2VydE9uZUFuZENhc2NhZGVNYW55VG9NYW55SW5zZXJ0cygpO1xuXG4gICAgamVzdC5jbGVhckFsbE1vY2tzKCk7XG5cbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuZGVsZXRlT25lQnlJZChUYWcsIDEpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLm50aENhbGxlZFdpdGgoMSwgJ1NFTEVDVCBgaWRgIEZST00gYFRhZ2AgV0hFUkUgYGlkYCA9IDEnKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCAnREVMRVRFIEZST00gYFRhZ2AgV0hFUkUgYGlkYCBJTiAoMSknKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygxKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZERlbGV0ZU9uZUJ5SWQoKSB7XG4gICAgY29uc3QgaWQgPSBhd2FpdCB0aGlzLnF1ZXJpZXIuaW5zZXJ0T25lKFVzZXIsIHsgY3JlYXRlZEF0OiAxLCBwcm9maWxlOiB7IGNyZWF0ZWRBdDogMSB9IH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgJ0lOU0VSVCBJTlRPIGBVc2VyYCAoYGNyZWF0ZWRBdGApIFZBTFVFUyAoMSknKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgyLCAnSU5TRVJUIElOVE8gYHVzZXJfcHJvZmlsZWAgKGBjcmVhdGVkQXRgLCBgY3JlYXRvcklkYCkgVkFMVUVTICgxLCAxKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmRlbGV0ZU9uZUJ5SWQoVXNlciwgaWQpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMywgJ0RFTEVURSBGUk9NIGBVc2VyYCBXSEVSRSBgaWRgIElOICgxKScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS5udGhDYWxsZWRXaXRoKDQsICdERUxFVEUgRlJPTSBgdXNlcl9wcm9maWxlYCBXSEVSRSBgcGtgIElOICgxKScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDEsICdTRUxFQ1QgYGlkYCBGUk9NIGBVc2VyYCBXSEVSRSBgaWRgID0gMScpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDIsICdTRUxFQ1QgYHBrYCBgaWRgIEZST00gYHVzZXJfcHJvZmlsZWAnKTtcblxuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMik7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcyg0KTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZERlbGV0ZU1hbnkoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmluc2VydE9uZShVc2VyLCB7IGNyZWF0ZWRBdDogMTIzIH0pO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMSwgJ0lOU0VSVCBJTlRPIGBVc2VyYCAoYGNyZWF0ZWRBdGApIFZBTFVFUyAoMTIzKScpO1xuXG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmRlbGV0ZU1hbnkoVXNlciwgeyAkZmlsdGVyOiB7IGNyZWF0ZWRBdDogMTIzIH0gfSk7XG5cbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aCgxLCAnU0VMRUNUIGBpZGAgRlJPTSBgVXNlcmAgV0hFUkUgYGNyZWF0ZWRBdGAgPSAxMjMnKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkubnRoQ2FsbGVkV2l0aCgyLCAnU0VMRUNUIGBwa2AgYGlkYCBGUk9NIGB1c2VyX3Byb2ZpbGVgJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgJ0RFTEVURSBGUk9NIGBVc2VyYCBXSEVSRSBgaWRgIElOICgxKScpO1xuXG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDIpO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkQ291bnQoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLmNvdW50KFVzZXIsIHsgJGZpbHRlcjogeyBjb21wYW55SWQ6IDEyMyB9IH0pO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS5udGhDYWxsZWRXaXRoKDEsICdTRUxFQ1QgQ09VTlQoKikgYGNvdW50YCBGUk9NIGBVc2VyYCBXSEVSRSBgY29tcGFueUlkYCA9IDEyMycpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVzZVRyYW5zYWN0aW9uKCkge1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlRmFsc3koKTtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuYmVnaW5UcmFuc2FjdGlvbigpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkV2l0aCh0aGlzLnF1ZXJpZXIuZGlhbGVjdC5iZWdpblRyYW5zYWN0aW9uQ29tbWFuZCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmUodHJ1ZSk7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLnVwZGF0ZU9uZUJ5SWQoVXNlciwgNSwgeyBuYW1lOiAnSG9sYScsIHVwZGF0ZWRBdDogMSB9KTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmhhc09wZW5UcmFuc2FjdGlvbikudG9CZSh0cnVlKTtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuY29tbWl0VHJhbnNhY3Rpb24oKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCB0aGlzLnF1ZXJpZXIuZGlhbGVjdC5iZWdpblRyYW5zYWN0aW9uQ29tbWFuZCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgXCJVUERBVEUgYFVzZXJgIFNFVCBgbmFtZWAgPSAnSG9sYScsIGB1cGRhdGVkQXRgID0gMSBXSEVSRSBgaWRgID0gNVwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgzLCAnQ09NTUlUJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmVGYWxzeSgpO1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5yZWxlYXNlKCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygzKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlRmFsc3koKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFVzZVRyYW5zYWN0aW9uQ2FsbGJhY2soKSB7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmVGYWxzeSgpO1xuICAgIGF3YWl0IHRoaXMucXVlcmllci50cmFuc2FjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFdpdGgodGhpcy5xdWVyaWVyLmRpYWxlY3QuYmVnaW5UcmFuc2FjdGlvbkNvbW1hbmQpO1xuICAgICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmUodHJ1ZSk7XG4gICAgICBhd2FpdCB0aGlzLnF1ZXJpZXIudXBkYXRlT25lQnlJZChVc2VyLCA1LCB7IG5hbWU6ICdIb2xhJywgdXBkYXRlZEF0OiAxIH0pO1xuICAgIH0pO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlRmFsc3koKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCB0aGlzLnF1ZXJpZXIuZGlhbGVjdC5iZWdpblRyYW5zYWN0aW9uQ29tbWFuZCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgXCJVUERBVEUgYFVzZXJgIFNFVCBgbmFtZWAgPSAnSG9sYScsIGB1cGRhdGVkQXRgID0gMSBXSEVSRSBgaWRgID0gNVwiKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgzLCAnQ09NTUlUJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygzKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDApO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkVGhyb3dJZlJvbGxiYWNrSWZFcnJvckluQ2FsbGJhY2soKSB7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmVGYWxzeSgpO1xuICAgIGNvbnN0IHByb20gPSB0aGlzLnF1ZXJpZXIudHJhbnNhY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRXaXRoKHRoaXMucXVlcmllci5kaWFsZWN0LmJlZ2luVHJhbnNhY3Rpb25Db21tYW5kKTtcbiAgICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlKHRydWUpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdzb21lIGVycm9yJyk7XG4gICAgfSk7XG4gICAgYXdhaXQgZXhwZWN0KHByb20pLnJlamVjdHMudG9UaHJvdygnc29tZSBlcnJvcicpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlRmFsc3koKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikubnRoQ2FsbGVkV2l0aCgxLCB0aGlzLnF1ZXJpZXIuZGlhbGVjdC5iZWdpblRyYW5zYWN0aW9uQ29tbWFuZCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLm50aENhbGxlZFdpdGgoMiwgJ1JPTExCQUNLJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDApO1xuICB9XG5cbiAgYXN5bmMgc2hvdWxkVGhyb3dJZlRyYW5zYWN0aW9uSXNQZW5kaW5nKCkge1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlRmFsc3koKTtcbiAgICBhd2FpdCB0aGlzLnF1ZXJpZXIuYmVnaW5UcmFuc2FjdGlvbigpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlKHRydWUpO1xuICAgIGF3YWl0IGV4cGVjdCh0aGlzLnF1ZXJpZXIuYmVnaW5UcmFuc2FjdGlvbigpKS5yZWplY3RzLnRvVGhyb3coJ3BlbmRpbmcgdHJhbnNhY3Rpb24nKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmhhc09wZW5UcmFuc2FjdGlvbikudG9CZSh0cnVlKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDEpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFRocm93SWZDb21taXRXaXRoTm9QZW5kaW5nVHJhbnNhY3Rpb24oKSB7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmVGYWxzeSgpO1xuICAgIGF3YWl0IGV4cGVjdCh0aGlzLnF1ZXJpZXIuY29tbWl0VHJhbnNhY3Rpb24oKSkucmVqZWN0cy50b1Rocm93KCdwZW5kaW5nIHRyYW5zYWN0aW9uJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmVGYWxzeSgpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIucnVuKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5hbGwpLnRvQmVDYWxsZWRUaW1lcygwKTtcbiAgfVxuXG4gIGFzeW5jIHNob3VsZFRocm93SWZSb2xsYmFja1dpdGhOb1BlbmRpbmdUcmFuc2FjdGlvbigpIHtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmhhc09wZW5UcmFuc2FjdGlvbikudG9CZUZhbHN5KCk7XG4gICAgYXdhaXQgZXhwZWN0KHRoaXMucXVlcmllci5yb2xsYmFja1RyYW5zYWN0aW9uKCkpLnJlamVjdHMudG9UaHJvdygnbm90IGEgcGVuZGluZyB0cmFuc2FjdGlvbicpO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuaGFzT3BlblRyYW5zYWN0aW9uKS50b0JlRmFsc3koKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLnJ1bikudG9CZUNhbGxlZFRpbWVzKDApO1xuICAgIGV4cGVjdCh0aGlzLnF1ZXJpZXIuYWxsKS50b0JlQ2FsbGVkVGltZXMoMCk7XG4gIH1cblxuICBhc3luYyBzaG91bGRUaHJvd0lmUmVsZWFzZVdpdGhQZW5kaW5nVHJhbnNhY3Rpb24oKSB7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmVGYWxzeSgpO1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5iZWdpblRyYW5zYWN0aW9uKCk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmUodHJ1ZSk7XG4gICAgYXdhaXQgdGhpcy5xdWVyaWVyLnVwZGF0ZU9uZUJ5SWQoVXNlciwgNSwgeyBuYW1lOiAnc29tZSBuYW1lJyB9KTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmhhc09wZW5UcmFuc2FjdGlvbikudG9CZSh0cnVlKTtcbiAgICBhd2FpdCBleHBlY3QodGhpcy5xdWVyaWVyLnJlbGVhc2UoKSkucmVqZWN0cy50b1Rocm93KCdwZW5kaW5nIHRyYW5zYWN0aW9uJyk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5oYXNPcGVuVHJhbnNhY3Rpb24pLnRvQmUodHJ1ZSk7XG4gICAgZXhwZWN0KHRoaXMucXVlcmllci5ydW4pLnRvQmVDYWxsZWRUaW1lcygyKTtcbiAgICBleHBlY3QodGhpcy5xdWVyaWVyLmFsbCkudG9CZUNhbGxlZFRpbWVzKDApO1xuICAgIGF3YWl0IHRoaXMucXVlcmllci5yb2xsYmFja1RyYW5zYWN0aW9uKCk7XG4gIH1cbn1cbiJdfQ==