@uql/core 0.4.80 → 0.4.83

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