@uql/core 0.4.89 → 0.4.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -35
- package/package.json +4 -4
- package/dialect/abstractSqlDialect-spec.d.ts +0 -49
- package/dialect/abstractSqlDialect-spec.js +0 -765
- package/dialect/mysqlDialect.spec.d.ts +0 -6
- package/dialect/mysqlDialect.spec.js +0 -33
- package/dialect/postgresDialect.spec.d.ts +0 -1
- package/dialect/postgresDialect.spec.js +0 -139
- package/dialect/sqliteDialect.spec.d.ts +0 -1
- package/dialect/sqliteDialect.spec.js +0 -12
- package/entity/decorator/definition.spec.d.ts +0 -1
- package/entity/decorator/definition.spec.js +0 -725
- package/entity/decorator/relation.spec.d.ts +0 -1
- package/entity/decorator/relation.spec.js +0 -55
- package/options.spec.d.ts +0 -1
- package/options.spec.js +0 -27
- package/querier/abstractQuerier-it.d.ts +0 -41
- package/querier/abstractQuerier-it.js +0 -410
- package/querier/abstractSqlQuerier-it.d.ts +0 -9
- package/querier/abstractSqlQuerier-it.js +0 -19
- package/querier/abstractSqlQuerier-spec.d.ts +0 -53
- package/querier/abstractSqlQuerier-spec.js +0 -607
- package/querier/decorator/injectQuerier.spec.d.ts +0 -1
- package/querier/decorator/injectQuerier.spec.js +0 -108
- package/querier/decorator/transactional.spec.d.ts +0 -1
- package/querier/decorator/transactional.spec.js +0 -239
- package/repository/genericRepository.spec.d.ts +0 -1
- package/repository/genericRepository.spec.js +0 -86
- package/test/entityMock.d.ts +0 -180
- package/test/entityMock.js +0 -451
- package/test/index.d.ts +0 -3
- package/test/index.js +0 -7
- package/test/it.util.d.ts +0 -4
- package/test/it.util.js +0 -60
- package/test/spec.util.d.ts +0 -13
- package/test/spec.util.js +0 -54
- package/util/dialect.util.spec.d.ts +0 -1
- package/util/dialect.util.spec.js +0 -23
- package/util/object.util.spec.d.ts +0 -1
- package/util/object.util.spec.js +0 -26
- package/util/sql.util.spec.d.ts +0 -1
- package/util/sql.util.spec.js +0 -164
- package/util/string.util.spec.d.ts +0 -1
- package/util/string.util.spec.js +0 -26
|
@@ -1,607 +0,0 @@
|
|
|
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
|