keez-invoicing 1.1.5
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/LICENSE +28 -0
- package/README.md +366 -0
- package/dist/coverage/lcov-report/block-navigation.js +71 -0
- package/dist/coverage/lcov-report/prettify.js +478 -0
- package/dist/coverage/lcov-report/sorter.js +177 -0
- package/dist/eslint.config.js +56 -0
- package/dist/jest.config.cjs +13 -0
- package/dist/jest.config.js +13 -0
- package/dist/src/api/__tests__/index.test.js +52 -0
- package/dist/src/api/authorise.js +48 -0
- package/dist/src/api/invoices/cancel.js +33 -0
- package/dist/src/api/invoices/create.js +97 -0
- package/dist/src/api/invoices/delete.js +33 -0
- package/dist/src/api/invoices/downloadPdf.js +31 -0
- package/dist/src/api/invoices/getAll.js +84 -0
- package/dist/src/api/invoices/sendMail.js +59 -0
- package/dist/src/api/invoices/submitEfactura.js +34 -0
- package/dist/src/api/invoices/update.js +61 -0
- package/dist/src/api/invoices/validate.js +39 -0
- package/dist/src/api/invoices/view.js +93 -0
- package/dist/src/api/items/create.js +42 -0
- package/dist/src/api/items/getAll.js +74 -0
- package/dist/src/api/items/getById.js +46 -0
- package/dist/src/api/items/index.js +14 -0
- package/dist/src/api/items/patch.js +49 -0
- package/dist/src/api/items/update.js +41 -0
- package/dist/src/config/constants.js +23 -0
- package/dist/src/config/constructorParam.js +3 -0
- package/dist/src/config/measureUnit.js +22 -0
- package/dist/src/config/paymentType.js +17 -0
- package/dist/src/config/paymentType.js.js +16 -0
- package/dist/src/dto/allInvoicesResponse.js +3 -0
- package/dist/src/dto/authResponse.js +3 -0
- package/dist/src/dto/common/index.js +3 -0
- package/dist/src/dto/common/paginationParams.js +3 -0
- package/dist/src/dto/createInvoiceRequest.js +3 -0
- package/dist/src/dto/invoiceResponse.js +3 -0
- package/dist/src/dto/invoices/index.js +3 -0
- package/dist/src/dto/invoices/invoiceFilterParams.js +3 -0
- package/dist/src/dto/invoices/invoiceRequestV2.js +3 -0
- package/dist/src/dto/invoices/sendInvoiceParams.js +3 -0
- package/dist/src/dto/items/allItemsResponse.js +3 -0
- package/dist/src/dto/items/index.js +3 -0
- package/dist/src/dto/items/itemRequest.js +3 -0
- package/dist/src/dto/items/itemResponse.js +3 -0
- package/dist/src/errors/KeezError.js +27 -0
- package/dist/src/helpers/logger.js +15 -0
- package/dist/src/index.js +15 -0
- package/dist/src/keezApi.js +283 -0
- package/dist/tests/additional-coverage.test.js +351 -0
- package/dist/tests/edge-cases.test.js +353 -0
- package/dist/tests/error-handling.test.js +224 -0
- package/dist/tests/filter-params.test.js +267 -0
- package/dist/tests/index.test.js +493 -0
- package/dist/tests/invoices-extended.test.js +168 -0
- package/dist/tests/items.test.js +142 -0
- package/dist/types/coverage/lcov-report/block-navigation.d.ts +1 -0
- package/dist/types/coverage/lcov-report/prettify.d.ts +0 -0
- package/dist/types/coverage/lcov-report/sorter.d.ts +1 -0
- package/dist/types/eslint.config.d.ts +2 -0
- package/dist/types/jest.config.d.cts +9 -0
- package/dist/types/jest.config.d.ts +9 -0
- package/dist/types/src/api/__tests__/index.test.d.ts +1 -0
- package/dist/types/src/api/authorise.d.ts +18 -0
- package/dist/types/src/api/invoices/cancel.d.ts +9 -0
- package/dist/types/src/api/invoices/create.d.ts +22 -0
- package/dist/types/src/api/invoices/delete.d.ts +9 -0
- package/dist/types/src/api/invoices/downloadPdf.d.ts +8 -0
- package/dist/types/src/api/invoices/getAll.d.ts +22 -0
- package/dist/types/src/api/invoices/sendMail.d.ts +24 -0
- package/dist/types/src/api/invoices/submitEfactura.d.ts +9 -0
- package/dist/types/src/api/invoices/update.d.ts +11 -0
- package/dist/types/src/api/invoices/validate.d.ts +21 -0
- package/dist/types/src/api/invoices/view.d.ts +22 -0
- package/dist/types/src/api/items/create.d.ts +10 -0
- package/dist/types/src/api/items/getAll.d.ts +10 -0
- package/dist/types/src/api/items/getById.d.ts +10 -0
- package/dist/types/src/api/items/index.d.ts +5 -0
- package/dist/types/src/api/items/patch.d.ts +11 -0
- package/dist/types/src/api/items/update.d.ts +11 -0
- package/dist/types/src/config/constants.d.ts +13 -0
- package/dist/types/src/config/constructorParam.d.ts +6 -0
- package/dist/types/src/config/measureUnit.d.ts +17 -0
- package/dist/types/src/config/paymentType.d.ts +12 -0
- package/dist/types/src/config/paymentType.js.d.ts +11 -0
- package/dist/types/src/dto/allInvoicesResponse.d.ts +21 -0
- package/dist/types/src/dto/authResponse.d.ts +7 -0
- package/dist/types/src/dto/common/index.d.ts +1 -0
- package/dist/types/src/dto/common/paginationParams.d.ts +4 -0
- package/dist/types/src/dto/createInvoiceRequest.d.ts +34 -0
- package/dist/types/src/dto/invoiceResponse.d.ts +48 -0
- package/dist/types/src/dto/invoices/index.d.ts +3 -0
- package/dist/types/src/dto/invoices/invoiceFilterParams.d.ts +8 -0
- package/dist/types/src/dto/invoices/invoiceRequestV2.d.ts +23 -0
- package/dist/types/src/dto/invoices/sendInvoiceParams.d.ts +5 -0
- package/dist/types/src/dto/items/allItemsResponse.d.ts +13 -0
- package/dist/types/src/dto/items/index.d.ts +3 -0
- package/dist/types/src/dto/items/itemRequest.d.ts +34 -0
- package/dist/types/src/dto/items/itemResponse.d.ts +15 -0
- package/dist/types/src/errors/KeezError.d.ts +11 -0
- package/dist/types/src/helpers/logger.d.ts +2 -0
- package/dist/types/src/index.d.ts +11 -0
- package/dist/types/src/keezApi.d.ts +114 -0
- package/dist/types/tests/additional-coverage.test.d.ts +1 -0
- package/dist/types/tests/edge-cases.test.d.ts +1 -0
- package/dist/types/tests/error-handling.test.d.ts +1 -0
- package/dist/types/tests/filter-params.test.d.ts +1 -0
- package/dist/types/tests/index.test.d.ts +1 -0
- package/dist/types/tests/invoices-extended.test.d.ts +1 -0
- package/dist/types/tests/items.test.d.ts +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const nock_1 = __importDefault(require("nock"));
|
|
7
|
+
const keezApi_1 = require("../src/keezApi");
|
|
8
|
+
const authorise_1 = require("../src/api/authorise");
|
|
9
|
+
const getAll_1 = require("../src/api/invoices/getAll");
|
|
10
|
+
const view_1 = require("../src/api/invoices/view");
|
|
11
|
+
const create_1 = require("../src/api/invoices/create");
|
|
12
|
+
const sendMail_1 = require("../src/api/invoices/sendMail");
|
|
13
|
+
const validate_1 = require("../src/api/invoices/validate");
|
|
14
|
+
const paymentType_1 = require("../src/config/paymentType");
|
|
15
|
+
const KeezError_1 = require("../src/errors/KeezError");
|
|
16
|
+
const STAGING_DOMAIN = 'https://staging.keez.ro';
|
|
17
|
+
const LIVE_DOMAIN = 'https://app.keez.ro';
|
|
18
|
+
describe('KeezApi class', () => {
|
|
19
|
+
let keezApi;
|
|
20
|
+
beforeAll(() => {
|
|
21
|
+
keezApi = new keezApi_1.KeezApi({
|
|
22
|
+
application_id: 'test-app-id',
|
|
23
|
+
client_eid: 'test-client-eid',
|
|
24
|
+
secret: 'test-secret',
|
|
25
|
+
live: true,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
nock_1.default.cleanAll();
|
|
30
|
+
});
|
|
31
|
+
test('should return live domain when live mode is true', () => {
|
|
32
|
+
keezApi.setLive(true);
|
|
33
|
+
expect(keezApi.getBaseDomain()).toBe(LIVE_DOMAIN);
|
|
34
|
+
});
|
|
35
|
+
test('should return staging domain when live mode is false', () => {
|
|
36
|
+
keezApi.setLive(false);
|
|
37
|
+
expect(keezApi.getBaseDomain()).toBe(STAGING_DOMAIN);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe('apiGenerateToken', () => {
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
nock_1.default.cleanAll();
|
|
43
|
+
});
|
|
44
|
+
test('should generate token successfully', async () => {
|
|
45
|
+
const mockResponse = {
|
|
46
|
+
access_token: 'test-access-token',
|
|
47
|
+
expires_in: 3600,
|
|
48
|
+
token_type: 'Bearer',
|
|
49
|
+
scope: 'public-api',
|
|
50
|
+
};
|
|
51
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
52
|
+
.post('/idp/connect/token')
|
|
53
|
+
.reply(200, mockResponse);
|
|
54
|
+
const result = await (0, authorise_1.apiGenerateToken)({
|
|
55
|
+
baseDomain: STAGING_DOMAIN,
|
|
56
|
+
appId: 'test-app-id',
|
|
57
|
+
apiSecret: 'test-secret',
|
|
58
|
+
});
|
|
59
|
+
expect(result.access_token).toBe('test-access-token');
|
|
60
|
+
expect(result.expires_in).toBe(3600);
|
|
61
|
+
expect(result.token_type).toBe('Bearer');
|
|
62
|
+
expect(result.scope).toBe('public-api');
|
|
63
|
+
expect(result.expires_at).toBeGreaterThan(Date.now());
|
|
64
|
+
});
|
|
65
|
+
test('should throw KeezAuthError on authentication failure', async () => {
|
|
66
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
67
|
+
.post('/idp/connect/token')
|
|
68
|
+
.reply(401, { error: 'invalid_client' });
|
|
69
|
+
await expect((0, authorise_1.apiGenerateToken)({
|
|
70
|
+
baseDomain: STAGING_DOMAIN,
|
|
71
|
+
appId: 'test-app-id',
|
|
72
|
+
apiSecret: 'wrong-secret',
|
|
73
|
+
})).rejects.toThrow(KeezError_1.KeezAuthError);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe('apiGetAllInvoices', () => {
|
|
77
|
+
afterEach(() => {
|
|
78
|
+
nock_1.default.cleanAll();
|
|
79
|
+
});
|
|
80
|
+
test('should get all invoices successfully', async () => {
|
|
81
|
+
const mockResponse = {
|
|
82
|
+
first: 0,
|
|
83
|
+
last: 1,
|
|
84
|
+
recordsCount: 2,
|
|
85
|
+
data: [
|
|
86
|
+
{
|
|
87
|
+
externalId: 'invoice-1',
|
|
88
|
+
series: 'PDI',
|
|
89
|
+
number: 1,
|
|
90
|
+
documentDate: 20230423,
|
|
91
|
+
dueDate: 20230430,
|
|
92
|
+
status: 'draft',
|
|
93
|
+
clientName: 'Test Client',
|
|
94
|
+
partnerName: 'Test Partner',
|
|
95
|
+
currencyCode: 'RON',
|
|
96
|
+
referenceCurrencyCode: 'RON',
|
|
97
|
+
netAmount: 100,
|
|
98
|
+
vatAmount: 19,
|
|
99
|
+
grossAmount: 119,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
externalId: 'invoice-2',
|
|
103
|
+
series: 'PDI',
|
|
104
|
+
number: 2,
|
|
105
|
+
documentDate: 20230424,
|
|
106
|
+
dueDate: 20230501,
|
|
107
|
+
status: 'valid',
|
|
108
|
+
clientName: 'Test Client 2',
|
|
109
|
+
partnerName: 'Test Partner 2',
|
|
110
|
+
currencyCode: 'EUR',
|
|
111
|
+
referenceCurrencyCode: 'RON',
|
|
112
|
+
netAmount: 200,
|
|
113
|
+
vatAmount: 38,
|
|
114
|
+
grossAmount: 238,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
};
|
|
118
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
119
|
+
.get('/api/v1.0/public-api/test-client-eid/invoices')
|
|
120
|
+
.reply(200, mockResponse);
|
|
121
|
+
const result = await (0, getAll_1.apiGetAllInvoices)({
|
|
122
|
+
baseDomain: STAGING_DOMAIN,
|
|
123
|
+
appId: 'test-app-id',
|
|
124
|
+
appClientId: 'test-client-eid',
|
|
125
|
+
bearerToken: 'test-token',
|
|
126
|
+
});
|
|
127
|
+
expect(result.recordsCount).toBe(2);
|
|
128
|
+
expect(result.data).toHaveLength(2);
|
|
129
|
+
expect(result.data[0].externalId).toBe('invoice-1');
|
|
130
|
+
expect(result.data[1].externalId).toBe('invoice-2');
|
|
131
|
+
});
|
|
132
|
+
test('should return empty array when no invoices exist', async () => {
|
|
133
|
+
const mockResponse = {
|
|
134
|
+
first: 0,
|
|
135
|
+
last: 0,
|
|
136
|
+
recordsCount: 0,
|
|
137
|
+
data: [],
|
|
138
|
+
};
|
|
139
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
140
|
+
.get('/api/v1.0/public-api/test-client-eid/invoices')
|
|
141
|
+
.reply(200, mockResponse);
|
|
142
|
+
const result = await (0, getAll_1.apiGetAllInvoices)({
|
|
143
|
+
baseDomain: STAGING_DOMAIN,
|
|
144
|
+
appId: 'test-app-id',
|
|
145
|
+
appClientId: 'test-client-eid',
|
|
146
|
+
bearerToken: 'test-token',
|
|
147
|
+
});
|
|
148
|
+
expect(result.recordsCount).toBe(0);
|
|
149
|
+
expect(result.data).toHaveLength(0);
|
|
150
|
+
});
|
|
151
|
+
test('should throw KeezApiError on failure', async () => {
|
|
152
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
153
|
+
.get('/api/v1.0/public-api/test-client-eid/invoices')
|
|
154
|
+
.reply(500, { error: 'Internal Server Error' });
|
|
155
|
+
await expect((0, getAll_1.apiGetAllInvoices)({
|
|
156
|
+
baseDomain: STAGING_DOMAIN,
|
|
157
|
+
appId: 'test-app-id',
|
|
158
|
+
appClientId: 'test-client-eid',
|
|
159
|
+
bearerToken: 'test-token',
|
|
160
|
+
})).rejects.toThrow(KeezError_1.KeezApiError);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('apiGetInvoiceByExternalId', () => {
|
|
164
|
+
afterEach(() => {
|
|
165
|
+
nock_1.default.cleanAll();
|
|
166
|
+
});
|
|
167
|
+
test('should get invoice by external ID successfully', async () => {
|
|
168
|
+
const mockResponse = {
|
|
169
|
+
currencyCode: 'RON',
|
|
170
|
+
discountGrossValue: 0,
|
|
171
|
+
discountNetValue: 0,
|
|
172
|
+
discountVatValue: 0,
|
|
173
|
+
discountValueOnNet: false,
|
|
174
|
+
exciseAmount: 0,
|
|
175
|
+
documentDate: 20230423,
|
|
176
|
+
dueDate: 20230430,
|
|
177
|
+
exchangeRate: 1,
|
|
178
|
+
grossAmount: 119,
|
|
179
|
+
netAmount: 100,
|
|
180
|
+
number: 1,
|
|
181
|
+
originalNetAmount: 100,
|
|
182
|
+
originalVatAmount: 19,
|
|
183
|
+
partner: {
|
|
184
|
+
addressDetails: 'Test Address',
|
|
185
|
+
cityName: 'Bucharest',
|
|
186
|
+
countryCode: 'RO',
|
|
187
|
+
countryName: 'Romania',
|
|
188
|
+
countyCode: 'RO.B',
|
|
189
|
+
countyName: 'Bucharest',
|
|
190
|
+
identificationNumber: '12345678',
|
|
191
|
+
isLegalPerson: false,
|
|
192
|
+
partnerName: 'Test Partner',
|
|
193
|
+
},
|
|
194
|
+
invoiceDetails: [
|
|
195
|
+
{
|
|
196
|
+
discountGrossValue: 0,
|
|
197
|
+
discountNetValue: 0,
|
|
198
|
+
discountVatValue: 0,
|
|
199
|
+
discountValueOnNet: false,
|
|
200
|
+
grossAmount: 119,
|
|
201
|
+
itemCode: 'ITEM-001',
|
|
202
|
+
itemDescription: 'Test Item',
|
|
203
|
+
itemExternalId: 'item-ext-1',
|
|
204
|
+
itemName: 'Test Item Name',
|
|
205
|
+
measureUnitId: 1,
|
|
206
|
+
netAmount: 100,
|
|
207
|
+
originalNetAmount: 100,
|
|
208
|
+
originalVatAmount: 19,
|
|
209
|
+
quantity: 1,
|
|
210
|
+
unMeasureUnit: 'buc',
|
|
211
|
+
unVatCategory: 'S',
|
|
212
|
+
unVatExemptionReason: '',
|
|
213
|
+
unitPrice: 100,
|
|
214
|
+
vatAmount: 19,
|
|
215
|
+
vatPercent: 19,
|
|
216
|
+
exciseAmount: 0,
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
paymentTypeId: 3,
|
|
220
|
+
referenceCurrencyCode: 'RON',
|
|
221
|
+
series: 'PDI',
|
|
222
|
+
status: 'draft',
|
|
223
|
+
vatAmount: 19,
|
|
224
|
+
vatOnCollection: false,
|
|
225
|
+
};
|
|
226
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
227
|
+
.get('/api/v1.0/public-api/test-client-eid/invoices/invoice-ext-1')
|
|
228
|
+
.reply(200, mockResponse);
|
|
229
|
+
const result = await (0, view_1.apiGetInvoiceByExternalId)({
|
|
230
|
+
baseDomain: STAGING_DOMAIN,
|
|
231
|
+
appId: 'test-app-id',
|
|
232
|
+
appClientId: 'test-client-eid',
|
|
233
|
+
bearerToken: 'test-token',
|
|
234
|
+
invoiceId: 'invoice-ext-1',
|
|
235
|
+
});
|
|
236
|
+
expect(result.grossAmount).toBe(119);
|
|
237
|
+
expect(result.partner.partnerName).toBe('Test Partner');
|
|
238
|
+
expect(result.items).toHaveLength(1);
|
|
239
|
+
expect(result.items[0].itemName).toBe('Test Item Name');
|
|
240
|
+
});
|
|
241
|
+
test('should throw KeezApiError when invoice not found', async () => {
|
|
242
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
243
|
+
.get('/api/v1.0/public-api/test-client-eid/invoices/non-existent')
|
|
244
|
+
.reply(404, { error: 'Invoice not found' });
|
|
245
|
+
await expect((0, view_1.apiGetInvoiceByExternalId)({
|
|
246
|
+
baseDomain: STAGING_DOMAIN,
|
|
247
|
+
appId: 'test-app-id',
|
|
248
|
+
appClientId: 'test-client-eid',
|
|
249
|
+
bearerToken: 'test-token',
|
|
250
|
+
invoiceId: 'non-existent',
|
|
251
|
+
})).rejects.toThrow(KeezError_1.KeezApiError);
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
describe('apiCreateInvoice', () => {
|
|
255
|
+
afterEach(() => {
|
|
256
|
+
nock_1.default.cleanAll();
|
|
257
|
+
});
|
|
258
|
+
test('should create invoice successfully', async () => {
|
|
259
|
+
const mockResponse = {
|
|
260
|
+
externalId: 'new-invoice-ext-id',
|
|
261
|
+
};
|
|
262
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
263
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices')
|
|
264
|
+
.reply(201, mockResponse);
|
|
265
|
+
const result = await (0, create_1.apiCreateInvoice)({
|
|
266
|
+
baseDomain: STAGING_DOMAIN,
|
|
267
|
+
appId: 'test-app-id',
|
|
268
|
+
appClientId: 'test-client-eid',
|
|
269
|
+
bearerToken: 'test-token',
|
|
270
|
+
invoice: {
|
|
271
|
+
series: 'PDI',
|
|
272
|
+
currencyCode: 'RON',
|
|
273
|
+
amount: 100,
|
|
274
|
+
paymentType: paymentType_1.PaymentType.BANK_TRANSFER,
|
|
275
|
+
partner: {
|
|
276
|
+
addressDetails: 'Test Address',
|
|
277
|
+
cityName: 'Bucharest',
|
|
278
|
+
countryCode: 'RO',
|
|
279
|
+
countryName: 'Romania',
|
|
280
|
+
countyCode: 'RO.B',
|
|
281
|
+
countyName: 'Bucharest',
|
|
282
|
+
identificationNumber: '12345678',
|
|
283
|
+
isLegalPerson: false,
|
|
284
|
+
partnerName: 'Test Partner',
|
|
285
|
+
},
|
|
286
|
+
itemId: 'item-ext-1',
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
expect(result).toBe('new-invoice-ext-id');
|
|
290
|
+
});
|
|
291
|
+
test('should create invoice with custom date and quantity', async () => {
|
|
292
|
+
const mockResponse = {
|
|
293
|
+
externalId: 'new-invoice-ext-id-2',
|
|
294
|
+
};
|
|
295
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
296
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices', (body) => body.documentDate === 20240115 && body.invoiceDetails[0].quantity === 5)
|
|
297
|
+
.reply(201, mockResponse);
|
|
298
|
+
const result = await (0, create_1.apiCreateInvoice)({
|
|
299
|
+
baseDomain: STAGING_DOMAIN,
|
|
300
|
+
appId: 'test-app-id',
|
|
301
|
+
appClientId: 'test-client-eid',
|
|
302
|
+
bearerToken: 'test-token',
|
|
303
|
+
invoice: {
|
|
304
|
+
series: 'PDI',
|
|
305
|
+
currencyCode: 'RON',
|
|
306
|
+
amount: 500,
|
|
307
|
+
paymentType: paymentType_1.PaymentType.CARD_ONLINE,
|
|
308
|
+
partner: {
|
|
309
|
+
addressDetails: 'Test Address',
|
|
310
|
+
cityName: 'Bucharest',
|
|
311
|
+
countryCode: 'RO',
|
|
312
|
+
countryName: 'Romania',
|
|
313
|
+
countyCode: 'RO.B',
|
|
314
|
+
countyName: 'Bucharest',
|
|
315
|
+
identificationNumber: '12345678',
|
|
316
|
+
isLegalPerson: false,
|
|
317
|
+
partnerName: 'Test Partner',
|
|
318
|
+
},
|
|
319
|
+
itemId: 'item-ext-1',
|
|
320
|
+
documentDate: 20240115,
|
|
321
|
+
dueDate: 20240130,
|
|
322
|
+
quantity: 5,
|
|
323
|
+
},
|
|
324
|
+
});
|
|
325
|
+
expect(result).toBe('new-invoice-ext-id-2');
|
|
326
|
+
});
|
|
327
|
+
test('should throw KeezApiError on validation error', async () => {
|
|
328
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
329
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices')
|
|
330
|
+
.reply(400, { Message: 'Validation failed' });
|
|
331
|
+
await expect((0, create_1.apiCreateInvoice)({
|
|
332
|
+
baseDomain: STAGING_DOMAIN,
|
|
333
|
+
appId: 'test-app-id',
|
|
334
|
+
appClientId: 'test-client-eid',
|
|
335
|
+
bearerToken: 'test-token',
|
|
336
|
+
invoice: {
|
|
337
|
+
series: 'PDI',
|
|
338
|
+
currencyCode: 'RON',
|
|
339
|
+
amount: -100,
|
|
340
|
+
paymentType: paymentType_1.PaymentType.BANK_TRANSFER,
|
|
341
|
+
partner: {
|
|
342
|
+
addressDetails: 'Test Address',
|
|
343
|
+
cityName: 'Bucharest',
|
|
344
|
+
countryCode: 'RO',
|
|
345
|
+
countryName: 'Romania',
|
|
346
|
+
countyCode: 'RO.B',
|
|
347
|
+
countyName: 'Bucharest',
|
|
348
|
+
identificationNumber: '',
|
|
349
|
+
isLegalPerson: false,
|
|
350
|
+
partnerName: '',
|
|
351
|
+
},
|
|
352
|
+
itemId: '',
|
|
353
|
+
},
|
|
354
|
+
})).rejects.toThrow(KeezError_1.KeezApiError);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
describe('apiSendInvoice', () => {
|
|
358
|
+
afterEach(() => {
|
|
359
|
+
nock_1.default.cleanAll();
|
|
360
|
+
});
|
|
361
|
+
test('should send invoice email successfully', async () => {
|
|
362
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
363
|
+
.post('/api/v1.0/public-api/invoices/delivery')
|
|
364
|
+
.reply(200);
|
|
365
|
+
const result = await (0, sendMail_1.apiSendInvoice)({
|
|
366
|
+
baseDomain: STAGING_DOMAIN,
|
|
367
|
+
appId: 'test-app-id',
|
|
368
|
+
bearerToken: 'test-token',
|
|
369
|
+
clientMail: 'test@example.com',
|
|
370
|
+
invoiceId: 'invoice-ext-1',
|
|
371
|
+
});
|
|
372
|
+
expect(result).toBe('SENT');
|
|
373
|
+
});
|
|
374
|
+
test('should throw KeezApiError on send failure', async () => {
|
|
375
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
376
|
+
.post('/api/v1.0/public-api/invoices/delivery')
|
|
377
|
+
.reply(500, { error: 'Email service unavailable' });
|
|
378
|
+
await expect((0, sendMail_1.apiSendInvoice)({
|
|
379
|
+
baseDomain: STAGING_DOMAIN,
|
|
380
|
+
appId: 'test-app-id',
|
|
381
|
+
bearerToken: 'test-token',
|
|
382
|
+
clientMail: 'test@example.com',
|
|
383
|
+
invoiceId: 'invoice-ext-1',
|
|
384
|
+
})).rejects.toThrow(KeezError_1.KeezApiError);
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
describe('apiValidateInvoice', () => {
|
|
388
|
+
afterEach(() => {
|
|
389
|
+
nock_1.default.cleanAll();
|
|
390
|
+
});
|
|
391
|
+
test('should validate invoice successfully', async () => {
|
|
392
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
393
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices/valid')
|
|
394
|
+
.reply(200);
|
|
395
|
+
const result = await (0, validate_1.apiValidateInvoice)({
|
|
396
|
+
baseDomain: STAGING_DOMAIN,
|
|
397
|
+
appId: 'test-app-id',
|
|
398
|
+
appClientId: 'test-client-eid',
|
|
399
|
+
bearerToken: 'test-token',
|
|
400
|
+
invoiceId: 'invoice-ext-1',
|
|
401
|
+
});
|
|
402
|
+
expect(result).toBe('VALIDATED');
|
|
403
|
+
});
|
|
404
|
+
test('should throw KeezApiError on validation failure', async () => {
|
|
405
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
406
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices/valid')
|
|
407
|
+
.reply(400, { Message: 'Invoice cannot be validated' });
|
|
408
|
+
await expect((0, validate_1.apiValidateInvoice)({
|
|
409
|
+
baseDomain: STAGING_DOMAIN,
|
|
410
|
+
appId: 'test-app-id',
|
|
411
|
+
appClientId: 'test-client-eid',
|
|
412
|
+
bearerToken: 'test-token',
|
|
413
|
+
invoiceId: 'invalid-invoice',
|
|
414
|
+
})).rejects.toThrow(KeezError_1.KeezApiError);
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
describe('KeezApi integration tests', () => {
|
|
418
|
+
let keezApi;
|
|
419
|
+
beforeEach(() => {
|
|
420
|
+
keezApi = new keezApi_1.KeezApi({
|
|
421
|
+
application_id: 'test-app-id',
|
|
422
|
+
client_eid: 'test-client-eid',
|
|
423
|
+
secret: 'test-secret',
|
|
424
|
+
live: false,
|
|
425
|
+
});
|
|
426
|
+
});
|
|
427
|
+
afterEach(() => {
|
|
428
|
+
nock_1.default.cleanAll();
|
|
429
|
+
});
|
|
430
|
+
test('should auto-refresh token when expired', async () => {
|
|
431
|
+
// Mock token generation
|
|
432
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
433
|
+
.post('/idp/connect/token')
|
|
434
|
+
.reply(200, {
|
|
435
|
+
access_token: 'fresh-token',
|
|
436
|
+
expires_in: 3600,
|
|
437
|
+
token_type: 'Bearer',
|
|
438
|
+
scope: 'public-api',
|
|
439
|
+
});
|
|
440
|
+
// Mock get all invoices
|
|
441
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
442
|
+
.get('/api/v1.0/public-api/test-client-eid/invoices')
|
|
443
|
+
.reply(200, {
|
|
444
|
+
first: 0,
|
|
445
|
+
last: 0,
|
|
446
|
+
recordsCount: 0,
|
|
447
|
+
data: [],
|
|
448
|
+
});
|
|
449
|
+
const result = await keezApi.getAllInvoices();
|
|
450
|
+
expect(result.recordsCount).toBe(0);
|
|
451
|
+
});
|
|
452
|
+
test('should create and validate invoice flow', async () => {
|
|
453
|
+
// Mock token generation
|
|
454
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
455
|
+
.post('/idp/connect/token')
|
|
456
|
+
.reply(200, {
|
|
457
|
+
access_token: 'test-token',
|
|
458
|
+
expires_in: 3600,
|
|
459
|
+
token_type: 'Bearer',
|
|
460
|
+
scope: 'public-api',
|
|
461
|
+
});
|
|
462
|
+
// Mock create invoice
|
|
463
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
464
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices')
|
|
465
|
+
.reply(201, { externalId: 'created-invoice-id' });
|
|
466
|
+
const invoiceId = await keezApi.createInvoice({
|
|
467
|
+
series: 'PDI',
|
|
468
|
+
currencyCode: 'RON',
|
|
469
|
+
amount: 100,
|
|
470
|
+
paymentType: paymentType_1.PaymentType.MEAL_VOUCHER,
|
|
471
|
+
partner: {
|
|
472
|
+
addressDetails: 'Test Address',
|
|
473
|
+
cityName: 'Bucharest',
|
|
474
|
+
countryCode: 'RO',
|
|
475
|
+
countryName: 'Romania',
|
|
476
|
+
countyCode: 'RO.B',
|
|
477
|
+
countyName: 'Bucharest',
|
|
478
|
+
identificationNumber: '12345678',
|
|
479
|
+
isLegalPerson: false,
|
|
480
|
+
partnerName: 'Test Partner',
|
|
481
|
+
},
|
|
482
|
+
itemId: 'item-ext-1',
|
|
483
|
+
});
|
|
484
|
+
expect(invoiceId).toBe('created-invoice-id');
|
|
485
|
+
// Mock validate invoice (reuse token)
|
|
486
|
+
(0, nock_1.default)(STAGING_DOMAIN)
|
|
487
|
+
.post('/api/v1.0/public-api/test-client-eid/invoices/valid')
|
|
488
|
+
.reply(200);
|
|
489
|
+
const validateResult = await keezApi.validateInvoice('created-invoice-id');
|
|
490
|
+
expect(validateResult).toBe('VALIDATED');
|
|
491
|
+
});
|
|
492
|
+
});
|
|
493
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3Rlc3RzL2luZGV4LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsdUNBQW9DO0FBQ3BDLCtDQUFtRDtBQUNuRCxrREFBMEQ7QUFDMUQsOENBQWdFO0FBQ2hFLGtEQUF5RDtBQUN6RCxzREFBeUQ7QUFDekQsc0RBQTZEO0FBQzdELHNEQUFtRDtBQUNuRCxrREFBaUU7QUFFakUsTUFBTSxjQUFjLEdBQUcseUJBQXlCLENBQUM7QUFDakQsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUM7QUFFMUMsUUFBUSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7SUFDM0IsSUFBSSxPQUFnQixDQUFDO0lBRXJCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxPQUFPLEdBQUcsSUFBSSxpQkFBTyxDQUFDO1lBQ2xCLGNBQWMsRUFBRSxhQUFhO1lBQzdCLFVBQVUsRUFBRSxpQkFBaUI7WUFDN0IsTUFBTSxFQUFFLGFBQWE7WUFDckIsSUFBSSxFQUFFLElBQUk7U0FDYixDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztJQUVILFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsa0RBQWtELEVBQUUsR0FBRyxFQUFFO1FBQzFELE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN0RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzREFBc0QsRUFBRSxHQUFHLEVBQUU7UUFDOUQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixNQUFNLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO0lBQzlCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbEQsTUFBTSxZQUFZLEdBQUc7WUFDakIsWUFBWSxFQUFFLG1CQUFtQjtZQUNqQyxVQUFVLEVBQUUsSUFBSTtZQUNoQixVQUFVLEVBQUUsUUFBUTtZQUNwQixLQUFLLEVBQUUsWUFBWTtTQUN0QixDQUFDO1FBRUYsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLG9CQUFvQixDQUFDO2FBQzFCLEtBQUssQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLDRCQUFnQixFQUFDO1lBQ2xDLFVBQVUsRUFBRSxjQUFjO1lBQzFCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFNBQVMsRUFBRSxhQUFhO1NBQzNCLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsc0RBQXNELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEUsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLG9CQUFvQixDQUFDO2FBQzFCLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBRTdDLE1BQU0sTUFBTSxDQUFDLElBQUEsNEJBQWdCLEVBQUM7WUFDMUIsVUFBVSxFQUFFLGNBQWM7WUFDMUIsS0FBSyxFQUFFLGFBQWE7WUFDcEIsU0FBUyxFQUFFLGNBQWM7U0FDNUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyx5QkFBYSxDQUFDLENBQUM7SUFDdkMsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDLENBQUMsQ0FBQztBQUVILFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLEVBQUU7SUFDL0IsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNYLGNBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNwQixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNwRCxNQUFNLFlBQVksR0FBRztZQUNqQixLQUFLLEVBQUUsQ0FBQztZQUNSLElBQUksRUFBRSxDQUFDO1lBQ1AsWUFBWSxFQUFFLENBQUM7WUFDZixJQUFJLEVBQUU7Z0JBQ0Y7b0JBQ0ksVUFBVSxFQUFFLFdBQVc7b0JBQ3ZCLE1BQU0sRUFBRSxLQUFLO29CQUNiLE1BQU0sRUFBRSxDQUFDO29CQUNULFlBQVksRUFBRSxRQUFRO29CQUN0QixPQUFPLEVBQUUsUUFBUTtvQkFDakIsTUFBTSxFQUFFLE9BQU87b0JBQ2YsVUFBVSxFQUFFLGFBQWE7b0JBQ3pCLFdBQVcsRUFBRSxjQUFjO29CQUMzQixZQUFZLEVBQUUsS0FBSztvQkFDbkIscUJBQXFCLEVBQUUsS0FBSztvQkFDNUIsU0FBUyxFQUFFLEdBQUc7b0JBQ2QsU0FBUyxFQUFFLEVBQUU7b0JBQ2IsV0FBVyxFQUFFLEdBQUc7aUJBQ25CO2dCQUNEO29CQUNJLFVBQVUsRUFBRSxXQUFXO29CQUN2QixNQUFNLEVBQUUsS0FBSztvQkFDYixNQUFNLEVBQUUsQ0FBQztvQkFDVCxZQUFZLEVBQUUsUUFBUTtvQkFDdEIsT0FBTyxFQUFFLFFBQVE7b0JBQ2pCLE1BQU0sRUFBRSxPQUFPO29CQUNmLFVBQVUsRUFBRSxlQUFlO29CQUMzQixXQUFXLEVBQUUsZ0JBQWdCO29CQUM3QixZQUFZLEVBQUUsS0FBSztvQkFDbkIscUJBQXFCLEVBQUUsS0FBSztvQkFDNUIsU0FBUyxFQUFFLEdBQUc7b0JBQ2QsU0FBUyxFQUFFLEVBQUU7b0JBQ2IsV0FBVyxFQUFFLEdBQUc7aUJBQ25CO2FBQ0o7U0FDSixDQUFDO1FBRUYsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsR0FBRyxDQUFDLCtDQUErQyxDQUFDO2FBQ3BELEtBQUssQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLDBCQUFpQixFQUFDO1lBQ25DLFVBQVUsRUFBRSxjQUFjO1lBQzFCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsV0FBVyxFQUFFLFlBQVk7U0FDNUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN4RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxrREFBa0QsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoRSxNQUFNLFlBQVksR0FBRztZQUNqQixLQUFLLEVBQUUsQ0FBQztZQUNSLElBQUksRUFBRSxDQUFDO1lBQ1AsWUFBWSxFQUFFLENBQUM7WUFDZixJQUFJLEVBQUUsRUFBRTtTQUNYLENBQUM7UUFFRixJQUFBLGNBQUksRUFBQyxjQUFjLENBQUM7YUFDZixHQUFHLENBQUMsK0NBQStDLENBQUM7YUFDcEQsS0FBSyxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUU5QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsMEJBQWlCLEVBQUM7WUFDbkMsVUFBVSxFQUFFLGNBQWM7WUFDMUIsS0FBSyxFQUFFLGFBQWE7WUFDcEIsV0FBVyxFQUFFLGlCQUFpQjtZQUM5QixXQUFXLEVBQUUsWUFBWTtTQUM1QixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4QyxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNwRCxJQUFBLGNBQUksRUFBQyxjQUFjLENBQUM7YUFDZixHQUFHLENBQUMsK0NBQStDLENBQUM7YUFDcEQsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSx1QkFBdUIsRUFBRSxDQUFDLENBQUM7UUFFcEQsTUFBTSxNQUFNLENBQUMsSUFBQSwwQkFBaUIsRUFBQztZQUMzQixVQUFVLEVBQUUsY0FBYztZQUMxQixLQUFLLEVBQUUsYUFBYTtZQUNwQixXQUFXLEVBQUUsaUJBQWlCO1lBQzlCLFdBQVcsRUFBRSxZQUFZO1NBQzVCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsd0JBQVksQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO0lBQ3ZDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsZ0RBQWdELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDOUQsTUFBTSxZQUFZLEdBQUc7WUFDakIsWUFBWSxFQUFFLEtBQUs7WUFDbkIsa0JBQWtCLEVBQUUsQ0FBQztZQUNyQixnQkFBZ0IsRUFBRSxDQUFDO1lBQ25CLGdCQUFnQixFQUFFLENBQUM7WUFDbkIsa0JBQWtCLEVBQUUsS0FBSztZQUN6QixZQUFZLEVBQUUsQ0FBQztZQUNmLFlBQVksRUFBRSxRQUFRO1lBQ3RCLE9BQU8sRUFBRSxRQUFRO1lBQ2pCLFlBQVksRUFBRSxDQUFDO1lBQ2YsV0FBVyxFQUFFLEdBQUc7WUFDaEIsU0FBUyxFQUFFLEdBQUc7WUFDZCxNQUFNLEVBQUUsQ0FBQztZQUNULGlCQUFpQixFQUFFLEdBQUc7WUFDdEIsaUJBQWlCLEVBQUUsRUFBRTtZQUNyQixPQUFPLEVBQUU7Z0JBQ0wsY0FBYyxFQUFFLGNBQWM7Z0JBQzlCLFFBQVEsRUFBRSxXQUFXO2dCQUNyQixXQUFXLEVBQUUsSUFBSTtnQkFDakIsV0FBVyxFQUFFLFNBQVM7Z0JBQ3RCLFVBQVUsRUFBRSxNQUFNO2dCQUNsQixVQUFVLEVBQUUsV0FBVztnQkFDdkIsb0JBQW9CLEVBQUUsVUFBVTtnQkFDaEMsYUFBYSxFQUFFLEtBQUs7Z0JBQ3BCLFdBQVcsRUFBRSxjQUFjO2FBQzlCO1lBQ0QsY0FBYyxFQUFFO2dCQUNaO29CQUNJLGtCQUFrQixFQUFFLENBQUM7b0JBQ3JCLGdCQUFnQixFQUFFLENBQUM7b0JBQ25CLGdCQUFnQixFQUFFLENBQUM7b0JBQ25CLGtCQUFrQixFQUFFLEtBQUs7b0JBQ3pCLFdBQVcsRUFBRSxHQUFHO29CQUNoQixRQUFRLEVBQUUsVUFBVTtvQkFDcEIsZUFBZSxFQUFFLFdBQVc7b0JBQzVCLGNBQWMsRUFBRSxZQUFZO29CQUM1QixRQUFRLEVBQUUsZ0JBQWdCO29CQUMxQixhQUFhLEVBQUUsQ0FBQztvQkFDaEIsU0FBUyxFQUFFLEdBQUc7b0JBQ2QsaUJBQWlCLEVBQUUsR0FBRztvQkFDdEIsaUJBQWlCLEVBQUUsRUFBRTtvQkFDckIsUUFBUSxFQUFFLENBQUM7b0JBQ1gsYUFBYSxFQUFFLEtBQUs7b0JBQ3BCLGFBQWEsRUFBRSxHQUFHO29CQUNsQixvQkFBb0IsRUFBRSxFQUFFO29CQUN4QixTQUFTLEVBQUUsR0FBRztvQkFDZCxTQUFTLEVBQUUsRUFBRTtvQkFDYixVQUFVLEVBQUUsRUFBRTtvQkFDZCxZQUFZLEVBQUUsQ0FBQztpQkFDbEI7YUFDSjtZQUNELGFBQWEsRUFBRSxDQUFDO1lBQ2hCLHFCQUFxQixFQUFFLEtBQUs7WUFDNUIsTUFBTSxFQUFFLEtBQUs7WUFDYixNQUFNLEVBQUUsT0FBTztZQUNmLFNBQVMsRUFBRSxFQUFFO1lBQ2IsZUFBZSxFQUFFLEtBQUs7U0FDekIsQ0FBQztRQUVGLElBQUEsY0FBSSxFQUFDLGNBQWMsQ0FBQzthQUNmLEdBQUcsQ0FBQyw2REFBNkQsQ0FBQzthQUNsRSxLQUFLLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRTlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxnQ0FBeUIsRUFBQztZQUMzQyxVQUFVLEVBQUUsY0FBYztZQUMxQixLQUFLLEVBQUUsYUFBYTtZQUNwQixXQUFXLEVBQUUsaUJBQWlCO1lBQzlCLFdBQVcsRUFBRSxZQUFZO1lBQ3pCLFNBQVMsRUFBRSxlQUFlO1NBQzdCLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN4RCxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM1RCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxrREFBa0QsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoRSxJQUFBLGNBQUksRUFBQyxjQUFjLENBQUM7YUFDZixHQUFHLENBQUMsNERBQTRELENBQUM7YUFDakUsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7UUFFaEQsTUFBTSxNQUFNLENBQUMsSUFBQSxnQ0FBeUIsRUFBQztZQUNuQyxVQUFVLEVBQUUsY0FBYztZQUMxQixLQUFLLEVBQUUsYUFBYTtZQUNwQixXQUFXLEVBQUUsaUJBQWlCO1lBQzlCLFdBQVcsRUFBRSxZQUFZO1lBQ3pCLFNBQVMsRUFBRSxjQUFjO1NBQzVCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsd0JBQVksQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO0lBQzlCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbEQsTUFBTSxZQUFZLEdBQUc7WUFDakIsVUFBVSxFQUFFLG9CQUFvQjtTQUNuQyxDQUFDO1FBRUYsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLCtDQUErQyxDQUFDO2FBQ3JELEtBQUssQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFFOUIsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLHlCQUFnQixFQUFDO1lBQ2xDLFVBQVUsRUFBRSxjQUFjO1lBQzFCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsV0FBVyxFQUFFLFlBQVk7WUFDekIsT0FBTyxFQUFFO2dCQUNMLE1BQU0sRUFBRSxLQUFLO2dCQUNiLFlBQVksRUFBRSxLQUFLO2dCQUNuQixNQUFNLEVBQUUsR0FBRztnQkFDWCxXQUFXLEVBQUUseUJBQVcsQ0FBQyxhQUFhO2dCQUN0QyxPQUFPLEVBQUU7b0JBQ0wsY0FBYyxFQUFFLGNBQWM7b0JBQzlCLFFBQVEsRUFBRSxXQUFXO29CQUNyQixXQUFXLEVBQUUsSUFBSTtvQkFDakIsV0FBVyxFQUFFLFNBQVM7b0JBQ3RCLFVBQVUsRUFBRSxNQUFNO29CQUNsQixVQUFVLEVBQUUsV0FBVztvQkFDdkIsb0JBQW9CLEVBQUUsVUFBVTtvQkFDaEMsYUFBYSxFQUFFLEtBQUs7b0JBQ3BCLFdBQVcsRUFBRSxjQUFjO2lCQUM5QjtnQkFDRCxNQUFNLEVBQUUsWUFBWTthQUN2QjtTQUNKLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxxREFBcUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNuRSxNQUFNLFlBQVksR0FBRztZQUNqQixVQUFVLEVBQUUsc0JBQXNCO1NBQ3JDLENBQUM7UUFFRixJQUFBLGNBQUksRUFBQyxjQUFjLENBQUM7YUFDZixJQUFJLENBQUMsK0NBQStDLEVBQUUsQ0FBQyxJQUFzRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUM7YUFDMU0sS0FBSyxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUU5QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEseUJBQWdCLEVBQUM7WUFDbEMsVUFBVSxFQUFFLGNBQWM7WUFDMUIsS0FBSyxFQUFFLGFBQWE7WUFDcEIsV0FBVyxFQUFFLGlCQUFpQjtZQUM5QixXQUFXLEVBQUUsWUFBWTtZQUN6QixPQUFPLEVBQUU7Z0JBQ0wsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE1BQU0sRUFBRSxHQUFHO2dCQUNYLFdBQVcsRUFBRSx5QkFBVyxDQUFDLFdBQVc7Z0JBQ3BDLE9BQU8sRUFBRTtvQkFDTCxjQUFjLEVBQUUsY0FBYztvQkFDOUIsUUFBUSxFQUFFLFdBQVc7b0JBQ3JCLFdBQVcsRUFBRSxJQUFJO29CQUNqQixXQUFXLEVBQUUsU0FBUztvQkFDdEIsVUFBVSxFQUFFLE1BQU07b0JBQ2xCLFVBQVUsRUFBRSxXQUFXO29CQUN2QixvQkFBb0IsRUFBRSxVQUFVO29CQUNoQyxhQUFhLEVBQUUsS0FBSztvQkFDcEIsV0FBVyxFQUFFLGNBQWM7aUJBQzlCO2dCQUNELE1BQU0sRUFBRSxZQUFZO2dCQUNwQixZQUFZLEVBQUUsUUFBUTtnQkFDdEIsT0FBTyxFQUFFLFFBQVE7Z0JBQ2pCLFFBQVEsRUFBRSxDQUFDO2FBQ2Q7U0FDSixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDaEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsK0NBQStDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0QsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLCtDQUErQyxDQUFDO2FBQ3JELEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQyxDQUFDO1FBRWxELE1BQU0sTUFBTSxDQUFDLElBQUEseUJBQWdCLEVBQUM7WUFDMUIsVUFBVSxFQUFFLGNBQWM7WUFDMUIsS0FBSyxFQUFFLGFBQWE7WUFDcEIsV0FBVyxFQUFFLGlCQUFpQjtZQUM5QixXQUFXLEVBQUUsWUFBWTtZQUN6QixPQUFPLEVBQUU7Z0JBQ0wsTUFBTSxFQUFFLEtBQUs7Z0JBQ2IsWUFBWSxFQUFFLEtBQUs7Z0JBQ25CLE1BQU0sRUFBRSxDQUFDLEdBQUc7Z0JBQ1osV0FBVyxFQUFFLHlCQUFXLENBQUMsYUFBYTtnQkFDdEMsT0FBTyxFQUFFO29CQUNMLGNBQWMsRUFBRSxjQUFjO29CQUM5QixRQUFRLEVBQUUsV0FBVztvQkFDckIsV0FBVyxFQUFFLElBQUk7b0JBQ2pCLFdBQVcsRUFBRSxTQUFTO29CQUN0QixVQUFVLEVBQUUsTUFBTTtvQkFDbEIsVUFBVSxFQUFFLFdBQVc7b0JBQ3ZCLG9CQUFvQixFQUFFLEVBQUU7b0JBQ3hCLGFBQWEsRUFBRSxLQUFLO29CQUNwQixXQUFXLEVBQUUsRUFBRTtpQkFDbEI7Z0JBQ0QsTUFBTSxFQUFFLEVBQUU7YUFDYjtTQUNKLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsd0JBQVksQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO0lBQzVCLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsd0NBQXdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdEQsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLHdDQUF3QyxDQUFDO2FBQzlDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVoQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEseUJBQWMsRUFBQztZQUNoQyxVQUFVLEVBQUUsY0FBYztZQUMxQixLQUFLLEVBQUUsYUFBYTtZQUNwQixXQUFXLEVBQUUsWUFBWTtZQUN6QixVQUFVLEVBQUUsa0JBQWtCO1lBQzlCLFNBQVMsRUFBRSxlQUFlO1NBQzdCLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsMkNBQTJDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDekQsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLHdDQUF3QyxDQUFDO2FBQzlDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsMkJBQTJCLEVBQUUsQ0FBQyxDQUFDO1FBRXhELE1BQU0sTUFBTSxDQUFDLElBQUEseUJBQWMsRUFBQztZQUN4QixVQUFVLEVBQUUsY0FBYztZQUMxQixLQUFLLEVBQUUsYUFBYTtZQUNwQixXQUFXLEVBQUUsWUFBWTtZQUN6QixVQUFVLEVBQUUsa0JBQWtCO1lBQzlCLFNBQVMsRUFBRSxlQUFlO1NBQzdCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsd0JBQVksQ0FBQyxDQUFDO0lBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsb0JBQW9CLEVBQUUsR0FBRyxFQUFFO0lBQ2hDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7UUFDWCxjQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsc0NBQXNDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEQsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLHFEQUFxRCxDQUFDO2FBQzNELEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVoQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsNkJBQWtCLEVBQUM7WUFDcEMsVUFBVSxFQUFFLGNBQWM7WUFDMUIsS0FBSyxFQUFFLGFBQWE7WUFDcEIsV0FBVyxFQUFFLGlCQUFpQjtZQUM5QixXQUFXLEVBQUUsWUFBWTtZQUN6QixTQUFTLEVBQUUsZUFBZTtTQUM3QixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLGlEQUFpRCxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9ELElBQUEsY0FBSSxFQUFDLGNBQWMsQ0FBQzthQUNmLElBQUksQ0FBQyxxREFBcUQsQ0FBQzthQUMzRCxLQUFLLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLENBQUMsQ0FBQztRQUU1RCxNQUFNLE1BQU0sQ0FBQyxJQUFBLDZCQUFrQixFQUFDO1lBQzVCLFVBQVUsRUFBRSxjQUFjO1lBQzFCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFdBQVcsRUFBRSxpQkFBaUI7WUFDOUIsV0FBVyxFQUFFLFlBQVk7WUFDekIsU0FBUyxFQUFFLGlCQUFpQjtTQUMvQixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLHdCQUFZLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtJQUN2QyxJQUFJLE9BQWdCLENBQUM7SUFFckIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNaLE9BQU8sR0FBRyxJQUFJLGlCQUFPLENBQUM7WUFDbEIsY0FBYyxFQUFFLGFBQWE7WUFDN0IsVUFBVSxFQUFFLGlCQUFpQjtZQUM3QixNQUFNLEVBQUUsYUFBYTtZQUNyQixJQUFJLEVBQUUsS0FBSztTQUNkLENBQUMsQ0FBQztJQUNQLENBQUMsQ0FBQyxDQUFDO0lBRUgsU0FBUyxDQUFDLEdBQUcsRUFBRTtRQUNYLGNBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNwQixDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx3Q0FBd0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN0RCx3QkFBd0I7UUFDeEIsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsSUFBSSxDQUFDLG9CQUFvQixDQUFDO2FBQzFCLEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDUixZQUFZLEVBQUUsYUFBYTtZQUMzQixVQUFVLEVBQUUsSUFBSTtZQUNoQixVQUFVLEVBQUUsUUFBUTtZQUNwQixLQUFLLEVBQUUsWUFBWTtTQUN0QixDQUFDLENBQUM7UUFFUCx3QkFBd0I7UUFDeEIsSUFBQSxjQUFJLEVBQUMsY0FBYyxDQUFDO2FBQ2YsR0FBRyxDQUFDLCtDQUErQyxDQUFDO2FBQ3BELEtBQUssQ0FBQyxHQUFHLEVBQUU7WUFDUixLQUFLLEVBQUUsQ0FBQztZQUNSLElBQUksRUFBRSxDQUFDO1lBQ1AsWUFBWSxFQUFFLENBQUM7WUFDZixJQUFJLEVBQUUsRUFBRTtTQUNYLENBQUMsQ0FBQztRQUVQLE1BQU0sTUFBTSxHQUFHLE1BQU0sT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzlDLE1BQU0sQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHlDQUF5QyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZELHdCQUF3QjtRQUN4QixJQUFBLGNBQUksRUFBQyxjQUFjLENBQUM7YUFDZixJQUFJLENBQUMsb0JBQW9CLENBQUM7YUFDMUIsS0FBSyxDQUFDLEdBQUcsRUFBRTtZQUNSLFlBQVksRUFBRSxZQUFZO1lBQzFCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLFVBQVUsRUFBRSxRQUFRO1lBQ3BCLEtBQUssRUFBRSxZQUFZO1NBQ3RCLENBQUMsQ0FBQztRQUVQLHNCQUFzQjtRQUN0QixJQUFBLGNBQUksRUFBQyxjQUFjLENBQUM7YUFDZixJQUFJLENBQUMsK0NBQStDLENBQUM7YUFDckQsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSxDQUFDLENBQUM7UUFFdEQsTUFBTSxTQUFTLEdBQUcsTUFBTSxPQUFPLENBQUMsYUFBYSxDQUFDO1lBQzFDLE1BQU0sRUFBRSxLQUFLO1lBQ2IsWUFBWSxFQUFFLEtBQUs7WUFDbkIsTUFBTSxFQUFFLEdBQUc7WUFDWCxXQUFXLEVBQUUseUJBQVcsQ0FBQyxZQUFZO1lBQ3JDLE9BQU8sRUFBRTtnQkFDTCxjQUFjLEVBQUUsY0FBYztnQkFDOUIsUUFBUSxFQUFFLFdBQVc7Z0JBQ3JCLFdBQVcsRUFBRSxJQUFJO2dCQUNqQixXQUFXLEVBQUUsU0FBUztnQkFDdEIsVUFBVSxFQUFFLE1BQU07Z0JBQ2xCLFVBQVUsRUFBRSxXQUFXO2dCQUN2QixvQkFBb0IsRUFBRSxVQUFVO2dCQUNoQyxhQUFhLEVBQUUsS0FBSztnQkFDcEIsV0FBVyxFQUFFLGNBQWM7YUFDOUI7WUFDRCxNQUFNLEVBQUUsWUFBWTtTQUN2QixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFFN0Msc0NBQXNDO1FBQ3RDLElBQUEsY0FBSSxFQUFDLGNBQWMsQ0FBQzthQUNmLElBQUksQ0FBQyxxREFBcUQsQ0FBQzthQUMzRCxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFaEIsTUFBTSxjQUFjLEdBQUcsTUFBTSxPQUFPLENBQUMsZUFBZSxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDM0UsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUM3QyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG5vY2sgZnJvbSAnbm9jayc7XG5pbXBvcnQgeyBLZWV6QXBpIH0gZnJvbSAnQC9rZWV6QXBpJztcbmltcG9ydCB7IGFwaUdlbmVyYXRlVG9rZW4gfSBmcm9tICdAL2FwaS9hdXRob3Jpc2UnO1xuaW1wb3J0IHsgYXBpR2V0QWxsSW52b2ljZXMgfSBmcm9tICdAL2FwaS9pbnZvaWNlcy9nZXRBbGwnO1xuaW1wb3J0IHsgYXBpR2V0SW52b2ljZUJ5RXh0ZXJuYWxJZCB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL3ZpZXcnO1xuaW1wb3J0IHsgYXBpQ3JlYXRlSW52b2ljZSB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL2NyZWF0ZSc7XG5pbXBvcnQgeyBhcGlTZW5kSW52b2ljZSB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL3NlbmRNYWlsJztcbmltcG9ydCB7IGFwaVZhbGlkYXRlSW52b2ljZSB9IGZyb20gJ0AvYXBpL2ludm9pY2VzL3ZhbGlkYXRlJztcbmltcG9ydCB7IFBheW1lbnRUeXBlIH0gZnJvbSAnQC9jb25maWcvcGF5bWVudFR5cGUnO1xuaW1wb3J0IHsgS2VlekF1dGhFcnJvciwgS2VlekFwaUVycm9yIH0gZnJvbSAnQC9lcnJvcnMvS2VlekVycm9yJztcblxuY29uc3QgU1RBR0lOR19ET01BSU4gPSAnaHR0cHM6Ly9zdGFnaW5nLmtlZXoucm8nO1xuY29uc3QgTElWRV9ET01BSU4gPSAnaHR0cHM6Ly9hcHAua2Vlei5ybyc7XG5cbmRlc2NyaWJlKCdLZWV6QXBpIGNsYXNzJywgKCkgPT4ge1xuICAgIGxldCBrZWV6QXBpOiBLZWV6QXBpO1xuXG4gICAgYmVmb3JlQWxsKCgpID0+IHtcbiAgICAgICAga2VlekFwaSA9IG5ldyBLZWV6QXBpKHtcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uX2lkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgY2xpZW50X2VpZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBzZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgICAgICBsaXZlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCByZXR1cm4gbGl2ZSBkb21haW4gd2hlbiBsaXZlIG1vZGUgaXMgdHJ1ZScsICgpID0+IHtcbiAgICAgICAga2VlekFwaS5zZXRMaXZlKHRydWUpO1xuICAgICAgICBleHBlY3Qoa2VlekFwaS5nZXRCYXNlRG9tYWluKCkpLnRvQmUoTElWRV9ET01BSU4pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHJldHVybiBzdGFnaW5nIGRvbWFpbiB3aGVuIGxpdmUgbW9kZSBpcyBmYWxzZScsICgpID0+IHtcbiAgICAgICAga2VlekFwaS5zZXRMaXZlKGZhbHNlKTtcbiAgICAgICAgZXhwZWN0KGtlZXpBcGkuZ2V0QmFzZURvbWFpbigpKS50b0JlKFNUQUdJTkdfRE9NQUlOKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXBpR2VuZXJhdGVUb2tlbicsICgpID0+IHtcbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgZ2VuZXJhdGUgdG9rZW4gc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2NrUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd0ZXN0LWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgICBleHBpcmVzX2luOiAzNjAwLFxuICAgICAgICAgICAgdG9rZW5fdHlwZTogJ0JlYXJlcicsXG4gICAgICAgICAgICBzY29wZTogJ3B1YmxpYy1hcGknLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2lkcC9jb25uZWN0L3Rva2VuJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpR2VuZXJhdGVUb2tlbih7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBpU2VjcmV0OiAndGVzdC1zZWNyZXQnLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0LmFjY2Vzc190b2tlbikudG9CZSgndGVzdC1hY2Nlc3MtdG9rZW4nKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5leHBpcmVzX2luKS50b0JlKDM2MDApO1xuICAgICAgICBleHBlY3QocmVzdWx0LnRva2VuX3R5cGUpLnRvQmUoJ0JlYXJlcicpO1xuICAgICAgICBleHBlY3QocmVzdWx0LnNjb3BlKS50b0JlKCdwdWJsaWMtYXBpJyk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQuZXhwaXJlc19hdCkudG9CZUdyZWF0ZXJUaGFuKERhdGUubm93KCkpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBdXRoRXJyb3Igb24gYXV0aGVudGljYXRpb24gZmFpbHVyZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgbm9jayhTVEFHSU5HX0RPTUFJTilcbiAgICAgICAgICAgIC5wb3N0KCcvaWRwL2Nvbm5lY3QvdG9rZW4nKVxuICAgICAgICAgICAgLnJlcGx5KDQwMSwgeyBlcnJvcjogJ2ludmFsaWRfY2xpZW50JyB9KTtcblxuICAgICAgICBhd2FpdCBleHBlY3QoYXBpR2VuZXJhdGVUb2tlbih7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBpU2VjcmV0OiAnd3Jvbmctc2VjcmV0JyxcbiAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdyhLZWV6QXV0aEVycm9yKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXBpR2V0QWxsSW52b2ljZXMnLCAoKSA9PiB7XG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIGdldCBhbGwgaW52b2ljZXMgc3VjY2Vzc2Z1bGx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBtb2NrUmVzcG9uc2UgPSB7XG4gICAgICAgICAgICBmaXJzdDogMCxcbiAgICAgICAgICAgIGxhc3Q6IDEsXG4gICAgICAgICAgICByZWNvcmRzQ291bnQ6IDIsXG4gICAgICAgICAgICBkYXRhOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBleHRlcm5hbElkOiAnaW52b2ljZS0xJyxcbiAgICAgICAgICAgICAgICAgICAgc2VyaWVzOiAnUERJJyxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyOiAxLFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudERhdGU6IDIwMjMwNDIzLFxuICAgICAgICAgICAgICAgICAgICBkdWVEYXRlOiAyMDIzMDQzMCxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnZHJhZnQnLFxuICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lOiAnVGVzdCBDbGllbnQnLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0bmVyTmFtZTogJ1Rlc3QgUGFydG5lcicsXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZUN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgICAgIG5ldEFtb3VudDogMTAwLFxuICAgICAgICAgICAgICAgICAgICB2YXRBbW91bnQ6IDE5LFxuICAgICAgICAgICAgICAgICAgICBncm9zc0Ftb3VudDogMTE5LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBleHRlcm5hbElkOiAnaW52b2ljZS0yJyxcbiAgICAgICAgICAgICAgICAgICAgc2VyaWVzOiAnUERJJyxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyOiAyLFxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudERhdGU6IDIwMjMwNDI0LFxuICAgICAgICAgICAgICAgICAgICBkdWVEYXRlOiAyMDIzMDUwMSxcbiAgICAgICAgICAgICAgICAgICAgc3RhdHVzOiAndmFsaWQnLFxuICAgICAgICAgICAgICAgICAgICBjbGllbnROYW1lOiAnVGVzdCBDbGllbnQgMicsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRuZXJOYW1lOiAnVGVzdCBQYXJ0bmVyIDInLFxuICAgICAgICAgICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdFVVInLFxuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VDdXJyZW5jeUNvZGU6ICdST04nLFxuICAgICAgICAgICAgICAgICAgICBuZXRBbW91bnQ6IDIwMCxcbiAgICAgICAgICAgICAgICAgICAgdmF0QW1vdW50OiAzOCxcbiAgICAgICAgICAgICAgICAgICAgZ3Jvc3NBbW91bnQ6IDIzOCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpR2V0QWxsSW52b2ljZXMoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGFwcENsaWVudElkOiAndGVzdC1jbGllbnQtZWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQucmVjb3Jkc0NvdW50KS50b0JlKDIpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmRhdGEpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5kYXRhWzBdLmV4dGVybmFsSWQpLnRvQmUoJ2ludm9pY2UtMScpO1xuICAgICAgICBleHBlY3QocmVzdWx0LmRhdGFbMV0uZXh0ZXJuYWxJZCkudG9CZSgnaW52b2ljZS0yJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgcmV0dXJuIGVtcHR5IGFycmF5IHdoZW4gbm8gaW52b2ljZXMgZXhpc3QnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGZpcnN0OiAwLFxuICAgICAgICAgICAgbGFzdDogMCxcbiAgICAgICAgICAgIHJlY29yZHNDb3VudDogMCxcbiAgICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAuZ2V0KCcvYXBpL3YxLjAvcHVibGljLWFwaS90ZXN0LWNsaWVudC1laWQvaW52b2ljZXMnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja1Jlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGlHZXRBbGxJbnZvaWNlcyh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdC5yZWNvcmRzQ291bnQpLnRvQmUoMCk7XG4gICAgICAgIGV4cGVjdChyZXN1bHQuZGF0YSkudG9IYXZlTGVuZ3RoKDApO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciBvbiBmYWlsdXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSg1MDAsIHsgZXJyb3I6ICdJbnRlcm5hbCBTZXJ2ZXIgRXJyb3InIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlHZXRBbGxJbnZvaWNlcyh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdyhLZWV6QXBpRXJyb3IpO1xuICAgIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdhcGlHZXRJbnZvaWNlQnlFeHRlcm5hbElkJywgKCkgPT4ge1xuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBnZXQgaW52b2ljZSBieSBleHRlcm5hbCBJRCBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICBkaXNjb3VudEdyb3NzVmFsdWU6IDAsXG4gICAgICAgICAgICBkaXNjb3VudE5ldFZhbHVlOiAwLFxuICAgICAgICAgICAgZGlzY291bnRWYXRWYWx1ZTogMCxcbiAgICAgICAgICAgIGRpc2NvdW50VmFsdWVPbk5ldDogZmFsc2UsXG4gICAgICAgICAgICBleGNpc2VBbW91bnQ6IDAsXG4gICAgICAgICAgICBkb2N1bWVudERhdGU6IDIwMjMwNDIzLFxuICAgICAgICAgICAgZHVlRGF0ZTogMjAyMzA0MzAsXG4gICAgICAgICAgICBleGNoYW5nZVJhdGU6IDEsXG4gICAgICAgICAgICBncm9zc0Ftb3VudDogMTE5LFxuICAgICAgICAgICAgbmV0QW1vdW50OiAxMDAsXG4gICAgICAgICAgICBudW1iZXI6IDEsXG4gICAgICAgICAgICBvcmlnaW5hbE5ldEFtb3VudDogMTAwLFxuICAgICAgICAgICAgb3JpZ2luYWxWYXRBbW91bnQ6IDE5LFxuICAgICAgICAgICAgcGFydG5lcjoge1xuICAgICAgICAgICAgICAgIGFkZHJlc3NEZXRhaWxzOiAnVGVzdCBBZGRyZXNzJyxcbiAgICAgICAgICAgICAgICBjaXR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgY291bnRyeUNvZGU6ICdSTycsXG4gICAgICAgICAgICAgICAgY291bnRyeU5hbWU6ICdSb21hbmlhJyxcbiAgICAgICAgICAgICAgICBjb3VudHlDb2RlOiAnUk8uQicsXG4gICAgICAgICAgICAgICAgY291bnR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgaWRlbnRpZmljYXRpb25OdW1iZXI6ICcxMjM0NTY3OCcsXG4gICAgICAgICAgICAgICAgaXNMZWdhbFBlcnNvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICdUZXN0IFBhcnRuZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGludm9pY2VEZXRhaWxzOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb3VudEdyb3NzVmFsdWU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2NvdW50TmV0VmFsdWU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2NvdW50VmF0VmFsdWU6IDAsXG4gICAgICAgICAgICAgICAgICAgIGRpc2NvdW50VmFsdWVPbk5ldDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGdyb3NzQW1vdW50OiAxMTksXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1Db2RlOiAnSVRFTS0wMDEnLFxuICAgICAgICAgICAgICAgICAgICBpdGVtRGVzY3JpcHRpb246ICdUZXN0IEl0ZW0nLFxuICAgICAgICAgICAgICAgICAgICBpdGVtRXh0ZXJuYWxJZDogJ2l0ZW0tZXh0LTEnLFxuICAgICAgICAgICAgICAgICAgICBpdGVtTmFtZTogJ1Rlc3QgSXRlbSBOYW1lJyxcbiAgICAgICAgICAgICAgICAgICAgbWVhc3VyZVVuaXRJZDogMSxcbiAgICAgICAgICAgICAgICAgICAgbmV0QW1vdW50OiAxMDAsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsTmV0QW1vdW50OiAxMDAsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsVmF0QW1vdW50OiAxOSxcbiAgICAgICAgICAgICAgICAgICAgcXVhbnRpdHk6IDEsXG4gICAgICAgICAgICAgICAgICAgIHVuTWVhc3VyZVVuaXQ6ICdidWMnLFxuICAgICAgICAgICAgICAgICAgICB1blZhdENhdGVnb3J5OiAnUycsXG4gICAgICAgICAgICAgICAgICAgIHVuVmF0RXhlbXB0aW9uUmVhc29uOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgdW5pdFByaWNlOiAxMDAsXG4gICAgICAgICAgICAgICAgICAgIHZhdEFtb3VudDogMTksXG4gICAgICAgICAgICAgICAgICAgIHZhdFBlcmNlbnQ6IDE5LFxuICAgICAgICAgICAgICAgICAgICBleGNpc2VBbW91bnQ6IDAsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBwYXltZW50VHlwZUlkOiAzLFxuICAgICAgICAgICAgcmVmZXJlbmNlQ3VycmVuY3lDb2RlOiAnUk9OJyxcbiAgICAgICAgICAgIHNlcmllczogJ1BESScsXG4gICAgICAgICAgICBzdGF0dXM6ICdkcmFmdCcsXG4gICAgICAgICAgICB2YXRBbW91bnQ6IDE5LFxuICAgICAgICAgICAgdmF0T25Db2xsZWN0aW9uOiBmYWxzZSxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzL2ludm9pY2UtZXh0LTEnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwgbW9ja1Jlc3BvbnNlKTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGlHZXRJbnZvaWNlQnlFeHRlcm5hbElkKHtcbiAgICAgICAgICAgIGJhc2VEb21haW46IFNUQUdJTkdfRE9NQUlOLFxuICAgICAgICAgICAgYXBwSWQ6ICd0ZXN0LWFwcC1pZCcsXG4gICAgICAgICAgICBhcHBDbGllbnRJZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBiZWFyZXJUb2tlbjogJ3Rlc3QtdG9rZW4nLFxuICAgICAgICAgICAgaW52b2ljZUlkOiAnaW52b2ljZS1leHQtMScsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGV4cGVjdChyZXN1bHQuZ3Jvc3NBbW91bnQpLnRvQmUoMTE5KTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5wYXJ0bmVyLnBhcnRuZXJOYW1lKS50b0JlKCdUZXN0IFBhcnRuZXInKTtcbiAgICAgICAgZXhwZWN0KHJlc3VsdC5pdGVtcykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgICBleHBlY3QocmVzdWx0Lml0ZW1zWzBdLml0ZW1OYW1lKS50b0JlKCdUZXN0IEl0ZW0gTmFtZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciB3aGVuIGludm9pY2Ugbm90IGZvdW5kJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLmdldCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzL25vbi1leGlzdGVudCcpXG4gICAgICAgICAgICAucmVwbHkoNDA0LCB7IGVycm9yOiAnSW52b2ljZSBub3QgZm91bmQnIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlHZXRJbnZvaWNlQnlFeHRlcm5hbElkKHtcbiAgICAgICAgICAgIGJhc2VEb21haW46IFNUQUdJTkdfRE9NQUlOLFxuICAgICAgICAgICAgYXBwSWQ6ICd0ZXN0LWFwcC1pZCcsXG4gICAgICAgICAgICBhcHBDbGllbnRJZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBiZWFyZXJUb2tlbjogJ3Rlc3QtdG9rZW4nLFxuICAgICAgICAgICAgaW52b2ljZUlkOiAnbm9uLWV4aXN0ZW50JyxcbiAgICAgICAgfSkpLnJlamVjdHMudG9UaHJvdyhLZWV6QXBpRXJyb3IpO1xuICAgIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdhcGlDcmVhdGVJbnZvaWNlJywgKCkgPT4ge1xuICAgIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgICAgIG5vY2suY2xlYW5BbGwoKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBjcmVhdGUgaW52b2ljZSBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vY2tSZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGV4dGVybmFsSWQ6ICduZXctaW52b2ljZS1leHQtaWQnLFxuICAgICAgICB9O1xuXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSgyMDEsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpQ3JlYXRlSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGludm9pY2U6IHtcbiAgICAgICAgICAgICAgICBzZXJpZXM6ICdQREknLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgYW1vdW50OiAxMDAsXG4gICAgICAgICAgICAgICAgcGF5bWVudFR5cGU6IFBheW1lbnRUeXBlLkJBTktfVFJBTlNGRVIsXG4gICAgICAgICAgICAgICAgcGFydG5lcjoge1xuICAgICAgICAgICAgICAgICAgICBhZGRyZXNzRGV0YWlsczogJ1Rlc3QgQWRkcmVzcycsXG4gICAgICAgICAgICAgICAgICAgIGNpdHlOYW1lOiAnQnVjaGFyZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgY291bnRyeUNvZGU6ICdSTycsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50cnlOYW1lOiAnUm9tYW5pYScsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50eUNvZGU6ICdSTy5CJyxcbiAgICAgICAgICAgICAgICAgICAgY291bnR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpY2F0aW9uTnVtYmVyOiAnMTIzNDU2NzgnLFxuICAgICAgICAgICAgICAgICAgICBpc0xlZ2FsUGVyc29uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICdUZXN0IFBhcnRuZXInLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaXRlbUlkOiAnaXRlbS1leHQtMScsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlKCduZXctaW52b2ljZS1leHQtaWQnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBjcmVhdGUgaW52b2ljZSB3aXRoIGN1c3RvbSBkYXRlIGFuZCBxdWFudGl0eScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgbW9ja1Jlc3BvbnNlID0ge1xuICAgICAgICAgICAgZXh0ZXJuYWxJZDogJ25ldy1pbnZvaWNlLWV4dC1pZC0yJyxcbiAgICAgICAgfTtcblxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcycsIChib2R5OiB7IGRvY3VtZW50RGF0ZTogbnVtYmVyOyBpbnZvaWNlRGV0YWlsczogeyBxdWFudGl0eTogbnVtYmVyIH1bXSB9KSA9PiBib2R5LmRvY3VtZW50RGF0ZSA9PT0gMjAyNDAxMTUgJiYgYm9keS5pbnZvaWNlRGV0YWlsc1swXS5xdWFudGl0eSA9PT0gNSlcbiAgICAgICAgICAgIC5yZXBseSgyMDEsIG1vY2tSZXNwb25zZSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpQ3JlYXRlSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGludm9pY2U6IHtcbiAgICAgICAgICAgICAgICBzZXJpZXM6ICdQREknLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1JPTicsXG4gICAgICAgICAgICAgICAgYW1vdW50OiA1MDAsXG4gICAgICAgICAgICAgICAgcGF5bWVudFR5cGU6IFBheW1lbnRUeXBlLkNBUkRfT05MSU5FLFxuICAgICAgICAgICAgICAgIHBhcnRuZXI6IHtcbiAgICAgICAgICAgICAgICAgICAgYWRkcmVzc0RldGFpbHM6ICdUZXN0IEFkZHJlc3MnLFxuICAgICAgICAgICAgICAgICAgICBjaXR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50cnlDb2RlOiAnUk8nLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHJ5TmFtZTogJ1JvbWFuaWEnLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHlDb2RlOiAnUk8uQicsXG4gICAgICAgICAgICAgICAgICAgIGNvdW50eU5hbWU6ICdCdWNoYXJlc3QnLFxuICAgICAgICAgICAgICAgICAgICBpZGVudGlmaWNhdGlvbk51bWJlcjogJzEyMzQ1Njc4JyxcbiAgICAgICAgICAgICAgICAgICAgaXNMZWdhbFBlcnNvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRuZXJOYW1lOiAnVGVzdCBQYXJ0bmVyJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGl0ZW1JZDogJ2l0ZW0tZXh0LTEnLFxuICAgICAgICAgICAgICAgIGRvY3VtZW50RGF0ZTogMjAyNDAxMTUsXG4gICAgICAgICAgICAgICAgZHVlRGF0ZTogMjAyNDAxMzAsXG4gICAgICAgICAgICAgICAgcXVhbnRpdHk6IDUsXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlKCduZXctaW52b2ljZS1leHQtaWQtMicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciBvbiB2YWxpZGF0aW9uIGVycm9yJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcycpXG4gICAgICAgICAgICAucmVwbHkoNDAwLCB7IE1lc3NhZ2U6ICdWYWxpZGF0aW9uIGZhaWxlZCcgfSk7XG5cbiAgICAgICAgYXdhaXQgZXhwZWN0KGFwaUNyZWF0ZUludm9pY2Uoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGFwcENsaWVudElkOiAndGVzdC1jbGllbnQtZWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgICAgICBpbnZvaWNlOiB7XG4gICAgICAgICAgICAgICAgc2VyaWVzOiAnUERJJyxcbiAgICAgICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdST04nLFxuICAgICAgICAgICAgICAgIGFtb3VudDogLTEwMCxcbiAgICAgICAgICAgICAgICBwYXltZW50VHlwZTogUGF5bWVudFR5cGUuQkFOS19UUkFOU0ZFUixcbiAgICAgICAgICAgICAgICBwYXJ0bmVyOiB7XG4gICAgICAgICAgICAgICAgICAgIGFkZHJlc3NEZXRhaWxzOiAnVGVzdCBBZGRyZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgY2l0eU5hbWU6ICdCdWNoYXJlc3QnLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHJ5Q29kZTogJ1JPJyxcbiAgICAgICAgICAgICAgICAgICAgY291bnRyeU5hbWU6ICdSb21hbmlhJyxcbiAgICAgICAgICAgICAgICAgICAgY291bnR5Q29kZTogJ1JPLkInLFxuICAgICAgICAgICAgICAgICAgICBjb3VudHlOYW1lOiAnQnVjaGFyZXN0JyxcbiAgICAgICAgICAgICAgICAgICAgaWRlbnRpZmljYXRpb25OdW1iZXI6ICcnLFxuICAgICAgICAgICAgICAgICAgICBpc0xlZ2FsUGVyc29uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICcnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaXRlbUlkOiAnJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pKS5yZWplY3RzLnRvVGhyb3coS2VlekFwaUVycm9yKTtcbiAgICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXBpU2VuZEludm9pY2UnLCAoKSA9PiB7XG4gICAgYWZ0ZXJFYWNoKCgpID0+IHtcbiAgICAgICAgbm9jay5jbGVhbkFsbCgpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHNlbmQgaW52b2ljZSBlbWFpbCBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvaW52b2ljZXMvZGVsaXZlcnknKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBpU2VuZEludm9pY2Uoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgICAgICBjbGllbnRNYWlsOiAndGVzdEBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICBpbnZvaWNlSWQ6ICdpbnZvaWNlLWV4dC0xJyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgnU0VOVCcpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2hvdWxkIHRocm93IEtlZXpBcGlFcnJvciBvbiBzZW5kIGZhaWx1cmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvaW52b2ljZXMvZGVsaXZlcnknKVxuICAgICAgICAgICAgLnJlcGx5KDUwMCwgeyBlcnJvcjogJ0VtYWlsIHNlcnZpY2UgdW5hdmFpbGFibGUnIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlTZW5kSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGNsaWVudE1haWw6ICd0ZXN0QGV4YW1wbGUuY29tJyxcbiAgICAgICAgICAgIGludm9pY2VJZDogJ2ludm9pY2UtZXh0LTEnLFxuICAgICAgICB9KSkucmVqZWN0cy50b1Rocm93KEtlZXpBcGlFcnJvcik7XG4gICAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ2FwaVZhbGlkYXRlSW52b2ljZScsICgpID0+IHtcbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgdmFsaWRhdGUgaW52b2ljZSBzdWNjZXNzZnVsbHknLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzL3ZhbGlkJylcbiAgICAgICAgICAgIC5yZXBseSgyMDApO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFwaVZhbGlkYXRlSW52b2ljZSh7XG4gICAgICAgICAgICBiYXNlRG9tYWluOiBTVEFHSU5HX0RPTUFJTixcbiAgICAgICAgICAgIGFwcElkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgYXBwQ2xpZW50SWQ6ICd0ZXN0LWNsaWVudC1laWQnLFxuICAgICAgICAgICAgYmVhcmVyVG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgIGludm9pY2VJZDogJ2ludm9pY2UtZXh0LTEnLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlKCdWQUxJREFURUQnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCB0aHJvdyBLZWV6QXBpRXJyb3Igb24gdmFsaWRhdGlvbiBmYWlsdXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcy92YWxpZCcpXG4gICAgICAgICAgICAucmVwbHkoNDAwLCB7IE1lc3NhZ2U6ICdJbnZvaWNlIGNhbm5vdCBiZSB2YWxpZGF0ZWQnIH0pO1xuXG4gICAgICAgIGF3YWl0IGV4cGVjdChhcGlWYWxpZGF0ZUludm9pY2Uoe1xuICAgICAgICAgICAgYmFzZURvbWFpbjogU1RBR0lOR19ET01BSU4sXG4gICAgICAgICAgICBhcHBJZDogJ3Rlc3QtYXBwLWlkJyxcbiAgICAgICAgICAgIGFwcENsaWVudElkOiAndGVzdC1jbGllbnQtZWlkJyxcbiAgICAgICAgICAgIGJlYXJlclRva2VuOiAndGVzdC10b2tlbicsXG4gICAgICAgICAgICBpbnZvaWNlSWQ6ICdpbnZhbGlkLWludm9pY2UnLFxuICAgICAgICB9KSkucmVqZWN0cy50b1Rocm93KEtlZXpBcGlFcnJvcik7XG4gICAgfSk7XG59KTtcblxuZGVzY3JpYmUoJ0tlZXpBcGkgaW50ZWdyYXRpb24gdGVzdHMnLCAoKSA9PiB7XG4gICAgbGV0IGtlZXpBcGk6IEtlZXpBcGk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAga2VlekFwaSA9IG5ldyBLZWV6QXBpKHtcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uX2lkOiAndGVzdC1hcHAtaWQnLFxuICAgICAgICAgICAgY2xpZW50X2VpZDogJ3Rlc3QtY2xpZW50LWVpZCcsXG4gICAgICAgICAgICBzZWNyZXQ6ICd0ZXN0LXNlY3JldCcsXG4gICAgICAgICAgICBsaXZlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgICBub2NrLmNsZWFuQWxsKCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzaG91bGQgYXV0by1yZWZyZXNoIHRva2VuIHdoZW4gZXhwaXJlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gTW9jayB0b2tlbiBnZW5lcmF0aW9uXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2lkcC9jb25uZWN0L3Rva2VuJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICdmcmVzaC10b2tlbicsXG4gICAgICAgICAgICAgICAgZXhwaXJlc19pbjogMzYwMCxcbiAgICAgICAgICAgICAgICB0b2tlbl90eXBlOiAnQmVhcmVyJyxcbiAgICAgICAgICAgICAgICBzY29wZTogJ3B1YmxpYy1hcGknLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gTW9jayBnZXQgYWxsIGludm9pY2VzXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAuZ2V0KCcvYXBpL3YxLjAvcHVibGljLWFwaS90ZXN0LWNsaWVudC1laWQvaW52b2ljZXMnKVxuICAgICAgICAgICAgLnJlcGx5KDIwMCwge1xuICAgICAgICAgICAgICAgIGZpcnN0OiAwLFxuICAgICAgICAgICAgICAgIGxhc3Q6IDAsXG4gICAgICAgICAgICAgICAgcmVjb3Jkc0NvdW50OiAwLFxuICAgICAgICAgICAgICAgIGRhdGE6IFtdLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQga2VlekFwaS5nZXRBbGxJbnZvaWNlcygpO1xuICAgICAgICBleHBlY3QocmVzdWx0LnJlY29yZHNDb3VudCkudG9CZSgwKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Nob3VsZCBjcmVhdGUgYW5kIHZhbGlkYXRlIGludm9pY2UgZmxvdycsIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gTW9jayB0b2tlbiBnZW5lcmF0aW9uXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2lkcC9jb25uZWN0L3Rva2VuJylcbiAgICAgICAgICAgIC5yZXBseSgyMDAsIHtcbiAgICAgICAgICAgICAgICBhY2Nlc3NfdG9rZW46ICd0ZXN0LXRva2VuJyxcbiAgICAgICAgICAgICAgICBleHBpcmVzX2luOiAzNjAwLFxuICAgICAgICAgICAgICAgIHRva2VuX3R5cGU6ICdCZWFyZXInLFxuICAgICAgICAgICAgICAgIHNjb3BlOiAncHVibGljLWFwaScsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAvLyBNb2NrIGNyZWF0ZSBpbnZvaWNlXG4gICAgICAgIG5vY2soU1RBR0lOR19ET01BSU4pXG4gICAgICAgICAgICAucG9zdCgnL2FwaS92MS4wL3B1YmxpYy1hcGkvdGVzdC1jbGllbnQtZWlkL2ludm9pY2VzJylcbiAgICAgICAgICAgIC5yZXBseSgyMDEsIHsgZXh0ZXJuYWxJZDogJ2NyZWF0ZWQtaW52b2ljZS1pZCcgfSk7XG5cbiAgICAgICAgY29uc3QgaW52b2ljZUlkID0gYXdhaXQga2VlekFwaS5jcmVhdGVJbnZvaWNlKHtcbiAgICAgICAgICAgIHNlcmllczogJ1BESScsXG4gICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdST04nLFxuICAgICAgICAgICAgYW1vdW50OiAxMDAsXG4gICAgICAgICAgICBwYXltZW50VHlwZTogUGF5bWVudFR5cGUuTUVBTF9WT1VDSEVSLFxuICAgICAgICAgICAgcGFydG5lcjoge1xuICAgICAgICAgICAgICAgIGFkZHJlc3NEZXRhaWxzOiAnVGVzdCBBZGRyZXNzJyxcbiAgICAgICAgICAgICAgICBjaXR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgY291bnRyeUNvZGU6ICdSTycsXG4gICAgICAgICAgICAgICAgY291bnRyeU5hbWU6ICdSb21hbmlhJyxcbiAgICAgICAgICAgICAgICBjb3VudHlDb2RlOiAnUk8uQicsXG4gICAgICAgICAgICAgICAgY291bnR5TmFtZTogJ0J1Y2hhcmVzdCcsXG4gICAgICAgICAgICAgICAgaWRlbnRpZmljYXRpb25OdW1iZXI6ICcxMjM0NTY3OCcsXG4gICAgICAgICAgICAgICAgaXNMZWdhbFBlcnNvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgcGFydG5lck5hbWU6ICdUZXN0IFBhcnRuZXInLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGl0ZW1JZDogJ2l0ZW0tZXh0LTEnLFxuICAgICAgICB9KTtcblxuICAgICAgICBleHBlY3QoaW52b2ljZUlkKS50b0JlKCdjcmVhdGVkLWludm9pY2UtaWQnKTtcblxuICAgICAgICAvLyBNb2NrIHZhbGlkYXRlIGludm9pY2UgKHJldXNlIHRva2VuKVxuICAgICAgICBub2NrKFNUQUdJTkdfRE9NQUlOKVxuICAgICAgICAgICAgLnBvc3QoJy9hcGkvdjEuMC9wdWJsaWMtYXBpL3Rlc3QtY2xpZW50LWVpZC9pbnZvaWNlcy92YWxpZCcpXG4gICAgICAgICAgICAucmVwbHkoMjAwKTtcblxuICAgICAgICBjb25zdCB2YWxpZGF0ZVJlc3VsdCA9IGF3YWl0IGtlZXpBcGkudmFsaWRhdGVJbnZvaWNlKCdjcmVhdGVkLWludm9pY2UtaWQnKTtcbiAgICAgICAgZXhwZWN0KHZhbGlkYXRlUmVzdWx0KS50b0JlKCdWQUxJREFURUQnKTtcbiAgICB9KTtcbn0pO1xuIl19
|