@rudderstack/integrations-lib 0.2.34 ā 0.2.35
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/sdks/sfmc/index.d.ts +26 -3
- package/build/sdks/sfmc/index.d.ts.map +1 -1
- package/build/sdks/sfmc/index.js +108 -16
- package/build/sdks/sfmc/type.d.ts +44 -24
- package/build/sdks/sfmc/type.d.ts.map +1 -1
- package/build/sdks/sfmc/type.js +1 -1
- package/build/utils/benchmark.d.ts +180 -0
- package/build/utils/benchmark.d.ts.map +1 -0
- package/build/utils/benchmark.js +288 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthObject, BusinessUnit, ContactAttributesResponse, CreateDataExtensionResponse, DataExtension, DataExtensionBody, DataFolder } from './type';
|
|
1
|
+
import { AuthObject, BusinessUnit, ContactAttributesResponse, CreateDataExtensionResponse, DataExtension, DataExtensionBody, DataFolder, EventDefinition, ContactAttributes, DataExtensionApiResponse } from './type';
|
|
2
2
|
import { RestError, SoapError } from './utils';
|
|
3
3
|
export default class SFMC {
|
|
4
4
|
authObject: AuthObject;
|
|
@@ -17,9 +17,12 @@ export default class SFMC {
|
|
|
17
17
|
getDestinationFields(dataExtensionId: string): Promise<DataExtensionBody | RestError>;
|
|
18
18
|
/**
|
|
19
19
|
* This method fetches the contact attributes. The method returns the contact attributes. If the contact attributes are not found, it returns a RestError.
|
|
20
|
-
* @
|
|
20
|
+
* @param page Page number
|
|
21
|
+
* @param pageSize Page size
|
|
22
|
+
* @returns {Promise<ContactAttributesResponse | RestError>}
|
|
21
23
|
*/
|
|
22
|
-
|
|
24
|
+
getContactAttributesItems(page: number, pageSize: number): Promise<ContactAttributesResponse | RestError>;
|
|
25
|
+
getContactAttributes(): Promise<ContactAttributes[] | RestError>;
|
|
23
26
|
/**
|
|
24
27
|
* This method creates a data extension. It requires the data extension fields. The method returns the data extension created. If the data extension is not created, it returns a RestError.
|
|
25
28
|
* @param body DataExtension fields
|
|
@@ -43,5 +46,25 @@ export default class SFMC {
|
|
|
43
46
|
* @returns
|
|
44
47
|
*/
|
|
45
48
|
getDataExtensions(dataFolderId?: string): Promise<DataExtension[] | SoapError>;
|
|
49
|
+
private static mapDataExtension;
|
|
50
|
+
/**
|
|
51
|
+
* This function fetches the data extension by id. It returns the data extension. If the data extension is not found, it returns a RestError.
|
|
52
|
+
* @param dataExtensionId Id of the data extension
|
|
53
|
+
* @returns {Promise<DataExtension | RestError>}
|
|
54
|
+
*/
|
|
55
|
+
getDataExtensionById(dataExtensionId: string): Promise<DataExtensionApiResponse | RestError>;
|
|
56
|
+
/**
|
|
57
|
+
* This function fetches the event definitions. It returns the event definitions. If the event definitions are not found, it returns a RestError.
|
|
58
|
+
* @param page Page number
|
|
59
|
+
* @param pageSize Page size
|
|
60
|
+
* @returns {Promise<EventDefinitionsResponse | RestError>}
|
|
61
|
+
*/
|
|
62
|
+
private getEventDefinitions;
|
|
63
|
+
/**
|
|
64
|
+
* This function fetches all the event definitions. It returns the event definitions. If the event definitions are not found, it returns a RestError.
|
|
65
|
+
* @returns {Promise<EventDefinition[] | RestError>}
|
|
66
|
+
*/
|
|
67
|
+
getAllEventDefinitions(): Promise<EventDefinition[] | RestError>;
|
|
68
|
+
private static getAllItemFromPages;
|
|
46
69
|
}
|
|
47
70
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdks/sfmc/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,YAAY,EAEZ,yBAAyB,EACzB,2BAA2B,EAC3B,aAAa,EACb,iBAAiB,EAEjB,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdks/sfmc/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,YAAY,EAEZ,yBAAyB,EACzB,2BAA2B,EAC3B,aAAa,EACb,iBAAiB,EAEjB,UAAU,EAEV,eAAe,EAEf,iBAAiB,EAEjB,wBAAwB,EACzB,MAAM,QAAQ,CAAC;AAChB,OAAO,EAML,SAAS,EACT,SAAS,EAEV,MAAM,SAAS,CAAC;AAEjB,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,UAAU,EAAE,UAAU,CAAC;gBAEX,UAAU,EAAE,UAAU;IAKlC,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAiCjC;;;OAGG;IACG,cAAc;IAWpB;;;;OAIG;IACG,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAsB3F;;;;;OAKG;IACG,yBAAyB,CAC7B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,yBAAyB,GAAG,SAAS,CAAC;IAsB3C,oBAAoB,IAAI,OAAO,CAAC,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAOtE;;;;OAIG;IACG,mBAAmB,CACvB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC;IAmBnD;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,GAAG,SAAS,CAAC;IAqD7D;;;;OAIG;IACG,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,GAAG,SAAS,CAAC;IAwChF;;;;OAIG;IACG,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,GAAG,SAAS,CAAC;IA8CpF,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAyB/B;;;;OAIG;IACG,oBAAoB,CACxB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,wBAAwB,GAAG,SAAS,CAAC;IAsBhD;;;;;OAKG;YACW,mBAAmB;IAuBjC;;;OAGG;IACG,sBAAsB,IAAI,OAAO,CAAC,eAAe,EAAE,GAAG,SAAS,CAAC;mBAOjD,mBAAmB;CA6BzC"}
|
package/build/sdks/sfmc/index.js
CHANGED
|
@@ -83,9 +83,11 @@ class SFMC {
|
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
85
|
* This method fetches the contact attributes. The method returns the contact attributes. If the contact attributes are not found, it returns a RestError.
|
|
86
|
-
* @
|
|
86
|
+
* @param page Page number
|
|
87
|
+
* @param pageSize Page size
|
|
88
|
+
* @returns {Promise<ContactAttributesResponse | RestError>}
|
|
87
89
|
*/
|
|
88
|
-
async
|
|
90
|
+
async getContactAttributesItems(page, pageSize) {
|
|
89
91
|
try {
|
|
90
92
|
const restHeaders = {
|
|
91
93
|
Authorization: `Bearer ${(await this.getAccessToken()).access_token}`,
|
|
@@ -93,7 +95,7 @@ class SFMC {
|
|
|
93
95
|
const requestOptions = {
|
|
94
96
|
method: 'GET',
|
|
95
97
|
baseURL: (0, utils_1.getUrl)(this.authObject.subDomain),
|
|
96
|
-
url:
|
|
98
|
+
url: `/contacts/v1/attributeSetDefinitions?$page=${page}&$pageSize=${pageSize}`,
|
|
97
99
|
headers: restHeaders,
|
|
98
100
|
};
|
|
99
101
|
const resp = await (0, axios_1.default)(requestOptions);
|
|
@@ -107,6 +109,10 @@ class SFMC {
|
|
|
107
109
|
throw err;
|
|
108
110
|
}
|
|
109
111
|
}
|
|
112
|
+
async getContactAttributes() {
|
|
113
|
+
const contactAttributes = await SFMC.getAllItemFromPages(this.getContactAttributesItems.bind(this));
|
|
114
|
+
return contactAttributes;
|
|
115
|
+
}
|
|
110
116
|
/**
|
|
111
117
|
* This method creates a data extension. It requires the data extension fields. The method returns the data extension created. If the data extension is not created, it returns a RestError.
|
|
112
118
|
* @param body DataExtension fields
|
|
@@ -244,8 +250,8 @@ class SFMC {
|
|
|
244
250
|
'Content-Type': 'text/xml',
|
|
245
251
|
},
|
|
246
252
|
data: dataFolderId
|
|
247
|
-
? await (0, utils_1.xmlBuilder)('DataExtension', ['NAME', 'ObjectId', 'CategoryId'], accessToken, (0, utils_1.parseFilter)({ leftOperand: 'CategoryId', rightOperand: dataFolderId }))
|
|
248
|
-
: await (0, utils_1.xmlBuilder)('DataExtension', ['NAME', 'ObjectId', 'CategoryId'], accessToken),
|
|
253
|
+
? await (0, utils_1.xmlBuilder)('DataExtension', ['NAME', 'ObjectId', 'CategoryId', 'CustomerKey', 'IsSendable'], accessToken, (0, utils_1.parseFilter)({ leftOperand: 'CategoryId', rightOperand: dataFolderId }))
|
|
254
|
+
: await (0, utils_1.xmlBuilder)('DataExtension', ['NAME', 'ObjectId', 'CategoryId', 'CustomerKey', 'IsSendable'], accessToken),
|
|
249
255
|
};
|
|
250
256
|
const resp = await (0, axios_1.default)(requestOptions);
|
|
251
257
|
const parsedData = (0, utils_1.parseXML)(resp.data);
|
|
@@ -254,19 +260,11 @@ class SFMC {
|
|
|
254
260
|
if (res) {
|
|
255
261
|
if (Array.isArray(res)) {
|
|
256
262
|
res.forEach((eachRes) => {
|
|
257
|
-
dataExtensions.push(
|
|
258
|
-
ObjectId: eachRes.PartnerProperties[0].Value,
|
|
259
|
-
Name: eachRes.PartnerProperties[1].Value,
|
|
260
|
-
CategoryId: eachRes.PartnerProperties[2].Value,
|
|
261
|
-
});
|
|
263
|
+
dataExtensions.push(SFMC.mapDataExtension(eachRes));
|
|
262
264
|
});
|
|
263
265
|
}
|
|
264
266
|
else {
|
|
265
|
-
dataExtensions.push(
|
|
266
|
-
ObjectId: res.PartnerProperties[0].Value,
|
|
267
|
-
Name: res.PartnerProperties[1].Value,
|
|
268
|
-
CategoryId: res.PartnerProperties[2].Value,
|
|
269
|
-
});
|
|
267
|
+
dataExtensions.push(SFMC.mapDataExtension(res));
|
|
270
268
|
}
|
|
271
269
|
return dataExtensions;
|
|
272
270
|
}
|
|
@@ -276,6 +274,100 @@ class SFMC {
|
|
|
276
274
|
throw new utils_1.SoapError(err);
|
|
277
275
|
}
|
|
278
276
|
}
|
|
277
|
+
static mapDataExtension(dataExtension) {
|
|
278
|
+
const getProperty = (props, name) => {
|
|
279
|
+
const property = props.find((prop) => prop.Name === name);
|
|
280
|
+
if (!property) {
|
|
281
|
+
throw new Error(`Missing required property: ${name}`);
|
|
282
|
+
}
|
|
283
|
+
return property.Value;
|
|
284
|
+
};
|
|
285
|
+
const { PartnerProperties } = dataExtension;
|
|
286
|
+
return {
|
|
287
|
+
ObjectId: getProperty(PartnerProperties, 'ObjectId'),
|
|
288
|
+
Name: getProperty(PartnerProperties, 'NAME'),
|
|
289
|
+
CategoryId: getProperty(PartnerProperties, 'CategoryId'),
|
|
290
|
+
ExternalKey: dataExtension.CustomerKey,
|
|
291
|
+
IsSendable: dataExtension.IsSendable,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* This function fetches the data extension by id. It returns the data extension. If the data extension is not found, it returns a RestError.
|
|
296
|
+
* @param dataExtensionId Id of the data extension
|
|
297
|
+
* @returns {Promise<DataExtension | RestError>}
|
|
298
|
+
*/
|
|
299
|
+
async getDataExtensionById(dataExtensionId) {
|
|
300
|
+
try {
|
|
301
|
+
const accessToken = (await this.getAccessToken()).access_token;
|
|
302
|
+
const requestOptions = {
|
|
303
|
+
method: 'GET',
|
|
304
|
+
baseURL: (0, utils_1.getUrl)(this.authObject.subDomain),
|
|
305
|
+
url: `/data/v1/customobjects/${dataExtensionId}`,
|
|
306
|
+
headers: {
|
|
307
|
+
Authorization: `Bearer ${accessToken}`,
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
const resp = await (0, axios_1.default)(requestOptions);
|
|
311
|
+
return resp.data;
|
|
312
|
+
}
|
|
313
|
+
catch (err) {
|
|
314
|
+
if (axios_1.default.isAxiosError(err)) {
|
|
315
|
+
const axiosError = err;
|
|
316
|
+
throw new utils_1.RestError(axiosError);
|
|
317
|
+
}
|
|
318
|
+
throw err;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* This function fetches the event definitions. It returns the event definitions. If the event definitions are not found, it returns a RestError.
|
|
323
|
+
* @param page Page number
|
|
324
|
+
* @param pageSize Page size
|
|
325
|
+
* @returns {Promise<EventDefinitionsResponse | RestError>}
|
|
326
|
+
*/
|
|
327
|
+
async getEventDefinitions(page, pageSize) {
|
|
328
|
+
try {
|
|
329
|
+
const accessToken = (await this.getAccessToken()).access_token;
|
|
330
|
+
const requestOptions = {
|
|
331
|
+
method: 'GET',
|
|
332
|
+
baseURL: (0, utils_1.getUrl)(this.authObject.subDomain),
|
|
333
|
+
url: `/interaction/v1/eventDefinitions?$page=${page}&$pageSize=${pageSize}`,
|
|
334
|
+
headers: {
|
|
335
|
+
Authorization: `Bearer ${accessToken}`,
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
const resp = await (0, axios_1.default)(requestOptions);
|
|
339
|
+
return resp.data;
|
|
340
|
+
}
|
|
341
|
+
catch (err) {
|
|
342
|
+
throw new utils_1.RestError(err);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* This function fetches all the event definitions. It returns the event definitions. If the event definitions are not found, it returns a RestError.
|
|
347
|
+
* @returns {Promise<EventDefinition[] | RestError>}
|
|
348
|
+
*/
|
|
349
|
+
async getAllEventDefinitions() {
|
|
350
|
+
const eventDefinitions = await SFMC.getAllItemFromPages(this.getEventDefinitions.bind(this));
|
|
351
|
+
return eventDefinitions;
|
|
352
|
+
}
|
|
353
|
+
static async getAllItemFromPages(getItems, pageSize = 50) {
|
|
354
|
+
// Get first page to determine total count
|
|
355
|
+
const firstPage = await getItems(1, pageSize);
|
|
356
|
+
if (firstPage instanceof utils_1.RestError) {
|
|
357
|
+
throw firstPage;
|
|
358
|
+
}
|
|
359
|
+
const totalPages = Math.ceil(firstPage.count / pageSize);
|
|
360
|
+
const remainingPages = Array.from({ length: totalPages - 1 }, (_, i) => i + 2);
|
|
361
|
+
const remainingResults = await Promise.all(remainingPages.map(async (page) => {
|
|
362
|
+
const result = await getItems(page, pageSize);
|
|
363
|
+
if (result instanceof utils_1.RestError) {
|
|
364
|
+
throw result;
|
|
365
|
+
}
|
|
366
|
+
return result;
|
|
367
|
+
}));
|
|
368
|
+
const allResults = [firstPage, ...remainingResults];
|
|
369
|
+
return allResults.flatMap((result) => (result instanceof utils_1.RestError ? [] : result.items));
|
|
370
|
+
}
|
|
279
371
|
}
|
|
280
372
|
exports.default = SFMC;
|
|
281
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2Rrcy9zZm1jL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsa0RBQTBDO0FBYTFDLG1DQVNpQjtBQUVqQixNQUFxQixJQUFJO0lBR3ZCLFlBQVksVUFBc0I7UUFDaEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO0lBQy9CLENBQUM7SUFFTyxNQUFNLENBQUMsa0JBQWtCLENBQUMsVUFBZTtRQUMvQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRztZQUNsQixFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFO1lBQ25ELEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7WUFDdkQ7Z0JBQ0UsR0FBRyxFQUFFLFdBQVc7Z0JBQ2hCLElBQUksRUFBRSxRQUFRO2dCQUNkLFFBQVEsRUFBRSxJQUFJO2dCQUNkLEtBQUssRUFBRSxZQUFZO2dCQUNuQixZQUFZLEVBQUUseUNBQXlDO2FBQ3hEO1NBQ0YsQ0FBQztRQUVGLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFO1lBQ25FLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM5QixJQUFJLFFBQVEsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsR0FBRyx3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LENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSzs0QkFDeEMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO3lCQUMvQyxDQUFDLENBQUM7b0JBQ0wsQ0FBQyxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztxQkFBTSxDQUFDO29CQUNOLGNBQWMsQ0FBQyxJQUFJLENBQUM7d0JBQ2xCLFFBQVEsRUFBRSxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSzt3QkFDeEMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLO3dCQUNwQyxVQUFVLEVBQUUsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUs7cUJBQzNDLENBQUMsQ0FBQztnQkFDTCxDQUFDO2dCQUNELE9BQU8sY0FBYyxDQUFDO1lBQ3hCLENBQUM7WUFDRCxNQUFNLElBQUksaUJBQVMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLGlCQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7Q0FDRjtBQW5TRCx1QkFtU0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXhpb3MsIHsgQXhpb3NFcnJvciB9IGZyb20gJ2F4aW9zJztcbmltcG9ydCB7XG4gIEF1dGhPYmplY3QsXG4gIEJ1c2luZXNzVW5pdCxcbiAgQnVzaW5lc3NVbml0UmVzcG9uc2UsXG4gIENvbnRhY3RBdHRyaWJ1dGVzUmVzcG9uc2UsXG4gIENyZWF0ZURhdGFFeHRlbnNpb25SZXNwb25zZSxcbiAgRGF0YUV4dGVuc2lvbixcbiAgRGF0YUV4dGVuc2lvbkJvZHksXG4gIERhdGFFeHRlbnNpb25SZXNwb25zZSxcbiAgRGF0YUZvbGRlcixcbiAgU0ZNQ0Vycm9yUmVzcG9uc2UsXG59IGZyb20gJy4vdHlwZSc7XG5pbXBvcnQge1xuICBnZXRVcmwsXG4gIGlzRXhwaXJlZCxcbiAgcGFyc2VGaWx0ZXIsXG4gIHBhcnNlWE1MLFxuICBnZXRUb2tlbixcbiAgUmVzdEVycm9yLFxuICBTb2FwRXJyb3IsXG4gIHhtbEJ1aWxkZXIsXG59IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTRk1DIHtcbiAgYXV0aE9iamVjdDogQXV0aE9iamVjdDtcblxuICBjb25zdHJ1Y3RvcihhdXRoT2JqZWN0OiBBdXRoT2JqZWN0KSB7XG4gICAgU0ZNQy52YWxpZGF0ZUF1dGhPYmplY3QoYXV0aE9iamVjdCk7XG4gICAgdGhpcy5hdXRoT2JqZWN0ID0gYXV0aE9iamVjdDtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlQXV0aE9iamVjdChhdXRoT2JqZWN0OiBhbnkpOiBhbnkge1xuICAgIGlmICghYXV0aE9iamVjdCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhdXRoT2JqZWN0IGlzIHJlcXVpcmVkLiBTZWUgdGhlIHJlYWRtZS4nKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0aW9ucyA9IFtcbiAgICAgIHsga2V5OiAnY2xpZW50SWQnLCB0eXBlOiAnc3RyaW5nJywgcmVxdWlyZWQ6IHRydWUgfSxcbiAgICAgIHsga2V5OiAnY2xpZW50U2VjcmV0JywgdHlwZTogJ3N0cmluZycsIHJlcXVpcmVkOiB0cnVlIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ3N1YkRvbWFpbicsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgcmVnZXg6IC9eXFx3ezI4fSQvZ20sXG4gICAgICAgIHJlZ2V4TWVzc2FnZTogJ3N1YkRvbWFpbiBtdXN0IGJlIGEgc3RyaW5nIG9mIGxlbmd0aCAyOCcsXG4gICAgICB9LFxuICAgIF07XG5cbiAgICB2YWxpZGF0aW9ucy5mb3JFYWNoKCh7IGtleSwgdHlwZSwgcmVxdWlyZWQsIHJlZ2V4LCByZWdleE1lc3NhZ2UgfSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBhdXRoT2JqZWN0W2tleV07XG4gICAgICBpZiAocmVxdWlyZWQgJiYgIXZhbHVlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtrZXl9IGlzIG1pc3Npbmcgb3IgaW52YWxpZGApO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gdHlwZSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke2tleX0gbXVzdCBiZSBhICR7dHlwZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZWdleCAmJiAhcmVnZXgudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHJlZ2V4TWVzc2FnZSB8fCBgJHtrZXl9IGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlZCBmb3JtYXRgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBhdXRoT2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgYWNjZXNzIHRva2VuLiBJZiB0aGUgdG9rZW4gaXMgZXhwaXJlZCwgaXQgd2lsbCBnZW5lcmF0ZSBhIG5ldyB0b2tlbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXV0aE9iamVjdD59ICBJdCByZXR1cm5zIHRoZSBhY2Nlc3MgdG9rZW4gb3IgZXJyb3JcbiAgICovXG4gIGFzeW5jIGdldEFjY2Vzc1Rva2VuKCkge1xuICAgIGlmIChpc0V4cGlyZWQodGhpcy5hdXRoT2JqZWN0KSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZ2V0VG9rZW4odGhpcy5hdXRoT2JqZWN0KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZ2VuZXJhdGUgdG9rZW4sIHdpdGggZXJyb3I6JHtlfWApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hdXRoT2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGZldGNoZXMgdGhlIGZpZWxkcyBvZiBhIGRhdGEgZXh0ZW5zaW9uLiBJdCByZXF1aXJlcyB0aGUgZGF0YSBleHRlbnNpb24gaWQuIFRoZSBtZXRob2QgcmV0dXJucyB0aGUgZmllbGRzIG9mIHRoZSBkYXRhIGV4dGVuc2lvbi4gSWYgdGhlIGRhdGEgZXh0ZW5zaW9uIGlzIG5vdCBmb3VuZCwgaXQgcmV0dXJucyBhIFJlc3RFcnJvci5cbiAgICogQHBhcmFtIGRhdGFFeHRlbnNpb25JZCBJZCBvZiB0aGUgZGF0YSBleHRlbnNpb24gd2hvc2UgZmllbGRzIGFyZSB0byBiZSBmZXRjaGVkXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyBnZXREZXN0aW5hdGlvbkZpZWxkcyhkYXRhRXh0ZW5zaW9uSWQ6IHN0cmluZyk6IFByb21pc2U8RGF0YUV4dGVuc2lvbkJvZHkgfCBSZXN0RXJyb3I+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdEhlYWRlcnMgPSB7XG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHsoYXdhaXQgdGhpcy5nZXRBY2Nlc3NUb2tlbigpKS5hY2Nlc3NfdG9rZW59YCxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgICAgYmFzZVVSTDogZ2V0VXJsKHRoaXMuYXV0aE9iamVjdC5zdWJEb21haW4pLFxuICAgICAgICB1cmw6IGAvZGF0YS92MS9jdXN0b21vYmplY3RzLyR7ZGF0YUV4dGVuc2lvbklkfS9maWVsZHNgLFxuICAgICAgICBoZWFkZXJzOiByZXN0SGVhZGVycyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdGlvbnMpO1xuICAgICAgcmV0dXJuIHJlc3AuZGF0YTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChheGlvcy5pc0F4aW9zRXJyb3IoZXJyKSkge1xuICAgICAgICBjb25zdCBheGlvc0Vycm9yID0gZXJyIGFzIEF4aW9zRXJyb3I8U0ZNQ0Vycm9yUmVzcG9uc2U+O1xuICAgICAgICB0aHJvdyBuZXcgUmVzdEVycm9yKGF4aW9zRXJyb3IpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBmZXRjaGVzIHRoZSBjb250YWN0IGF0dHJpYnV0ZXMuIFRoZSBtZXRob2QgcmV0dXJucyB0aGUgY29udGFjdCBhdHRyaWJ1dGVzLiBJZiB0aGUgY29udGFjdCBhdHRyaWJ1dGVzIGFyZSBub3QgZm91bmQsIGl0IHJldHVybnMgYSBSZXN0RXJyb3IuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyBnZXRDb250YWN0QXR0cmlidXRlcygpOiBQcm9taXNlPENvbnRhY3RBdHRyaWJ1dGVzUmVzcG9uc2UgfCBSZXN0RXJyb3I+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdEhlYWRlcnMgPSB7XG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHsoYXdhaXQgdGhpcy5nZXRBY2Nlc3NUb2tlbigpKS5hY2Nlc3NfdG9rZW59YCxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgICAgYmFzZVVSTDogZ2V0VXJsKHRoaXMuYXV0aE9iamVjdC5zdWJEb21haW4pLFxuICAgICAgICB1cmw6ICcvY29udGFjdHMvdjEvYXR0cmlidXRlU2V0RGVmaW5pdGlvbnMnLFxuICAgICAgICBoZWFkZXJzOiByZXN0SGVhZGVycyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdGlvbnMpO1xuICAgICAgcmV0dXJuIHJlc3AuZGF0YTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChheGlvcy5pc0F4aW9zRXJyb3IoZXJyKSkge1xuICAgICAgICBjb25zdCBheGlvc0Vycm9yID0gZXJyIGFzIEF4aW9zRXJyb3I8U0ZNQ0Vycm9yUmVzcG9uc2U+O1xuICAgICAgICB0aHJvdyBuZXcgUmVzdEVycm9yKGF4aW9zRXJyb3IpO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgZGF0YSBleHRlbnNpb24uIEl0IHJlcXVpcmVzIHRoZSBkYXRhIGV4dGVuc2lvbiBmaWVsZHMuIFRoZSBtZXRob2QgcmV0dXJucyB0aGUgZGF0YSBleHRlbnNpb24gY3JlYXRlZC4gSWYgdGhlIGRhdGEgZXh0ZW5zaW9uIGlzIG5vdCBjcmVhdGVkLCBpdCByZXR1cm5zIGEgUmVzdEVycm9yLlxuICAgKiBAcGFyYW0gYm9keSBEYXRhRXh0ZW5zaW9uIGZpZWxkc1xuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgYXN5bmMgY3JlYXRlRGF0YUV4dGVuc2lvbihcbiAgICBib2R5OiBEYXRhRXh0ZW5zaW9uQm9keSxcbiAgKTogUHJvbWlzZTxDcmVhdGVEYXRhRXh0ZW5zaW9uUmVzcG9uc2UgfCBSZXN0RXJyb3I+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdEhlYWRlcnMgPSB7XG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHsoYXdhaXQgdGhpcy5nZXRBY2Nlc3NUb2tlbigpKS5hY2Nlc3NfdG9rZW59YCxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJhc2VVUkw6IGdldFVybCh0aGlzLmF1dGhPYmplY3Quc3ViRG9tYWluKSxcbiAgICAgICAgdXJsOiAnL2RhdGEvdjEvY3VzdG9tb2JqZWN0cycsXG4gICAgICAgIGhlYWRlcnM6IHJlc3RIZWFkZXJzLFxuICAgICAgICBkYXRhOiBib2R5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBheGlvcyhyZXF1ZXN0T3B0aW9ucyk7XG4gICAgICByZXR1cm4gcmVzcC5kYXRhO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgUmVzdEVycm9yKGVycik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGZldGNoZXMgdGhlIGJ1c2luZXNzIHVuaXRzLiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGJ1c2luZXNzIHVuaXRzLiBJZiB0aGUgYnVzaW5lc3MgdW5pdHMgYXJlIG5vdCBmb3VuZCwgaXQgcmV0dXJucyBhIFNvYXBFcnJvci5cbiAgICogQHJldHVybnNcbiAgICovXG4gIGFzeW5jIGdldEJ1c2luZXNzVW5pdHMoKTogUHJvbWlzZTxCdXNpbmVzc1VuaXRbXSB8IFNvYXBFcnJvcj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhY2Nlc3NUb2tlbiA9IChhd2FpdCB0aGlzLmdldEFjY2Vzc1Rva2VuKCkpLmFjY2Vzc190b2tlbjtcbiAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYmFzZVVSTDogYGh0dHBzOi8vJHt0aGlzLmF1dGhPYmplY3Quc3ViRG9tYWlufS5zb2FwLm1hcmtldGluZ2Nsb3VkYXBpcy5jb21gLFxuICAgICAgICB1cmw6ICcvU2VydmljZS5hc214JyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIFNPQVBBY3Rpb246ICdSZXRyaWV2ZScsXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L3htbCcsXG4gICAgICAgIH0sXG4gICAgICAgIGRhdGE6IGF3YWl0IHhtbEJ1aWxkZXIoJ0J1c2luZXNzVW5pdCcsIFsnbmFtZScsICdpZCddLCBhY2Nlc3NUb2tlbiksXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRpb25zKTtcbiAgICAgIGNvbnN0IHBhcnNlZERhdGEgPSBwYXJzZVhNTChyZXNwLmRhdGEpO1xuICAgICAgY29uc3QgcmVzID0gcGFyc2VkRGF0YS5SZXRyaWV2ZVJlc3BvbnNlTXNnPy5SZXN1bHRzIGFzXG4gICAgICAgIHwgQnVzaW5lc3NVbml0UmVzcG9uc2VcbiAgICAgICAgfCBCdXNpbmVzc1VuaXRSZXNwb25zZVtdO1xuICAgICAgY29uc3QgYnVzaW5lc3NVbml0czogQnVzaW5lc3NVbml0W10gPSBbXTtcbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgY29uc3QgY3JlYXRlQnVzaW5lc3NVbml0ID0gKHJlc3BvbnNlOiBCdXNpbmVzc1VuaXRSZXNwb25zZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgUGFydG5lclByb3BlcnRpZXMgfSA9IHJlc3BvbnNlO1xuICAgICAgICAgIGNvbnN0IGVudHJ5ID0ge30gYXMgQnVzaW5lc3NVbml0O1xuICAgICAgICAgIFBhcnRuZXJQcm9wZXJ0aWVzLmZvckVhY2goKHByb3ApID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAocHJvcC5OYW1lKSB7XG4gICAgICAgICAgICAgIGNhc2UgJ25hbWUnOlxuICAgICAgICAgICAgICAgIGVudHJ5Lk5hbWUgPSBwcm9wLlZhbHVlIGFzIHN0cmluZztcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAnaWQnOlxuICAgICAgICAgICAgICAgIGVudHJ5LklEID0gcHJvcC5WYWx1ZSBhcyBudW1iZXI7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFNvYXBFcnJvcihgVW5rbm93biBwcm9wZXJ0eTogJHtwcm9wfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiBlbnRyeTtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXMpKSB7XG4gICAgICAgICAgcmVzLmZvckVhY2goKGVhY2hSZXMpID0+IHtcbiAgICAgICAgICAgIGJ1c2luZXNzVW5pdHMucHVzaChjcmVhdGVCdXNpbmVzc1VuaXQoZWFjaFJlcykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1c2luZXNzVW5pdHMucHVzaChjcmVhdGVCdXNpbmVzc1VuaXQocmVzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJ1c2luZXNzVW5pdHM7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgU29hcEVycm9yKCdObyBCdXNpbmVzcyBVbml0cyBmb3VuZCcpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgbmV3IFNvYXBFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBmZXRjaGVzIHRoZSBkYXRhIGZvbGRlcnMuIEl0IGJ1c2luZXNzIHVuaXQgaWQgaXMgcHJvdmlkZWQgYWxsIGRhdGEgZm9sZGVyIHVuZGVyIHRoYXQgYnVzaW5lc3MgaWQgd291bGQgYmUgcmV0cmlldmVkIG90aGVyd2lzZSBhbGwgdGhlIGRhdGEgZm9sZGVyIHdpbGwgYmUgcmV0cmlldmVkLiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGRhdGEgZm9sZGVycy4gSWYgdGhlIGRhdGEgZm9sZGVycyBhcmUgbm90IGZvdW5kLCBpdCByZXR1cm5zIGEgU29hcEVycm9yLlxuICAgKiBAcGFyYW0gYnVzaW5lc3NVbml0SWQgdGhpcyBpcyB0aGUgaWQgb2YgdGhlIGJ1c2luZXNzIHVuaXRcbiAgICogQHJldHVybnNcbiAgICovXG4gIGFzeW5jIGdldERhdGFGb2xkZXJzKGJ1c2luZXNzVW5pdElkPzogc3RyaW5nKTogUHJvbWlzZTxEYXRhRm9sZGVyW10gfCBTb2FwRXJyb3I+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSAoYXdhaXQgdGhpcy5nZXRBY2Nlc3NUb2tlbigpKS5hY2Nlc3NfdG9rZW47XG4gICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJhc2VVUkw6IGBodHRwczovLyR7dGhpcy5hdXRoT2JqZWN0LnN1YkRvbWFpbn0uc29hcC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tYCxcbiAgICAgICAgdXJsOiAnL1NlcnZpY2UuYXNteCcsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBTT0FQQWN0aW9uOiAnUmV0cmlldmUnLFxuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC94bWwnLFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBidXNpbmVzc1VuaXRJZFxuICAgICAgICAgID8gYXdhaXQgeG1sQnVpbGRlcihcbiAgICAgICAgICAgICAgJ0RhdGFGb2xkZXInLFxuICAgICAgICAgICAgICBbJ05hbWUnLCAnSUQnLCAnUGFyZW50Rm9sZGVyLklEJ10sXG4gICAgICAgICAgICAgIGFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgICBwYXJzZUZpbHRlcih7IGxlZnRPcGVyYW5kOiAnQ2xpZW50LklEJywgcmlnaHRPcGVyYW5kOiBidXNpbmVzc1VuaXRJZCB9KSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGF3YWl0IHhtbEJ1aWxkZXIoJ0RhdGFGb2xkZXInLCBbJ05hbWUnLCAnSUQnLCAnUGFyZW50Rm9sZGVyLklEJ10sIGFjY2Vzc1Rva2VuKSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdGlvbnMpO1xuICAgICAgY29uc3QgcGFyc2VkRGF0YSA9IHBhcnNlWE1MKHJlc3AuZGF0YSk7XG4gICAgICBjb25zdCByZXMgPSBwYXJzZWREYXRhLlJldHJpZXZlUmVzcG9uc2VNc2c/LlJlc3VsdHMgYXMgRGF0YUZvbGRlciB8IERhdGFGb2xkZXJbXTtcbiAgICAgIGNvbnN0IGRhdGFGb2xkZXJzOiBEYXRhRm9sZGVyW10gPSBbXTtcbiAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVzKSkge1xuICAgICAgICAgIHJlcy5mb3JFYWNoKChlYWNoUmVzKSA9PiB7XG4gICAgICAgICAgICBkYXRhRm9sZGVycy5wdXNoKGVhY2hSZXMpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGFGb2xkZXJzLnB1c2gocmVzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YUZvbGRlcnM7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgU29hcEVycm9yKCdObyBEYXRhIEZvbGRlciBmb3VuZCcpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgbmV3IFNvYXBFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGZldGNoZXMgdGhlIGRhdGEgZXh0ZW5zaW9ucy4gSXQgdGhlIGRhdGEgZm9sZGVyIGlkIGlzIHByb3ZpZGVkIGFsbCB0aGUgZGF0YSBleHRlbnNpb24gdW5kZXIgdGhhdCBkYXRhIGZvbGRlciB3aWxsIGJlIHJldHJpZXZlZCBvdGhlcndpc2UgYWxsIHRoZSBkYXRhIGV4dGVuc2lvbnMgdW5kZXIgdGhlIGFjY2VzcyB0b2tlbiB3aWxsIGJlIGZldGNoZWQuIFRoZSBtZXRob2QgcmV0dXJucyB0aGUgZGF0YSBleHRlbnNpb25zLiBJZiB0aGUgZGF0YSBleHRlbnNpb25zIGFyZSBub3QgZm91bmQsIGl0IHJldHVybnMgYSBTb2FwRXJyb3IuXG4gICAqIEBwYXJhbSBkYXRhRm9sZGVySWQgSWQgb2YgdGhlIGRhdGEgZm9sZGVyXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyBnZXREYXRhRXh0ZW5zaW9ucyhkYXRhRm9sZGVySWQ/OiBzdHJpbmcpOiBQcm9taXNlPERhdGFFeHRlbnNpb25bXSB8IFNvYXBFcnJvcj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhY2Nlc3NUb2tlbiA9IChhd2FpdCB0aGlzLmdldEFjY2Vzc1Rva2VuKCkpLmFjY2Vzc190b2tlbjtcbiAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYmFzZVVSTDogYGh0dHBzOi8vJHt0aGlzLmF1dGhPYmplY3Quc3ViRG9tYWlufS5zb2FwLm1hcmtldGluZ2Nsb3VkYXBpcy5jb21gLFxuICAgICAgICB1cmw6ICcvU2VydmljZS5hc214JyxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIFNPQVBBY3Rpb246ICdSZXRyaWV2ZScsXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L3htbCcsXG4gICAgICAgIH0sXG4gICAgICAgIGRhdGE6IGRhdGFGb2xkZXJJZFxuICAgICAgICAgID8gYXdhaXQgeG1sQnVpbGRlcihcbiAgICAgICAgICAgICAgJ0RhdGFFeHRlbnNpb24nLFxuICAgICAgICAgICAgICBbJ05BTUUnLCAnT2JqZWN0SWQnLCAnQ2F0ZWdvcnlJZCddLFxuICAgICAgICAgICAgICBhY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgcGFyc2VGaWx0ZXIoeyBsZWZ0T3BlcmFuZDogJ0NhdGVnb3J5SWQnLCByaWdodE9wZXJhbmQ6IGRhdGFGb2xkZXJJZCB9KSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGF3YWl0IHhtbEJ1aWxkZXIoJ0RhdGFFeHRlbnNpb24nLCBbJ05BTUUnLCAnT2JqZWN0SWQnLCAnQ2F0ZWdvcnlJZCddLCBhY2Nlc3NUb2tlbiksXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRpb25zKTtcbiAgICAgIGNvbnN0IHBhcnNlZERhdGEgPSBwYXJzZVhNTChyZXNwLmRhdGEpO1xuICAgICAgY29uc3QgcmVzID0gcGFyc2VkRGF0YS5SZXRyaWV2ZVJlc3BvbnNlTXNnPy5SZXN1bHRzIGFzXG4gICAgICAgIHwgRGF0YUV4dGVuc2lvblJlc3BvbnNlXG4gICAgICAgIHwgRGF0YUV4dGVuc2lvblJlc3BvbnNlW107XG4gICAgICBjb25zdCBkYXRhRXh0ZW5zaW9uczogRGF0YUV4dGVuc2lvbltdID0gW107XG4gICAgICBpZiAocmVzKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlcykpIHtcbiAgICAgICAgICByZXMuZm9yRWFjaCgoZWFjaFJlcykgPT4ge1xuICAgICAgICAgICAgZGF0YUV4dGVuc2lvbnMucHVzaCh7XG4gICAgICAgICAgICAgIE9iamVjdElkOiBlYWNoUmVzLlBhcnRuZXJQcm9wZXJ0aWVzWzBdLlZhbHVlLFxuICAgICAgICAgICAgICBOYW1lOiBlYWNoUmVzLlBhcnRuZXJQcm9wZXJ0aWVzWzFdLlZhbHVlLFxuICAgICAgICAgICAgICBDYXRlZ29yeUlkOiBlYWNoUmVzLlBhcnRuZXJQcm9wZXJ0aWVzWzJdLlZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGF0YUV4dGVuc2lvbnMucHVzaCh7XG4gICAgICAgICAgICBPYmplY3RJZDogcmVzLlBhcnRuZXJQcm9wZXJ0aWVzWzBdLlZhbHVlLFxuICAgICAgICAgICAgTmFtZTogcmVzLlBhcnRuZXJQcm9wZXJ0aWVzWzFdLlZhbHVlLFxuICAgICAgICAgICAgQ2F0ZWdvcnlJZDogcmVzLlBhcnRuZXJQcm9wZXJ0aWVzWzJdLlZhbHVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRhRXh0ZW5zaW9ucztcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBTb2FwRXJyb3IoJ05vIERhdGEgRXh0ZW5zaW9uIGZvdW5kJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aHJvdyBuZXcgU29hcEVycm9yKGVycik7XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
373
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2Rrcy9zZm1jL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsa0RBQTBDO0FBa0IxQyxtQ0FTaUI7QUFFakIsTUFBcUIsSUFBSTtJQUd2QixZQUFZLFVBQXNCO1FBQ2hDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRU8sTUFBTSxDQUFDLGtCQUFrQixDQUFDLFVBQWU7UUFDL0MsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQXlDLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUc7WUFDbEIsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtZQUNuRCxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFO1lBQ3ZEO2dCQUNFLEdBQUcsRUFBRSxXQUFXO2dCQUNoQixJQUFJLEVBQUUsUUFBUTtnQkFDZCxRQUFRLEVBQUUsSUFBSTtnQkFDZCxLQUFLLEVBQUUsWUFBWTtnQkFDbkIsWUFBWSxFQUFFLHlDQUF5QzthQUN4RDtTQUNGLENBQUM7UUFFRixXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRTtZQUNuRSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDOUIsSUFBSSxRQUFRLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLEdBQUcs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LENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sY0FBYyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRS9FLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUN4QyxjQUFjLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNoQyxNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDOUMsSUFBSSxNQUFNLFlBQVksaUJBQVMsRUFBRSxDQUFDO2dCQUNoQyxNQUFNLE1BQU0sQ0FBQztZQUNmLENBQUM7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBRUYsTUFBTSxVQUFVLEdBQUcsQ0FBQyxTQUFTLEVBQUUsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3BELE9BQU8sVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLFlBQVksaUJBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUMzRixDQUFDO0NBQ0Y7QUF2YUQsdUJBdWFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF4aW9zLCB7IEF4aW9zRXJyb3IgfSBmcm9tICdheGlvcyc7XG5pbXBvcnQge1xuICBBdXRoT2JqZWN0LFxuICBCdXNpbmVzc1VuaXQsXG4gIEJ1c2luZXNzVW5pdFJlc3BvbnNlLFxuICBDb250YWN0QXR0cmlidXRlc1Jlc3BvbnNlLFxuICBDcmVhdGVEYXRhRXh0ZW5zaW9uUmVzcG9uc2UsXG4gIERhdGFFeHRlbnNpb24sXG4gIERhdGFFeHRlbnNpb25Cb2R5LFxuICBEYXRhRXh0ZW5zaW9uUmVzcG9uc2UsXG4gIERhdGFGb2xkZXIsXG4gIFNGTUNFcnJvclJlc3BvbnNlLFxuICBFdmVudERlZmluaXRpb24sXG4gIEV2ZW50RGVmaW5pdGlvbnNSZXNwb25zZSxcbiAgQ29udGFjdEF0dHJpYnV0ZXMsXG4gIERhdGFFeHRlbnNpb25QYXJ0bmVyUHJvcGVydHksXG4gIERhdGFFeHRlbnNpb25BcGlSZXNwb25zZSxcbn0gZnJvbSAnLi90eXBlJztcbmltcG9ydCB7XG4gIGdldFVybCxcbiAgaXNFeHBpcmVkLFxuICBwYXJzZUZpbHRlcixcbiAgcGFyc2VYTUwsXG4gIGdldFRva2VuLFxuICBSZXN0RXJyb3IsXG4gIFNvYXBFcnJvcixcbiAgeG1sQnVpbGRlcixcbn0gZnJvbSAnLi91dGlscyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNGTUMge1xuICBhdXRoT2JqZWN0OiBBdXRoT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKGF1dGhPYmplY3Q6IEF1dGhPYmplY3QpIHtcbiAgICBTRk1DLnZhbGlkYXRlQXV0aE9iamVjdChhdXRoT2JqZWN0KTtcbiAgICB0aGlzLmF1dGhPYmplY3QgPSBhdXRoT2JqZWN0O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVBdXRoT2JqZWN0KGF1dGhPYmplY3Q6IGFueSk6IGFueSB7XG4gICAgaWYgKCFhdXRoT2JqZWN0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2F1dGhPYmplY3QgaXMgcmVxdWlyZWQuIFNlZSB0aGUgcmVhZG1lLicpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRpb25zID0gW1xuICAgICAgeyBrZXk6ICdjbGllbnRJZCcsIHR5cGU6ICdzdHJpbmcnLCByZXF1aXJlZDogdHJ1ZSB9LFxuICAgICAgeyBrZXk6ICdjbGllbnRTZWNyZXQnLCB0eXBlOiAnc3RyaW5nJywgcmVxdWlyZWQ6IHRydWUgfSxcbiAgICAgIHtcbiAgICAgICAga2V5OiAnc3ViRG9tYWluJyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICByZWdleDogL15cXHd7Mjh9JC9nbSxcbiAgICAgICAgcmVnZXhNZXNzYWdlOiAnc3ViRG9tYWluIG11c3QgYmUgYSBzdHJpbmcgb2YgbGVuZ3RoIDI4JyxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIHZhbGlkYXRpb25zLmZvckVhY2goKHsga2V5LCB0eXBlLCByZXF1aXJlZCwgcmVnZXgsIHJlZ2V4TWVzc2FnZSB9KSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGF1dGhPYmplY3Rba2V5XTtcbiAgICAgIGlmIChyZXF1aXJlZCAmJiAhdmFsdWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2tleX0gaXMgbWlzc2luZyBvciBpbnZhbGlkYCk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSB0eXBlKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7a2V5fSBtdXN0IGJlIGEgJHt0eXBlfWApO1xuICAgICAgfVxuICAgICAgaWYgKHJlZ2V4ICYmICFyZWdleC50ZXN0KHZhbHVlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IocmVnZXhNZXNzYWdlIHx8IGAke2tleX0gZG9lcyBub3QgbWF0Y2ggdGhlIHJlcXVpcmVkIGZvcm1hdGApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF1dGhPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBhY2Nlc3MgdG9rZW4uIElmIHRoZSB0b2tlbiBpcyBleHBpcmVkLCBpdCB3aWxsIGdlbmVyYXRlIGEgbmV3IHRva2VuLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBdXRoT2JqZWN0Pn0gIEl0IHJldHVybnMgdGhlIGFjY2VzcyB0b2tlbiBvciBlcnJvclxuICAgKi9cbiAgYXN5bmMgZ2V0QWNjZXNzVG9rZW4oKSB7XG4gICAgaWYgKGlzRXhwaXJlZCh0aGlzLmF1dGhPYmplY3QpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBnZXRUb2tlbih0aGlzLmF1dGhPYmplY3QpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBnZW5lcmF0ZSB0b2tlbiwgd2l0aCBlcnJvcjoke2V9YCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmF1dGhPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgZmV0Y2hlcyB0aGUgZmllbGRzIG9mIGEgZGF0YSBleHRlbnNpb24uIEl0IHJlcXVpcmVzIHRoZSBkYXRhIGV4dGVuc2lvbiBpZC4gVGhlIG1ldGhvZCByZXR1cm5zIHRoZSBmaWVsZHMgb2YgdGhlIGRhdGEgZXh0ZW5zaW9uLiBJZiB0aGUgZGF0YSBleHRlbnNpb24gaXMgbm90IGZvdW5kLCBpdCByZXR1cm5zIGEgUmVzdEVycm9yLlxuICAgKiBAcGFyYW0gZGF0YUV4dGVuc2lvbklkIElkIG9mIHRoZSBkYXRhIGV4dGVuc2lvbiB3aG9zZSBmaWVsZHMgYXJlIHRvIGJlIGZldGNoZWRcbiAgICogQHJldHVybnNcbiAgICovXG4gIGFzeW5jIGdldERlc3RpbmF0aW9uRmllbGRzKGRhdGFFeHRlbnNpb25JZDogc3RyaW5nKTogUHJvbWlzZTxEYXRhRXh0ZW5zaW9uQm9keSB8IFJlc3RFcnJvcj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN0SGVhZGVycyA9IHtcbiAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAkeyhhd2FpdCB0aGlzLmdldEFjY2Vzc1Rva2VuKCkpLmFjY2Vzc190b2tlbn1gLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICBiYXNlVVJMOiBnZXRVcmwodGhpcy5hdXRoT2JqZWN0LnN1YkRvbWFpbiksXG4gICAgICAgIHVybDogYC9kYXRhL3YxL2N1c3RvbW9iamVjdHMvJHtkYXRhRXh0ZW5zaW9uSWR9L2ZpZWxkc2AsXG4gICAgICAgIGhlYWRlcnM6IHJlc3RIZWFkZXJzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBheGlvcyhyZXF1ZXN0T3B0aW9ucyk7XG4gICAgICByZXR1cm4gcmVzcC5kYXRhO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGF4aW9zLmlzQXhpb3NFcnJvcihlcnIpKSB7XG4gICAgICAgIGNvbnN0IGF4aW9zRXJyb3IgPSBlcnIgYXMgQXhpb3NFcnJvcjxTRk1DRXJyb3JSZXNwb25zZT47XG4gICAgICAgIHRocm93IG5ldyBSZXN0RXJyb3IoYXhpb3NFcnJvcik7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGZldGNoZXMgdGhlIGNvbnRhY3QgYXR0cmlidXRlcy4gVGhlIG1ldGhvZCByZXR1cm5zIHRoZSBjb250YWN0IGF0dHJpYnV0ZXMuIElmIHRoZSBjb250YWN0IGF0dHJpYnV0ZXMgYXJlIG5vdCBmb3VuZCwgaXQgcmV0dXJucyBhIFJlc3RFcnJvci5cbiAgICogQHBhcmFtIHBhZ2UgUGFnZSBudW1iZXJcbiAgICogQHBhcmFtIHBhZ2VTaXplIFBhZ2Ugc2l6ZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxDb250YWN0QXR0cmlidXRlc1Jlc3BvbnNlIHwgUmVzdEVycm9yPn1cbiAgICovXG4gIGFzeW5jIGdldENvbnRhY3RBdHRyaWJ1dGVzSXRlbXMoXG4gICAgcGFnZTogbnVtYmVyLFxuICAgIHBhZ2VTaXplOiBudW1iZXIsXG4gICk6IFByb21pc2U8Q29udGFjdEF0dHJpYnV0ZXNSZXNwb25zZSB8IFJlc3RFcnJvcj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN0SGVhZGVycyA9IHtcbiAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAkeyhhd2FpdCB0aGlzLmdldEFjY2Vzc1Rva2VuKCkpLmFjY2Vzc190b2tlbn1gLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlcXVlc3RPcHRpb25zID0ge1xuICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICBiYXNlVVJMOiBnZXRVcmwodGhpcy5hdXRoT2JqZWN0LnN1YkRvbWFpbiksXG4gICAgICAgIHVybDogYC9jb250YWN0cy92MS9hdHRyaWJ1dGVTZXREZWZpbml0aW9ucz8kcGFnZT0ke3BhZ2V9JiRwYWdlU2l6ZT0ke3BhZ2VTaXplfWAsXG4gICAgICAgIGhlYWRlcnM6IHJlc3RIZWFkZXJzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBheGlvcyhyZXF1ZXN0T3B0aW9ucyk7XG4gICAgICByZXR1cm4gcmVzcC5kYXRhO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGF4aW9zLmlzQXhpb3NFcnJvcihlcnIpKSB7XG4gICAgICAgIGNvbnN0IGF4aW9zRXJyb3IgPSBlcnIgYXMgQXhpb3NFcnJvcjxTRk1DRXJyb3JSZXNwb25zZT47XG4gICAgICAgIHRocm93IG5ldyBSZXN0RXJyb3IoYXhpb3NFcnJvcik7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2V0Q29udGFjdEF0dHJpYnV0ZXMoKTogUHJvbWlzZTxDb250YWN0QXR0cmlidXRlc1tdIHwgUmVzdEVycm9yPiB7XG4gICAgY29uc3QgY29udGFjdEF0dHJpYnV0ZXMgPSBhd2FpdCBTRk1DLmdldEFsbEl0ZW1Gcm9tUGFnZXM8Q29udGFjdEF0dHJpYnV0ZXM+KFxuICAgICAgdGhpcy5nZXRDb250YWN0QXR0cmlidXRlc0l0ZW1zLmJpbmQodGhpcyksXG4gICAgKTtcbiAgICByZXR1cm4gY29udGFjdEF0dHJpYnV0ZXM7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgY3JlYXRlcyBhIGRhdGEgZXh0ZW5zaW9uLiBJdCByZXF1aXJlcyB0aGUgZGF0YSBleHRlbnNpb24gZmllbGRzLiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGRhdGEgZXh0ZW5zaW9uIGNyZWF0ZWQuIElmIHRoZSBkYXRhIGV4dGVuc2lvbiBpcyBub3QgY3JlYXRlZCwgaXQgcmV0dXJucyBhIFJlc3RFcnJvci5cbiAgICogQHBhcmFtIGJvZHkgRGF0YUV4dGVuc2lvbiBmaWVsZHNcbiAgICogQHJldHVybnNcbiAgICovXG4gIGFzeW5jIGNyZWF0ZURhdGFFeHRlbnNpb24oXG4gICAgYm9keTogRGF0YUV4dGVuc2lvbkJvZHksXG4gICk6IFByb21pc2U8Q3JlYXRlRGF0YUV4dGVuc2lvblJlc3BvbnNlIHwgUmVzdEVycm9yPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3RIZWFkZXJzID0ge1xuICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7KGF3YWl0IHRoaXMuZ2V0QWNjZXNzVG9rZW4oKSkuYWNjZXNzX3Rva2VufWAsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBiYXNlVVJMOiBnZXRVcmwodGhpcy5hdXRoT2JqZWN0LnN1YkRvbWFpbiksXG4gICAgICAgIHVybDogJy9kYXRhL3YxL2N1c3RvbW9iamVjdHMnLFxuICAgICAgICBoZWFkZXJzOiByZXN0SGVhZGVycyxcbiAgICAgICAgZGF0YTogYm9keSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdGlvbnMpO1xuICAgICAgcmV0dXJuIHJlc3AuZGF0YTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IFJlc3RFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIG1ldGhvZCBmZXRjaGVzIHRoZSBidXNpbmVzcyB1bml0cy4gVGhlIG1ldGhvZCByZXR1cm5zIHRoZSBidXNpbmVzcyB1bml0cy4gSWYgdGhlIGJ1c2luZXNzIHVuaXRzIGFyZSBub3QgZm91bmQsIGl0IHJldHVybnMgYSBTb2FwRXJyb3IuXG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyBnZXRCdXNpbmVzc1VuaXRzKCk6IFByb21pc2U8QnVzaW5lc3NVbml0W10gfCBTb2FwRXJyb3I+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSAoYXdhaXQgdGhpcy5nZXRBY2Nlc3NUb2tlbigpKS5hY2Nlc3NfdG9rZW47XG4gICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJhc2VVUkw6IGBodHRwczovLyR7dGhpcy5hdXRoT2JqZWN0LnN1YkRvbWFpbn0uc29hcC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tYCxcbiAgICAgICAgdXJsOiAnL1NlcnZpY2UuYXNteCcsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBTT0FQQWN0aW9uOiAnUmV0cmlldmUnLFxuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC94bWwnLFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBhd2FpdCB4bWxCdWlsZGVyKCdCdXNpbmVzc1VuaXQnLCBbJ25hbWUnLCAnaWQnXSwgYWNjZXNzVG9rZW4pLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBheGlvcyhyZXF1ZXN0T3B0aW9ucyk7XG4gICAgICBjb25zdCBwYXJzZWREYXRhID0gcGFyc2VYTUwocmVzcC5kYXRhKTtcbiAgICAgIGNvbnN0IHJlcyA9IHBhcnNlZERhdGEuUmV0cmlldmVSZXNwb25zZU1zZz8uUmVzdWx0cyBhc1xuICAgICAgICB8IEJ1c2luZXNzVW5pdFJlc3BvbnNlXG4gICAgICAgIHwgQnVzaW5lc3NVbml0UmVzcG9uc2VbXTtcbiAgICAgIGNvbnN0IGJ1c2luZXNzVW5pdHM6IEJ1c2luZXNzVW5pdFtdID0gW107XG4gICAgICBpZiAocmVzKSB7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUJ1c2luZXNzVW5pdCA9IChyZXNwb25zZTogQnVzaW5lc3NVbml0UmVzcG9uc2UpID0+IHtcbiAgICAgICAgICBjb25zdCB7IFBhcnRuZXJQcm9wZXJ0aWVzIH0gPSByZXNwb25zZTtcbiAgICAgICAgICBjb25zdCBlbnRyeSA9IHt9IGFzIEJ1c2luZXNzVW5pdDtcbiAgICAgICAgICBQYXJ0bmVyUHJvcGVydGllcy5mb3JFYWNoKChwcm9wKSA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKHByb3AuTmFtZSkge1xuICAgICAgICAgICAgICBjYXNlICduYW1lJzpcbiAgICAgICAgICAgICAgICBlbnRyeS5OYW1lID0gcHJvcC5WYWx1ZSBhcyBzdHJpbmc7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ2lkJzpcbiAgICAgICAgICAgICAgICBlbnRyeS5JRCA9IHByb3AuVmFsdWUgYXMgbnVtYmVyO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBTb2FwRXJyb3IoYFVua25vd24gcHJvcGVydHk6ICR7cHJvcH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gZW50cnk7XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVzKSkge1xuICAgICAgICAgIHJlcy5mb3JFYWNoKChlYWNoUmVzKSA9PiB7XG4gICAgICAgICAgICBidXNpbmVzc1VuaXRzLnB1c2goY3JlYXRlQnVzaW5lc3NVbml0KGVhY2hSZXMpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidXNpbmVzc1VuaXRzLnB1c2goY3JlYXRlQnVzaW5lc3NVbml0KHJlcykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBidXNpbmVzc1VuaXRzO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IFNvYXBFcnJvcignTm8gQnVzaW5lc3MgVW5pdHMgZm91bmQnKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRocm93IG5ldyBTb2FwRXJyb3IoZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBtZXRob2QgZmV0Y2hlcyB0aGUgZGF0YSBmb2xkZXJzLiBJdCBidXNpbmVzcyB1bml0IGlkIGlzIHByb3ZpZGVkIGFsbCBkYXRhIGZvbGRlciB1bmRlciB0aGF0IGJ1c2luZXNzIGlkIHdvdWxkIGJlIHJldHJpZXZlZCBvdGhlcndpc2UgYWxsIHRoZSBkYXRhIGZvbGRlciB3aWxsIGJlIHJldHJpZXZlZC4gVGhlIG1ldGhvZCByZXR1cm5zIHRoZSBkYXRhIGZvbGRlcnMuIElmIHRoZSBkYXRhIGZvbGRlcnMgYXJlIG5vdCBmb3VuZCwgaXQgcmV0dXJucyBhIFNvYXBFcnJvci5cbiAgICogQHBhcmFtIGJ1c2luZXNzVW5pdElkIHRoaXMgaXMgdGhlIGlkIG9mIHRoZSBidXNpbmVzcyB1bml0XG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBhc3luYyBnZXREYXRhRm9sZGVycyhidXNpbmVzc1VuaXRJZD86IHN0cmluZyk6IFByb21pc2U8RGF0YUZvbGRlcltdIHwgU29hcEVycm9yPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGFjY2Vzc1Rva2VuID0gKGF3YWl0IHRoaXMuZ2V0QWNjZXNzVG9rZW4oKSkuYWNjZXNzX3Rva2VuO1xuICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBiYXNlVVJMOiBgaHR0cHM6Ly8ke3RoaXMuYXV0aE9iamVjdC5zdWJEb21haW59LnNvYXAubWFya2V0aW5nY2xvdWRhcGlzLmNvbWAsXG4gICAgICAgIHVybDogJy9TZXJ2aWNlLmFzbXgnLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgU09BUEFjdGlvbjogJ1JldHJpZXZlJyxcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ3RleHQveG1sJyxcbiAgICAgICAgfSxcbiAgICAgICAgZGF0YTogYnVzaW5lc3NVbml0SWRcbiAgICAgICAgICA/IGF3YWl0IHhtbEJ1aWxkZXIoXG4gICAgICAgICAgICAgICdEYXRhRm9sZGVyJyxcbiAgICAgICAgICAgICAgWydOYW1lJywgJ0lEJywgJ1BhcmVudEZvbGRlci5JRCddLFxuICAgICAgICAgICAgICBhY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgcGFyc2VGaWx0ZXIoeyBsZWZ0T3BlcmFuZDogJ0NsaWVudC5JRCcsIHJpZ2h0T3BlcmFuZDogYnVzaW5lc3NVbml0SWQgfSksXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiBhd2FpdCB4bWxCdWlsZGVyKCdEYXRhRm9sZGVyJywgWydOYW1lJywgJ0lEJywgJ1BhcmVudEZvbGRlci5JRCddLCBhY2Nlc3NUb2tlbiksXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRpb25zKTtcbiAgICAgIGNvbnN0IHBhcnNlZERhdGEgPSBwYXJzZVhNTChyZXNwLmRhdGEpO1xuICAgICAgY29uc3QgcmVzID0gcGFyc2VkRGF0YS5SZXRyaWV2ZVJlc3BvbnNlTXNnPy5SZXN1bHRzIGFzIERhdGFGb2xkZXIgfCBEYXRhRm9sZGVyW107XG4gICAgICBjb25zdCBkYXRhRm9sZGVyczogRGF0YUZvbGRlcltdID0gW107XG4gICAgICBpZiAocmVzKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlcykpIHtcbiAgICAgICAgICByZXMuZm9yRWFjaCgoZWFjaFJlcykgPT4ge1xuICAgICAgICAgICAgZGF0YUZvbGRlcnMucHVzaChlYWNoUmVzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkYXRhRm9sZGVycy5wdXNoKHJlcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGFGb2xkZXJzO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IFNvYXBFcnJvcignTm8gRGF0YSBGb2xkZXIgZm91bmQnKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRocm93IG5ldyBTb2FwRXJyb3IoZXJyKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBmZXRjaGVzIHRoZSBkYXRhIGV4dGVuc2lvbnMuIEl0IHRoZSBkYXRhIGZvbGRlciBpZCBpcyBwcm92aWRlZCBhbGwgdGhlIGRhdGEgZXh0ZW5zaW9uIHVuZGVyIHRoYXQgZGF0YSBmb2xkZXIgd2lsbCBiZSByZXRyaWV2ZWQgb3RoZXJ3aXNlIGFsbCB0aGUgZGF0YSBleHRlbnNpb25zIHVuZGVyIHRoZSBhY2Nlc3MgdG9rZW4gd2lsbCBiZSBmZXRjaGVkLiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGRhdGEgZXh0ZW5zaW9ucy4gSWYgdGhlIGRhdGEgZXh0ZW5zaW9ucyBhcmUgbm90IGZvdW5kLCBpdCByZXR1cm5zIGEgU29hcEVycm9yLlxuICAgKiBAcGFyYW0gZGF0YUZvbGRlcklkIElkIG9mIHRoZSBkYXRhIGZvbGRlclxuICAgKiBAcmV0dXJuc1xuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YUV4dGVuc2lvbnMoZGF0YUZvbGRlcklkPzogc3RyaW5nKTogUHJvbWlzZTxEYXRhRXh0ZW5zaW9uW10gfCBTb2FwRXJyb3I+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgYWNjZXNzVG9rZW4gPSAoYXdhaXQgdGhpcy5nZXRBY2Nlc3NUb2tlbigpKS5hY2Nlc3NfdG9rZW47XG4gICAgICBjb25zdCByZXF1ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJhc2VVUkw6IGBodHRwczovLyR7dGhpcy5hdXRoT2JqZWN0LnN1YkRvbWFpbn0uc29hcC5tYXJrZXRpbmdjbG91ZGFwaXMuY29tYCxcbiAgICAgICAgdXJsOiAnL1NlcnZpY2UuYXNteCcsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBTT0FQQWN0aW9uOiAnUmV0cmlldmUnLFxuICAgICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC94bWwnLFxuICAgICAgICB9LFxuICAgICAgICBkYXRhOiBkYXRhRm9sZGVySWRcbiAgICAgICAgICA/IGF3YWl0IHhtbEJ1aWxkZXIoXG4gICAgICAgICAgICAgICdEYXRhRXh0ZW5zaW9uJyxcbiAgICAgICAgICAgICAgWydOQU1FJywgJ09iamVjdElkJywgJ0NhdGVnb3J5SWQnLCAnQ3VzdG9tZXJLZXknLCAnSXNTZW5kYWJsZSddLFxuICAgICAgICAgICAgICBhY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgcGFyc2VGaWx0ZXIoeyBsZWZ0T3BlcmFuZDogJ0NhdGVnb3J5SWQnLCByaWdodE9wZXJhbmQ6IGRhdGFGb2xkZXJJZCB9KSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IGF3YWl0IHhtbEJ1aWxkZXIoXG4gICAgICAgICAgICAgICdEYXRhRXh0ZW5zaW9uJyxcbiAgICAgICAgICAgICAgWydOQU1FJywgJ09iamVjdElkJywgJ0NhdGVnb3J5SWQnLCAnQ3VzdG9tZXJLZXknLCAnSXNTZW5kYWJsZSddLFxuICAgICAgICAgICAgICBhY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICksXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGF4aW9zKHJlcXVlc3RPcHRpb25zKTtcbiAgICAgIGNvbnN0IHBhcnNlZERhdGEgPSBwYXJzZVhNTChyZXNwLmRhdGEpO1xuICAgICAgY29uc3QgcmVzID0gcGFyc2VkRGF0YS5SZXRyaWV2ZVJlc3BvbnNlTXNnPy5SZXN1bHRzIGFzXG4gICAgICAgIHwgRGF0YUV4dGVuc2lvblJlc3BvbnNlXG4gICAgICAgIHwgRGF0YUV4dGVuc2lvblJlc3BvbnNlW107XG4gICAgICBjb25zdCBkYXRhRXh0ZW5zaW9uczogRGF0YUV4dGVuc2lvbltdID0gW107XG4gICAgICBpZiAocmVzKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlcykpIHtcbiAgICAgICAgICByZXMuZm9yRWFjaCgoZWFjaFJlcykgPT4ge1xuICAgICAgICAgICAgZGF0YUV4dGVuc2lvbnMucHVzaChTRk1DLm1hcERhdGFFeHRlbnNpb24oZWFjaFJlcykpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRhdGFFeHRlbnNpb25zLnB1c2goU0ZNQy5tYXBEYXRhRXh0ZW5zaW9uKHJlcykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRhRXh0ZW5zaW9ucztcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBTb2FwRXJyb3IoJ05vIERhdGEgRXh0ZW5zaW9uIGZvdW5kJyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aHJvdyBuZXcgU29hcEVycm9yKGVycik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgbWFwRGF0YUV4dGVuc2lvbihkYXRhRXh0ZW5zaW9uOiBEYXRhRXh0ZW5zaW9uUmVzcG9uc2UpOiBEYXRhRXh0ZW5zaW9uIHtcbiAgICBjb25zdCBnZXRQcm9wZXJ0eSA9IDxUIGV4dGVuZHMgRGF0YUV4dGVuc2lvblBhcnRuZXJQcm9wZXJ0eT4oXG4gICAgICBwcm9wczogRGF0YUV4dGVuc2lvblBhcnRuZXJQcm9wZXJ0eVtdLFxuICAgICAgbmFtZTogVFsnTmFtZSddLFxuICAgICk6IFRbJ1ZhbHVlJ10gPT4ge1xuICAgICAgY29uc3QgcHJvcGVydHkgPSBwcm9wcy5maW5kKChwcm9wKTogcHJvcCBpcyBUID0+IHByb3AuTmFtZSA9PT0gbmFtZSk7XG4gICAgICBpZiAoIXByb3BlcnR5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyByZXF1aXJlZCBwcm9wZXJ0eTogJHtuYW1lfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHByb3BlcnR5LlZhbHVlIGFzIFRbJ1ZhbHVlJ107XG4gICAgfTtcblxuICAgIGNvbnN0IHsgUGFydG5lclByb3BlcnRpZXMgfSA9IGRhdGFFeHRlbnNpb247XG4gICAgcmV0dXJuIHtcbiAgICAgIE9iamVjdElkOiBnZXRQcm9wZXJ0eTxEYXRhRXh0ZW5zaW9uUGFydG5lclByb3BlcnR5PihQYXJ0bmVyUHJvcGVydGllcywgJ09iamVjdElkJykgYXMgc3RyaW5nLFxuICAgICAgTmFtZTogZ2V0UHJvcGVydHk8RGF0YUV4dGVuc2lvblBhcnRuZXJQcm9wZXJ0eT4oUGFydG5lclByb3BlcnRpZXMsICdOQU1FJykgYXMgc3RyaW5nLFxuICAgICAgQ2F0ZWdvcnlJZDogZ2V0UHJvcGVydHk8RGF0YUV4dGVuc2lvblBhcnRuZXJQcm9wZXJ0eT4oXG4gICAgICAgIFBhcnRuZXJQcm9wZXJ0aWVzLFxuICAgICAgICAnQ2F0ZWdvcnlJZCcsXG4gICAgICApIGFzIG51bWJlcixcbiAgICAgIEV4dGVybmFsS2V5OiBkYXRhRXh0ZW5zaW9uLkN1c3RvbWVyS2V5LFxuICAgICAgSXNTZW5kYWJsZTogZGF0YUV4dGVuc2lvbi5Jc1NlbmRhYmxlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBmZXRjaGVzIHRoZSBkYXRhIGV4dGVuc2lvbiBieSBpZC4gSXQgcmV0dXJucyB0aGUgZGF0YSBleHRlbnNpb24uIElmIHRoZSBkYXRhIGV4dGVuc2lvbiBpcyBub3QgZm91bmQsIGl0IHJldHVybnMgYSBSZXN0RXJyb3IuXG4gICAqIEBwYXJhbSBkYXRhRXh0ZW5zaW9uSWQgSWQgb2YgdGhlIGRhdGEgZXh0ZW5zaW9uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPERhdGFFeHRlbnNpb24gfCBSZXN0RXJyb3I+fVxuICAgKi9cbiAgYXN5bmMgZ2V0RGF0YUV4dGVuc2lvbkJ5SWQoXG4gICAgZGF0YUV4dGVuc2lvbklkOiBzdHJpbmcsXG4gICk6IFByb21pc2U8RGF0YUV4dGVuc2lvbkFwaVJlc3BvbnNlIHwgUmVzdEVycm9yPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGFjY2Vzc1Rva2VuID0gKGF3YWl0IHRoaXMuZ2V0QWNjZXNzVG9rZW4oKSkuYWNjZXNzX3Rva2VuO1xuICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgIGJhc2VVUkw6IGdldFVybCh0aGlzLmF1dGhPYmplY3Quc3ViRG9tYWluKSxcbiAgICAgICAgdXJsOiBgL2RhdGEvdjEvY3VzdG9tb2JqZWN0cy8ke2RhdGFFeHRlbnNpb25JZH1gLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2FjY2Vzc1Rva2VufWAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGF4aW9zPERhdGFFeHRlbnNpb25BcGlSZXNwb25zZT4ocmVxdWVzdE9wdGlvbnMpO1xuICAgICAgcmV0dXJuIHJlc3AuZGF0YTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgaWYgKGF4aW9zLmlzQXhpb3NFcnJvcihlcnIpKSB7XG4gICAgICAgIGNvbnN0IGF4aW9zRXJyb3IgPSBlcnIgYXMgQXhpb3NFcnJvcjxTRk1DRXJyb3JSZXNwb25zZT47XG4gICAgICAgIHRocm93IG5ldyBSZXN0RXJyb3IoYXhpb3NFcnJvcik7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gZmV0Y2hlcyB0aGUgZXZlbnQgZGVmaW5pdGlvbnMuIEl0IHJldHVybnMgdGhlIGV2ZW50IGRlZmluaXRpb25zLiBJZiB0aGUgZXZlbnQgZGVmaW5pdGlvbnMgYXJlIG5vdCBmb3VuZCwgaXQgcmV0dXJucyBhIFJlc3RFcnJvci5cbiAgICogQHBhcmFtIHBhZ2UgUGFnZSBudW1iZXJcbiAgICogQHBhcmFtIHBhZ2VTaXplIFBhZ2Ugc2l6ZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxFdmVudERlZmluaXRpb25zUmVzcG9uc2UgfCBSZXN0RXJyb3I+fVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZXRFdmVudERlZmluaXRpb25zKFxuICAgIHBhZ2U6IG51bWJlcixcbiAgICBwYWdlU2l6ZTogbnVtYmVyLFxuICApOiBQcm9taXNlPEV2ZW50RGVmaW5pdGlvbnNSZXNwb25zZSB8IFJlc3RFcnJvcj4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBhY2Nlc3NUb2tlbiA9IChhd2FpdCB0aGlzLmdldEFjY2Vzc1Rva2VuKCkpLmFjY2Vzc190b2tlbjtcblxuICAgICAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgIGJhc2VVUkw6IGdldFVybCh0aGlzLmF1dGhPYmplY3Quc3ViRG9tYWluKSxcbiAgICAgICAgdXJsOiBgL2ludGVyYWN0aW9uL3YxL2V2ZW50RGVmaW5pdGlvbnM/JHBhZ2U9JHtwYWdlfSYkcGFnZVNpemU9JHtwYWdlU2l6ZX1gLFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2FjY2Vzc1Rva2VufWAsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgYXhpb3MocmVxdWVzdE9wdGlvbnMpO1xuICAgICAgcmV0dXJuIHJlc3AuZGF0YTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IFJlc3RFcnJvcihlcnIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGZldGNoZXMgYWxsIHRoZSBldmVudCBkZWZpbml0aW9ucy4gSXQgcmV0dXJucyB0aGUgZXZlbnQgZGVmaW5pdGlvbnMuIElmIHRoZSBldmVudCBkZWZpbml0aW9ucyBhcmUgbm90IGZvdW5kLCBpdCByZXR1cm5zIGEgUmVzdEVycm9yLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxFdmVudERlZmluaXRpb25bXSB8IFJlc3RFcnJvcj59XG4gICAqL1xuICBhc3luYyBnZXRBbGxFdmVudERlZmluaXRpb25zKCk6IFByb21pc2U8RXZlbnREZWZpbml0aW9uW10gfCBSZXN0RXJyb3I+IHtcbiAgICBjb25zdCBldmVudERlZmluaXRpb25zID0gYXdhaXQgU0ZNQy5nZXRBbGxJdGVtRnJvbVBhZ2VzPEV2ZW50RGVmaW5pdGlvbj4oXG4gICAgICB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbnMuYmluZCh0aGlzKSxcbiAgICApO1xuICAgIHJldHVybiBldmVudERlZmluaXRpb25zO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgZ2V0QWxsSXRlbUZyb21QYWdlczxUPihcbiAgICBnZXRJdGVtczogKFxuICAgICAgcGFnZTogbnVtYmVyLFxuICAgICAgcGFnZVNpemU6IG51bWJlcixcbiAgICApID0+IFByb21pc2U8eyBpdGVtczogVFtdOyBjb3VudDogbnVtYmVyIH0gfCBSZXN0RXJyb3I+LFxuICAgIHBhZ2VTaXplOiBudW1iZXIgPSA1MCxcbiAgKTogUHJvbWlzZTxUW10gfCBSZXN0RXJyb3I+IHtcbiAgICAvLyBHZXQgZmlyc3QgcGFnZSB0byBkZXRlcm1pbmUgdG90YWwgY291bnRcbiAgICBjb25zdCBmaXJzdFBhZ2UgPSBhd2FpdCBnZXRJdGVtcygxLCBwYWdlU2l6ZSk7XG4gICAgaWYgKGZpcnN0UGFnZSBpbnN0YW5jZW9mIFJlc3RFcnJvcikge1xuICAgICAgdGhyb3cgZmlyc3RQYWdlO1xuICAgIH1cblxuICAgIGNvbnN0IHRvdGFsUGFnZXMgPSBNYXRoLmNlaWwoZmlyc3RQYWdlLmNvdW50IC8gcGFnZVNpemUpO1xuICAgIGNvbnN0IHJlbWFpbmluZ1BhZ2VzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogdG90YWxQYWdlcyAtIDEgfSwgKF8sIGkpID0+IGkgKyAyKTtcblxuICAgIGNvbnN0IHJlbWFpbmluZ1Jlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHJlbWFpbmluZ1BhZ2VzLm1hcChhc3luYyAocGFnZSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnZXRJdGVtcyhwYWdlLCBwYWdlU2l6ZSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBSZXN0RXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCBhbGxSZXN1bHRzID0gW2ZpcnN0UGFnZSwgLi4ucmVtYWluaW5nUmVzdWx0c107XG4gICAgcmV0dXJuIGFsbFJlc3VsdHMuZmxhdE1hcCgocmVzdWx0KSA9PiAocmVzdWx0IGluc3RhbmNlb2YgUmVzdEVycm9yID8gW10gOiByZXN1bHQuaXRlbXMpKTtcbiAgfVxufVxuIl19
|
|
@@ -28,6 +28,9 @@ export interface Fields {
|
|
|
28
28
|
export interface DataExtensionBody {
|
|
29
29
|
name: string;
|
|
30
30
|
categoryID: string;
|
|
31
|
+
isSendable?: boolean;
|
|
32
|
+
sendableCustomObjectField?: string;
|
|
33
|
+
sendableSubscriberField?: string;
|
|
31
34
|
dataRetentionProperties?: {
|
|
32
35
|
isDeleteAtEndOfRetentionPeriod?: boolean;
|
|
33
36
|
isRowBasedRetention?: boolean;
|
|
@@ -54,18 +57,22 @@ export interface DataExtension {
|
|
|
54
57
|
Name: string;
|
|
55
58
|
ObjectId: string;
|
|
56
59
|
CategoryId: number;
|
|
60
|
+
ExternalKey: string;
|
|
61
|
+
IsSendable: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface ContactAttributes {
|
|
64
|
+
isReadOnly: boolean;
|
|
65
|
+
attributes: [{
|
|
66
|
+
isReadOnly: boolean;
|
|
67
|
+
fullyQualifiedName: string;
|
|
68
|
+
dataType: string;
|
|
69
|
+
}];
|
|
57
70
|
}
|
|
58
71
|
export interface ContactAttributesResponse {
|
|
59
|
-
items: [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
isReadOnly: boolean;
|
|
64
|
-
fullyQualifiedName: string;
|
|
65
|
-
dataType: string;
|
|
66
|
-
}];
|
|
67
|
-
}
|
|
68
|
-
];
|
|
72
|
+
items: ContactAttributes[];
|
|
73
|
+
count: number;
|
|
74
|
+
page: number;
|
|
75
|
+
pageSize: number;
|
|
69
76
|
}
|
|
70
77
|
export interface DataExtensionFields {
|
|
71
78
|
fields: Fields[];
|
|
@@ -90,21 +97,14 @@ export type PartnerProperty = PartnerPropertyName | PartnerPropertyID;
|
|
|
90
97
|
export interface BusinessUnitResponse {
|
|
91
98
|
PartnerProperties: PartnerProperty[];
|
|
92
99
|
}
|
|
100
|
+
export type DataExtensionPartnerProperty = {
|
|
101
|
+
Name: 'NAME' | 'ObjectId' | 'CategoryId';
|
|
102
|
+
Value: string | number;
|
|
103
|
+
};
|
|
93
104
|
export interface DataExtensionResponse {
|
|
94
|
-
PartnerProperties: [
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
Value: string;
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
Name: string;
|
|
101
|
-
Value: string;
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
Name: string;
|
|
105
|
-
Value: number;
|
|
106
|
-
}
|
|
107
|
-
];
|
|
105
|
+
PartnerProperties: DataExtensionPartnerProperty[];
|
|
106
|
+
CustomerKey: string;
|
|
107
|
+
IsSendable: boolean;
|
|
108
108
|
}
|
|
109
109
|
export interface SoapResponseBody {
|
|
110
110
|
RetrieveResponseMsg: {
|
|
@@ -116,5 +116,25 @@ export interface SFMCErrorResponse {
|
|
|
116
116
|
documentation: string;
|
|
117
117
|
message: string;
|
|
118
118
|
}
|
|
119
|
+
export interface EventDefinitionsResponse {
|
|
120
|
+
items: EventDefinition[];
|
|
121
|
+
count: number;
|
|
122
|
+
page: number;
|
|
123
|
+
pageSize: number;
|
|
124
|
+
}
|
|
125
|
+
export interface EventDefinition {
|
|
126
|
+
id: string;
|
|
127
|
+
name: string;
|
|
128
|
+
description: string;
|
|
129
|
+
eventDefinitionKey: string;
|
|
130
|
+
dataExtensionId: string;
|
|
131
|
+
dataExtensionName: string;
|
|
132
|
+
}
|
|
133
|
+
export interface DataExtensionApiResponse {
|
|
134
|
+
id: string;
|
|
135
|
+
name: string;
|
|
136
|
+
key: string;
|
|
137
|
+
isSendable: boolean;
|
|
138
|
+
}
|
|
119
139
|
export {};
|
|
120
140
|
//# sourceMappingURL=type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/sdks/sfmc/type.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AACD,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB,CAAC,EAAE;QACxB,8BAA8B,CAAC,EAAE,OAAO,CAAC;QACzC,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,8BAA8B,CAAC,EAAE,OAAO,CAAC;KAC1C,CAAC;IACF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AACD,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"type.d.ts","sourceRoot":"","sources":["../../../src/sdks/sfmc/type.ts"],"names":[],"mappings":"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"}
|
package/build/sdks/sfmc/type.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZGtzL3NmbWMvdHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBBdXRoT2JqZWN0IHtcbiAgY2xpZW50SWQ6IHN0cmluZztcbiAgY2xpZW50U2VjcmV0OiBzdHJpbmc7XG4gIHN1YkRvbWFpbjogc3RyaW5nO1xuICBleHBpcmF0aW9uPzogbnVtYmVyO1xuICBhY2Nlc3NfdG9rZW4/
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZGtzL3NmbWMvdHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBBdXRoT2JqZWN0IHtcbiAgY2xpZW50SWQ6IHN0cmluZztcbiAgY2xpZW50U2VjcmV0OiBzdHJpbmc7XG4gIHN1YkRvbWFpbjogc3RyaW5nO1xuICBleHBpcmF0aW9uPzogbnVtYmVyO1xuICBhY2Nlc3NfdG9rZW4/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsdGVyT2JqIHtcbiAgbGVmdE9wZXJhbmQ6IHN0cmluZztcbiAgcmlnaHRPcGVyYW5kOiBzdHJpbmc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEZpZWxkcyB7XG4gIG5hbWU6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBzY2FsZT86IG51bWJlcjtcbiAgcHJlY2lzaW9uPzogbnVtYmVyO1xuICBsZW5ndGg6IG51bWJlcjtcbiAgaXNOdWxsYWJsZTogYm9vbGVhbjtcbiAgaXNQcmltYXJ5S2V5OiBib29sZWFuO1xuICBpc0hpZGRlbjogYm9vbGVhbjtcbiAgaXNSZWFkT25seTogYm9vbGVhbjtcbiAgaXNPdmVycmlkYWJsZTogYm9vbGVhbjtcbiAgaXNUZW1wbGF0ZUZpZWxkOiBib29sZWFuO1xuICBpc0luaGVyaXRhYmxlOiBib29sZWFuO1xuICBtdXN0T3ZlcnJpZGU6IGJvb2xlYW47XG4gIG9yZGluYWw6IDA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YUV4dGVuc2lvbkJvZHkge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNhdGVnb3J5SUQ6IHN0cmluZztcbiAgaXNTZW5kYWJsZT86IGJvb2xlYW47XG4gIHNlbmRhYmxlQ3VzdG9tT2JqZWN0RmllbGQ/OiBzdHJpbmc7XG4gIHNlbmRhYmxlU3Vic2NyaWJlckZpZWxkPzogc3RyaW5nO1xuICBkYXRhUmV0ZW50aW9uUHJvcGVydGllcz86IHtcbiAgICBpc0RlbGV0ZUF0RW5kT2ZSZXRlbnRpb25QZXJpb2Q/OiBib29sZWFuO1xuICAgIGlzUm93QmFzZWRSZXRlbnRpb24/OiBib29sZWFuO1xuICAgIGlzUmVzZXRSZXRlbnRpb25QZXJpb2RPbkltcG9ydD86IGJvb2xlYW47XG4gIH07XG4gIGZpZWxkczogRmllbGRzW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVzaW5lc3NVbml0IHtcbiAgTmFtZTogc3RyaW5nO1xuICBJRDogbnVtYmVyO1xufVxuZXhwb3J0IGludGVyZmFjZSBEYXRhRm9sZGVyIHtcbiAgUGFydG5lcktleTogc3RyaW5nO1xuICBJRDogbnVtYmVyO1xuICBPYmplY3RJRDogc3RyaW5nO1xuICBQYXJlbnRGb2xkZXI6IHtcbiAgICBQYXJ0bmVyS2V5OiBzdHJpbmc7XG4gICAgSUQ6IG51bWJlcjtcbiAgICBPYmplY3RJRDogc3RyaW5nO1xuICB9O1xuICBOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YUV4dGVuc2lvbiB7XG4gIE5hbWU6IHN0cmluZztcbiAgT2JqZWN0SWQ6IHN0cmluZztcbiAgQ2F0ZWdvcnlJZDogbnVtYmVyO1xuICBFeHRlcm5hbEtleTogc3RyaW5nO1xuICBJc1NlbmRhYmxlOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbnRhY3RBdHRyaWJ1dGVzIHtcbiAgaXNSZWFkT25seTogYm9vbGVhbjtcbiAgYXR0cmlidXRlczogW3sgaXNSZWFkT25seTogYm9vbGVhbjsgZnVsbHlRdWFsaWZpZWROYW1lOiBzdHJpbmc7IGRhdGFUeXBlOiBzdHJpbmcgfV07XG59XG5leHBvcnQgaW50ZXJmYWNlIENvbnRhY3RBdHRyaWJ1dGVzUmVzcG9uc2Uge1xuICBpdGVtczogQ29udGFjdEF0dHJpYnV0ZXNbXTtcbiAgY291bnQ6IG51bWJlcjtcbiAgcGFnZTogbnVtYmVyO1xuICBwYWdlU2l6ZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFFeHRlbnNpb25GaWVsZHMge1xuICBmaWVsZHM6IEZpZWxkc1tdO1xuICBmaWVsZENvdW50OiBudW1iZXI7XG4gIGZpZWxkUGFnZTogbnVtYmVyO1xuICBmaWVsZFBhZ2VTaXplOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlRGF0YUV4dGVuc2lvblJlc3BvbnNlXG4gIGV4dGVuZHMgT21pdDxEYXRhRXh0ZW5zaW9uRmllbGRzLCAnZmllbHNQYWdlJyB8ICdmaWVsZFBhZ2VTaXplJz4ge1xuICBpZDogc3RyaW5nO1xuICBrZXk6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUGFydG5lclByb3BlcnR5SUQge1xuICBOYW1lOiAnaWQnO1xuICBWYWx1ZTogbnVtYmVyO1xufVxuaW50ZXJmYWNlIFBhcnRuZXJQcm9wZXJ0eU5hbWUge1xuICBOYW1lOiAnbmFtZSc7XG4gIFZhbHVlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCB0eXBlIFBhcnRuZXJQcm9wZXJ0eSA9IFBhcnRuZXJQcm9wZXJ0eU5hbWUgfCBQYXJ0bmVyUHJvcGVydHlJRDtcbmV4cG9ydCBpbnRlcmZhY2UgQnVzaW5lc3NVbml0UmVzcG9uc2Uge1xuICBQYXJ0bmVyUHJvcGVydGllczogUGFydG5lclByb3BlcnR5W107XG59XG5cbmV4cG9ydCB0eXBlIERhdGFFeHRlbnNpb25QYXJ0bmVyUHJvcGVydHkgPSB7XG4gIE5hbWU6ICdOQU1FJyB8ICdPYmplY3RJZCcgfCAnQ2F0ZWdvcnlJZCc7XG4gIFZhbHVlOiBzdHJpbmcgfCBudW1iZXI7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFFeHRlbnNpb25SZXNwb25zZSB7XG4gIFBhcnRuZXJQcm9wZXJ0aWVzOiBEYXRhRXh0ZW5zaW9uUGFydG5lclByb3BlcnR5W107XG4gIEN1c3RvbWVyS2V5OiBzdHJpbmc7XG4gIElzU2VuZGFibGU6IGJvb2xlYW47XG59XG5leHBvcnQgaW50ZXJmYWNlIFNvYXBSZXNwb25zZUJvZHkge1xuICBSZXRyaWV2ZVJlc3BvbnNlTXNnOiB7XG4gICAgUmVzdWx0czpcbiAgICAgIHwgQnVzaW5lc3NVbml0UmVzcG9uc2VcbiAgICAgIHwgQnVzaW5lc3NVbml0UmVzcG9uc2VbXVxuICAgICAgfCBEYXRhRm9sZGVyXG4gICAgICB8IERhdGFGb2xkZXJbXVxuICAgICAgfCBEYXRhRXh0ZW5zaW9uUmVzcG9uc2VcbiAgICAgIHwgRGF0YUV4dGVuc2lvblJlc3BvbnNlW107XG4gIH07XG59XG5leHBvcnQgaW50ZXJmYWNlIFNGTUNFcnJvclJlc3BvbnNlIHtcbiAgZXJyb3Jjb2RlOiBzdHJpbmc7XG4gIGRvY3VtZW50YXRpb246IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEV2ZW50RGVmaW5pdGlvbnNSZXNwb25zZSB7XG4gIGl0ZW1zOiBFdmVudERlZmluaXRpb25bXTtcbiAgY291bnQ6IG51bWJlcjtcbiAgcGFnZTogbnVtYmVyO1xuICBwYWdlU2l6ZTogbnVtYmVyO1xufVxuZXhwb3J0IGludGVyZmFjZSBFdmVudERlZmluaXRpb24ge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGV2ZW50RGVmaW5pdGlvbktleTogc3RyaW5nO1xuICBkYXRhRXh0ZW5zaW9uSWQ6IHN0cmluZztcbiAgZGF0YUV4dGVuc2lvbk5hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEYXRhRXh0ZW5zaW9uQXBpUmVzcG9uc2Uge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIGtleTogc3RyaW5nO1xuICBpc1NlbmRhYmxlOiBib29sZWFuO1xufVxuIl19
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Benchmark utilities for performance testing
|
|
3
|
+
*
|
|
4
|
+
* Provides easy-to-use tools for measuring function performance,
|
|
5
|
+
* memory usage, and creating performance comparisons.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { benchmark, createBenchmarkSuite } from './benchmark';
|
|
10
|
+
*
|
|
11
|
+
* // Simple benchmark
|
|
12
|
+
* const result = await benchmark('myFunction', () => myFunction(data));
|
|
13
|
+
* console.log(`Duration: ${result.duration}ms`);
|
|
14
|
+
*
|
|
15
|
+
* // Benchmark suite
|
|
16
|
+
* const suite = createBenchmarkSuite('Array Operations');
|
|
17
|
+
* suite.add('native map', () => data.map(x => x * 2));
|
|
18
|
+
* suite.add('custom map', () => customMap(data, x => x * 2));
|
|
19
|
+
* await suite.run();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Result of a benchmark measurement
|
|
24
|
+
*/
|
|
25
|
+
export type BenchmarkResult = {
|
|
26
|
+
/** Name of the benchmark */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Total duration in milliseconds */
|
|
29
|
+
duration: number;
|
|
30
|
+
/** Operations per second */
|
|
31
|
+
opsPerSecond: number;
|
|
32
|
+
/** Memory used in bytes (heap difference) */
|
|
33
|
+
memoryUsed: number;
|
|
34
|
+
/** Number of iterations run */
|
|
35
|
+
iterations: number;
|
|
36
|
+
/** Average duration per iteration in milliseconds */
|
|
37
|
+
avgDuration: number;
|
|
38
|
+
/** Standard deviation of durations */
|
|
39
|
+
stdDev: number;
|
|
40
|
+
/** Minimum duration observed */
|
|
41
|
+
minDuration: number;
|
|
42
|
+
/** Maximum duration observed */
|
|
43
|
+
maxDuration: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Configuration options for benchmarks
|
|
47
|
+
*/
|
|
48
|
+
export type BenchmarkOptions = {
|
|
49
|
+
/** Number of iterations to run (default: 1) */
|
|
50
|
+
iterations?: number;
|
|
51
|
+
/** Number of warmup runs before measuring (default: 1) */
|
|
52
|
+
warmupRuns?: number;
|
|
53
|
+
/** Whether to force garbage collection between runs (default: false) */
|
|
54
|
+
forceGC?: boolean;
|
|
55
|
+
/** Whether to measure memory usage (default: true) */
|
|
56
|
+
measureMemory?: boolean;
|
|
57
|
+
/** Timeout in milliseconds for the entire benchmark (default: 30000) */
|
|
58
|
+
timeout?: number;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Benchmark function type
|
|
62
|
+
*/
|
|
63
|
+
export type BenchmarkFunction<T = unknown> = () => T | Promise<T>;
|
|
64
|
+
/**
|
|
65
|
+
* Run a benchmark for a single function
|
|
66
|
+
*
|
|
67
|
+
* @param name - Name of the benchmark
|
|
68
|
+
* @param fn - Function to benchmark
|
|
69
|
+
* @param options - Benchmark configuration options
|
|
70
|
+
* @returns Promise resolving to benchmark results
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const result = await benchmark('Array.map', () => {
|
|
75
|
+
* return largeArray.map(x => x * 2);
|
|
76
|
+
* }, { iterations: 10, warmupRuns: 3 });
|
|
77
|
+
*
|
|
78
|
+
* console.log(`${result.name}: ${result.avgDuration.toFixed(2)}ms avg`);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function benchmark(name: string, fn: BenchmarkFunction, options?: BenchmarkOptions): Promise<BenchmarkResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Compare multiple functions with the same benchmark configuration
|
|
84
|
+
*
|
|
85
|
+
* @param benchmarks - Object with benchmark names and functions
|
|
86
|
+
* @param options - Benchmark configuration options
|
|
87
|
+
* @returns Promise resolving to array of benchmark results
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const results = await compareBenchmarks({
|
|
92
|
+
* 'native map': () => data.map(x => x * 2),
|
|
93
|
+
* 'for loop': () => {
|
|
94
|
+
* const result = [];
|
|
95
|
+
* for (let i = 0; i < data.length; i++) {
|
|
96
|
+
* result.push(data[i] * 2);
|
|
97
|
+
* }
|
|
98
|
+
* return result;
|
|
99
|
+
* }
|
|
100
|
+
* }, { iterations: 5 });
|
|
101
|
+
*
|
|
102
|
+
* results.forEach(result => {
|
|
103
|
+
* console.log(`${result.name}: ${result.avgDuration.toFixed(2)}ms`);
|
|
104
|
+
* });
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function compareBenchmarks(benchmarks: Record<string, BenchmarkFunction>, options?: BenchmarkOptions): Promise<BenchmarkResult[]>;
|
|
108
|
+
/**
|
|
109
|
+
* Benchmark suite for organizing and running multiple related benchmarks
|
|
110
|
+
*/
|
|
111
|
+
export declare class BenchmarkSuite {
|
|
112
|
+
readonly suiteName: string;
|
|
113
|
+
private benchmarks;
|
|
114
|
+
private options;
|
|
115
|
+
constructor(suiteName: string, options?: BenchmarkOptions);
|
|
116
|
+
/**
|
|
117
|
+
* Add a benchmark to the suite
|
|
118
|
+
*
|
|
119
|
+
* @param name - Name of the benchmark
|
|
120
|
+
* @param fn - Function to benchmark
|
|
121
|
+
* @returns This suite instance for chaining
|
|
122
|
+
*/
|
|
123
|
+
add(name: string, fn: BenchmarkFunction): this;
|
|
124
|
+
/**
|
|
125
|
+
* Run all benchmarks in the suite
|
|
126
|
+
*
|
|
127
|
+
* @param customOptions - Override suite options for this run
|
|
128
|
+
* @returns Promise resolving to array of benchmark results
|
|
129
|
+
*/
|
|
130
|
+
run(customOptions?: BenchmarkOptions): Promise<BenchmarkResult[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Get the number of benchmarks in the suite
|
|
133
|
+
*/
|
|
134
|
+
get size(): number;
|
|
135
|
+
/**
|
|
136
|
+
* Clear all benchmarks from the suite
|
|
137
|
+
*/
|
|
138
|
+
clear(): this;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Create a new benchmark suite
|
|
142
|
+
*
|
|
143
|
+
* @param suiteName - Name of the benchmark suite
|
|
144
|
+
* @param options - Default options for all benchmarks in the suite
|
|
145
|
+
* @returns New BenchmarkSuite instance
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const suite = createBenchmarkSuite('String Operations', {
|
|
150
|
+
* iterations: 10,
|
|
151
|
+
* warmupRuns: 2
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* suite
|
|
155
|
+
* .add('concat', () => str1 + str2)
|
|
156
|
+
* .add('template', () => `${str1}${str2}`)
|
|
157
|
+
* .add('join', () => [str1, str2].join(''));
|
|
158
|
+
*
|
|
159
|
+
* await suite.run();
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
export declare function createBenchmarkSuite(suiteName: string, options?: BenchmarkOptions): BenchmarkSuite;
|
|
163
|
+
/**
|
|
164
|
+
* Utility to measure memory usage of a function
|
|
165
|
+
*
|
|
166
|
+
* @param fn - Function to measure
|
|
167
|
+
* @param forceGC - Whether to force garbage collection before measuring
|
|
168
|
+
* @returns Memory usage in bytes
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const memoryUsed = await measureMemory(() => {
|
|
173
|
+
* return new Array(100000).fill(0).map(x => ({ value: x }));
|
|
174
|
+
* });
|
|
175
|
+
*
|
|
176
|
+
* console.log(`Memory used: ${(memoryUsed / 1024 / 1024).toFixed(2)}MB`);
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
export declare function measureMemory(fn: BenchmarkFunction, forceGC?: boolean): Promise<number>;
|
|
180
|
+
//# sourceMappingURL=benchmark.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../../src/utils/benchmark.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,GAAG,OAAO,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAqBlE;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,iBAAiB,EACrB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CA4E1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC7C,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAM5B;AAED;;GAEG;AACH,qBAAa,cAAc;aAKG,SAAS,EAAE,MAAM;IAJ7C,OAAO,CAAC,UAAU,CAAsD;IAExE,OAAO,CAAC,OAAO,CAAmB;gBAEN,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;IAI7E;;;;;;OAMG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,iBAAiB,GAAG,IAAI;IAK9C;;;;;OAKG;IACG,GAAG,CAAC,aAAa,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAkEvE;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,gBAAgB,GACzB,cAAc,CAEhB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CAAC,EAAE,EAAE,iBAAiB,EAAE,OAAO,UAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAU1F"}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Benchmark utilities for performance testing
|
|
4
|
+
*
|
|
5
|
+
* Provides easy-to-use tools for measuring function performance,
|
|
6
|
+
* memory usage, and creating performance comparisons.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { benchmark, createBenchmarkSuite } from './benchmark';
|
|
11
|
+
*
|
|
12
|
+
* // Simple benchmark
|
|
13
|
+
* const result = await benchmark('myFunction', () => myFunction(data));
|
|
14
|
+
* console.log(`Duration: ${result.duration}ms`);
|
|
15
|
+
*
|
|
16
|
+
* // Benchmark suite
|
|
17
|
+
* const suite = createBenchmarkSuite('Array Operations');
|
|
18
|
+
* suite.add('native map', () => data.map(x => x * 2));
|
|
19
|
+
* suite.add('custom map', () => customMap(data, x => x * 2));
|
|
20
|
+
* await suite.run();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.BenchmarkSuite = void 0;
|
|
25
|
+
exports.benchmark = benchmark;
|
|
26
|
+
exports.compareBenchmarks = compareBenchmarks;
|
|
27
|
+
exports.createBenchmarkSuite = createBenchmarkSuite;
|
|
28
|
+
exports.measureMemory = measureMemory;
|
|
29
|
+
/**
|
|
30
|
+
* Force garbage collection if available
|
|
31
|
+
*/
|
|
32
|
+
function forceGarbageCollection() {
|
|
33
|
+
if (typeof global !== 'undefined' && global.gc) {
|
|
34
|
+
global.gc();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calculate standard deviation of an array of numbers
|
|
39
|
+
*/
|
|
40
|
+
function calculateStdDev(values) {
|
|
41
|
+
const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
|
|
42
|
+
const squaredDiffs = values.map((val) => (val - mean) ** 2);
|
|
43
|
+
const avgSquaredDiff = squaredDiffs.reduce((sum, val) => sum + val, 0) / values.length;
|
|
44
|
+
return Math.sqrt(avgSquaredDiff);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run a benchmark for a single function
|
|
48
|
+
*
|
|
49
|
+
* @param name - Name of the benchmark
|
|
50
|
+
* @param fn - Function to benchmark
|
|
51
|
+
* @param options - Benchmark configuration options
|
|
52
|
+
* @returns Promise resolving to benchmark results
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const result = await benchmark('Array.map', () => {
|
|
57
|
+
* return largeArray.map(x => x * 2);
|
|
58
|
+
* }, { iterations: 10, warmupRuns: 3 });
|
|
59
|
+
*
|
|
60
|
+
* console.log(`${result.name}: ${result.avgDuration.toFixed(2)}ms avg`);
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
// eslint-disable-next-line require-await
|
|
64
|
+
async function benchmark(name, fn, options = {}) {
|
|
65
|
+
const { iterations = 1, warmupRuns = 1, forceGC = false, measureMemory: shouldMeasureMemory = true, timeout = 30000, } = options;
|
|
66
|
+
// Timeout protection
|
|
67
|
+
let timeoutId;
|
|
68
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
69
|
+
timeoutId = setTimeout(() => reject(new Error(`Benchmark "${name}" timed out after ${timeout}ms`)), timeout);
|
|
70
|
+
});
|
|
71
|
+
const benchmarkPromise = async () => {
|
|
72
|
+
// Warmup runs
|
|
73
|
+
await Promise.all(Array.from({ length: warmupRuns }, async () => {
|
|
74
|
+
await fn();
|
|
75
|
+
}));
|
|
76
|
+
if (forceGC) {
|
|
77
|
+
forceGarbageCollection();
|
|
78
|
+
}
|
|
79
|
+
const durations = [];
|
|
80
|
+
const startMemory = shouldMeasureMemory ? process.memoryUsage().heapUsed : 0;
|
|
81
|
+
const overallStart = performance.now();
|
|
82
|
+
// Actual benchmark runs
|
|
83
|
+
for (let i = 0; i < iterations; i += 1) {
|
|
84
|
+
if (forceGC && i > 0) {
|
|
85
|
+
forceGarbageCollection();
|
|
86
|
+
}
|
|
87
|
+
const iterationStart = performance.now();
|
|
88
|
+
// eslint-disable-next-line no-await-in-loop
|
|
89
|
+
await fn();
|
|
90
|
+
const iterationEnd = performance.now();
|
|
91
|
+
durations.push(iterationEnd - iterationStart);
|
|
92
|
+
}
|
|
93
|
+
const overallEnd = performance.now();
|
|
94
|
+
const endMemory = shouldMeasureMemory ? process.memoryUsage().heapUsed : 0;
|
|
95
|
+
const totalDuration = overallEnd - overallStart;
|
|
96
|
+
const avgDuration = durations.length > 0 ? durations.reduce((sum, d) => sum + d, 0) / durations.length : 0;
|
|
97
|
+
const minDuration = durations.length > 0 ? Math.min(...durations) : 0;
|
|
98
|
+
const maxDuration = durations.length > 0 ? Math.max(...durations) : 0;
|
|
99
|
+
const stdDev = durations.length > 0 ? calculateStdDev(durations) : 0;
|
|
100
|
+
const opsPerSecond = totalDuration > 0 ? iterations / (totalDuration / 1000) : 0;
|
|
101
|
+
const memoryUsed = endMemory - startMemory;
|
|
102
|
+
return {
|
|
103
|
+
name,
|
|
104
|
+
duration: totalDuration,
|
|
105
|
+
opsPerSecond,
|
|
106
|
+
memoryUsed,
|
|
107
|
+
iterations,
|
|
108
|
+
avgDuration,
|
|
109
|
+
stdDev,
|
|
110
|
+
minDuration,
|
|
111
|
+
maxDuration,
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
return Promise.race([benchmarkPromise(), timeoutPromise]).finally(() => {
|
|
115
|
+
clearTimeout(timeoutId);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compare multiple functions with the same benchmark configuration
|
|
120
|
+
*
|
|
121
|
+
* @param benchmarks - Object with benchmark names and functions
|
|
122
|
+
* @param options - Benchmark configuration options
|
|
123
|
+
* @returns Promise resolving to array of benchmark results
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const results = await compareBenchmarks({
|
|
128
|
+
* 'native map': () => data.map(x => x * 2),
|
|
129
|
+
* 'for loop': () => {
|
|
130
|
+
* const result = [];
|
|
131
|
+
* for (let i = 0; i < data.length; i++) {
|
|
132
|
+
* result.push(data[i] * 2);
|
|
133
|
+
* }
|
|
134
|
+
* return result;
|
|
135
|
+
* }
|
|
136
|
+
* }, { iterations: 5 });
|
|
137
|
+
*
|
|
138
|
+
* results.forEach(result => {
|
|
139
|
+
* console.log(`${result.name}: ${result.avgDuration.toFixed(2)}ms`);
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
async function compareBenchmarks(benchmarks, options = {}) {
|
|
144
|
+
const results = await Promise.all(Object.entries(benchmarks).map(([name, fn]) => benchmark(name, fn, options)));
|
|
145
|
+
return results.sort((a, b) => a.avgDuration - b.avgDuration);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Benchmark suite for organizing and running multiple related benchmarks
|
|
149
|
+
*/
|
|
150
|
+
class BenchmarkSuite {
|
|
151
|
+
constructor(suiteName, options = {}) {
|
|
152
|
+
this.suiteName = suiteName;
|
|
153
|
+
this.benchmarks = [];
|
|
154
|
+
this.options = options;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Add a benchmark to the suite
|
|
158
|
+
*
|
|
159
|
+
* @param name - Name of the benchmark
|
|
160
|
+
* @param fn - Function to benchmark
|
|
161
|
+
* @returns This suite instance for chaining
|
|
162
|
+
*/
|
|
163
|
+
add(name, fn) {
|
|
164
|
+
this.benchmarks.push({ name, fn });
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Run all benchmarks in the suite
|
|
169
|
+
*
|
|
170
|
+
* @param customOptions - Override suite options for this run
|
|
171
|
+
* @returns Promise resolving to array of benchmark results
|
|
172
|
+
*/
|
|
173
|
+
async run(customOptions) {
|
|
174
|
+
const options = { ...this.options, ...customOptions };
|
|
175
|
+
const results = [];
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.log(`\nš Running benchmark suite: ${this.suiteName}`);
|
|
178
|
+
// eslint-disable-next-line no-console
|
|
179
|
+
console.log('='.repeat(60));
|
|
180
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
181
|
+
for (const { name, fn } of this.benchmarks) {
|
|
182
|
+
// eslint-disable-next-line no-console
|
|
183
|
+
console.log(`\nā±ļø Running: ${name}...`);
|
|
184
|
+
try {
|
|
185
|
+
// eslint-disable-next-line no-await-in-loop
|
|
186
|
+
const result = await benchmark(name, fn, options);
|
|
187
|
+
results.push(result);
|
|
188
|
+
// eslint-disable-next-line no-console
|
|
189
|
+
console.log(` ā
${result.avgDuration.toFixed(2)}ms avg (${result.opsPerSecond.toFixed(0)} ops/sec)`);
|
|
190
|
+
if (options.measureMemory) {
|
|
191
|
+
// eslint-disable-next-line no-console
|
|
192
|
+
console.log(` š¾ Memory: ${(result.memoryUsed / 1024 / 1024).toFixed(2)}MB`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
// eslint-disable-next-line no-console
|
|
197
|
+
console.log(` ā Failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Summary
|
|
201
|
+
if (results.length > 1) {
|
|
202
|
+
// eslint-disable-next-line no-console
|
|
203
|
+
console.log(`\nš Summary (sorted by performance):`);
|
|
204
|
+
const sortedResults = [...results].sort((a, b) => a.avgDuration - b.avgDuration);
|
|
205
|
+
const fastest = sortedResults[0];
|
|
206
|
+
sortedResults.forEach((result, index) => {
|
|
207
|
+
const relative = result.avgDuration / fastest.avgDuration;
|
|
208
|
+
let icon = ' ';
|
|
209
|
+
if (index === 0)
|
|
210
|
+
icon = 'š„';
|
|
211
|
+
else if (index === 1)
|
|
212
|
+
icon = 'š„';
|
|
213
|
+
else if (index === 2)
|
|
214
|
+
icon = 'š„';
|
|
215
|
+
// eslint-disable-next-line no-console
|
|
216
|
+
console.log(` ${icon} ${result.name.padEnd(25)} | ${result.avgDuration.toFixed(2)}ms | ${relative.toFixed(2)}x`);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
// eslint-disable-next-line no-console
|
|
220
|
+
console.log(`\nā
Suite completed: ${results.length}/${this.benchmarks.length} benchmarks successful\n`);
|
|
221
|
+
return results;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Get the number of benchmarks in the suite
|
|
225
|
+
*/
|
|
226
|
+
get size() {
|
|
227
|
+
return this.benchmarks.length;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Clear all benchmarks from the suite
|
|
231
|
+
*/
|
|
232
|
+
clear() {
|
|
233
|
+
this.benchmarks = [];
|
|
234
|
+
return this;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.BenchmarkSuite = BenchmarkSuite;
|
|
238
|
+
/**
|
|
239
|
+
* Create a new benchmark suite
|
|
240
|
+
*
|
|
241
|
+
* @param suiteName - Name of the benchmark suite
|
|
242
|
+
* @param options - Default options for all benchmarks in the suite
|
|
243
|
+
* @returns New BenchmarkSuite instance
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* ```typescript
|
|
247
|
+
* const suite = createBenchmarkSuite('String Operations', {
|
|
248
|
+
* iterations: 10,
|
|
249
|
+
* warmupRuns: 2
|
|
250
|
+
* });
|
|
251
|
+
*
|
|
252
|
+
* suite
|
|
253
|
+
* .add('concat', () => str1 + str2)
|
|
254
|
+
* .add('template', () => `${str1}${str2}`)
|
|
255
|
+
* .add('join', () => [str1, str2].join(''));
|
|
256
|
+
*
|
|
257
|
+
* await suite.run();
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
function createBenchmarkSuite(suiteName, options) {
|
|
261
|
+
return new BenchmarkSuite(suiteName, options);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Utility to measure memory usage of a function
|
|
265
|
+
*
|
|
266
|
+
* @param fn - Function to measure
|
|
267
|
+
* @param forceGC - Whether to force garbage collection before measuring
|
|
268
|
+
* @returns Memory usage in bytes
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* const memoryUsed = await measureMemory(() => {
|
|
273
|
+
* return new Array(100000).fill(0).map(x => ({ value: x }));
|
|
274
|
+
* });
|
|
275
|
+
*
|
|
276
|
+
* console.log(`Memory used: ${(memoryUsed / 1024 / 1024).toFixed(2)}MB`);
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
279
|
+
async function measureMemory(fn, forceGC = true) {
|
|
280
|
+
if (forceGC) {
|
|
281
|
+
forceGarbageCollection();
|
|
282
|
+
}
|
|
283
|
+
const startMemory = process.memoryUsage().heapUsed;
|
|
284
|
+
await fn();
|
|
285
|
+
const endMemory = process.memoryUsage().heapUsed;
|
|
286
|
+
return endMemory - startMemory;
|
|
287
|
+
}
|
|
288
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVuY2htYXJrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2JlbmNobWFyay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHOzs7QUFvRkgsOEJBZ0ZDO0FBMkJELDhDQVNDO0FBd0lELG9EQUtDO0FBa0JELHNDQVVDO0FBbFVEOztHQUVHO0FBQ0gsU0FBUyxzQkFBc0I7SUFDN0IsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQy9DLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGVBQWUsQ0FBQyxNQUFnQjtJQUN2QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3ZFLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzVELE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdkYsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILHlDQUF5QztBQUNsQyxLQUFLLFVBQVUsU0FBUyxDQUM3QixJQUFZLEVBQ1osRUFBcUIsRUFDckIsVUFBNEIsRUFBRTtJQUU5QixNQUFNLEVBQ0osVUFBVSxHQUFHLENBQUMsRUFDZCxVQUFVLEdBQUcsQ0FBQyxFQUNkLE9BQU8sR0FBRyxLQUFLLEVBQ2YsYUFBYSxFQUFFLG1CQUFtQixHQUFHLElBQUksRUFDekMsT0FBTyxHQUFHLEtBQUssR0FDaEIsR0FBRyxPQUFPLENBQUM7SUFFWixxQkFBcUI7SUFDckIsSUFBSSxTQUF5QixDQUFDO0lBQzlCLE1BQU0sY0FBYyxHQUFHLElBQUksT0FBTyxDQUFRLENBQUMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3RELFNBQVMsR0FBRyxVQUFVLENBQ3BCLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxjQUFjLElBQUkscUJBQXFCLE9BQU8sSUFBSSxDQUFDLENBQUMsRUFDM0UsT0FBTyxDQUNSLENBQUM7SUFDSixDQUFDLENBQUMsQ0FBQztJQUVILE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxJQUE4QixFQUFFO1FBQzVELGNBQWM7UUFDZCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2YsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsRUFBRSxLQUFLLElBQUksRUFBRTtZQUM1QyxNQUFNLEVBQUUsRUFBRSxDQUFDO1FBQ2IsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixzQkFBc0IsRUFBRSxDQUFDO1FBQzNCLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBYSxFQUFFLENBQUM7UUFDL0IsTUFBTSxXQUFXLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3RSxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFdkMsd0JBQXdCO1FBQ3hCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLElBQUksT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDckIsc0JBQXNCLEVBQUUsQ0FBQztZQUMzQixDQUFDO1lBRUQsTUFBTSxjQUFjLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3pDLDRDQUE0QztZQUM1QyxNQUFNLEVBQUUsRUFBRSxDQUFDO1lBQ1gsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBRXZDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxHQUFHLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDckMsTUFBTSxTQUFTLEdBQUcsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUUzRSxNQUFNLGFBQWEsR0FBRyxVQUFVLEdBQUcsWUFBWSxDQUFDO1FBQ2hELE1BQU0sV0FBVyxHQUNmLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekYsTUFBTSxXQUFXLEdBQUcsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RSxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckUsTUFBTSxZQUFZLEdBQUcsYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxHQUFHLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakYsTUFBTSxVQUFVLEdBQUcsU0FBUyxHQUFHLFdBQVcsQ0FBQztRQUUzQyxPQUFPO1lBQ0wsSUFBSTtZQUNKLFFBQVEsRUFBRSxhQUFhO1lBQ3ZCLFlBQVk7WUFDWixVQUFVO1lBQ1YsVUFBVTtZQUNWLFdBQVc7WUFDWCxNQUFNO1lBQ04sV0FBVztZQUNYLFdBQVc7U0FDWixDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBRUYsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxjQUFjLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7UUFDckUsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFDSSxLQUFLLFVBQVUsaUJBQWlCLENBQ3JDLFVBQTZDLEVBQzdDLFVBQTRCLEVBQUU7SUFFOUIsTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUMvQixNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUM3RSxDQUFDO0lBRUYsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDL0QsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBYSxjQUFjO0lBS3pCLFlBQTRCLFNBQWlCLEVBQUUsVUFBNEIsRUFBRTtRQUFqRCxjQUFTLEdBQVQsU0FBUyxDQUFRO1FBSnJDLGVBQVUsR0FBbUQsRUFBRSxDQUFDO1FBS3RFLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxHQUFHLENBQUMsSUFBWSxFQUFFLEVBQXFCO1FBQ3JDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUFDLGFBQWdDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsYUFBYSxFQUFFLENBQUM7UUFDdEQsTUFBTSxPQUFPLEdBQXNCLEVBQUUsQ0FBQztRQUV0QyxzQ0FBc0M7UUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDL0Qsc0NBQXNDO1FBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTVCLGdEQUFnRDtRQUNoRCxLQUFLLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzNDLHNDQUFzQztZQUN0QyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixJQUFJLEtBQUssQ0FBQyxDQUFDO1lBRXpDLElBQUksQ0FBQztnQkFDSCw0Q0FBNEM7Z0JBQzVDLE1BQU0sTUFBTSxHQUFHLE1BQU0sU0FBUyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2xELE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBRXJCLHNDQUFzQztnQkFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FDVCxRQUFRLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxXQUFXLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUN6RSxDQUFDLENBQ0YsV0FBVyxDQUNiLENBQUM7Z0JBQ0YsSUFBSSxPQUFPLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQzFCLHNDQUFzQztvQkFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNqRixDQUFDO1lBQ0gsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2Ysc0NBQXNDO2dCQUN0QyxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO1lBQzFGLENBQUM7UUFDSCxDQUFDO1FBRUQsVUFBVTtRQUNWLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixzQ0FBc0M7WUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sYUFBYSxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUNqRixNQUFNLE9BQU8sR0FBRyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFakMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDdEMsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDO2dCQUMxRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBQ2hCLElBQUksS0FBSyxLQUFLLENBQUM7b0JBQUUsSUFBSSxHQUFHLElBQUksQ0FBQztxQkFDeEIsSUFBSSxLQUFLLEtBQUssQ0FBQztvQkFBRSxJQUFJLEdBQUcsSUFBSSxDQUFDO3FCQUM3QixJQUFJLEtBQUssS0FBSyxDQUFDO29CQUFFLElBQUksR0FBRyxJQUFJLENBQUM7Z0JBRWxDLHNDQUFzQztnQkFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FDVCxNQUFNLElBQUksSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxNQUFNLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FDbEUsQ0FBQyxDQUNGLFFBQVEsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUNoQyxDQUFDO1lBQ0osQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsc0NBQXNDO1FBQ3RDLE9BQU8sQ0FBQyxHQUFHLENBQ1Qsd0JBQXdCLE9BQU8sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLDBCQUEwQixDQUMzRixDQUFDO1FBRUYsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxJQUFJO1FBQ04sT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztJQUNoQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLO1FBQ0gsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUM7UUFDckIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ0Y7QUEzR0Qsd0NBMkdDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFCRztBQUNILFNBQWdCLG9CQUFvQixDQUNsQyxTQUFpQixFQUNqQixPQUEwQjtJQUUxQixPQUFPLElBQUksY0FBYyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0ksS0FBSyxVQUFVLGFBQWEsQ0FBQyxFQUFxQixFQUFFLE9BQU8sR0FBRyxJQUFJO0lBQ3ZFLElBQUksT0FBTyxFQUFFLENBQUM7UUFDWixzQkFBc0IsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO0lBQ25ELE1BQU0sRUFBRSxFQUFFLENBQUM7SUFDWCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO0lBRWpELE9BQU8sU0FBUyxHQUFHLFdBQVcsQ0FBQztBQUNqQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCZW5jaG1hcmsgdXRpbGl0aWVzIGZvciBwZXJmb3JtYW5jZSB0ZXN0aW5nXG4gKlxuICogUHJvdmlkZXMgZWFzeS10by11c2UgdG9vbHMgZm9yIG1lYXN1cmluZyBmdW5jdGlvbiBwZXJmb3JtYW5jZSxcbiAqIG1lbW9yeSB1c2FnZSwgYW5kIGNyZWF0aW5nIHBlcmZvcm1hbmNlIGNvbXBhcmlzb25zLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBiZW5jaG1hcmssIGNyZWF0ZUJlbmNobWFya1N1aXRlIH0gZnJvbSAnLi9iZW5jaG1hcmsnO1xuICpcbiAqIC8vIFNpbXBsZSBiZW5jaG1hcmtcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJlbmNobWFyaygnbXlGdW5jdGlvbicsICgpID0+IG15RnVuY3Rpb24oZGF0YSkpO1xuICogY29uc29sZS5sb2coYER1cmF0aW9uOiAke3Jlc3VsdC5kdXJhdGlvbn1tc2ApO1xuICpcbiAqIC8vIEJlbmNobWFyayBzdWl0ZVxuICogY29uc3Qgc3VpdGUgPSBjcmVhdGVCZW5jaG1hcmtTdWl0ZSgnQXJyYXkgT3BlcmF0aW9ucycpO1xuICogc3VpdGUuYWRkKCduYXRpdmUgbWFwJywgKCkgPT4gZGF0YS5tYXAoeCA9PiB4ICogMikpO1xuICogc3VpdGUuYWRkKCdjdXN0b20gbWFwJywgKCkgPT4gY3VzdG9tTWFwKGRhdGEsIHggPT4geCAqIDIpKTtcbiAqIGF3YWl0IHN1aXRlLnJ1bigpO1xuICogYGBgXG4gKi9cblxuLyoqXG4gKiBSZXN1bHQgb2YgYSBiZW5jaG1hcmsgbWVhc3VyZW1lbnRcbiAqL1xuZXhwb3J0IHR5cGUgQmVuY2htYXJrUmVzdWx0ID0ge1xuICAvKiogTmFtZSBvZiB0aGUgYmVuY2htYXJrICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqIFRvdGFsIGR1cmF0aW9uIGluIG1pbGxpc2Vjb25kcyAqL1xuICBkdXJhdGlvbjogbnVtYmVyO1xuICAvKiogT3BlcmF0aW9ucyBwZXIgc2Vjb25kICovXG4gIG9wc1BlclNlY29uZDogbnVtYmVyO1xuICAvKiogTWVtb3J5IHVzZWQgaW4gYnl0ZXMgKGhlYXAgZGlmZmVyZW5jZSkgKi9cbiAgbWVtb3J5VXNlZDogbnVtYmVyO1xuICAvKiogTnVtYmVyIG9mIGl0ZXJhdGlvbnMgcnVuICovXG4gIGl0ZXJhdGlvbnM6IG51bWJlcjtcbiAgLyoqIEF2ZXJhZ2UgZHVyYXRpb24gcGVyIGl0ZXJhdGlvbiBpbiBtaWxsaXNlY29uZHMgKi9cbiAgYXZnRHVyYXRpb246IG51bWJlcjtcbiAgLyoqIFN0YW5kYXJkIGRldmlhdGlvbiBvZiBkdXJhdGlvbnMgKi9cbiAgc3RkRGV2OiBudW1iZXI7XG4gIC8qKiBNaW5pbXVtIGR1cmF0aW9uIG9ic2VydmVkICovXG4gIG1pbkR1cmF0aW9uOiBudW1iZXI7XG4gIC8qKiBNYXhpbXVtIGR1cmF0aW9uIG9ic2VydmVkICovXG4gIG1heER1cmF0aW9uOiBudW1iZXI7XG59O1xuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgYmVuY2htYXJrc1xuICovXG5leHBvcnQgdHlwZSBCZW5jaG1hcmtPcHRpb25zID0ge1xuICAvKiogTnVtYmVyIG9mIGl0ZXJhdGlvbnMgdG8gcnVuIChkZWZhdWx0OiAxKSAqL1xuICBpdGVyYXRpb25zPzogbnVtYmVyO1xuICAvKiogTnVtYmVyIG9mIHdhcm11cCBydW5zIGJlZm9yZSBtZWFzdXJpbmcgKGRlZmF1bHQ6IDEpICovXG4gIHdhcm11cFJ1bnM/OiBudW1iZXI7XG4gIC8qKiBXaGV0aGVyIHRvIGZvcmNlIGdhcmJhZ2UgY29sbGVjdGlvbiBiZXR3ZWVuIHJ1bnMgKGRlZmF1bHQ6IGZhbHNlKSAqL1xuICBmb3JjZUdDPzogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgdG8gbWVhc3VyZSBtZW1vcnkgdXNhZ2UgKGRlZmF1bHQ6IHRydWUpICovXG4gIG1lYXN1cmVNZW1vcnk/OiBib29sZWFuO1xuICAvKiogVGltZW91dCBpbiBtaWxsaXNlY29uZHMgZm9yIHRoZSBlbnRpcmUgYmVuY2htYXJrIChkZWZhdWx0OiAzMDAwMCkgKi9cbiAgdGltZW91dD86IG51bWJlcjtcbn07XG5cbi8qKlxuICogQmVuY2htYXJrIGZ1bmN0aW9uIHR5cGVcbiAqL1xuZXhwb3J0IHR5cGUgQmVuY2htYXJrRnVuY3Rpb248VCA9IHVua25vd24+ID0gKCkgPT4gVCB8IFByb21pc2U8VD47XG5cbi8qKlxuICogRm9yY2UgZ2FyYmFnZSBjb2xsZWN0aW9uIGlmIGF2YWlsYWJsZVxuICovXG5mdW5jdGlvbiBmb3JjZUdhcmJhZ2VDb2xsZWN0aW9uKCk6IHZvaWQge1xuICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgZ2xvYmFsLmdjKSB7XG4gICAgZ2xvYmFsLmdjKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxjdWxhdGUgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIGFuIGFycmF5IG9mIG51bWJlcnNcbiAqL1xuZnVuY3Rpb24gY2FsY3VsYXRlU3RkRGV2KHZhbHVlczogbnVtYmVyW10pOiBudW1iZXIge1xuICBjb25zdCBtZWFuID0gdmFsdWVzLnJlZHVjZSgoc3VtLCB2YWwpID0+IHN1bSArIHZhbCwgMCkgLyB2YWx1ZXMubGVuZ3RoO1xuICBjb25zdCBzcXVhcmVkRGlmZnMgPSB2YWx1ZXMubWFwKCh2YWwpID0+ICh2YWwgLSBtZWFuKSAqKiAyKTtcbiAgY29uc3QgYXZnU3F1YXJlZERpZmYgPSBzcXVhcmVkRGlmZnMucmVkdWNlKChzdW0sIHZhbCkgPT4gc3VtICsgdmFsLCAwKSAvIHZhbHVlcy5sZW5ndGg7XG4gIHJldHVybiBNYXRoLnNxcnQoYXZnU3F1YXJlZERpZmYpO1xufVxuXG4vKipcbiAqIFJ1biBhIGJlbmNobWFyayBmb3IgYSBzaW5nbGUgZnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0gbmFtZSAtIE5hbWUgb2YgdGhlIGJlbmNobWFya1xuICogQHBhcmFtIGZuIC0gRnVuY3Rpb24gdG8gYmVuY2htYXJrXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEJlbmNobWFyayBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGJlbmNobWFyayByZXN1bHRzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJlbmNobWFyaygnQXJyYXkubWFwJywgKCkgPT4ge1xuICogICByZXR1cm4gbGFyZ2VBcnJheS5tYXAoeCA9PiB4ICogMik7XG4gKiB9LCB7IGl0ZXJhdGlvbnM6IDEwLCB3YXJtdXBSdW5zOiAzIH0pO1xuICpcbiAqIGNvbnNvbGUubG9nKGAke3Jlc3VsdC5uYW1lfTogJHtyZXN1bHQuYXZnRHVyYXRpb24udG9GaXhlZCgyKX1tcyBhdmdgKTtcbiAqIGBgYFxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVxdWlyZS1hd2FpdFxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJlbmNobWFyayhcbiAgbmFtZTogc3RyaW5nLFxuICBmbjogQmVuY2htYXJrRnVuY3Rpb24sXG4gIG9wdGlvbnM6IEJlbmNobWFya09wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8QmVuY2htYXJrUmVzdWx0PiB7XG4gIGNvbnN0IHtcbiAgICBpdGVyYXRpb25zID0gMSxcbiAgICB3YXJtdXBSdW5zID0gMSxcbiAgICBmb3JjZUdDID0gZmFsc2UsXG4gICAgbWVhc3VyZU1lbW9yeTogc2hvdWxkTWVhc3VyZU1lbW9yeSA9IHRydWUsXG4gICAgdGltZW91dCA9IDMwMDAwLFxuICB9ID0gb3B0aW9ucztcblxuICAvLyBUaW1lb3V0IHByb3RlY3Rpb25cbiAgbGV0IHRpbWVvdXRJZDogTm9kZUpTLlRpbWVvdXQ7XG4gIGNvbnN0IHRpbWVvdXRQcm9taXNlID0gbmV3IFByb21pc2U8bmV2ZXI+KChfLCByZWplY3QpID0+IHtcbiAgICB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KFxuICAgICAgKCkgPT4gcmVqZWN0KG5ldyBFcnJvcihgQmVuY2htYXJrIFwiJHtuYW1lfVwiIHRpbWVkIG91dCBhZnRlciAke3RpbWVvdXR9bXNgKSksXG4gICAgICB0aW1lb3V0LFxuICAgICk7XG4gIH0pO1xuXG4gIGNvbnN0IGJlbmNobWFya1Byb21pc2UgPSBhc3luYyAoKTogUHJvbWlzZTxCZW5jaG1hcmtSZXN1bHQ+ID0+IHtcbiAgICAvLyBXYXJtdXAgcnVuc1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgQXJyYXkuZnJvbSh7IGxlbmd0aDogd2FybXVwUnVucyB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IGZuKCk7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgaWYgKGZvcmNlR0MpIHtcbiAgICAgIGZvcmNlR2FyYmFnZUNvbGxlY3Rpb24oKTtcbiAgICB9XG5cbiAgICBjb25zdCBkdXJhdGlvbnM6IG51bWJlcltdID0gW107XG4gICAgY29uc3Qgc3RhcnRNZW1vcnkgPSBzaG91bGRNZWFzdXJlTWVtb3J5ID8gcHJvY2Vzcy5tZW1vcnlVc2FnZSgpLmhlYXBVc2VkIDogMDtcbiAgICBjb25zdCBvdmVyYWxsU3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICAgIC8vIEFjdHVhbCBiZW5jaG1hcmsgcnVuc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlcmF0aW9uczsgaSArPSAxKSB7XG4gICAgICBpZiAoZm9yY2VHQyAmJiBpID4gMCkge1xuICAgICAgICBmb3JjZUdhcmJhZ2VDb2xsZWN0aW9uKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGl0ZXJhdGlvblN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXdhaXQtaW4tbG9vcFxuICAgICAgYXdhaXQgZm4oKTtcbiAgICAgIGNvbnN0IGl0ZXJhdGlvbkVuZCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuXG4gICAgICBkdXJhdGlvbnMucHVzaChpdGVyYXRpb25FbmQgLSBpdGVyYXRpb25TdGFydCk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3ZlcmFsbEVuZCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgIGNvbnN0IGVuZE1lbW9yeSA9IHNob3VsZE1lYXN1cmVNZW1vcnkgPyBwcm9jZXNzLm1lbW9yeVVzYWdlKCkuaGVhcFVzZWQgOiAwO1xuXG4gICAgY29uc3QgdG90YWxEdXJhdGlvbiA9IG92ZXJhbGxFbmQgLSBvdmVyYWxsU3RhcnQ7XG4gICAgY29uc3QgYXZnRHVyYXRpb24gPVxuICAgICAgZHVyYXRpb25zLmxlbmd0aCA+IDAgPyBkdXJhdGlvbnMucmVkdWNlKChzdW0sIGQpID0+IHN1bSArIGQsIDApIC8gZHVyYXRpb25zLmxlbmd0aCA6IDA7XG4gICAgY29uc3QgbWluRHVyYXRpb24gPSBkdXJhdGlvbnMubGVuZ3RoID4gMCA/IE1hdGgubWluKC4uLmR1cmF0aW9ucykgOiAwO1xuICAgIGNvbnN0IG1heER1cmF0aW9uID0gZHVyYXRpb25zLmxlbmd0aCA+IDAgPyBNYXRoLm1heCguLi5kdXJhdGlvbnMpIDogMDtcbiAgICBjb25zdCBzdGREZXYgPSBkdXJhdGlvbnMubGVuZ3RoID4gMCA/IGNhbGN1bGF0ZVN0ZERldihkdXJhdGlvbnMpIDogMDtcbiAgICBjb25zdCBvcHNQZXJTZWNvbmQgPSB0b3RhbER1cmF0aW9uID4gMCA/IGl0ZXJhdGlvbnMgLyAodG90YWxEdXJhdGlvbiAvIDEwMDApIDogMDtcbiAgICBjb25zdCBtZW1vcnlVc2VkID0gZW5kTWVtb3J5IC0gc3RhcnRNZW1vcnk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSxcbiAgICAgIGR1cmF0aW9uOiB0b3RhbER1cmF0aW9uLFxuICAgICAgb3BzUGVyU2Vjb25kLFxuICAgICAgbWVtb3J5VXNlZCxcbiAgICAgIGl0ZXJhdGlvbnMsXG4gICAgICBhdmdEdXJhdGlvbixcbiAgICAgIHN0ZERldixcbiAgICAgIG1pbkR1cmF0aW9uLFxuICAgICAgbWF4RHVyYXRpb24sXG4gICAgfTtcbiAgfTtcblxuICByZXR1cm4gUHJvbWlzZS5yYWNlKFtiZW5jaG1hcmtQcm9taXNlKCksIHRpbWVvdXRQcm9taXNlXSkuZmluYWxseSgoKSA9PiB7XG4gICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbXBhcmUgbXVsdGlwbGUgZnVuY3Rpb25zIHdpdGggdGhlIHNhbWUgYmVuY2htYXJrIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBAcGFyYW0gYmVuY2htYXJrcyAtIE9iamVjdCB3aXRoIGJlbmNobWFyayBuYW1lcyBhbmQgZnVuY3Rpb25zXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEJlbmNobWFyayBjb25maWd1cmF0aW9uIG9wdGlvbnNcbiAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGFycmF5IG9mIGJlbmNobWFyayByZXN1bHRzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBjb21wYXJlQmVuY2htYXJrcyh7XG4gKiAgICduYXRpdmUgbWFwJzogKCkgPT4gZGF0YS5tYXAoeCA9PiB4ICogMiksXG4gKiAgICdmb3IgbG9vcCc6ICgpID0+IHtcbiAqICAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAqICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAqICAgICAgIHJlc3VsdC5wdXNoKGRhdGFbaV0gKiAyKTtcbiAqICAgICB9XG4gKiAgICAgcmV0dXJuIHJlc3VsdDtcbiAqICAgfVxuICogfSwgeyBpdGVyYXRpb25zOiA1IH0pO1xuICpcbiAqIHJlc3VsdHMuZm9yRWFjaChyZXN1bHQgPT4ge1xuICogICBjb25zb2xlLmxvZyhgJHtyZXN1bHQubmFtZX06ICR7cmVzdWx0LmF2Z0R1cmF0aW9uLnRvRml4ZWQoMil9bXNgKTtcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb21wYXJlQmVuY2htYXJrcyhcbiAgYmVuY2htYXJrczogUmVjb3JkPHN0cmluZywgQmVuY2htYXJrRnVuY3Rpb24+LFxuICBvcHRpb25zOiBCZW5jaG1hcmtPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPEJlbmNobWFya1Jlc3VsdFtdPiB7XG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBPYmplY3QuZW50cmllcyhiZW5jaG1hcmtzKS5tYXAoKFtuYW1lLCBmbl0pID0+IGJlbmNobWFyayhuYW1lLCBmbiwgb3B0aW9ucykpLFxuICApO1xuXG4gIHJldHVybiByZXN1bHRzLnNvcnQoKGEsIGIpID0+IGEuYXZnRHVyYXRpb24gLSBiLmF2Z0R1cmF0aW9uKTtcbn1cblxuLyoqXG4gKiBCZW5jaG1hcmsgc3VpdGUgZm9yIG9yZ2FuaXppbmcgYW5kIHJ1bm5pbmcgbXVsdGlwbGUgcmVsYXRlZCBiZW5jaG1hcmtzXG4gKi9cbmV4cG9ydCBjbGFzcyBCZW5jaG1hcmtTdWl0ZSB7XG4gIHByaXZhdGUgYmVuY2htYXJrczogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IGZuOiBCZW5jaG1hcmtGdW5jdGlvbiB9PiA9IFtdO1xuXG4gIHByaXZhdGUgb3B0aW9uczogQmVuY2htYXJrT3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgc3VpdGVOYW1lOiBzdHJpbmcsIG9wdGlvbnM6IEJlbmNobWFya09wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgYmVuY2htYXJrIHRvIHRoZSBzdWl0ZVxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSAtIE5hbWUgb2YgdGhlIGJlbmNobWFya1xuICAgKiBAcGFyYW0gZm4gLSBGdW5jdGlvbiB0byBiZW5jaG1hcmtcbiAgICogQHJldHVybnMgVGhpcyBzdWl0ZSBpbnN0YW5jZSBmb3IgY2hhaW5pbmdcbiAgICovXG4gIGFkZChuYW1lOiBzdHJpbmcsIGZuOiBCZW5jaG1hcmtGdW5jdGlvbik6IHRoaXMge1xuICAgIHRoaXMuYmVuY2htYXJrcy5wdXNoKHsgbmFtZSwgZm4gfSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogUnVuIGFsbCBiZW5jaG1hcmtzIGluIHRoZSBzdWl0ZVxuICAgKlxuICAgKiBAcGFyYW0gY3VzdG9tT3B0aW9ucyAtIE92ZXJyaWRlIHN1aXRlIG9wdGlvbnMgZm9yIHRoaXMgcnVuXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGFycmF5IG9mIGJlbmNobWFyayByZXN1bHRzXG4gICAqL1xuICBhc3luYyBydW4oY3VzdG9tT3B0aW9ucz86IEJlbmNobWFya09wdGlvbnMpOiBQcm9taXNlPEJlbmNobWFya1Jlc3VsdFtdPiB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHsgLi4udGhpcy5vcHRpb25zLCAuLi5jdXN0b21PcHRpb25zIH07XG4gICAgY29uc3QgcmVzdWx0czogQmVuY2htYXJrUmVzdWx0W10gPSBbXTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coYFxcbvCfmoAgUnVubmluZyBiZW5jaG1hcmsgc3VpdGU6ICR7dGhpcy5zdWl0ZU5hbWV9YCk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZygnPScucmVwZWF0KDYwKSk7XG5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1zeW50YXhcbiAgICBmb3IgKGNvbnN0IHsgbmFtZSwgZm4gfSBvZiB0aGlzLmJlbmNobWFya3MpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLmxvZyhgXFxu4o+x77iPICBSdW5uaW5nOiAke25hbWV9Li4uYCk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGJlbmNobWFyayhuYW1lLCBmbiwgb3B0aW9ucyk7XG4gICAgICAgIHJlc3VsdHMucHVzaChyZXN1bHQpO1xuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGAgICDinIUgJHtyZXN1bHQuYXZnRHVyYXRpb24udG9GaXhlZCgyKX1tcyBhdmcgKCR7cmVzdWx0Lm9wc1BlclNlY29uZC50b0ZpeGVkKFxuICAgICAgICAgICAgMCxcbiAgICAgICAgICApfSBvcHMvc2VjKWAsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChvcHRpb25zLm1lYXN1cmVNZW1vcnkpIHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgIGNvbnNvbGUubG9nKGAgICDwn5K+IE1lbW9yeTogJHsocmVzdWx0Lm1lbW9yeVVzZWQgLyAxMDI0IC8gMTAyNCkudG9GaXhlZCgyKX1NQmApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICBjb25zb2xlLmxvZyhgICAg4p2MIEZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6ICdVbmtub3duIGVycm9yJ31gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTdW1tYXJ5XG4gICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUubG9nKGBcXG7wn5OKIFN1bW1hcnkgKHNvcnRlZCBieSBwZXJmb3JtYW5jZSk6YCk7XG4gICAgICBjb25zdCBzb3J0ZWRSZXN1bHRzID0gWy4uLnJlc3VsdHNdLnNvcnQoKGEsIGIpID0+IGEuYXZnRHVyYXRpb24gLSBiLmF2Z0R1cmF0aW9uKTtcbiAgICAgIGNvbnN0IGZhc3Rlc3QgPSBzb3J0ZWRSZXN1bHRzWzBdO1xuXG4gICAgICBzb3J0ZWRSZXN1bHRzLmZvckVhY2goKHJlc3VsdCwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgcmVsYXRpdmUgPSByZXN1bHQuYXZnRHVyYXRpb24gLyBmYXN0ZXN0LmF2Z0R1cmF0aW9uO1xuICAgICAgICBsZXQgaWNvbiA9ICcgICc7XG4gICAgICAgIGlmIChpbmRleCA9PT0gMCkgaWNvbiA9ICfwn6WHJztcbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT09IDEpIGljb24gPSAn8J+liCc7XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID09PSAyKSBpY29uID0gJ/CfpYknO1xuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGAgICAke2ljb259ICR7cmVzdWx0Lm5hbWUucGFkRW5kKDI1KX0gfCAke3Jlc3VsdC5hdmdEdXJhdGlvbi50b0ZpeGVkKFxuICAgICAgICAgICAgMixcbiAgICAgICAgICApfW1zIHwgJHtyZWxhdGl2ZS50b0ZpeGVkKDIpfXhgLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGBcXG7inIUgU3VpdGUgY29tcGxldGVkOiAke3Jlc3VsdHMubGVuZ3RofS8ke3RoaXMuYmVuY2htYXJrcy5sZW5ndGh9IGJlbmNobWFya3Mgc3VjY2Vzc2Z1bFxcbmAsXG4gICAgKTtcblxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIGJlbmNobWFya3MgaW4gdGhlIHN1aXRlXG4gICAqL1xuICBnZXQgc2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmJlbmNobWFya3MubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBiZW5jaG1hcmtzIGZyb20gdGhlIHN1aXRlXG4gICAqL1xuICBjbGVhcigpOiB0aGlzIHtcbiAgICB0aGlzLmJlbmNobWFya3MgPSBbXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBiZW5jaG1hcmsgc3VpdGVcbiAqXG4gKiBAcGFyYW0gc3VpdGVOYW1lIC0gTmFtZSBvZiB0aGUgYmVuY2htYXJrIHN1aXRlXG4gKiBAcGFyYW0gb3B0aW9ucyAtIERlZmF1bHQgb3B0aW9ucyBmb3IgYWxsIGJlbmNobWFya3MgaW4gdGhlIHN1aXRlXG4gKiBAcmV0dXJucyBOZXcgQmVuY2htYXJrU3VpdGUgaW5zdGFuY2VcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3Qgc3VpdGUgPSBjcmVhdGVCZW5jaG1hcmtTdWl0ZSgnU3RyaW5nIE9wZXJhdGlvbnMnLCB7XG4gKiAgIGl0ZXJhdGlvbnM6IDEwLFxuICogICB3YXJtdXBSdW5zOiAyXG4gKiB9KTtcbiAqXG4gKiBzdWl0ZVxuICogICAuYWRkKCdjb25jYXQnLCAoKSA9PiBzdHIxICsgc3RyMilcbiAqICAgLmFkZCgndGVtcGxhdGUnLCAoKSA9PiBgJHtzdHIxfSR7c3RyMn1gKVxuICogICAuYWRkKCdqb2luJywgKCkgPT4gW3N0cjEsIHN0cjJdLmpvaW4oJycpKTtcbiAqXG4gKiBhd2FpdCBzdWl0ZS5ydW4oKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQmVuY2htYXJrU3VpdGUoXG4gIHN1aXRlTmFtZTogc3RyaW5nLFxuICBvcHRpb25zPzogQmVuY2htYXJrT3B0aW9ucyxcbik6IEJlbmNobWFya1N1aXRlIHtcbiAgcmV0dXJuIG5ldyBCZW5jaG1hcmtTdWl0ZShzdWl0ZU5hbWUsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIFV0aWxpdHkgdG8gbWVhc3VyZSBtZW1vcnkgdXNhZ2Ugb2YgYSBmdW5jdGlvblxuICpcbiAqIEBwYXJhbSBmbiAtIEZ1bmN0aW9uIHRvIG1lYXN1cmVcbiAqIEBwYXJhbSBmb3JjZUdDIC0gV2hldGhlciB0byBmb3JjZSBnYXJiYWdlIGNvbGxlY3Rpb24gYmVmb3JlIG1lYXN1cmluZ1xuICogQHJldHVybnMgTWVtb3J5IHVzYWdlIGluIGJ5dGVzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGNvbnN0IG1lbW9yeVVzZWQgPSBhd2FpdCBtZWFzdXJlTWVtb3J5KCgpID0+IHtcbiAqICAgcmV0dXJuIG5ldyBBcnJheSgxMDAwMDApLmZpbGwoMCkubWFwKHggPT4gKHsgdmFsdWU6IHggfSkpO1xuICogfSk7XG4gKlxuICogY29uc29sZS5sb2coYE1lbW9yeSB1c2VkOiAkeyhtZW1vcnlVc2VkIC8gMTAyNCAvIDEwMjQpLnRvRml4ZWQoMil9TUJgKTtcbiAqIGBgYFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWVhc3VyZU1lbW9yeShmbjogQmVuY2htYXJrRnVuY3Rpb24sIGZvcmNlR0MgPSB0cnVlKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgaWYgKGZvcmNlR0MpIHtcbiAgICBmb3JjZUdhcmJhZ2VDb2xsZWN0aW9uKCk7XG4gIH1cblxuICBjb25zdCBzdGFydE1lbW9yeSA9IHByb2Nlc3MubWVtb3J5VXNhZ2UoKS5oZWFwVXNlZDtcbiAgYXdhaXQgZm4oKTtcbiAgY29uc3QgZW5kTWVtb3J5ID0gcHJvY2Vzcy5tZW1vcnlVc2FnZSgpLmhlYXBVc2VkO1xuXG4gIHJldHVybiBlbmRNZW1vcnkgLSBzdGFydE1lbW9yeTtcbn1cbiJdfQ==
|