@rudderstack/integrations-lib 0.2.30 → 0.2.32
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/build/constants.d.ts +5 -64
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +1 -1
- package/build/logger.d.ts +1 -1
- package/build/logger.d.ts.map +1 -1
- package/build/logger.js +1 -1
- package/build/sdks/googleAdsRestAPI/googleAds.d.ts +2 -2
- package/build/sdks/googleAdsRestAPI/googleAds.d.ts.map +1 -1
- package/build/sdks/googleAdsRestAPI/googleAds.js +2 -2
- package/build/sdks/sfmc/index.d.ts +1 -1
- package/build/sdks/sfmc/index.d.ts.map +1 -1
- package/build/sdks/sfmc/index.js +11 -3
- package/build/sdks/sfmc/type.d.ts +5 -0
- package/build/sdks/sfmc/type.d.ts.map +1 -1
- package/build/sdks/sfmc/type.js +1 -1
- package/build/sdks/sfmc/utils.d.ts +6 -5
- package/build/sdks/sfmc/utils.d.ts.map +1 -1
- package/build/sdks/sfmc/utils.js +6 -6
- package/build/sdks/zoho/types.d.ts +2 -20
- package/build/sdks/zoho/types.d.ts.map +1 -1
- package/build/sdks/zoho/types.js +1 -1
- package/build/utils/misc.d.ts +20 -7
- package/build/utils/misc.d.ts.map +1 -1
- package/build/utils/misc.js +29 -2
- package/build/utils/request.d.ts +8 -1
- package/build/utils/request.d.ts.map +1 -1
- package/build/utils/request.js +1 -1
- package/package.json +2 -1
- package/build/lib/set-value/set-value.test.d.ts +0 -2
- package/build/lib/set-value/set-value.test.d.ts.map +0 -1
- package/build/lib/set-value/set-value.test.js +0 -105
- package/build/network/clients/axios_client.test.d.ts +0 -2
- package/build/network/clients/axios_client.test.d.ts.map +0 -1
- package/build/network/clients/axios_client.test.js +0 -276
- package/build/network/factory.test.d.ts +0 -2
- package/build/network/factory.test.d.ts.map +0 -1
- package/build/network/factory.test.js +0 -51
- package/build/sdks/customerio_audience/index.test.d.ts +0 -2
- package/build/sdks/customerio_audience/index.test.d.ts.map +0 -1
- package/build/sdks/customerio_audience/index.test.js +0 -121
- package/build/sdks/googleAdsRestAPI/googleAds.test.d.ts +0 -2
- package/build/sdks/googleAdsRestAPI/googleAds.test.d.ts.map +0 -1
- package/build/sdks/googleAdsRestAPI/googleAds.test.js +0 -771
- package/build/sdks/sfmc/index.test.d.ts +0 -2
- package/build/sdks/sfmc/index.test.d.ts.map +0 -1
- package/build/sdks/sfmc/index.test.js +0 -751
- package/build/sdks/sfmc/utils.test.d.ts +0 -2
- package/build/sdks/sfmc/utils.test.d.ts.map +0 -1
- package/build/sdks/sfmc/utils.test.js +0 -32
- package/build/sdks/zoho/zoho.test.d.ts +0 -2
- package/build/sdks/zoho/zoho.test.d.ts.map +0 -1
- package/build/sdks/zoho/zoho.test.js +0 -472
- package/build/structured-logger.test.d.ts +0 -2
- package/build/structured-logger.test.d.ts.map +0 -1
- package/build/structured-logger.test.js +0 -93
- package/build/utils/json-schema-generator.test.d.ts +0 -2
- package/build/utils/json-schema-generator.test.d.ts.map +0 -1
- package/build/utils/json-schema-generator.test.js +0 -368
- package/build/utils/misc.test.d.ts +0 -2
- package/build/utils/misc.test.d.ts.map +0 -1
- package/build/utils/misc.test.js +0 -2260
- package/build/utils/request.test.d.ts +0 -2
- package/build/utils/request.test.d.ts.map +0 -1
- package/build/utils/request.test.js +0 -72
- package/build/utils/tests.test.d.ts +0 -2
- package/build/utils/tests.test.d.ts.map +0 -1
- package/build/utils/tests.test.js +0 -89
- package/build/utils/zod.test.d.ts +0 -2
- package/build/utils/zod.test.d.ts.map +0 -1
- package/build/utils/zod.test.js +0 -48
|
@@ -1,771 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
|
|
40
|
-
const axios_1 = __importStar(require("axios"));
|
|
41
|
-
const googleAds_1 = __importDefault(require("./googleAds"));
|
|
42
|
-
describe('Google ads SDK', () => {
|
|
43
|
-
let mock;
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
mock = new axios_mock_adapter_1.default(axios_1.default, { onNoMatch: 'throwException' });
|
|
46
|
-
});
|
|
47
|
-
afterEach(() => {
|
|
48
|
-
mock.restore();
|
|
49
|
-
});
|
|
50
|
-
describe('Test getConversionAction function', () => {
|
|
51
|
-
const testCases = [
|
|
52
|
-
{
|
|
53
|
-
name: 'should return conversion action ID when API returns success response',
|
|
54
|
-
authObject: {
|
|
55
|
-
accessToken: 'test-access-token',
|
|
56
|
-
customerId: '123456789',
|
|
57
|
-
developerToken: 'test-developer-token',
|
|
58
|
-
},
|
|
59
|
-
mockResponse: [
|
|
60
|
-
{
|
|
61
|
-
results: [
|
|
62
|
-
{
|
|
63
|
-
conversionAction: {
|
|
64
|
-
resourceName: 'customers/123456789/conversionActions/9876543',
|
|
65
|
-
id: '9876543',
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
],
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
conversionName: 'test_conversion',
|
|
72
|
-
status: 200,
|
|
73
|
-
expectedResult: 'customers/123456789/conversionActions/9876543',
|
|
74
|
-
expectedRequest: {
|
|
75
|
-
url: '/123456789/googleAds:searchStream',
|
|
76
|
-
data: JSON.stringify({
|
|
77
|
-
query: "SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'test_conversion'",
|
|
78
|
-
}),
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: 'handle failure scenario when accessToken is wrong',
|
|
83
|
-
authObject: {
|
|
84
|
-
customerId: '123456789',
|
|
85
|
-
developerToken: 'test-developer-token',
|
|
86
|
-
accessToken: 'wrong-access-token',
|
|
87
|
-
},
|
|
88
|
-
mockResponse: [
|
|
89
|
-
{
|
|
90
|
-
error: {
|
|
91
|
-
code: 401,
|
|
92
|
-
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
|
|
93
|
-
status: 'UNAUTHENTICATED',
|
|
94
|
-
},
|
|
95
|
-
},
|
|
96
|
-
],
|
|
97
|
-
mockResponseHeader: new axios_1.AxiosHeaders({
|
|
98
|
-
'transfer-encoding': 'chunked',
|
|
99
|
-
}),
|
|
100
|
-
conversionName: 'test_conversion',
|
|
101
|
-
status: 401,
|
|
102
|
-
expectedResult: {
|
|
103
|
-
headers: new axios_1.AxiosHeaders({
|
|
104
|
-
'transfer-encoding': 'chunked',
|
|
105
|
-
}),
|
|
106
|
-
message: undefined,
|
|
107
|
-
responseBody: [
|
|
108
|
-
{
|
|
109
|
-
error: {
|
|
110
|
-
code: 401,
|
|
111
|
-
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
|
|
112
|
-
status: 'UNAUTHENTICATED',
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
statusCode: 401,
|
|
117
|
-
type: 'application-error',
|
|
118
|
-
},
|
|
119
|
-
expectedRequest: {
|
|
120
|
-
url: '/123456789/googleAds:searchStream',
|
|
121
|
-
data: JSON.stringify({
|
|
122
|
-
query: "SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'test_conversion'",
|
|
123
|
-
}),
|
|
124
|
-
},
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
name: 'handle the situation when the conversion is not available',
|
|
128
|
-
authObject: {
|
|
129
|
-
accessToken: 'test-access-token',
|
|
130
|
-
customerId: '123456789',
|
|
131
|
-
developerToken: 'test-developer-token',
|
|
132
|
-
},
|
|
133
|
-
mockResponse: [],
|
|
134
|
-
conversionName: 'non-existing-conversion',
|
|
135
|
-
status: 200,
|
|
136
|
-
expectedResult: null,
|
|
137
|
-
expectedRequest: {
|
|
138
|
-
url: '/123456789/googleAds:searchStream',
|
|
139
|
-
data: JSON.stringify({
|
|
140
|
-
query: "SELECT conversion_action.id FROM conversion_action WHERE conversion_action.name = 'non-existing-conversion'",
|
|
141
|
-
}),
|
|
142
|
-
},
|
|
143
|
-
},
|
|
144
|
-
];
|
|
145
|
-
testCases.forEach(({ name, authObject, mockResponse, conversionName, expectedRequest, expectedResult, status, mockResponseHeader, }) => {
|
|
146
|
-
it(name, async () => {
|
|
147
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
148
|
-
mock
|
|
149
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789/googleAds:searchStream')
|
|
150
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
151
|
-
const result = await googleAds.getConversionActionId(conversionName);
|
|
152
|
-
expect(mock.history.post[0]).toMatchObject(expectedRequest);
|
|
153
|
-
expect(result).toEqual(expectedResult);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
describe('Test getCustomVariable function', () => {
|
|
158
|
-
const testCases = [
|
|
159
|
-
{
|
|
160
|
-
name: 'should return an array of CustomVariableResults when API call succeeds',
|
|
161
|
-
authObject: {
|
|
162
|
-
accessToken: 'test-access-token',
|
|
163
|
-
customerId: '123456789',
|
|
164
|
-
developerToken: 'test-developer-token',
|
|
165
|
-
},
|
|
166
|
-
mockResponse: [
|
|
167
|
-
{
|
|
168
|
-
results: [
|
|
169
|
-
{
|
|
170
|
-
conversionCustomVariable: {
|
|
171
|
-
resourceName: 'customers/123/conversionCustomVariables/456',
|
|
172
|
-
name: 'test_variable',
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
fieldMask: 'conversion_custom_variable.name',
|
|
177
|
-
requestId: '123456',
|
|
178
|
-
queryResourceConsumption: '100',
|
|
179
|
-
},
|
|
180
|
-
],
|
|
181
|
-
status: 200,
|
|
182
|
-
expectedResult: [
|
|
183
|
-
{
|
|
184
|
-
conversionCustomVariable: {
|
|
185
|
-
resourceName: 'customers/123/conversionCustomVariables/456',
|
|
186
|
-
name: 'test_variable',
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
],
|
|
190
|
-
expectedRequest: {
|
|
191
|
-
url: '/123456789/googleAds:searchStream',
|
|
192
|
-
data: JSON.stringify({
|
|
193
|
-
query: 'SELECT conversion_custom_variable.name FROM conversion_custom_variable',
|
|
194
|
-
}),
|
|
195
|
-
},
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
name: 'should handle the scenario when there is not any customVariables',
|
|
199
|
-
authObject: {
|
|
200
|
-
accessToken: 'test-access-token',
|
|
201
|
-
customerId: '123456789',
|
|
202
|
-
developerToken: 'test-developer-token',
|
|
203
|
-
},
|
|
204
|
-
status: 200,
|
|
205
|
-
mockResponse: [
|
|
206
|
-
{
|
|
207
|
-
results: [],
|
|
208
|
-
fieldMask: 'conversion_custom_variable.name',
|
|
209
|
-
requestId: '123456',
|
|
210
|
-
queryResourceConsumption: '100',
|
|
211
|
-
},
|
|
212
|
-
],
|
|
213
|
-
expectedResult: [],
|
|
214
|
-
expectedRequest: {
|
|
215
|
-
url: '/123456789/googleAds:searchStream',
|
|
216
|
-
data: JSON.stringify({
|
|
217
|
-
query: 'SELECT conversion_custom_variable.name FROM conversion_custom_variable',
|
|
218
|
-
}),
|
|
219
|
-
},
|
|
220
|
-
},
|
|
221
|
-
{
|
|
222
|
-
name: 'should return an array of CustomVariableResults when API call succeeds',
|
|
223
|
-
authObject: {
|
|
224
|
-
accessToken: 'wrong-access-token',
|
|
225
|
-
customerId: '123456789',
|
|
226
|
-
developerToken: 'test-developer-token',
|
|
227
|
-
},
|
|
228
|
-
mockResponse: [
|
|
229
|
-
{
|
|
230
|
-
error: {
|
|
231
|
-
code: 401,
|
|
232
|
-
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
|
|
233
|
-
status: 'UNAUTHENTICATED',
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
status: 401,
|
|
238
|
-
expectedResult: {
|
|
239
|
-
headers: new axios_1.AxiosHeaders({
|
|
240
|
-
'transfer-encoding': 'chunked',
|
|
241
|
-
}),
|
|
242
|
-
message: undefined,
|
|
243
|
-
responseBody: [
|
|
244
|
-
{
|
|
245
|
-
error: {
|
|
246
|
-
code: 401,
|
|
247
|
-
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
|
|
248
|
-
status: 'UNAUTHENTICATED',
|
|
249
|
-
},
|
|
250
|
-
},
|
|
251
|
-
],
|
|
252
|
-
statusCode: 401,
|
|
253
|
-
type: 'application-error',
|
|
254
|
-
},
|
|
255
|
-
expectedRequest: {
|
|
256
|
-
url: '/123456789/googleAds:searchStream',
|
|
257
|
-
data: JSON.stringify({
|
|
258
|
-
query: 'SELECT conversion_custom_variable.name FROM conversion_custom_variable',
|
|
259
|
-
}),
|
|
260
|
-
},
|
|
261
|
-
mockResponseHeader: new axios_1.AxiosHeaders({
|
|
262
|
-
'transfer-encoding': 'chunked',
|
|
263
|
-
}),
|
|
264
|
-
},
|
|
265
|
-
];
|
|
266
|
-
testCases.forEach(({ name, authObject, mockResponse, expectedRequest, expectedResult, status, mockResponseHeader, }) => {
|
|
267
|
-
it(name, async () => {
|
|
268
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
269
|
-
mock
|
|
270
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789/googleAds:searchStream')
|
|
271
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
272
|
-
const result = await googleAds.getCustomVariable();
|
|
273
|
-
expect(mock.history.post[0]).toMatchObject(expectedRequest);
|
|
274
|
-
expect(result).toEqual(expectedResult);
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
describe('Test addConversionAdjustMent function', () => {
|
|
279
|
-
const TestCases = [
|
|
280
|
-
{
|
|
281
|
-
name: 'should successfully upload conversion adjustments with valid data',
|
|
282
|
-
authObject: {
|
|
283
|
-
accessToken: 'valid-access-token',
|
|
284
|
-
customerId: '123456789',
|
|
285
|
-
developerToken: 'test-developer-token',
|
|
286
|
-
},
|
|
287
|
-
requestData: {
|
|
288
|
-
conversionAdjustments: [
|
|
289
|
-
{
|
|
290
|
-
gclidDateTimePair: {
|
|
291
|
-
gclid: 'test-gclid',
|
|
292
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
293
|
-
},
|
|
294
|
-
adjustmentType: 'RESTATEMENT',
|
|
295
|
-
restatementValue: {
|
|
296
|
-
adjustedValue: 100,
|
|
297
|
-
currencyCode: 'USD',
|
|
298
|
-
},
|
|
299
|
-
userIdentifiers: [
|
|
300
|
-
{
|
|
301
|
-
userIdentifierSource: 'FIRST_PARTY',
|
|
302
|
-
hashedEmail: '389205904d6c7bb83fc676513911226f2be25bf1465616bb9b29587100ab1414',
|
|
303
|
-
},
|
|
304
|
-
],
|
|
305
|
-
},
|
|
306
|
-
],
|
|
307
|
-
partialFailure: false,
|
|
308
|
-
},
|
|
309
|
-
status: 200,
|
|
310
|
-
mockResponse: {
|
|
311
|
-
conversionAdjustments: [
|
|
312
|
-
{
|
|
313
|
-
gclidDateTimePair: {
|
|
314
|
-
gclid: 'test-gclid',
|
|
315
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
316
|
-
},
|
|
317
|
-
adjustmentType: 'RESTATEMENT',
|
|
318
|
-
restatementValue: {
|
|
319
|
-
adjustedValue: 100,
|
|
320
|
-
currencyCode: 'USD',
|
|
321
|
-
},
|
|
322
|
-
userIdentifiers: [],
|
|
323
|
-
},
|
|
324
|
-
],
|
|
325
|
-
partialFailure: false,
|
|
326
|
-
},
|
|
327
|
-
expectedResult: {
|
|
328
|
-
type: 'success',
|
|
329
|
-
statusCode: 200,
|
|
330
|
-
responseBody: {
|
|
331
|
-
conversionAdjustments: [
|
|
332
|
-
{
|
|
333
|
-
gclidDateTimePair: {
|
|
334
|
-
gclid: 'test-gclid',
|
|
335
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
336
|
-
},
|
|
337
|
-
adjustmentType: 'RESTATEMENT',
|
|
338
|
-
restatementValue: { adjustedValue: 100, currencyCode: 'USD' },
|
|
339
|
-
userIdentifiers: [],
|
|
340
|
-
},
|
|
341
|
-
],
|
|
342
|
-
partialFailure: false,
|
|
343
|
-
},
|
|
344
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
345
|
-
},
|
|
346
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
name: 'should successfully handle failure scenario',
|
|
350
|
-
authObject: {
|
|
351
|
-
accessToken: 'wrong-access-token',
|
|
352
|
-
customerId: '123456789',
|
|
353
|
-
developerToken: 'test-developer-token',
|
|
354
|
-
},
|
|
355
|
-
requestData: {
|
|
356
|
-
conversionAdjustments: [
|
|
357
|
-
{
|
|
358
|
-
gclidDateTimePair: {
|
|
359
|
-
gclid: 'test-gclid',
|
|
360
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
361
|
-
},
|
|
362
|
-
adjustmentType: 'RESTATEMENT',
|
|
363
|
-
restatementValue: {
|
|
364
|
-
adjustedValue: 100,
|
|
365
|
-
currencyCode: 'USD',
|
|
366
|
-
},
|
|
367
|
-
userIdentifiers: [
|
|
368
|
-
{
|
|
369
|
-
userIdentifierSource: 'FIRST_PARTY',
|
|
370
|
-
hashedEmail: '389205904d6c7bb83fc676513911226f2be25bf1465616bb9b29587100ab1414',
|
|
371
|
-
},
|
|
372
|
-
],
|
|
373
|
-
},
|
|
374
|
-
],
|
|
375
|
-
partialFailure: false,
|
|
376
|
-
},
|
|
377
|
-
status: 401,
|
|
378
|
-
mockResponse: {
|
|
379
|
-
headers: new axios_1.AxiosHeaders({
|
|
380
|
-
'transfer-encoding': 'chunked',
|
|
381
|
-
}),
|
|
382
|
-
message: undefined,
|
|
383
|
-
responseBody: [
|
|
384
|
-
{
|
|
385
|
-
error: {
|
|
386
|
-
code: 401,
|
|
387
|
-
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
|
|
388
|
-
status: 'UNAUTHENTICATED',
|
|
389
|
-
},
|
|
390
|
-
},
|
|
391
|
-
],
|
|
392
|
-
statusCode: 401,
|
|
393
|
-
type: 'application-error',
|
|
394
|
-
},
|
|
395
|
-
expectedResult: {
|
|
396
|
-
headers: new axios_1.AxiosHeaders({
|
|
397
|
-
'Content-Type': 'application/json',
|
|
398
|
-
}),
|
|
399
|
-
message: undefined,
|
|
400
|
-
responseBody: {
|
|
401
|
-
headers: { 'transfer-encoding': 'chunked' },
|
|
402
|
-
responseBody: [
|
|
403
|
-
{
|
|
404
|
-
error: {
|
|
405
|
-
code: 401,
|
|
406
|
-
message: 'Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.',
|
|
407
|
-
status: 'UNAUTHENTICATED',
|
|
408
|
-
},
|
|
409
|
-
},
|
|
410
|
-
],
|
|
411
|
-
statusCode: 401,
|
|
412
|
-
type: 'application-error',
|
|
413
|
-
},
|
|
414
|
-
statusCode: 401,
|
|
415
|
-
type: 'application-error',
|
|
416
|
-
},
|
|
417
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
418
|
-
},
|
|
419
|
-
];
|
|
420
|
-
TestCases.forEach(({ name, authObject, mockResponse, requestData, expectedResult, mockResponseHeader, status, }) => {
|
|
421
|
-
it(name, async () => {
|
|
422
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
423
|
-
mock
|
|
424
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789:uploadConversionAdjustments')
|
|
425
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
426
|
-
const result = await googleAds.addConversionAdjustMent(requestData);
|
|
427
|
-
expect(result).toEqual(expectedResult);
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
});
|
|
431
|
-
describe('Test createOfflineUserDataJob function', () => {
|
|
432
|
-
const TestCases = [
|
|
433
|
-
{
|
|
434
|
-
name: 'should return job ID when response type is success for customerMatchUserList job',
|
|
435
|
-
authObject: {
|
|
436
|
-
accessToken: 'valid-access-token',
|
|
437
|
-
customerId: '123456789',
|
|
438
|
-
developerToken: 'test-developer-token',
|
|
439
|
-
loginCustomerId: '987654321',
|
|
440
|
-
},
|
|
441
|
-
requestData: {
|
|
442
|
-
job: {
|
|
443
|
-
type: 'CUSTOMER_MATCH_USER_LIST',
|
|
444
|
-
customerMatchUserListMetadata: {
|
|
445
|
-
userList: 'customers/123456789/userLists/1234',
|
|
446
|
-
},
|
|
447
|
-
},
|
|
448
|
-
},
|
|
449
|
-
status: 200,
|
|
450
|
-
mockResponse: {
|
|
451
|
-
resourceName: 'customers/123456789/offlineUserDataJobs/5678',
|
|
452
|
-
},
|
|
453
|
-
expectedResult: {
|
|
454
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
455
|
-
responseBody: {
|
|
456
|
-
resourceName: 'customers/123456789/offlineUserDataJobs/5678',
|
|
457
|
-
},
|
|
458
|
-
statusCode: 200,
|
|
459
|
-
type: 'success',
|
|
460
|
-
},
|
|
461
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
name: 'should return job ID when response type is success for store sales job',
|
|
465
|
-
authObject: {
|
|
466
|
-
accessToken: 'valid-access-token',
|
|
467
|
-
customerId: '123456789',
|
|
468
|
-
developerToken: 'test-developer-token',
|
|
469
|
-
},
|
|
470
|
-
requestData: {
|
|
471
|
-
job: {
|
|
472
|
-
storeSalesMetadata: {
|
|
473
|
-
custom_key: 'CUSTOM_KEY',
|
|
474
|
-
loyaltyFraction: 1,
|
|
475
|
-
transaction_upload_fraction: '1',
|
|
476
|
-
},
|
|
477
|
-
type: 'STORE_SALES_UPLOAD_FIRST_PARTY',
|
|
478
|
-
},
|
|
479
|
-
},
|
|
480
|
-
status: 200,
|
|
481
|
-
mockResponse: {
|
|
482
|
-
resourceName: 'customers/123456789/offlineUserDataJobs/5678',
|
|
483
|
-
},
|
|
484
|
-
expectedResult: {
|
|
485
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
486
|
-
responseBody: {
|
|
487
|
-
resourceName: 'customers/123456789/offlineUserDataJobs/5678',
|
|
488
|
-
},
|
|
489
|
-
statusCode: 200,
|
|
490
|
-
type: 'success',
|
|
491
|
-
},
|
|
492
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
493
|
-
},
|
|
494
|
-
];
|
|
495
|
-
TestCases.forEach(({ name, authObject, mockResponse, status, requestData, expectedResult, mockResponseHeader, }) => {
|
|
496
|
-
it(name, async () => {
|
|
497
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
498
|
-
mock
|
|
499
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789/offlineUserDataJobs:create')
|
|
500
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
501
|
-
const result = await googleAds.createOfflineUserDataJob(requestData);
|
|
502
|
-
expect(result).toEqual(expectedResult);
|
|
503
|
-
});
|
|
504
|
-
});
|
|
505
|
-
});
|
|
506
|
-
describe('Test addUserToOfflineUserDataJob function', () => {
|
|
507
|
-
const TestCases = [
|
|
508
|
-
{
|
|
509
|
-
name: 'should successfully add user data to an offline user data job',
|
|
510
|
-
authObject: {
|
|
511
|
-
accessToken: 'valid-access-token',
|
|
512
|
-
customerId: '123456789',
|
|
513
|
-
developerToken: 'test-developer-token',
|
|
514
|
-
loginCustomerId: '987654321',
|
|
515
|
-
},
|
|
516
|
-
jobId: '1234',
|
|
517
|
-
requestData: {
|
|
518
|
-
operations: [
|
|
519
|
-
{
|
|
520
|
-
create: {
|
|
521
|
-
userIdentifiers: [{ hashedEmail: 'hashed_email_value' }],
|
|
522
|
-
},
|
|
523
|
-
},
|
|
524
|
-
],
|
|
525
|
-
enablePartialFailure: false,
|
|
526
|
-
},
|
|
527
|
-
status: 200,
|
|
528
|
-
mockResponse: {},
|
|
529
|
-
expectedResult: {
|
|
530
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
531
|
-
responseBody: {},
|
|
532
|
-
statusCode: 200,
|
|
533
|
-
type: 'success',
|
|
534
|
-
},
|
|
535
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
536
|
-
},
|
|
537
|
-
];
|
|
538
|
-
TestCases.forEach(({ name, authObject, mockResponse, status, requestData, expectedResult, mockResponseHeader, jobId, }) => {
|
|
539
|
-
it(name, async () => {
|
|
540
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
541
|
-
mock
|
|
542
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789/offlineUserDataJobs/1234:addOperations')
|
|
543
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
544
|
-
const result = await googleAds.addUserToOfflineUserDataJob(jobId, requestData);
|
|
545
|
-
expect(result).toEqual(expectedResult);
|
|
546
|
-
});
|
|
547
|
-
});
|
|
548
|
-
});
|
|
549
|
-
describe('Test addConversionsToOfflineUserDataJob function', () => {
|
|
550
|
-
const TestCases = [
|
|
551
|
-
{
|
|
552
|
-
name: 'should successfully add store sales conversion data to an offline user data job',
|
|
553
|
-
authObject: {
|
|
554
|
-
accessToken: 'valid-access-token',
|
|
555
|
-
customerId: '123456789',
|
|
556
|
-
developerToken: 'test-developer-token',
|
|
557
|
-
loginCustomerId: '987654321',
|
|
558
|
-
},
|
|
559
|
-
jobId: '1234',
|
|
560
|
-
requestData: {
|
|
561
|
-
operations: [
|
|
562
|
-
{
|
|
563
|
-
create: {
|
|
564
|
-
userIdentifiers: [{ hashedEmail: 'hashed-email-value' }],
|
|
565
|
-
transactionInfo: {
|
|
566
|
-
conversionAction: 'customers/123456789/conversionActions/987',
|
|
567
|
-
conversionDateTime: '2023-01-01 12:00:00',
|
|
568
|
-
conversionValue: 10.99,
|
|
569
|
-
currencyCode: 'USD',
|
|
570
|
-
},
|
|
571
|
-
},
|
|
572
|
-
},
|
|
573
|
-
],
|
|
574
|
-
enablePartialFailure: true,
|
|
575
|
-
},
|
|
576
|
-
status: 200,
|
|
577
|
-
mockResponse: {},
|
|
578
|
-
expectedResult: {
|
|
579
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
580
|
-
responseBody: {},
|
|
581
|
-
statusCode: 200,
|
|
582
|
-
type: 'success',
|
|
583
|
-
},
|
|
584
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
585
|
-
},
|
|
586
|
-
];
|
|
587
|
-
TestCases.forEach(({ name, authObject, mockResponse, status, requestData, expectedResult, mockResponseHeader, jobId, }) => {
|
|
588
|
-
it(name, async () => {
|
|
589
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
590
|
-
mock
|
|
591
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789/offlineUserDataJobs/1234:addOperations')
|
|
592
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
593
|
-
const result = await googleAds.addConversionsToOfflineUserDataJob(jobId, requestData);
|
|
594
|
-
expect(result).toEqual(expectedResult);
|
|
595
|
-
});
|
|
596
|
-
});
|
|
597
|
-
});
|
|
598
|
-
describe('Test runOfflineUserDataJob function', () => {
|
|
599
|
-
const TestCases = [
|
|
600
|
-
{
|
|
601
|
-
name: 'should successfully run an offline user data job with valid jobId',
|
|
602
|
-
authObject: {
|
|
603
|
-
accessToken: 'valid-access-token',
|
|
604
|
-
customerId: '123456789',
|
|
605
|
-
developerToken: 'test-developer-token',
|
|
606
|
-
loginCustomerId: '987654321',
|
|
607
|
-
},
|
|
608
|
-
jobId: '1234',
|
|
609
|
-
requestData: {},
|
|
610
|
-
status: 200,
|
|
611
|
-
mockResponse: {
|
|
612
|
-
success: true,
|
|
613
|
-
data: { name: 'test-job', done: true },
|
|
614
|
-
},
|
|
615
|
-
expectedResult: {
|
|
616
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
617
|
-
responseBody: {
|
|
618
|
-
success: true,
|
|
619
|
-
data: { name: 'test-job', done: true },
|
|
620
|
-
},
|
|
621
|
-
statusCode: 200,
|
|
622
|
-
type: 'success',
|
|
623
|
-
},
|
|
624
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
625
|
-
},
|
|
626
|
-
];
|
|
627
|
-
TestCases.forEach(({ name, authObject, mockResponse, status, expectedResult, mockResponseHeader, jobId }) => {
|
|
628
|
-
it(name, async () => {
|
|
629
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
630
|
-
mock
|
|
631
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789/offlineUserDataJobs/1234:run')
|
|
632
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
633
|
-
const result = await googleAds.runOfflineUserDataJob(jobId);
|
|
634
|
-
expect(result).toEqual(expectedResult);
|
|
635
|
-
});
|
|
636
|
-
});
|
|
637
|
-
});
|
|
638
|
-
describe('Test uploadClickConversion function', () => {
|
|
639
|
-
const TestCases = [
|
|
640
|
-
{
|
|
641
|
-
name: 'should successfully add user data to an offline user data job',
|
|
642
|
-
authObject: {
|
|
643
|
-
accessToken: 'valid-access-token',
|
|
644
|
-
customerId: '123456789',
|
|
645
|
-
developerToken: 'test-developer-token',
|
|
646
|
-
loginCustomerId: '987654321',
|
|
647
|
-
},
|
|
648
|
-
requestData: {
|
|
649
|
-
conversions: [
|
|
650
|
-
{
|
|
651
|
-
gclid: 'test-gclid',
|
|
652
|
-
conversionAction: 'test-action',
|
|
653
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
654
|
-
conversionValue: 100,
|
|
655
|
-
currencyCode: 'USD',
|
|
656
|
-
},
|
|
657
|
-
],
|
|
658
|
-
},
|
|
659
|
-
status: 200,
|
|
660
|
-
mockResponse: {
|
|
661
|
-
success: true,
|
|
662
|
-
data: {
|
|
663
|
-
results: [
|
|
664
|
-
{
|
|
665
|
-
gclid: 'test-gclid',
|
|
666
|
-
conversionAction: 'test-action',
|
|
667
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
668
|
-
},
|
|
669
|
-
],
|
|
670
|
-
},
|
|
671
|
-
},
|
|
672
|
-
expectedResult: {
|
|
673
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
674
|
-
responseBody: {
|
|
675
|
-
data: {
|
|
676
|
-
results: [
|
|
677
|
-
{
|
|
678
|
-
conversionAction: 'test-action',
|
|
679
|
-
conversionDateTime: '2023-01-01T00:00:00Z',
|
|
680
|
-
gclid: 'test-gclid',
|
|
681
|
-
},
|
|
682
|
-
],
|
|
683
|
-
},
|
|
684
|
-
success: true,
|
|
685
|
-
},
|
|
686
|
-
statusCode: 200,
|
|
687
|
-
type: 'success',
|
|
688
|
-
},
|
|
689
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
690
|
-
},
|
|
691
|
-
];
|
|
692
|
-
TestCases.forEach(({ name, authObject, mockResponse, status, expectedResult, mockResponseHeader, requestData, }) => {
|
|
693
|
-
it(name, async () => {
|
|
694
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
695
|
-
mock
|
|
696
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789:uploadClickConversions')
|
|
697
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
698
|
-
const result = await googleAds.uploadClickConversion(requestData);
|
|
699
|
-
expect(result).toEqual(expectedResult);
|
|
700
|
-
});
|
|
701
|
-
});
|
|
702
|
-
});
|
|
703
|
-
describe('Test uploadCallConversion function', () => {
|
|
704
|
-
const TestCases = [
|
|
705
|
-
{
|
|
706
|
-
name: 'should successfully upload call conversion data and return a successful response',
|
|
707
|
-
authObject: {
|
|
708
|
-
accessToken: 'valid-access-token',
|
|
709
|
-
customerId: '123456789',
|
|
710
|
-
developerToken: 'test-developer-token',
|
|
711
|
-
loginCustomerId: '987654321',
|
|
712
|
-
},
|
|
713
|
-
requestData: {
|
|
714
|
-
conversions: [
|
|
715
|
-
{
|
|
716
|
-
callerId: '1234567890',
|
|
717
|
-
callStartDateTime: '2023-01-01T12:00:00Z',
|
|
718
|
-
conversionAction: 'action1',
|
|
719
|
-
conversionDateTime: '2023-01-01T12:05:00Z',
|
|
720
|
-
},
|
|
721
|
-
],
|
|
722
|
-
partialFailure: false,
|
|
723
|
-
},
|
|
724
|
-
status: 200,
|
|
725
|
-
mockResponse: {
|
|
726
|
-
success: true,
|
|
727
|
-
data: {
|
|
728
|
-
results: [
|
|
729
|
-
{
|
|
730
|
-
callerId: '1234567890',
|
|
731
|
-
callStartDateTime: '2023-01-01T12:00:00Z',
|
|
732
|
-
conversionAction: 'action1',
|
|
733
|
-
conversionDateTime: '2023-01-01T12:05:00Z',
|
|
734
|
-
},
|
|
735
|
-
],
|
|
736
|
-
},
|
|
737
|
-
},
|
|
738
|
-
expectedResult: {
|
|
739
|
-
headers: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
740
|
-
responseBody: {
|
|
741
|
-
data: {
|
|
742
|
-
results: [
|
|
743
|
-
{
|
|
744
|
-
callStartDateTime: '2023-01-01T12:00:00Z',
|
|
745
|
-
callerId: '1234567890',
|
|
746
|
-
conversionAction: 'action1',
|
|
747
|
-
conversionDateTime: '2023-01-01T12:05:00Z',
|
|
748
|
-
},
|
|
749
|
-
],
|
|
750
|
-
},
|
|
751
|
-
success: true,
|
|
752
|
-
},
|
|
753
|
-
statusCode: 200,
|
|
754
|
-
type: 'success',
|
|
755
|
-
},
|
|
756
|
-
mockResponseHeader: new axios_1.AxiosHeaders({ 'Content-Type': 'application/json' }),
|
|
757
|
-
},
|
|
758
|
-
];
|
|
759
|
-
TestCases.forEach(({ name, authObject, mockResponse, status, expectedResult, mockResponseHeader, requestData, }) => {
|
|
760
|
-
it(name, async () => {
|
|
761
|
-
const googleAds = new googleAds_1.default(authObject);
|
|
762
|
-
mock
|
|
763
|
-
.onPost('https://googleads.googleapis.com/v19/customers/123456789:uploadClickConversions')
|
|
764
|
-
.reply(status, mockResponse, mockResponseHeader);
|
|
765
|
-
const result = await googleAds.uploadClickConversion(requestData);
|
|
766
|
-
expect(result).toEqual(expectedResult);
|
|
767
|
-
});
|
|
768
|
-
});
|
|
769
|
-
});
|
|
770
|
-
});
|
|
771
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlQWRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2Rrcy9nb29nbGVBZHNSZXN0QVBJL2dvb2dsZUFkcy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNEVBQWtEO0FBQ2xELCtDQUE0QztBQUM1Qyw0REFBb0M7QUFFcEMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEdBQUcsRUFBRTtJQUM5QixJQUFJLElBQXNCLENBQUM7SUFFM0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLElBQUksR0FBRyxJQUFJLDRCQUFnQixDQUFDLGVBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7SUFDdEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2IsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pCLENBQUMsQ0FBQyxDQUFDO0lBQ0gsUUFBUSxDQUFDLG1DQUFtQyxFQUFFLEdBQUcsRUFBRTtRQUNqRCxNQUFNLFNBQVMsR0FBRztZQUNoQjtnQkFDRSxJQUFJLEVBQUUsc0VBQXNFO2dCQUM1RSxVQUFVLEVBQUU7b0JBQ1YsV0FBVyxFQUFFLG1CQUFtQjtvQkFDaEMsVUFBVSxFQUFFLFdBQVc7b0JBQ3ZCLGNBQWMsRUFBRSxzQkFBc0I7aUJBQ3ZDO2dCQUNELFlBQVksRUFBRTtvQkFDWjt3QkFDRSxPQUFPLEVBQUU7NEJBQ1A7Z0NBQ0UsZ0JBQWdCLEVBQUU7b0NBQ2hCLFlBQVksRUFBRSwrQ0FBK0M7b0NBQzdELEVBQUUsRUFBRSxTQUFTO2lDQUNkOzZCQUNGO3lCQUNGO3FCQUNGO2lCQUNGO2dCQUNELGNBQWMsRUFBRSxpQkFBaUI7Z0JBQ2pDLE1BQU0sRUFBRSxHQUFHO2dCQUNYLGNBQWMsRUFBRSwrQ0FBK0M7Z0JBQy9ELGVBQWUsRUFBRTtvQkFDZixHQUFHLEVB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LE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDekMsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQ0YsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQXhpb3NNb2NrQWRhcHRlciBmcm9tICdheGlvcy1tb2NrLWFkYXB0ZXInO1xuaW1wb3J0IGF4aW9zLCB7IEF4aW9zSGVhZGVycyB9IGZyb20gJ2F4aW9zJztcbmltcG9ydCBHb29nbGVBZHMgZnJvbSAnLi9nb29nbGVBZHMnO1xuXG5kZXNjcmliZSgnR29vZ2xlIGFkcyBTREsnLCAoKSA9PiB7XG4gIGxldCBtb2NrOiBBeGlvc01vY2tBZGFwdGVyO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIG1vY2sgPSBuZXcgQXhpb3NNb2NrQWRhcHRlcihheGlvcywgeyBvbk5vTWF0Y2g6ICd0aHJvd0V4Y2VwdGlvbicgfSk7XG4gIH0pO1xuXG4gIGFmdGVyRWFjaCgoKSA9PiB7XG4gICAgbW9jay5yZXN0b3JlKCk7XG4gIH0pO1xuICBkZXNjcmliZSgnVGVzdCBnZXRDb252ZXJzaW9uQWN0aW9uIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IHRlc3RDYXNlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Nob3VsZCByZXR1cm4gY29udmVyc2lvbiBhY3Rpb24gSUQgd2hlbiBBUEkgcmV0dXJucyBzdWNjZXNzIHJlc3BvbnNlJyxcbiAgICAgICAgYXV0aE9iamVjdDoge1xuICAgICAgICAgIGFjY2Vzc1Rva2VuOiAndGVzdC1hY2Nlc3MtdG9rZW4nLFxuICAgICAgICAgIGN1c3RvbWVySWQ6ICcxMjM0NTY3ODknLFxuICAgICAgICAgIGRldmVsb3BlclRva2VuOiAndGVzdC1kZXZlbG9wZXItdG9rZW4nLFxuICAgICAgICB9LFxuICAgICAgICBtb2NrUmVzcG9uc2U6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXN1bHRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb252ZXJzaW9uQWN0aW9uOiB7XG4gICAgICAgICAgICAgICAgICByZXNvdXJjZU5hbWU6ICdjdXN0b21lcnMvMTIzNDU2Nzg5L2NvbnZlcnNpb25BY3Rpb25zLzk4NzY1NDMnLFxuICAgICAgICAgICAgICAgICAgaWQ6ICc5ODc2NTQzJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBjb252ZXJzaW9uTmFtZTogJ3Rlc3RfY29udmVyc2lvbicsXG4gICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICBleHBlY3RlZFJlc3VsdDogJ2N1c3RvbWVycy8xMjM0NTY3ODkvY29udmVyc2lvbkFjdGlvbnMvOTg3NjU0MycsXG4gICAgICAgIGV4cGVjdGVkUmVxdWVzdDoge1xuICAgICAgICAgIHVybDogJy8xMjM0NTY3ODkvZ29vZ2xlQWRzOnNlYXJjaFN0cmVhbScsXG4gICAgICAgICAgZGF0YTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgcXVlcnk6XG4gICAgICAgICAgICAgIFwiU0VMRUNUIGNvbnZlcnNpb25fYWN0aW9uLmlkIEZST00gY29udmVyc2lvbl9hY3Rpb24gV0hFUkUgY29udmVyc2lvbl9hY3Rpb24ubmFtZSA9ICd0ZXN0X2NvbnZlcnNpb24nXCIsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnaGFuZGxlIGZhaWx1cmUgc2NlbmFyaW8gd2hlbiBhY2Nlc3NUb2tlbiBpcyB3cm9uZycsXG4gICAgICAgIGF1dGhPYmplY3Q6IHtcbiAgICAgICAgICBjdXN0b21lcklkOiAnMTIzNDU2Nzg5JyxcbiAgICAgICAgICBkZXZlbG9wZXJUb2tlbjogJ3Rlc3QtZGV2ZWxvcGVyLXRva2VuJyxcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ3dyb25nLWFjY2Vzcy10b2tlbicsXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZTogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgIGNvZGU6IDQwMSxcbiAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAnUmVxdWVzdCBoYWQgaW52YWxpZCBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFscy4gRXhwZWN0ZWQgT0F1dGggMiBhY2Nlc3MgdG9rZW4sIGxvZ2luIGNvb2tpZSBvciBvdGhlciB2YWxpZCBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFsLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vaWRlbnRpdHkvc2lnbi1pbi93ZWIvZGV2Y29uc29sZS1wcm9qZWN0LicsXG4gICAgICAgICAgICAgIHN0YXR1czogJ1VOQVVUSEVOVElDQVRFRCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcjogbmV3IEF4aW9zSGVhZGVycyh7XG4gICAgICAgICAgJ3RyYW5zZmVyLWVuY29kaW5nJzogJ2NodW5rZWQnLFxuICAgICAgICB9KSxcbiAgICAgICAgY29udmVyc2lvbk5hbWU6ICd0ZXN0X2NvbnZlcnNpb24nLFxuICAgICAgICBzdGF0dXM6IDQwMSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IHtcbiAgICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzKHtcbiAgICAgICAgICAgICd0cmFuc2Zlci1lbmNvZGluZyc6ICdjaHVua2VkJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBtZXNzYWdlOiB1bmRlZmluZWQsXG4gICAgICAgICAgcmVzcG9uc2VCb2R5OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgICAgY29kZTogNDAxLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAgICAgICAnUmVxdWVzdCBoYWQgaW52YWxpZCBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFscy4gRXhwZWN0ZWQgT0F1dGggMiBhY2Nlc3MgdG9rZW4sIGxvZ2luIGNvb2tpZSBvciBvdGhlciB2YWxpZCBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFsLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vaWRlbnRpdHkvc2lnbi1pbi93ZWIvZGV2Y29uc29sZS1wcm9qZWN0LicsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiAnVU5BVVRIRU5USUNBVEVEJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBzdGF0dXNDb2RlOiA0MDEsXG4gICAgICAgICAgdHlwZTogJ2FwcGxpY2F0aW9uLWVycm9yJyxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwZWN0ZWRSZXF1ZXN0OiB7XG4gICAgICAgICAgdXJsOiAnLzEyMzQ1Njc4OS9nb29nbGVBZHM6c2VhcmNoU3RyZWFtJyxcbiAgICAgICAgICBkYXRhOiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBxdWVyeTpcbiAgICAgICAgICAgICAgXCJTRUxFQ1QgY29udmVyc2lvbl9hY3Rpb24uaWQgRlJPTSBjb252ZXJzaW9uX2FjdGlvbiBXSEVSRSBjb252ZXJzaW9uX2FjdGlvbi5uYW1lID0gJ3Rlc3RfY29udmVyc2lvbidcIixcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdoYW5kbGUgdGhlIHNpdHVhdGlvbiB3aGVuIHRoZSBjb252ZXJzaW9uIGlzIG5vdCBhdmFpbGFibGUnLFxuICAgICAgICBhdXRoT2JqZWN0OiB7XG4gICAgICAgICAgYWNjZXNzVG9rZW46ICd0ZXN0LWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgY3VzdG9tZXJJZDogJzEyMzQ1Njc4OScsXG4gICAgICAgICAgZGV2ZWxvcGVyVG9rZW46ICd0ZXN0LWRldmVsb3Blci10b2tlbicsXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZTogW10sXG4gICAgICAgIGNvbnZlcnNpb25OYW1lOiAnbm9uLWV4aXN0aW5nLWNvbnZlcnNpb24nLFxuICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IG51bGwsXG4gICAgICAgIGV4cGVjdGVkUmVxdWVzdDoge1xuICAgICAgICAgIHVybDogJy8xMjM0NTY3ODkvZ29vZ2xlQWRzOnNlYXJjaFN0cmVhbScsXG4gICAgICAgICAgZGF0YTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgcXVlcnk6XG4gICAgICAgICAgICAgIFwiU0VMRUNUIGNvbnZlcnNpb25fYWN0aW9uLmlkIEZST00gY29udmVyc2lvbl9hY3Rpb24gV0hFUkUgY29udmVyc2lvbl9hY3Rpb24ubmFtZSA9ICdub24tZXhpc3RpbmctY29udmVyc2lvbidcIixcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICB0ZXN0Q2FzZXMuZm9yRWFjaChcbiAgICAgICh7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGF1dGhPYmplY3QsXG4gICAgICAgIG1vY2tSZXNwb25zZSxcbiAgICAgICAgY29udmVyc2lvbk5hbWUsXG4gICAgICAgIGV4cGVjdGVkUmVxdWVzdCxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQsXG4gICAgICAgIHN0YXR1cyxcbiAgICAgICAgbW9ja1Jlc3BvbnNlSGVhZGVyLFxuICAgICAgfSkgPT4ge1xuICAgICAgICBpdChuYW1lLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ29vZ2xlQWRzID0gbmV3IEdvb2dsZUFkcyhhdXRoT2JqZWN0KTtcbiAgICAgICAgICBtb2NrXG4gICAgICAgICAgICAub25Qb3N0KFxuICAgICAgICAgICAgICAnaHR0cHM6Ly9nb29nbGVhZHMuZ29vZ2xlYXBpcy5jb20vdjE5L2N1c3RvbWVycy8xMjM0NTY3ODkvZ29vZ2xlQWRzOnNlYXJjaFN0cmVhbScsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucmVwbHkoc3RhdHVzLCBtb2NrUmVzcG9uc2UsIG1vY2tSZXNwb25zZUhlYWRlcik7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ29vZ2xlQWRzLmdldENvbnZlcnNpb25BY3Rpb25JZChjb252ZXJzaW9uTmFtZSk7XG4gICAgICAgICAgZXhwZWN0KG1vY2suaGlzdG9yeS5wb3N0WzBdKS50b01hdGNoT2JqZWN0KGV4cGVjdGVkUmVxdWVzdCk7XG4gICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbChleHBlY3RlZFJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICApO1xuICB9KTtcblxuICBkZXNjcmliZSgnVGVzdCBnZXRDdXN0b21WYXJpYWJsZSBmdW5jdGlvbicsICgpID0+IHtcbiAgICBjb25zdCB0ZXN0Q2FzZXMgPSBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzaG91bGQgcmV0dXJuIGFuIGFycmF5IG9mIEN1c3RvbVZhcmlhYmxlUmVzdWx0cyB3aGVuIEFQSSBjYWxsIHN1Y2NlZWRzJyxcbiAgICAgICAgYXV0aE9iamVjdDoge1xuICAgICAgICAgIGFjY2Vzc1Rva2VuOiAndGVzdC1hY2Nlc3MtdG9rZW4nLFxuICAgICAgICAgIGN1c3RvbWVySWQ6ICcxMjM0NTY3ODknLFxuICAgICAgICAgIGRldmVsb3BlclRva2VuOiAndGVzdC1kZXZlbG9wZXItdG9rZW4nLFxuICAgICAgICB9LFxuICAgICAgICBtb2NrUmVzcG9uc2U6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXN1bHRzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBjb252ZXJzaW9uQ3VzdG9tVmFyaWFibGU6IHtcbiAgICAgICAgICAgICAgICAgIHJlc291cmNlTmFtZTogJ2N1c3RvbWVycy8xMjMvY29udmVyc2lvbkN1c3RvbVZhcmlhYmxlcy80NTYnLFxuICAgICAgICAgICAgICAgICAgbmFtZTogJ3Rlc3RfdmFyaWFibGUnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgZmllbGRNYXNrOiAnY29udmVyc2lvbl9jdXN0b21fdmFyaWFibGUubmFtZScsXG4gICAgICAgICAgICByZXF1ZXN0SWQ6ICcxMjM0NTYnLFxuICAgICAgICAgICAgcXVlcnlSZXNvdXJjZUNvbnN1bXB0aW9uOiAnMTAwJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb252ZXJzaW9uQ3VzdG9tVmFyaWFibGU6IHtcbiAgICAgICAgICAgICAgcmVzb3VyY2VOYW1lOiAnY3VzdG9tZXJzLzEyMy9jb252ZXJzaW9uQ3VzdG9tVmFyaWFibGVzLzQ1NicsXG4gICAgICAgICAgICAgIG5hbWU6ICd0ZXN0X3ZhcmlhYmxlJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZXhwZWN0ZWRSZXF1ZXN0OiB7XG4gICAgICAgICAgdXJsOiAnLzEyMzQ1Njc4OS9nb29nbGVBZHM6c2VhcmNoU3RyZWFtJyxcbiAgICAgICAgICBkYXRhOiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBxdWVyeTogJ1NFTEVDVCBjb252ZXJzaW9uX2N1c3RvbV92YXJpYWJsZS5uYW1lIEZST00gY29udmVyc2lvbl9jdXN0b21fdmFyaWFibGUnLFxuICAgICAgICAgIH0pLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Nob3VsZCBoYW5kbGUgdGhlIHNjZW5hcmlvIHdoZW4gdGhlcmUgaXMgbm90IGFueSBjdXN0b21WYXJpYWJsZXMnLFxuICAgICAgICBhdXRoT2JqZWN0OiB7XG4gICAgICAgICAgYWNjZXNzVG9rZW46ICd0ZXN0LWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgY3VzdG9tZXJJZDogJzEyMzQ1Njc4OScsXG4gICAgICAgICAgZGV2ZWxvcGVyVG9rZW46ICd0ZXN0LWRldmVsb3Blci10b2tlbicsXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICBtb2NrUmVzcG9uc2U6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXN1bHRzOiBbXSxcbiAgICAgICAgICAgIGZpZWxkTWFzazogJ2NvbnZlcnNpb25fY3VzdG9tX3ZhcmlhYmxlLm5hbWUnLFxuICAgICAgICAgICAgcmVxdWVzdElkOiAnMTIzNDU2JyxcbiAgICAgICAgICAgIHF1ZXJ5UmVzb3VyY2VDb25zdW1wdGlvbjogJzEwMCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IFtdLFxuICAgICAgICBleHBlY3RlZFJlcXVlc3Q6IHtcbiAgICAgICAgICB1cmw6ICcvMTIzNDU2Nzg5L2dvb2dsZUFkczpzZWFyY2hTdHJlYW0nLFxuICAgICAgICAgIGRhdGE6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIHF1ZXJ5OiAnU0VMRUNUIGNvbnZlcnNpb25fY3VzdG9tX3ZhcmlhYmxlLm5hbWUgRlJPTSBjb252ZXJzaW9uX2N1c3RvbV92YXJpYWJsZScsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2hvdWxkIHJldHVybiBhbiBhcnJheSBvZiBDdXN0b21WYXJpYWJsZVJlc3VsdHMgd2hlbiBBUEkgY2FsbCBzdWNjZWVkcycsXG4gICAgICAgIGF1dGhPYmplY3Q6IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ3dyb25nLWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgY3VzdG9tZXJJZDogJzEyMzQ1Njc4OScsXG4gICAgICAgICAgZGV2ZWxvcGVyVG9rZW46ICd0ZXN0LWRldmVsb3Blci10b2tlbicsXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZTogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGVycm9yOiB7XG4gICAgICAgICAgICAgIGNvZGU6IDQwMSxcbiAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAnUmVxdWVzdCBoYWQgaW52YWxpZCBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFscy4gRXhwZWN0ZWQgT0F1dGggMiBhY2Nlc3MgdG9rZW4sIGxvZ2luIGNvb2tpZSBvciBvdGhlciB2YWxpZCBhdXRoZW50aWNhdGlvbiBjcmVkZW50aWFsLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vaWRlbnRpdHkvc2lnbi1pbi93ZWIvZGV2Y29uc29sZS1wcm9qZWN0LicsXG4gICAgICAgICAgICAgIHN0YXR1czogJ1VOQVVUSEVOVElDQVRFRCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICBleHBlY3RlZFJlc3VsdDoge1xuICAgICAgICAgIGhlYWRlcnM6IG5ldyBBeGlvc0hlYWRlcnMoe1xuICAgICAgICAgICAgJ3RyYW5zZmVyLWVuY29kaW5nJzogJ2NodW5rZWQnLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIG1lc3NhZ2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgICBjb2RlOiA0MDEsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICdSZXF1ZXN0IGhhZCBpbnZhbGlkIGF1dGhlbnRpY2F0aW9uIGNyZWRlbnRpYWxzLiBFeHBlY3RlZCBPQXV0aCAyIGFjY2VzcyB0b2tlbiwgbG9naW4gY29va2llIG9yIG90aGVyIHZhbGlkIGF1dGhlbnRpY2F0aW9uIGNyZWRlbnRpYWwuIFNlZSBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9pZGVudGl0eS9zaWduLWluL3dlYi9kZXZjb25zb2xlLXByb2plY3QuJyxcbiAgICAgICAgICAgICAgICBzdGF0dXM6ICdVTkFVVEhFTlRJQ0FURUQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDQwMSxcbiAgICAgICAgICB0eXBlOiAnYXBwbGljYXRpb24tZXJyb3InLFxuICAgICAgICB9LFxuICAgICAgICBleHBlY3RlZFJlcXVlc3Q6IHtcbiAgICAgICAgICB1cmw6ICcvMTIzNDU2Nzg5L2dvb2dsZUFkczpzZWFyY2hTdHJlYW0nLFxuICAgICAgICAgIGRhdGE6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIHF1ZXJ5OiAnU0VMRUNUIGNvbnZlcnNpb25fY3VzdG9tX3ZhcmlhYmxlLm5hbWUgRlJPTSBjb252ZXJzaW9uX2N1c3RvbV92YXJpYWJsZScsXG4gICAgICAgICAgfSksXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcjogbmV3IEF4aW9zSGVhZGVycyh7XG4gICAgICAgICAgJ3RyYW5zZmVyLWVuY29kaW5nJzogJ2NodW5rZWQnLFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIHRlc3RDYXNlcy5mb3JFYWNoKFxuICAgICAgKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgYXV0aE9iamVjdCxcbiAgICAgICAgbW9ja1Jlc3BvbnNlLFxuICAgICAgICBleHBlY3RlZFJlcXVlc3QsXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0LFxuICAgICAgICBzdGF0dXMsXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcixcbiAgICAgIH0pID0+IHtcbiAgICAgICAgaXQobmFtZSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGdvb2dsZUFkcyA9IG5ldyBHb29nbGVBZHMoYXV0aE9iamVjdCk7XG4gICAgICAgICAgbW9ja1xuICAgICAgICAgICAgLm9uUG9zdChcbiAgICAgICAgICAgICAgJ2h0dHBzOi8vZ29vZ2xlYWRzLmdvb2dsZWFwaXMuY29tL3YxOS9jdXN0b21lcnMvMTIzNDU2Nzg5L2dvb2dsZUFkczpzZWFyY2hTdHJlYW0nLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KHN0YXR1cywgbW9ja1Jlc3BvbnNlLCBtb2NrUmVzcG9uc2VIZWFkZXIpO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdvb2dsZUFkcy5nZXRDdXN0b21WYXJpYWJsZSgpO1xuICAgICAgICAgIGV4cGVjdChtb2NrLmhpc3RvcnkucG9zdFswXSkudG9NYXRjaE9iamVjdChleHBlY3RlZFJlcXVlc3QpO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Rlc3QgYWRkQ29udmVyc2lvbkFkanVzdE1lbnQgZnVuY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgVGVzdENhc2VzID0gW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnc2hvdWxkIHN1Y2Nlc3NmdWxseSB1cGxvYWQgY29udmVyc2lvbiBhZGp1c3RtZW50cyB3aXRoIHZhbGlkIGRhdGEnLFxuICAgICAgICBhdXRoT2JqZWN0OiB7XG4gICAgICAgICAgYWNjZXNzVG9rZW46ICd2YWxpZC1hY2Nlc3MtdG9rZW4nLFxuICAgICAgICAgIGN1c3RvbWVySWQ6ICcxMjM0NTY3ODknLFxuICAgICAgICAgIGRldmVsb3BlclRva2VuOiAndGVzdC1kZXZlbG9wZXItdG9rZW4nLFxuICAgICAgICB9LFxuICAgICAgICByZXF1ZXN0RGF0YToge1xuICAgICAgICAgIGNvbnZlcnNpb25BZGp1c3RtZW50czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBnY2xpZERhdGVUaW1lUGFpcjoge1xuICAgICAgICAgICAgICAgIGdjbGlkOiAndGVzdC1nY2xpZCcsXG4gICAgICAgICAgICAgICAgY29udmVyc2lvbkRhdGVUaW1lOiAnMjAyMy0wMS0wMVQwMDowMDowMFonLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhZGp1c3RtZW50VHlwZTogJ1JFU1RBVEVNRU5UJyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgcmVzdGF0ZW1lbnRWYWx1ZToge1xuICAgICAgICAgICAgICAgIGFkanVzdGVkVmFsdWU6IDEwMCxcbiAgICAgICAgICAgICAgICBjdXJyZW5jeUNvZGU6ICdVU0QnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB1c2VySWRlbnRpZmllcnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB1c2VySWRlbnRpZmllclNvdXJjZTogJ0ZJUlNUX1BBUlRZJyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIGhhc2hlZEVtYWlsOiAnMzg5MjA1OTA0ZDZjN2JiODNmYzY3NjUxMzkxMTIyNmYyYmUyNWJmMTQ2NTYxNmJiOWIyOTU4NzEwMGFiMTQxNCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXJ0aWFsRmFpbHVyZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICBtb2NrUmVzcG9uc2U6IHtcbiAgICAgICAgICBjb252ZXJzaW9uQWRqdXN0bWVudHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZ2NsaWREYXRlVGltZVBhaXI6IHtcbiAgICAgICAgICAgICAgICBnY2xpZDogJ3Rlc3QtZ2NsaWQnLFxuICAgICAgICAgICAgICAgIGNvbnZlcnNpb25EYXRlVGltZTogJzIwMjMtMDEtMDFUMDA6MDA6MDBaJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgYWRqdXN0bWVudFR5cGU6ICdSRVNUQVRFTUVOVCcsXG4gICAgICAgICAgICAgIHJlc3RhdGVtZW50VmFsdWU6IHtcbiAgICAgICAgICAgICAgICBhZGp1c3RlZFZhbHVlOiAxMDAsXG4gICAgICAgICAgICAgICAgY3VycmVuY3lDb2RlOiAnVVNEJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdXNlcklkZW50aWZpZXJzOiBbXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXJ0aWFsRmFpbHVyZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0OiB7XG4gICAgICAgICAgdHlwZTogJ3N1Y2Nlc3MnLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IHtcbiAgICAgICAgICAgIGNvbnZlcnNpb25BZGp1c3RtZW50czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZ2NsaWREYXRlVGltZVBhaXI6IHtcbiAgICAgICAgICAgICAgICAgIGdjbGlkOiAndGVzdC1nY2xpZCcsXG4gICAgICAgICAgICAgICAgICBjb252ZXJzaW9uRGF0ZVRpbWU6ICcyMDIzLTAxLTAxVDAwOjAwOjAwWicsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBhZGp1c3RtZW50VHlwZTogJ1JFU1RBVEVNRU5UJyxcbiAgICAgICAgICAgICAgICByZXN0YXRlbWVudFZhbHVlOiB7IGFkanVzdGVkVmFsdWU6IDEwMCwgY3VycmVuY3lDb2RlOiAnVVNEJyB9LFxuICAgICAgICAgICAgICAgIHVzZXJJZGVudGlmaWVyczogW10sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgcGFydGlhbEZhaWx1cmU6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaGVhZGVyczogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcjogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2hvdWxkIHN1Y2Nlc3NmdWxseSBoYW5kbGUgZmFpbHVyZSBzY2VuYXJpbycsXG4gICAgICAgIGF1dGhPYmplY3Q6IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ3dyb25nLWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgY3VzdG9tZXJJZDogJzEyMzQ1Njc4OScsXG4gICAgICAgICAgZGV2ZWxvcGVyVG9rZW46ICd0ZXN0LWRldmVsb3Blci10b2tlbicsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3REYXRhOiB7XG4gICAgICAgICAgY29udmVyc2lvbkFkanVzdG1lbnRzOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGdjbGlkRGF0ZVRpbWVQYWlyOiB7XG4gICAgICAgICAgICAgICAgZ2NsaWQ6ICd0ZXN0LWdjbGlkJyxcbiAgICAgICAgICAgICAgICBjb252ZXJzaW9uRGF0ZVRpbWU6ICcyMDIzLTAxLTAxVDAwOjAwOjAwWicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGFkanVzdG1lbnRUeXBlOiAnUkVTVEFURU1FTlQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgICByZXN0YXRlbWVudFZhbHVlOiB7XG4gICAgICAgICAgICAgICAgYWRqdXN0ZWRWYWx1ZTogMTAwLFxuICAgICAgICAgICAgICAgIGN1cnJlbmN5Q29kZTogJ1VTRCcsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHVzZXJJZGVudGlmaWVyczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHVzZXJJZGVudGlmaWVyU291cmNlOiAnRklSU1RfUEFSVFknIGFzIGNvbnN0LFxuICAgICAgICAgICAgICAgICAgaGFzaGVkRW1haWw6ICczODkyMDU5MDRkNmM3YmI4M2ZjNjc2NTEzOTExMjI2ZjJiZTI1YmYxNDY1NjE2YmI5YjI5NTg3MTAwYWIxNDE0JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBhcnRpYWxGYWlsdXJlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RhdHVzOiA0MDEsXG4gICAgICAgIG1vY2tSZXNwb25zZToge1xuICAgICAgICAgIGhlYWRlcnM6IG5ldyBBeGlvc0hlYWRlcnMoe1xuICAgICAgICAgICAgJ3RyYW5zZmVyLWVuY29kaW5nJzogJ2NodW5rZWQnLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIG1lc3NhZ2U6IHVuZGVmaW5lZCxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXJyb3I6IHtcbiAgICAgICAgICAgICAgICBjb2RlOiA0MDEsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICdSZXF1ZXN0IGhhZCBpbnZhbGlkIGF1dGhlbnRpY2F0aW9uIGNyZWRlbnRpYWxzLiBFeHBlY3RlZCBPQXV0aCAyIGFjY2VzcyB0b2tlbiwgbG9naW4gY29va2llIG9yIG90aGVyIHZhbGlkIGF1dGhlbnRpY2F0aW9uIGNyZWRlbnRpYWwuIFNlZSBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9pZGVudGl0eS9zaWduLWluL3dlYi9kZXZjb25zb2xlLXByb2plY3QuJyxcbiAgICAgICAgICAgICAgICBzdGF0dXM6ICdVTkFVVEhFTlRJQ0FURUQnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDQwMSxcbiAgICAgICAgICB0eXBlOiAnYXBwbGljYXRpb24tZXJyb3InLFxuICAgICAgICB9LFxuICAgICAgICBleHBlY3RlZFJlc3VsdDoge1xuICAgICAgICAgIGhlYWRlcnM6IG5ldyBBeGlvc0hlYWRlcnMoe1xuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBtZXNzYWdlOiB1bmRlZmluZWQsXG4gICAgICAgICAgcmVzcG9uc2VCb2R5OiB7XG4gICAgICAgICAgICBoZWFkZXJzOiB7ICd0cmFuc2Zlci1lbmNvZGluZyc6ICdjaHVua2VkJyB9LFxuICAgICAgICAgICAgcmVzcG9uc2VCb2R5OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgICAgICAgY29kZTogNDAxLFxuICAgICAgICAgICAgICAgICAgbWVzc2FnZTpcbiAgICAgICAgICAgICAgICAgICAgJ1JlcXVlc3QgaGFkIGludmFsaWQgYXV0aGVudGljYXRpb24gY3JlZGVudGlhbHMuIEV4cGVjdGVkIE9BdXRoIDIgYWNjZXNzIHRva2VuLCBsb2dpbiBjb29raWUgb3Igb3RoZXIgdmFsaWQgYXV0aGVudGljYXRpb24gY3JlZGVudGlhbC4gU2VlIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2lkZW50aXR5L3NpZ24taW4vd2ViL2RldmNvbnNvbGUtcHJvamVjdC4nLFxuICAgICAgICAgICAgICAgICAgc3RhdHVzOiAnVU5BVVRIRU5USUNBVEVEJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IDQwMSxcbiAgICAgICAgICAgIHR5cGU6ICdhcHBsaWNhdGlvbi1lcnJvcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0dXNDb2RlOiA0MDEsXG4gICAgICAgICAgdHlwZTogJ2FwcGxpY2F0aW9uLWVycm9yJyxcbiAgICAgICAgfSxcbiAgICAgICAgbW9ja1Jlc3BvbnNlSGVhZGVyOiBuZXcgQXhpb3NIZWFkZXJzKHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBUZXN0Q2FzZXMuZm9yRWFjaChcbiAgICAgICh7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGF1dGhPYmplY3QsXG4gICAgICAgIG1vY2tSZXNwb25zZSxcbiAgICAgICAgcmVxdWVzdERhdGEsXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0LFxuICAgICAgICBtb2NrUmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIHN0YXR1cyxcbiAgICAgIH0pID0+IHtcbiAgICAgICAgaXQobmFtZSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGdvb2dsZUFkcyA9IG5ldyBHb29nbGVBZHMoYXV0aE9iamVjdCk7XG4gICAgICAgICAgbW9ja1xuICAgICAgICAgICAgLm9uUG9zdChcbiAgICAgICAgICAgICAgJ2h0dHBzOi8vZ29vZ2xlYWRzLmdvb2dsZWFwaXMuY29tL3YxOS9jdXN0b21lcnMvMTIzNDU2Nzg5OnVwbG9hZENvbnZlcnNpb25BZGp1c3RtZW50cycsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucmVwbHkoc3RhdHVzLCBtb2NrUmVzcG9uc2UsIG1vY2tSZXNwb25zZUhlYWRlcik7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ29vZ2xlQWRzLmFkZENvbnZlcnNpb25BZGp1c3RNZW50KHJlcXVlc3REYXRhKTtcbiAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKGV4cGVjdGVkUmVzdWx0KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUZXN0IGNyZWF0ZU9mZmxpbmVVc2VyRGF0YUpvYiBmdW5jdGlvbicsICgpID0+IHtcbiAgICBjb25zdCBUZXN0Q2FzZXMgPSBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzaG91bGQgcmV0dXJuIGpvYiBJRCB3aGVuIHJlc3BvbnNlIHR5cGUgaXMgc3VjY2VzcyBmb3IgY3VzdG9tZXJNYXRjaFVzZXJMaXN0IGpvYicsXG4gICAgICAgIGF1dGhPYmplY3Q6IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ3ZhbGlkLWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgY3VzdG9tZXJJZDogJzEyMzQ1Njc4OScsXG4gICAgICAgICAgZGV2ZWxvcGVyVG9rZW46ICd0ZXN0LWRldmVsb3Blci10b2tlbicsXG4gICAgICAgICAgbG9naW5DdXN0b21lcklkOiAnOTg3NjU0MzIxJyxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWVzdERhdGE6IHtcbiAgICAgICAgICBqb2I6IHtcbiAgICAgICAgICAgIHR5cGU6ICdDVVNUT01FUl9NQVRDSF9VU0VSX0xJU1QnIGFzIGNvbnN0LFxuICAgICAgICAgICAgY3VzdG9tZXJNYXRjaFVzZXJMaXN0TWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgdXNlckxpc3Q6ICdjdXN0b21lcnMvMTIzNDU2Nzg5L3VzZXJMaXN0cy8xMjM0JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgIG1vY2tSZXNwb25zZToge1xuICAgICAgICAgIHJlc291cmNlTmFtZTogJ2N1c3RvbWVycy8xMjM0NTY3ODkvb2ZmbGluZVVzZXJEYXRhSm9icy81Njc4JyxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IHtcbiAgICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzKHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IHtcbiAgICAgICAgICAgIHJlc291cmNlTmFtZTogJ2N1c3RvbWVycy8xMjM0NTY3ODkvb2ZmbGluZVVzZXJEYXRhSm9icy81Njc4JyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgICAgICB0eXBlOiAnc3VjY2VzcycsXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcjogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnc2hvdWxkIHJldHVybiBqb2IgSUQgd2hlbiByZXNwb25zZSB0eXBlIGlzIHN1Y2Nlc3MgZm9yIHN0b3JlIHNhbGVzIGpvYicsXG4gICAgICAgIGF1dGhPYmplY3Q6IHtcbiAgICAgICAgICBhY2Nlc3NUb2tlbjogJ3ZhbGlkLWFjY2Vzcy10b2tlbicsXG4gICAgICAgICAgY3VzdG9tZXJJZDogJzEyMzQ1Njc4OScsXG4gICAgICAgICAgZGV2ZWxvcGVyVG9rZW46ICd0ZXN0LWRldmVsb3Blci10b2tlbicsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3REYXRhOiB7XG4gICAgICAgICAgam9iOiB7XG4gICAgICAgICAgICBzdG9yZVNhbGVzTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgY3VzdG9tX2tleTogJ0NVU1RPTV9LRVknLFxuICAgICAgICAgICAgICBsb3lhbHR5RnJhY3Rpb246IDEsXG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uX3VwbG9hZF9mcmFjdGlvbjogJzEnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGU6ICdTVE9SRV9TQUxFU19VUExPQURfRklSU1RfUEFSVFknIGFzIGNvbnN0LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICBtb2NrUmVzcG9uc2U6IHtcbiAgICAgICAgICByZXNvdXJjZU5hbWU6ICdjdXN0b21lcnMvMTIzNDU2Nzg5L29mZmxpbmVVc2VyRGF0YUpvYnMvNTY3OCcsXG4gICAgICAgIH0sXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0OiB7XG4gICAgICAgICAgaGVhZGVyczogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICAgICAgcmVzcG9uc2VCb2R5OiB7XG4gICAgICAgICAgICByZXNvdXJjZU5hbWU6ICdjdXN0b21lcnMvMTIzNDU2Nzg5L29mZmxpbmVVc2VyRGF0YUpvYnMvNTY3OCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgdHlwZTogJ3N1Y2Nlc3MnLFxuICAgICAgICB9LFxuICAgICAgICBtb2NrUmVzcG9uc2VIZWFkZXI6IG5ldyBBeGlvc0hlYWRlcnMoeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pLFxuICAgICAgfSxcbiAgICBdO1xuICAgIFRlc3RDYXNlcy5mb3JFYWNoKFxuICAgICAgKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgYXV0aE9iamVjdCxcbiAgICAgICAgbW9ja1Jlc3BvbnNlLFxuICAgICAgICBzdGF0dXMsXG4gICAgICAgIHJlcXVlc3REYXRhLFxuICAgICAgICBleHBlY3RlZFJlc3VsdCxcbiAgICAgICAgbW9ja1Jlc3BvbnNlSGVhZGVyLFxuICAgICAgfSkgPT4ge1xuICAgICAgICBpdChuYW1lLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ29vZ2xlQWRzID0gbmV3IEdvb2dsZUFkcyhhdXRoT2JqZWN0KTtcbiAgICAgICAgICBtb2NrXG4gICAgICAgICAgICAub25Qb3N0KFxuICAgICAgICAgICAgICAnaHR0cHM6Ly9nb29nbGVhZHMuZ29vZ2xlYXBpcy5jb20vdjE5L2N1c3RvbWVycy8xMjM0NTY3ODkvb2ZmbGluZVVzZXJEYXRhSm9iczpjcmVhdGUnLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KHN0YXR1cywgbW9ja1Jlc3BvbnNlLCBtb2NrUmVzcG9uc2VIZWFkZXIpO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdvb2dsZUFkcy5jcmVhdGVPZmZsaW5lVXNlckRhdGFKb2IocmVxdWVzdERhdGEpO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Rlc3QgYWRkVXNlclRvT2ZmbGluZVVzZXJEYXRhSm9iIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IFRlc3RDYXNlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Nob3VsZCBzdWNjZXNzZnVsbHkgYWRkIHVzZXIgZGF0YSB0byBhbiBvZmZsaW5lIHVzZXIgZGF0YSBqb2InLFxuICAgICAgICBhdXRoT2JqZWN0OiB7XG4gICAgICAgICAgYWNjZXNzVG9rZW46ICd2YWxpZC1hY2Nlc3MtdG9rZW4nLFxuICAgICAgICAgIGN1c3RvbWVySWQ6ICcxMjM0NTY3ODknLFxuICAgICAgICAgIGRldmVsb3BlclRva2VuOiAndGVzdC1kZXZlbG9wZXItdG9rZW4nLFxuICAgICAgICAgIGxvZ2luQ3VzdG9tZXJJZDogJzk4NzY1NDMyMScsXG4gICAgICAgIH0sXG4gICAgICAgIGpvYklkOiAnMTIzNCcsXG4gICAgICAgIHJlcXVlc3REYXRhOiB7XG4gICAgICAgICAgb3BlcmF0aW9uczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBjcmVhdGU6IHtcbiAgICAgICAgICAgICAgICB1c2VySWRlbnRpZmllcnM6IFt7IGhhc2hlZEVtYWlsOiAnaGFzaGVkX2VtYWlsX3ZhbHVlJyB9XSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBlbmFibGVQYXJ0aWFsRmFpbHVyZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICBtb2NrUmVzcG9uc2U6IHt9LFxuICAgICAgICBleHBlY3RlZFJlc3VsdDoge1xuICAgICAgICAgIGhlYWRlcnM6IG5ldyBBeGlvc0hlYWRlcnMoeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pLFxuICAgICAgICAgIHJlc3BvbnNlQm9keToge30sXG4gICAgICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgICAgIHR5cGU6ICdzdWNjZXNzJyxcbiAgICAgICAgfSxcbiAgICAgICAgbW9ja1Jlc3BvbnNlSGVhZGVyOiBuZXcgQXhpb3NIZWFkZXJzKHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSxcbiAgICAgIH0sXG4gICAgXTtcbiAgICBUZXN0Q2FzZXMuZm9yRWFjaChcbiAgICAgICh7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGF1dGhPYmplY3QsXG4gICAgICAgIG1vY2tSZXNwb25zZSxcbiAgICAgICAgc3RhdHVzLFxuICAgICAgICByZXF1ZXN0RGF0YSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQsXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcixcbiAgICAgICAgam9iSWQsXG4gICAgICB9KSA9PiB7XG4gICAgICAgIGl0KG5hbWUsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBnb29nbGVBZHMgPSBuZXcgR29vZ2xlQWRzKGF1dGhPYmplY3QpO1xuICAgICAgICAgIG1vY2tcbiAgICAgICAgICAgIC5vblBvc3QoXG4gICAgICAgICAgICAgICdodHRwczovL2dvb2dsZWFkcy5nb29nbGVhcGlzLmNvbS92MTkvY3VzdG9tZXJzLzEyMzQ1Njc4OS9vZmZsaW5lVXNlckRhdGFKb2JzLzEyMzQ6YWRkT3BlcmF0aW9ucycsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucmVwbHkoc3RhdHVzLCBtb2NrUmVzcG9uc2UsIG1vY2tSZXNwb25zZUhlYWRlcik7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ29vZ2xlQWRzLmFkZFVzZXJUb09mZmxpbmVVc2VyRGF0YUpvYihqb2JJZCwgcmVxdWVzdERhdGEpO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Rlc3QgYWRkQ29udmVyc2lvbnNUb09mZmxpbmVVc2VyRGF0YUpvYiBmdW5jdGlvbicsICgpID0+IHtcbiAgICBjb25zdCBUZXN0Q2FzZXMgPSBbXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdzaG91bGQgc3VjY2Vzc2Z1bGx5IGFkZCBzdG9yZSBzYWxlcyBjb252ZXJzaW9uIGRhdGEgdG8gYW4gb2ZmbGluZSB1c2VyIGRhdGEgam9iJyxcbiAgICAgICAgYXV0aE9iamVjdDoge1xuICAgICAgICAgIGFjY2Vzc1Rva2VuOiAndmFsaWQtYWNjZXNzLXRva2VuJyxcbiAgICAgICAgICBjdXN0b21lcklkOiAnMTIzNDU2Nzg5JyxcbiAgICAgICAgICBkZXZlbG9wZXJUb2tlbjogJ3Rlc3QtZGV2ZWxvcGVyLXRva2VuJyxcbiAgICAgICAgICBsb2dpbkN1c3RvbWVySWQ6ICc5ODc2NTQzMjEnLFxuICAgICAgICB9LFxuICAgICAgICBqb2JJZDogJzEyMzQnLFxuICAgICAgICByZXF1ZXN0RGF0YToge1xuICAgICAgICAgIG9wZXJhdGlvbnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY3JlYXRlOiB7XG4gICAgICAgICAgICAgICAgdXNlcklkZW50aWZpZXJzOiBbeyBoYXNoZWRFbWFpbDogJ2hhc2hlZC1lbWFpbC12YWx1ZScgfV0sXG4gICAgICAgICAgICAgICAgdHJhbnNhY3Rpb25JbmZvOiB7XG4gICAgICAgICAgICAgICAgICBjb252ZXJzaW9uQWN0aW9uOiAnY3VzdG9tZXJzLzEyMzQ1Njc4OS9jb252ZXJzaW9uQWN0aW9ucy85ODcnLFxuICAgICAgICAgICAgICAgICAgY29udmVyc2lvbkRhdGVUaW1lOiAnMjAyMy0wMS0wMSAxMjowMDowMCcsXG4gICAgICAgICAgICAgICAgICBjb252ZXJzaW9uVmFsdWU6IDEwLjk5LFxuICAgICAgICAgICAgICAgICAgY3VycmVuY3lDb2RlOiAnVVNEJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGVuYWJsZVBhcnRpYWxGYWlsdXJlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgbW9ja1Jlc3BvbnNlOiB7fSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IHtcbiAgICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzKHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IHt9LFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgICAgICB0eXBlOiAnc3VjY2VzcycsXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcjogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICB9LFxuICAgIF07XG4gICAgVGVzdENhc2VzLmZvckVhY2goXG4gICAgICAoe1xuICAgICAgICBuYW1lLFxuICAgICAgICBhdXRoT2JqZWN0LFxuICAgICAgICBtb2NrUmVzcG9uc2UsXG4gICAgICAgIHN0YXR1cyxcbiAgICAgICAgcmVxdWVzdERhdGEsXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0LFxuICAgICAgICBtb2NrUmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIGpvYklkLFxuICAgICAgfSkgPT4ge1xuICAgICAgICBpdChuYW1lLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ29vZ2xlQWRzID0gbmV3IEdvb2dsZUFkcyhhdXRoT2JqZWN0KTtcbiAgICAgICAgICBtb2NrXG4gICAgICAgICAgICAub25Qb3N0KFxuICAgICAgICAgICAgICAnaHR0cHM6Ly9nb29nbGVhZHMuZ29vZ2xlYXBpcy5jb20vdjE5L2N1c3RvbWVycy8xMjM0NTY3ODkvb2ZmbGluZVVzZXJEYXRhSm9icy8xMjM0OmFkZE9wZXJhdGlvbnMnLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KHN0YXR1cywgbW9ja1Jlc3BvbnNlLCBtb2NrUmVzcG9uc2VIZWFkZXIpO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdvb2dsZUFkcy5hZGRDb252ZXJzaW9uc1RvT2ZmbGluZVVzZXJEYXRhSm9iKGpvYklkLCByZXF1ZXN0RGF0YSk7XG4gICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbChleHBlY3RlZFJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICApO1xuICB9KTtcblxuICBkZXNjcmliZSgnVGVzdCBydW5PZmZsaW5lVXNlckRhdGFKb2IgZnVuY3Rpb24nLCAoKSA9PiB7XG4gICAgY29uc3QgVGVzdENhc2VzID0gW1xuICAgICAge1xuICAgICAgICBuYW1lOiAnc2hvdWxkIHN1Y2Nlc3NmdWxseSBydW4gYW4gb2ZmbGluZSB1c2VyIGRhdGEgam9iIHdpdGggdmFsaWQgam9iSWQnLFxuICAgICAgICBhdXRoT2JqZWN0OiB7XG4gICAgICAgICAgYWNjZXNzVG9rZW46ICd2YWxpZC1hY2Nlc3MtdG9rZW4nLFxuICAgICAgICAgIGN1c3RvbWVySWQ6ICcxMjM0NTY3ODknLFxuICAgICAgICAgIGRldmVsb3BlclRva2VuOiAndGVzdC1kZXZlbG9wZXItdG9rZW4nLFxuICAgICAgICAgIGxvZ2luQ3VzdG9tZXJJZDogJzk4NzY1NDMyMScsXG4gICAgICAgIH0sXG4gICAgICAgIGpvYklkOiAnMTIzNCcsXG4gICAgICAgIHJlcXVlc3REYXRhOiB7fSxcbiAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgIG1vY2tSZXNwb25zZToge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZGF0YTogeyBuYW1lOiAndGVzdC1qb2InLCBkb25lOiB0cnVlIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0OiB7XG4gICAgICAgICAgaGVhZGVyczogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICAgICAgcmVzcG9uc2VCb2R5OiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZGF0YTogeyBuYW1lOiAndGVzdC1qb2InLCBkb25lOiB0cnVlIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgdHlwZTogJ3N1Y2Nlc3MnLFxuICAgICAgICB9LFxuICAgICAgICBtb2NrUmVzcG9uc2VIZWFkZXI6IG5ldyBBeGlvc0hlYWRlcnMoeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pLFxuICAgICAgfSxcbiAgICBdO1xuICAgIFRlc3RDYXNlcy5mb3JFYWNoKFxuICAgICAgKHsgbmFtZSwgYXV0aE9iamVjdCwgbW9ja1Jlc3BvbnNlLCBzdGF0dXMsIGV4cGVjdGVkUmVzdWx0LCBtb2NrUmVzcG9uc2VIZWFkZXIsIGpvYklkIH0pID0+IHtcbiAgICAgICAgaXQobmFtZSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGdvb2dsZUFkcyA9IG5ldyBHb29nbGVBZHMoYXV0aE9iamVjdCk7XG4gICAgICAgICAgbW9ja1xuICAgICAgICAgICAgLm9uUG9zdChcbiAgICAgICAgICAgICAgJ2h0dHBzOi8vZ29vZ2xlYWRzLmdvb2dsZWFwaXMuY29tL3YxOS9jdXN0b21lcnMvMTIzNDU2Nzg5L29mZmxpbmVVc2VyRGF0YUpvYnMvMTIzNDpydW4nLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnJlcGx5KHN0YXR1cywgbW9ja1Jlc3BvbnNlLCBtb2NrUmVzcG9uc2VIZWFkZXIpO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdvb2dsZUFkcy5ydW5PZmZsaW5lVXNlckRhdGFKb2Ioam9iSWQpO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoZXhwZWN0ZWRSZXN1bHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1Rlc3QgdXBsb2FkQ2xpY2tDb252ZXJzaW9uIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IFRlc3RDYXNlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Nob3VsZCBzdWNjZXNzZnVsbHkgYWRkIHVzZXIgZGF0YSB0byBhbiBvZmZsaW5lIHVzZXIgZGF0YSBqb2InLFxuICAgICAgICBhdXRoT2JqZWN0OiB7XG4gICAgICAgICAgYWNjZXNzVG9rZW46ICd2YWxpZC1hY2Nlc3MtdG9rZW4nLFxuICAgICAgICAgIGN1c3RvbWVySWQ6ICcxMjM0NTY3ODknLFxuICAgICAgICAgIGRldmVsb3BlclRva2VuOiAndGVzdC1kZXZlbG9wZXItdG9rZW4nLFxuICAgICAgICAgIGxvZ2luQ3VzdG9tZXJJZDogJzk4NzY1NDMyMScsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3REYXRhOiB7XG4gICAgICAgICAgY29udmVyc2lvbnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZ2NsaWQ6ICd0ZXN0LWdjbGlkJyxcbiAgICAgICAgICAgICAgY29udmVyc2lvbkFjdGlvbjogJ3Rlc3QtYWN0aW9uJyxcbiAgICAgICAgICAgICAgY29udmVyc2lvbkRhdGVUaW1lOiAnMjAyMy0wMS0wMVQwMDowMDowMFonLFxuICAgICAgICAgICAgICBjb252ZXJzaW9uVmFsdWU6IDEwMCxcbiAgICAgICAgICAgICAgY3VycmVuY3lDb2RlOiAnVVNEJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgIG1vY2tSZXNwb25zZToge1xuICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgcmVzdWx0czogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZ2NsaWQ6ICd0ZXN0LWdjbGlkJyxcbiAgICAgICAgICAgICAgICBjb252ZXJzaW9uQWN0aW9uOiAndGVzdC1hY3Rpb24nLFxuICAgICAgICAgICAgICAgIGNvbnZlcnNpb25EYXRlVGltZTogJzIwMjMtMDEtMDFUMDA6MDA6MDBaJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IHtcbiAgICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzKHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IHtcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgcmVzdWx0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGNvbnZlcnNpb25BY3Rpb246ICd0ZXN0LWFjdGlvbicsXG4gICAgICAgICAgICAgICAgICBjb252ZXJzaW9uRGF0ZVRpbWU6ICcyMDIzLTAxLTAxVDAwOjAwOjAwWicsXG4gICAgICAgICAgICAgICAgICBnY2xpZDogJ3Rlc3QtZ2NsaWQnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgICAgICB0eXBlOiAnc3VjY2VzcycsXG4gICAgICAgIH0sXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcjogbmV3IEF4aW9zSGVhZGVycyh7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSksXG4gICAgICB9LFxuICAgIF07XG4gICAgVGVzdENhc2VzLmZvckVhY2goXG4gICAgICAoe1xuICAgICAgICBuYW1lLFxuICAgICAgICBhdXRoT2JqZWN0LFxuICAgICAgICBtb2NrUmVzcG9uc2UsXG4gICAgICAgIHN0YXR1cyxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQsXG4gICAgICAgIG1vY2tSZXNwb25zZUhlYWRlcixcbiAgICAgICAgcmVxdWVzdERhdGEsXG4gICAgICB9KSA9PiB7XG4gICAgICAgIGl0KG5hbWUsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBnb29nbGVBZHMgPSBuZXcgR29vZ2xlQWRzKGF1dGhPYmplY3QpO1xuICAgICAgICAgIG1vY2tcbiAgICAgICAgICAgIC5vblBvc3QoXG4gICAgICAgICAgICAgICdodHRwczovL2dvb2dsZWFkcy5nb29nbGVhcGlzLmNvbS92MTkvY3VzdG9tZXJzLzEyMzQ1Njc4OTp1cGxvYWRDbGlja0NvbnZlcnNpb25zJyxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5yZXBseShzdGF0dXMsIG1vY2tSZXNwb25zZSwgbW9ja1Jlc3BvbnNlSGVhZGVyKTtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnb29nbGVBZHMudXBsb2FkQ2xpY2tDb252ZXJzaW9uKHJlcXVlc3REYXRhKTtcbiAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKGV4cGVjdGVkUmVzdWx0KTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdUZXN0IHVwbG9hZENhbGxDb252ZXJzaW9uIGZ1bmN0aW9uJywgKCkgPT4ge1xuICAgIGNvbnN0IFRlc3RDYXNlcyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3Nob3VsZCBzdWNjZXNzZnVsbHkgdXBsb2FkIGNhbGwgY29udmVyc2lvbiBkYXRhIGFuZCByZXR1cm4gYSBzdWNjZXNzZnVsIHJlc3BvbnNlJyxcbiAgICAgICAgYXV0aE9iamVjdDoge1xuICAgICAgICAgIGFjY2Vzc1Rva2VuOiAndmFsaWQtYWNjZXNzLXRva2VuJyxcbiAgICAgICAgICBjdXN0b21lcklkOiAnMTIzNDU2Nzg5JyxcbiAgICAgICAgICBkZXZlbG9wZXJUb2tlbjogJ3Rlc3QtZGV2ZWxvcGVyLXRva2VuJyxcbiAgICAgICAgICBsb2dpbkN1c3RvbWVySWQ6ICc5ODc2NTQzMjEnLFxuICAgICAgICB9LFxuICAgICAgICByZXF1ZXN0RGF0YToge1xuICAgICAgICAgIGNvbnZlcnNpb25zOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNhbGxlcklkOiAnMTIzNDU2Nzg5MCcsXG4gICAgICAgICAgICAgIGNhbGxTdGFydERhdGVUaW1lOiAnMjAyMy0wMS0wMVQxMjowMDowMFonLFxuICAgICAgICAgICAgICBjb252ZXJzaW9uQWN0aW9uOiAnYWN0aW9uMScsXG4gICAgICAgICAgICAgIGNvbnZlcnNpb25EYXRlVGltZTogJzIwMjMtMDEtMDFUMTI6MDU6MDBaJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgICBwYXJ0aWFsRmFpbHVyZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICBtb2NrUmVzcG9uc2U6IHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIHJlc3VsdHM6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNhbGxlcklkOiAnMTIzNDU2Nzg5MCcsXG4gICAgICAgICAgICAgICAgY2FsbFN0YXJ0RGF0ZVRpbWU6ICcyMDIzLTAxLTAxVDEyOjAwOjAwWicsXG4gICAgICAgICAgICAgICAgY29udmVyc2lvbkFjdGlvbjogJ2FjdGlvbjEnLFxuICAgICAgICAgICAgICAgIGNvbnZlcnNpb25EYXRlVGltZTogJzIwMjMtMDEtMDFUMTI6MDU6MDBaJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwZWN0ZWRSZXN1bHQ6IHtcbiAgICAgICAgICBoZWFkZXJzOiBuZXcgQXhpb3NIZWFkZXJzKHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9KSxcbiAgICAgICAgICByZXNwb25zZUJvZHk6IHtcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgcmVzdWx0czogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGNhbGxTdGFydERhdGVUaW1lOiAnMjAyMy0wMS0wMVQxMjowMDowMFonLFxuICAgICAgICAgICAgICAgICAgY2FsbGVySWQ6ICcxMjM0NTY3ODkwJyxcbiAgICAgICAgICAgICAgICAgIGNvbnZlcnNpb25BY3Rpb246ICdhY3Rpb24xJyxcbiAgICAgICAgICAgICAgICAgIGNvbnZlcnNpb25EYXRlVGltZTogJzIwMjMtMDEtMDFUMTI6MDU6MDBaJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgdHlwZTogJ3N1Y2Nlc3MnLFxuICAgICAgICB9LFxuICAgICAgICBtb2NrUmVzcG9uc2VIZWFkZXI6IG5ldyBBeGlvc0hlYWRlcnMoeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0pLFxuICAgICAgfSxcbiAgICBdO1xuICAgIFRlc3RDYXNlcy5mb3JFYWNoKFxuICAgICAgKHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgYXV0aE9iamVjdCxcbiAgICAgICAgbW9ja1Jlc3BvbnNlLFxuICAgICAgICBzdGF0dXMsXG4gICAgICAgIGV4cGVjdGVkUmVzdWx0LFxuICAgICAgICBtb2NrUmVzcG9uc2VIZWFkZXIsXG4gICAgICAgIHJlcXVlc3REYXRhLFxuICAgICAgfSkgPT4ge1xuICAgICAgICBpdChuYW1lLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ29vZ2xlQWRzID0gbmV3IEdvb2dsZUFkcyhhdXRoT2JqZWN0KTtcbiAgICAgICAgICBtb2NrXG4gICAgICAgICAgICAub25Qb3N0KFxuICAgICAgICAgICAgICAnaHR0cHM6Ly9nb29nbGVhZHMuZ29vZ2xlYXBpcy5jb20vdjE5L2N1c3RvbWVycy8xMjM0NTY3ODk6dXBsb2FkQ2xpY2tDb252ZXJzaW9ucycsXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucmVwbHkoc3RhdHVzLCBtb2NrUmVzcG9uc2UsIG1vY2tSZXNwb25zZUhlYWRlcik7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ29vZ2xlQWRzLnVwbG9hZENsaWNrQ29udmVyc2lvbihyZXF1ZXN0RGF0YSk7XG4gICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbChleHBlY3RlZFJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICApO1xuICB9KTtcbn0pO1xuIl19
|