UNPKG

@orbit/jsonapi

Version:

JSON:API support for Orbit.

290 lines 49.3 kB
import { clone, deepSet, toArray } from '@orbit/utils'; import { cloneRecordIdentity, equalRecordIdentities, recordDiffs } from '@orbit/records'; import { buildTransform } from '@orbit/data'; import { JSONAPISerializers } from '../serializers/jsonapi-serializers'; export const TransformRequestProcessors = { async addRecord(requestProcessor, request) { var _a, _b; const { record } = request; const serializer = requestProcessor.serializerFor(JSONAPISerializers.ResourceDocument); const requestDoc = serializer.serialize({ data: record }); const settings = { ...requestProcessor.buildFetchSettings(request), method: 'POST', json: requestDoc }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceURL(record.type); const details = await requestProcessor.fetch(url, settings); const document = details.document; requestProcessor.preprocessResponseDocument(document, request); const recordDoc = serializer.deserialize(document, { primaryRecord: record }); return handleChanges(record, recordDoc, details); }, async removeRecord(requestProcessor, request) { var _a, _b; const { record } = request; const { type, id } = record; const settings = { ...requestProcessor.buildFetchSettings(request), method: 'DELETE' }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceURL(type, id); const details = await requestProcessor.fetch(url, settings); return { transforms: [], data: record, details }; }, async updateRecord(requestProcessor, request) { var _a, _b; const { record } = request; const { type, id } = record; const serializer = requestProcessor.serializerFor(JSONAPISerializers.ResourceDocument); const requestDoc = serializer.serialize({ data: record }); const settings = { ...requestProcessor.buildFetchSettings(request), method: 'PATCH', json: requestDoc }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceURL(type, id); const details = await requestProcessor.fetch(url, settings); const { document } = details; if (document) { requestProcessor.preprocessResponseDocument(document, request); const recordDoc = serializer.deserialize(document, { primaryRecord: record }); return handleChanges(record, recordDoc, details); } else { return { transforms: [], data: record, details }; } }, async addToRelatedRecords(requestProcessor, request) { var _a, _b; const { relationship, record, relatedRecords } = request; const { type, id } = record; const resourceIdentitySerializer = requestProcessor.serializerFor(JSONAPISerializers.ResourceIdentity); const json = { data: relatedRecords.map((r) => resourceIdentitySerializer.serialize(r)) }; const settings = { ...requestProcessor.buildFetchSettings(request), method: 'POST', json }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceRelationshipURL(type, id, relationship); const details = await requestProcessor.fetch(url, settings); return { transforms: [], data: record, details }; }, async removeFromRelatedRecords(requestProcessor, request) { var _a, _b; const { relationship, record, relatedRecords } = request; const { type, id } = record; const resourceIdentitySerializer = requestProcessor.serializerFor(JSONAPISerializers.ResourceIdentity); const json = { data: relatedRecords.map((r) => resourceIdentitySerializer.serialize(r)) }; const settings = { ...requestProcessor.buildFetchSettings(request), method: 'DELETE', json }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceRelationshipURL(type, id, relationship); const details = await requestProcessor.fetch(url, settings); return { transforms: [], data: record, details }; }, async replaceRelatedRecord(requestProcessor, request) { var _a, _b; const { relationship, relatedRecord, record } = request; const { type, id } = record; const resourceIdentitySerializer = requestProcessor.serializerFor(JSONAPISerializers.ResourceIdentity); const json = { data: relatedRecord ? resourceIdentitySerializer.serialize(relatedRecord) : null }; const settings = { ...requestProcessor.buildFetchSettings(request), method: 'PATCH', json }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceRelationshipURL(type, id, relationship); const details = await requestProcessor.fetch(url, settings); return { transforms: [], data: record, details }; }, async replaceRelatedRecords(requestProcessor, request) { var _a, _b; const { relationship, relatedRecords, record } = request; const { type, id } = record; const resourceIdentitySerializer = requestProcessor.serializerFor(JSONAPISerializers.ResourceIdentity); const json = { data: relatedRecords.map((r) => resourceIdentitySerializer.serialize(r)) }; const settings = { ...requestProcessor.buildFetchSettings(request), method: 'PATCH', json }; const url = (_b = (_a = request.options) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : requestProcessor.urlBuilder.resourceRelationshipURL(type, id, relationship); const details = await requestProcessor.fetch(url, settings); return { transforms: [], data: record, details }; } }; export function getTransformRequests(requestProcessor, transform) { const requests = []; let prevRequest = null; for (let operation of toArray(transform.operations)) { let request; let newRequestNeeded = true; if (prevRequest && equalRecordIdentities(prevRequest.record, operation.record)) { if (operation.op === 'removeRecord') { newRequestNeeded = false; if (prevRequest.op !== 'removeRecord') { prevRequest = null; requests.pop(); } } else if (prevRequest.op === 'addRecord' || prevRequest.op === 'updateRecord') { if (operation.op === 'replaceAttribute') { newRequestNeeded = false; replaceRecordAttribute(prevRequest.record, operation.attribute, operation.value); } else if (operation.op === 'replaceRelatedRecord') { newRequestNeeded = false; replaceRecordHasOne(prevRequest.record, operation.relationship, operation.relatedRecord); } else if (operation.op === 'replaceRelatedRecords') { newRequestNeeded = false; replaceRecordHasMany(prevRequest.record, operation.relationship, operation.relatedRecords); } } else if (prevRequest.op === 'addToRelatedRecords' && operation.op === 'addToRelatedRecords' && prevRequest.relationship === operation.relationship) { newRequestNeeded = false; prevRequest.relatedRecords.push(cloneRecordIdentity(operation.relatedRecord)); } else if (prevRequest.op === 'removeFromRelatedRecords' && operation.op === 'removeFromRelatedRecords' && prevRequest.relationship === operation.relationship) { newRequestNeeded = false; prevRequest.relatedRecords.push(cloneRecordIdentity(operation.relatedRecord)); } } if (newRequestNeeded) { request = OperationToRequestMap[operation.op](operation); } if (request) { const options = requestProcessor.mergeRequestOptions([ request.options, transform.options, operation.options ]); if (options) request.options = options; requests.push(request); prevRequest = request; } } return requests; } const OperationToRequestMap = { addRecord(operation) { const op = operation; return { op: 'addRecord', record: clone(op.record) }; }, removeRecord(operation) { const op = operation; return { op: 'removeRecord', record: cloneRecordIdentity(op.record) }; }, replaceAttribute(operation) { const op = operation; const record = cloneRecordIdentity(op.record); replaceRecordAttribute(record, op.attribute, op.value); return { op: 'updateRecord', record }; }, updateRecord(operation) { return { op: 'updateRecord', record: clone(operation.record) }; }, addToRelatedRecords(operation) { const { record, relationship, relatedRecord } = operation; return { op: 'addToRelatedRecords', record: cloneRecordIdentity(record), relationship, relatedRecords: [cloneRecordIdentity(relatedRecord)] }; }, removeFromRelatedRecords(operation) { const { record, relationship, relatedRecord } = operation; return { op: 'removeFromRelatedRecords', record: cloneRecordIdentity(record), relationship, relatedRecords: [cloneRecordIdentity(relatedRecord)] }; }, replaceRelatedRecord(operation) { const record = cloneRecordIdentity(operation.record); const { relationship, relatedRecord } = operation; deepSet(record, ['relationships', relationship, 'data'], relatedRecord); return { op: 'updateRecord', record }; }, replaceRelatedRecords(operation) { const record = cloneRecordIdentity(operation.record); const { relationship, relatedRecords } = operation; deepSet(record, ['relationships', relationship, 'data'], relatedRecords); return { op: 'updateRecord', record }; } }; function replaceRecordAttribute(record, attribute, value) { deepSet(record, ['attributes', attribute], value); } function replaceRecordHasOne(record, relationship, relatedRecord) { deepSet(record, ['relationships', relationship, 'data'], relatedRecord ? cloneRecordIdentity(relatedRecord) : null); } function replaceRecordHasMany(record, relationship, relatedRecords) { deepSet(record, ['relationships', relationship, 'data'], relatedRecords.map((r) => cloneRecordIdentity(r))); } function handleChanges(record, recordDoc, details) { let updatedRecord = recordDoc.data; let transforms = []; let updateOps = recordDiffs(record, updatedRecord); if (updateOps.length > 0) { transforms.push(buildTransform(updateOps)); } if (recordDoc.included && recordDoc.included.length > 0) { let includedOps = recordDoc.included.map((record) => { return { op: 'updateRecord', record }; }); transforms.push(buildTransform(includedOps)); } return { transforms, data: updatedRecord, details }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtLXJlcXVlc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi90cmFuc2Zvcm0tcmVxdWVzdHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQVEsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdELE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIscUJBQXFCLEVBQ3JCLFdBQVcsRUFhWixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxjQUFjLEVBQWdCLE1BQU0sYUFBYSxDQUFDO0FBSzNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBNEV4RSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBb0M7SUFDekUsS0FBSyxDQUFDLFNBQVMsQ0FDYixnQkFBeUMsRUFDekMsT0FBK0I7O1FBRS9CLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUEyQixDQUFDO1FBQy9DLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLGFBQWEsQ0FDL0Msa0JBQWtCLENBQUMsZ0JBQWdCLENBQ1AsQ0FBQztRQUMvQixNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDO1lBQ3RDLElBQUksRUFBRSxNQUFNO1NBQ2IsQ0FBcUIsQ0FBQztRQUN2QixNQUFNLFFBQVEsR0FBRztZQUNmLEdBQUcsZ0JBQWdCLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDO1lBQy9DLE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLFVBQVU7U0FDakIsQ0FBQztRQUNGLE1BQU0sR0FBRyxHQUNQLE1BQUEsTUFBQSxPQUFPLENBQUMsT0FBTywwQ0FBRSxHQUFHLG1DQUNwQixnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV2RCxNQUFNLE9BQU8sR0FBRyxNQUFNLGdCQUFnQixDQUFD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QztBQUNKLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FDcEIsTUFBeUIsRUFDekIsU0FBeUIsRUFDekIsT0FBd0I7SUFFeEIsSUFBSSxhQUFhLEdBQXNCLFNBQVMsQ0FBQyxJQUF5QixDQUFDO0lBQzNFLElBQUksVUFBVSxHQUFzQixFQUFFLENBQUM7SUFDdkMsSUFBSSxTQUFTLEdBQUcsV0FBVyxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQztJQUNuRCxJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3hCLFVBQVUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7S0FDNUM7SUFDRCxJQUFJLFNBQVMsQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1FBQ3ZELElBQUksV0FBVyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDbEQsT0FBTyxFQUFFLEVBQUUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFxQixDQUFDO1FBQzNELENBQUMsQ0FBQyxDQUFDO1FBQ0gsVUFBVSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQWtCLFdBQVcsQ0FBQyxDQUFDLENBQUM7S0FDL0Q7SUFDRCxPQUFPLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDdEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNsb25lLCBkZWVwU2V0LCBEaWN0LCB0b0FycmF5IH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7XG4gIGNsb25lUmVjb3JkSWRlbnRpdHksXG4gIGVxdWFsUmVjb3JkSWRlbnRpdGllcyxcbiAgcmVjb3JkRGlmZnMsXG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBSZWNvcmRJZGVudGl0eSxcbiAgUmVjb3JkT3BlcmF0aW9uLFxuICBBZGRSZWNvcmRPcGVyYXRpb24sXG4gIFJlbW92ZVJlY29yZE9wZXJhdGlvbixcbiAgUmVwbGFjZUF0dHJpYnV0ZU9wZXJhdGlvbixcbiAgQWRkVG9SZWxhdGVkUmVjb3Jkc09wZXJhdGlvbixcbiAgUmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzT3BlcmF0aW9uLFxuICBSZXBsYWNlUmVsYXRlZFJlY29yZE9wZXJhdGlvbixcbiAgUmVwbGFjZVJlbGF0ZWRSZWNvcmRzT3BlcmF0aW9uLFxuICBSZWNvcmRUcmFuc2Zvcm0sXG4gIFJlY29yZE9wZXJhdGlvblJlc3VsdFxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5pbXBvcnQgeyBidWlsZFRyYW5zZm9ybSwgRnVsbFJlc3BvbnNlIH0gZnJvbSAnQG9yYml0L2RhdGEnO1xuaW1wb3J0IHsgSlNPTkFQSVJlcXVlc3RQcm9jZXNzb3IgfSBmcm9tICcuLi9qc29uYXBpLXJlcXVlc3QtcHJvY2Vzc29yJztcbmltcG9ydCB7IFJlc291cmNlRG9jdW1lbnQgfSBmcm9tICcuLi9yZXNvdXJjZS1kb2N1bWVudCc7XG5pbXBvcnQgeyBSZWNvcmREb2N1bWVudCB9IGZyb20gJy4uL3JlY29yZC1kb2N1bWVudCc7XG5pbXBvcnQgeyBKU09OQVBJUmVxdWVzdE9wdGlvbnMgfSBmcm9tICcuL2pzb25hcGktcmVxdWVzdC1vcHRpb25zJztcbmltcG9ydCB7IEpTT05BUElTZXJpYWxpemVycyB9IGZyb20gJy4uL3NlcmlhbGl6ZXJzL2pzb25hcGktc2VyaWFsaXplcnMnO1xuaW1wb3J0IHsgSlNPTkFQSURvY3VtZW50U2VyaWFsaXplciB9IGZyb20gJy4uL3NlcmlhbGl6ZXJzL2pzb25hcGktZG9jdW1lbnQtc2VyaWFsaXplcic7XG5pbXBvcnQgeyBKU09OQVBJUmVzb3VyY2VJZGVudGl0eVNlcmlhbGl6ZXIgfSBmcm9tICcuLi9zZXJpYWxpemVycy9qc29uYXBpLXJlc291cmNlLWlkZW50aXR5LXNlcmlhbGl6ZXInO1xuaW1wb3J0IHsgSlNPTkFQSVJlc3BvbnNlIH0gZnJvbSAnLi4vanNvbmFwaS1yZXNwb25zZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZVRyYW5zZm9ybVJlY29yZFJlcXVlc3Qge1xuICBvcDogc3RyaW5nO1xuICBvcHRpb25zPzogSlNPTkFQSVJlcXVlc3RPcHRpb25zO1xuICByZWNvcmQ6IFJlY29yZElkZW50aXR5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zZm9ybVJlY29yZFJlbGF0aW9uc2hpcFJlcXVlc3RcbiAgZXh0ZW5kcyBCYXNlVHJhbnNmb3JtUmVjb3JkUmVxdWVzdCB7XG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFkZFJlY29yZFJlcXVlc3QgZXh0ZW5kcyBCYXNlVHJhbnNmb3JtUmVjb3JkUmVxdWVzdCB7XG4gIG9wOiAnYWRkUmVjb3JkJztcbiAgcmVjb3JkOiBJbml0aWFsaXplZFJlY29yZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZW1vdmVSZWNvcmRSZXF1ZXN0IGV4dGVuZHMgQmFzZVRyYW5zZm9ybVJlY29yZFJlcXVlc3Qge1xuICBvcDogJ3JlbW92ZVJlY29yZCc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXBkYXRlUmVjb3JkUmVxdWVzdCBleHRlbmRzIEJhc2VUcmFuc2Zvcm1SZWNvcmRSZXF1ZXN0IHtcbiAgb3A6ICd1cGRhdGVSZWNvcmQnO1xuICByZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFkZFRvUmVsYXRlZFJlY29yZHNSZXF1ZXN0XG4gIGV4dGVuZHMgVHJhbnNmb3JtUmVjb3JkUmVsYXRpb25zaGlwUmVxdWVzdCB7XG4gIG9wOiAnYWRkVG9SZWxhdGVkUmVjb3Jkcyc7XG4gIHJlbGF0ZWRSZWNvcmRzOiBSZWNvcmRJZGVudGl0eVtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc1JlcXVlc3RcbiAgZXh0ZW5kcyBUcmFuc2Zvcm1SZWNvcmRSZWxhdGlvbnNoaXBSZXF1ZXN0IHtcbiAgb3A6ICdyZW1vdmVGcm9tUmVsYXRlZFJlY29yZHMnO1xuICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBsYWNlUmVsYXRlZFJlY29yZFJlcXVlc3RcbiAgZXh0ZW5kcyBUcmFuc2Zvcm1SZWNvcmRSZWxhdGlvbnNoaXBSZXF1ZXN0IHtcbiAgb3A6ICdyZXBsYWNlUmVsYXRlZFJlY29yZCc7XG4gIHJlbGF0ZWRSZWNvcmQ6IFJlY29yZElkZW50aXR5O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlcGxhY2VSZWxhdGVkUmVjb3Jkc1JlcXVlc3RcbiAgZXh0ZW5kcyBUcmFuc2Zvcm1SZWNvcmRSZWxhdGlvbnNoaXBSZXF1ZXN0IHtcbiAgb3A6ICdyZXBsYWNlUmVsYXRlZFJlY29yZCc7XG4gIHJlbGF0ZWRSZWNvcmRzOiBSZWNvcmRJZGVudGl0eVtdO1xufVxuXG5leHBvcnQgdHlwZSBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0ID1cbiAgfCBBZGRSZWNvcmRSZXF1ZXN0XG4gIHwgUmVtb3ZlUmVjb3JkUmVxdWVzdFxuICB8IFVwZGF0ZVJlY29yZFJlcXVlc3RcbiAgfCBBZGRUb1JlbGF0ZWRSZWNvcmRzUmVxdWVzdFxuICB8IFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc1JlcXVlc3RcbiAgfCBSZXBsYWNlUmVsYXRlZFJlY29yZFJlcXVlc3RcbiAgfCBSZXBsYWNlUmVsYXRlZFJlY29yZHNSZXF1ZXN0O1xuXG5leHBvcnQgdHlwZSBUcmFuc2Zvcm1SZXF1ZXN0UHJvY2Vzc29yUmVzcG9uc2UgPSBGdWxsUmVzcG9uc2U8XG4gIFJlY29yZE9wZXJhdGlvblJlc3VsdCxcbiAgSlNPTkFQSVJlc3BvbnNlLFxuICBSZWNvcmRPcGVyYXRpb25cbj47XG5cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNmb3JtUmVxdWVzdFByb2Nlc3NvciB7XG4gIChcbiAgICByZXF1ZXN0UHJvY2Vzc29yOiBKU09OQVBJUmVxdWVzdFByb2Nlc3NvcixcbiAgICByZXF1ZXN0OiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IFByb21pc2U8VHJhbnNmb3JtUmVxdWVzdFByb2Nlc3NvclJlc3BvbnNlPjtcbn1cblxuZXhwb3J0IGNvbnN0IFRyYW5zZm9ybVJlcXVlc3RQcm9jZXNzb3JzOiBEaWN0PFRyYW5zZm9ybVJlcXVlc3RQcm9jZXNzb3I+ID0ge1xuICBhc3luYyBhZGRSZWNvcmQoXG4gICAgcmVxdWVzdFByb2Nlc3NvcjogSlNPTkFQSVJlcXVlc3RQcm9jZXNzb3IsXG4gICAgcmVxdWVzdDogUmVjb3JkVHJhbnNmb3JtUmVxdWVzdFxuICApOiBQcm9taXNlPFRyYW5zZm9ybVJlcXVlc3RQcm9jZXNzb3JSZXNwb25zZT4ge1xuICAgIGNvbnN0IHsgcmVjb3JkIH0gPSByZXF1ZXN0IGFzIEFkZFJlY29yZFJlcXVlc3Q7XG4gICAgY29uc3Qgc2VyaWFsaXplciA9IHJlcXVlc3RQcm9jZXNzb3Iuc2VyaWFsaXplckZvcihcbiAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZURvY3VtZW50XG4gICAgKSBhcyBKU09OQVBJRG9jdW1lbnRTZXJpYWxpemVyO1xuICAgIGNvbnN0IHJlcXVlc3REb2MgPSBzZXJpYWxpemVyLnNlcmlhbGl6ZSh7XG4gICAgICBkYXRhOiByZWNvcmRcbiAgICB9KSBhcyBSZXNvdXJjZURvY3VtZW50O1xuICAgIGNvbnN0IHNldHRpbmdzID0ge1xuICAgICAgLi4ucmVxdWVzdFByb2Nlc3Nvci5idWlsZEZldGNoU2V0dGluZ3MocmVxdWVzdCksXG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGpzb246IHJlcXVlc3REb2NcbiAgICB9O1xuICAgIGNvbnN0IHVybCA9XG4gICAgICByZXF1ZXN0Lm9wdGlvbnM/LnVybCA/P1xuICAgICAgcmVxdWVzdFByb2Nlc3Nvci51cmxCdWlsZGVyLnJlc291cmNlVVJMKHJlY29yZC50eXBlKTtcblxuICAgIGNvbnN0IGRldGFpbHMgPSBhd2FpdCByZXF1ZXN0UHJvY2Vzc29yLmZldGNoKHVybCwgc2V0dGluZ3MpO1xuICAgIGNvbnN0IGRvY3VtZW50ID0gZGV0YWlscy5kb2N1bWVudCBhcyBSZXNvdXJjZURvY3VtZW50O1xuICAgIHJlcXVlc3RQcm9jZXNzb3IucHJlcHJvY2Vzc1Jlc3BvbnNlRG9jdW1lbnQoZG9jdW1lbnQsIHJlcXVlc3QpO1xuXG4gICAgY29uc3QgcmVjb3JkRG9jID0gc2VyaWFsaXplci5kZXNlcmlhbGl6ZShkb2N1bWVudCwge1xuICAgICAgcHJpbWFyeVJlY29yZDogcmVjb3JkXG4gICAgfSk7XG4gICAgcmV0dXJuIGhhbmRsZUNoYW5nZXMocmVjb3JkLCByZWNvcmREb2MsIGRldGFpbHMpO1xuICB9LFxuXG4gIGFzeW5jIHJlbW92ZVJlY29yZChcbiAgICByZXF1ZXN0UHJvY2Vzc29yOiBKU09OQVBJUmVxdWVzdFByb2Nlc3NvcixcbiAgICByZXF1ZXN0OiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IFByb21pc2U8VHJhbnNmb3JtUmVxdWVzdFByb2Nlc3NvclJlc3BvbnNlPiB7XG4gICAgY29uc3QgeyByZWNvcmQgfSA9IHJlcXVlc3QgYXMgUmVtb3ZlUmVjb3JkUmVxdWVzdDtcbiAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSByZWNvcmQ7XG4gICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICAuLi5yZXF1ZXN0UHJvY2Vzc29yLmJ1aWxkRmV0Y2hTZXR0aW5ncyhyZXF1ZXN0KSxcbiAgICAgIG1ldGhvZDogJ0RFTEVURSdcbiAgICB9O1xuICAgIGNvbnN0IHVybCA9XG4gICAgICByZXF1ZXN0Lm9wdGlvbnM/LnVybCA/PyByZXF1ZXN0UHJvY2Vzc29yLnVybEJ1aWxkZXIucmVzb3VyY2VVUkwodHlwZSwgaWQpO1xuXG4gICAgY29uc3QgZGV0YWlscyA9IGF3YWl0IHJlcXVlc3RQcm9jZXNzb3IuZmV0Y2godXJsLCBzZXR0aW5ncyk7XG4gICAgcmV0dXJuIHsgdHJhbnNmb3JtczogW10sIGRhdGE6IHJlY29yZCwgZGV0YWlscyB9O1xuICB9LFxuXG4gIGFzeW5jIHVwZGF0ZVJlY29yZChcbiAgICByZXF1ZXN0UHJvY2Vzc29yOiBKU09OQVBJUmVxdWVzdFByb2Nlc3NvcixcbiAgICByZXF1ZXN0OiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0XG4gICk6IFByb21pc2U8VHJhbnNmb3JtUmVxdWVzdFByb2Nlc3NvclJlc3BvbnNlPiB7XG4gICAgY29uc3QgeyByZWNvcmQgfSA9IHJlcXVlc3QgYXMgVXBkYXRlUmVjb3JkUmVxdWVzdDtcbiAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSByZWNvcmQ7XG4gICAgY29uc3Qgc2VyaWFsaXplciA9IHJlcXVlc3RQcm9jZXNzb3Iuc2VyaWFsaXplckZvcihcbiAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZURvY3VtZW50XG4gICAgKSBhcyBKU09OQVBJRG9jdW1lbnRTZXJpYWxpemVyO1xuICAgIGNvbnN0IHJlcXVlc3REb2MgPSBzZXJpYWxpemVyLnNlcmlhbGl6ZSh7XG4gICAgICBkYXRhOiByZWNvcmRcbiAgICB9KSBhcyBSZXNvdXJjZURvY3VtZW50O1xuICAgIGNvbnN0IHNldHRpbmdzID0ge1xuICAgICAgLi4ucmVxdWVzdFByb2Nlc3Nvci5idWlsZEZldGNoU2V0dGluZ3MocmVxdWVzdCksXG4gICAgICBtZXRob2Q6ICdQQVRDSCcsXG4gICAgICBqc29uOiByZXF1ZXN0RG9jXG4gICAgfTtcbiAgICBjb25zdCB1cmwgPVxuICAgICAgcmVxdWVzdC5vcHRpb25zPy51cmwgPz8gcmVxdWVzdFByb2Nlc3Nvci51cmxCdWlsZGVyLnJlc291cmNlVVJMKHR5cGUsIGlkKTtcblxuICAgIGNvbnN0IGRldGFpbHMgPSBhd2FpdCByZXF1ZXN0UHJvY2Vzc29yLmZldGNoKHVybCwgc2V0dGluZ3MpO1xuICAgIGNvbnN0IHsgZG9jdW1lbnQgfSA9IGRldGFpbHM7XG4gICAgaWYgKGRvY3VtZW50KSB7XG4gICAgICByZXF1ZXN0UHJvY2Vzc29yLnByZXByb2Nlc3NSZXNwb25zZURvY3VtZW50KGRvY3VtZW50LCByZXF1ZXN0KTtcbiAgICAgIGNvbnN0IHJlY29yZERvYyA9IHNlcmlhbGl6ZXIuZGVzZXJpYWxpemUoZG9jdW1lbnQsIHtcbiAgICAgICAgcHJpbWFyeVJlY29yZDogcmVjb3JkXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBoYW5kbGVDaGFuZ2VzKHJlY29yZCwgcmVjb3JkRG9jLCBkZXRhaWxzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHsgdHJhbnNmb3JtczogW10sIGRhdGE6IHJlY29yZCwgZGV0YWlscyB9O1xuICAgIH1cbiAgfSxcblxuICBhc3luYyBhZGRUb1JlbGF0ZWRSZWNvcmRzKFxuICAgIHJlcXVlc3RQcm9jZXNzb3I6IEpTT05BUElSZXF1ZXN0UHJvY2Vzc29yLFxuICAgIHJlcXVlc3Q6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogUHJvbWlzZTxUcmFuc2Zvcm1SZXF1ZXN0UHJvY2Vzc29yUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7XG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGVkUmVjb3Jkc1xuICAgIH0gPSByZXF1ZXN0IGFzIEFkZFRvUmVsYXRlZFJlY29yZHNSZXF1ZXN0O1xuICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IHJlY29yZDtcbiAgICBjb25zdCByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplciA9IHJlcXVlc3RQcm9jZXNzb3Iuc2VyaWFsaXplckZvcihcbiAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZUlkZW50aXR5XG4gICAgKSBhcyBKU09OQVBJUmVzb3VyY2VJZGVudGl0eVNlcmlhbGl6ZXI7XG4gICAgY29uc3QganNvbiA9IHtcbiAgICAgIGRhdGE6IHJlbGF0ZWRSZWNvcmRzLm1hcCgocikgPT4gcmVzb3VyY2VJZGVudGl0eVNlcmlhbGl6ZXIuc2VyaWFsaXplKHIpKVxuICAgIH07XG4gICAgY29uc3Qgc2V0dGluZ3MgPSB7XG4gICAgICAuLi5yZXF1ZXN0UHJvY2Vzc29yLmJ1aWxkRmV0Y2hTZXR0aW5ncyhyZXF1ZXN0KSxcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAganNvblxuICAgIH07XG4gICAgY29uc3QgdXJsID1cbiAgICAgIHJlcXVlc3Qub3B0aW9ucz8udXJsID8/XG4gICAgICByZXF1ZXN0UHJvY2Vzc29yLnVybEJ1aWxkZXIucmVzb3VyY2VSZWxhdGlvbnNoaXBVUkwoXG4gICAgICAgIHR5cGUsXG4gICAgICAgIGlkLFxuICAgICAgICByZWxhdGlvbnNoaXBcbiAgICAgICk7XG5cbiAgICBjb25zdCBkZXRhaWxzID0gYXdhaXQgcmVxdWVzdFByb2Nlc3Nvci5mZXRjaCh1cmwsIHNldHRpbmdzKTtcbiAgICByZXR1cm4geyB0cmFuc2Zvcm1zOiBbXSwgZGF0YTogcmVjb3JkLCBkZXRhaWxzIH07XG4gIH0sXG5cbiAgYXN5bmMgcmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzKFxuICAgIHJlcXVlc3RQcm9jZXNzb3I6IEpTT05BUElSZXF1ZXN0UHJvY2Vzc29yLFxuICAgIHJlcXVlc3Q6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogUHJvbWlzZTxUcmFuc2Zvcm1SZXF1ZXN0UHJvY2Vzc29yUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7XG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGVkUmVjb3Jkc1xuICAgIH0gPSByZXF1ZXN0IGFzIFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc1JlcXVlc3Q7XG4gICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gcmVjb3JkO1xuICAgIGNvbnN0IHJlc291cmNlSWRlbnRpdHlTZXJpYWxpemVyID0gcmVxdWVzdFByb2Nlc3Nvci5zZXJpYWxpemVyRm9yKFxuICAgICAgSlNPTkFQSVNlcmlhbGl6ZXJzLlJlc291cmNlSWRlbnRpdHlcbiAgICApIGFzIEpTT05BUElSZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplcjtcbiAgICBjb25zdCBqc29uID0ge1xuICAgICAgZGF0YTogcmVsYXRlZFJlY29yZHMubWFwKChyKSA9PiByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplci5zZXJpYWxpemUocikpXG4gICAgfTtcbiAgICBjb25zdCBzZXR0aW5ncyA9IHtcbiAgICAgIC4uLnJlcXVlc3RQcm9jZXNzb3IuYnVpbGRGZXRjaFNldHRpbmdzKHJlcXVlc3QpLFxuICAgICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICAgIGpzb25cbiAgICB9O1xuICAgIGNvbnN0IHVybCA9XG4gICAgICByZXF1ZXN0Lm9wdGlvbnM/LnVybCA/P1xuICAgICAgcmVxdWVzdFByb2Nlc3Nvci51cmxCdWlsZGVyLnJlc291cmNlUmVsYXRpb25zaGlwVVJMKFxuICAgICAgICB0eXBlLFxuICAgICAgICBpZCxcbiAgICAgICAgcmVsYXRpb25zaGlwXG4gICAgICApO1xuXG4gICAgY29uc3QgZGV0YWlscyA9IGF3YWl0IHJlcXVlc3RQcm9jZXNzb3IuZmV0Y2godXJsLCBzZXR0aW5ncyk7XG4gICAgcmV0dXJuIHsgdHJhbnNmb3JtczogW10sIGRhdGE6IHJlY29yZCwgZGV0YWlscyB9O1xuICB9LFxuXG4gIGFzeW5jIHJlcGxhY2VSZWxhdGVkUmVjb3JkKFxuICAgIHJlcXVlc3RQcm9jZXNzb3I6IEpTT05BUElSZXF1ZXN0UHJvY2Vzc29yLFxuICAgIHJlcXVlc3Q6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogUHJvbWlzZTxUcmFuc2Zvcm1SZXF1ZXN0UHJvY2Vzc29yUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7XG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkLFxuICAgICAgcmVjb3JkXG4gICAgfSA9IHJlcXVlc3QgYXMgUmVwbGFjZVJlbGF0ZWRSZWNvcmRSZXF1ZXN0O1xuICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IHJlY29yZDtcbiAgICBjb25zdCByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplciA9IHJlcXVlc3RQcm9jZXNzb3Iuc2VyaWFsaXplckZvcihcbiAgICAgIEpTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZUlkZW50aXR5XG4gICAgKSBhcyBKU09OQVBJUmVzb3VyY2VJZGVudGl0eVNlcmlhbGl6ZXI7XG4gICAgY29uc3QganNvbiA9IHtcbiAgICAgIGRhdGE6IHJlbGF0ZWRSZWNvcmRcbiAgICAgICAgPyByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplci5zZXJpYWxpemUocmVsYXRlZFJlY29yZClcbiAgICAgICAgOiBudWxsXG4gICAgfTtcbiAgICBjb25zdCBzZXR0aW5ncyA9IHtcbiAgICAgIC4uLnJlcXVlc3RQcm9jZXNzb3IuYnVpbGRGZXRjaFNldHRpbmdzKHJlcXVlc3QpLFxuICAgICAgbWV0aG9kOiAnUEFUQ0gnLFxuICAgICAganNvblxuICAgIH07XG4gICAgY29uc3QgdXJsID1cbiAgICAgIHJlcXVlc3Qub3B0aW9ucz8udXJsID8/XG4gICAgICByZXF1ZXN0UHJvY2Vzc29yLnVybEJ1aWxkZXIucmVzb3VyY2VSZWxhdGlvbnNoaXBVUkwoXG4gICAgICAgIHR5cGUsXG4gICAgICAgIGlkLFxuICAgICAgICByZWxhdGlvbnNoaXBcbiAgICAgICk7XG5cbiAgICBjb25zdCBkZXRhaWxzID0gYXdhaXQgcmVxdWVzdFByb2Nlc3Nvci5mZXRjaCh1cmwsIHNldHRpbmdzKTtcbiAgICByZXR1cm4geyB0cmFuc2Zvcm1zOiBbXSwgZGF0YTogcmVjb3JkLCBkZXRhaWxzIH07XG4gIH0sXG5cbiAgYXN5bmMgcmVwbGFjZVJlbGF0ZWRSZWNvcmRzKFxuICAgIHJlcXVlc3RQcm9jZXNzb3I6IEpTT05BUElSZXF1ZXN0UHJvY2Vzc29yLFxuICAgIHJlcXVlc3Q6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3RcbiAgKTogUHJvbWlzZTxUcmFuc2Zvcm1SZXF1ZXN0UHJvY2Vzc29yUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7XG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkcyxcbiAgICAgIHJlY29yZFxuICAgIH0gPSByZXF1ZXN0IGFzIFJlcGxhY2VSZWxhdGVkUmVjb3Jkc1JlcXVlc3Q7XG4gICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gcmVjb3JkO1xuICAgIGNvbnN0IHJlc291cmNlSWRlbnRpdHlTZXJpYWxpemVyID0gcmVxdWVzdFByb2Nlc3Nvci5zZXJpYWxpemVyRm9yKFxuICAgICAgSlNPTkFQSVNlcmlhbGl6ZXJzLlJlc291cmNlSWRlbnRpdHlcbiAgICApIGFzIEpTT05BUElSZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplcjtcbiAgICBjb25zdCBqc29uID0ge1xuICAgICAgZGF0YTogcmVsYXRlZFJlY29yZHMubWFwKChyKSA9PiByZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplci5zZXJpYWxpemUocikpXG4gICAgfTtcbiAgICBjb25zdCBzZXR0aW5ncyA9IHtcbiAgICAgIC4uLnJlcXVlc3RQcm9jZXNzb3IuYnVpbGRGZXRjaFNldHRpbmdzKHJlcXVlc3QpLFxuICAgICAgbWV0aG9kOiAnUEFUQ0gnLFxuICAgICAganNvblxuICAgIH07XG4gICAgY29uc3QgdXJsID1cbiAgICAgIHJlcXVlc3Qub3B0aW9ucz8udXJsID8/XG4gICAgICByZXF1ZXN0UHJvY2Vzc29yLnVybEJ1aWxkZXIucmVzb3VyY2VSZWxhdGlvbnNoaXBVUkwoXG4gICAgICAgIHR5cGUsXG4gICAgICAgIGlkLFxuICAgICAgICByZWxhdGlvbnNoaXBcbiAgICAgICk7XG5cbiAgICBjb25zdCBkZXRhaWxzID0gYXdhaXQgcmVxdWVzdFByb2Nlc3Nvci5mZXRjaCh1cmwsIHNldHRpbmdzKTtcbiAgICByZXR1cm4geyB0cmFuc2Zvcm1zOiBbXSwgZGF0YTogcmVjb3JkLCBkZXRhaWxzIH07XG4gIH1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc2Zvcm1SZXF1ZXN0cyhcbiAgcmVxdWVzdFByb2Nlc3NvcjogSlNPTkFQSVJlcXVlc3RQcm9jZXNzb3IsXG4gIHRyYW5zZm9ybTogUmVjb3JkVHJhbnNmb3JtXG4pOiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0W10ge1xuICBjb25zdCByZXF1ZXN0czogUmVjb3JkVHJhbnNmb3JtUmVxdWVzdFtdID0gW107XG4gIGxldCBwcmV2UmVxdWVzdDogUmVjb3JkVHJhbnNmb3JtUmVxdWVzdCB8IG51bGwgPSBudWxsO1xuXG4gIGZvciAobGV0IG9wZXJhdGlvbiBvZiB0b0FycmF5KHRyYW5zZm9ybS5vcGVyYXRpb25zKSkge1xuICAgIGxldCByZXF1ZXN0O1xuICAgIGxldCBuZXdSZXF1ZXN0TmVlZGVkID0gdHJ1ZTtcblxuICAgIGlmIChcbiAgICAgIHByZXZSZXF1ZXN0ICYmXG4gICAgICBlcXVhbFJlY29yZElkZW50aXRpZXMocHJldlJlcXVlc3QucmVjb3JkLCBvcGVyYXRpb24ucmVjb3JkKVxuICAgICkge1xuICAgICAgaWYgKG9wZXJhdGlvbi5vcCA9PT0gJ3JlbW92ZVJlY29yZCcpIHtcbiAgICAgICAgbmV3UmVxdWVzdE5lZWRlZCA9IGZhbHNlO1xuXG4gICAgICAgIGlmIChwcmV2UmVxdWVzdC5vcCAhPT0gJ3JlbW92ZVJlY29yZCcpIHtcbiAgICAgICAgICBwcmV2UmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgcmVxdWVzdHMucG9wKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHByZXZSZXF1ZXN0Lm9wID09PSAnYWRkUmVjb3JkJyB8fFxuICAgICAgICBwcmV2UmVxdWVzdC5vcCA9PT0gJ3VwZGF0ZVJlY29yZCdcbiAgICAgICkge1xuICAgICAgICBpZiAob3BlcmF0aW9uLm9wID09PSAncmVwbGFjZUF0dHJpYnV0ZScpIHtcbiAgICAgICAgICBuZXdSZXF1ZXN0TmVlZGVkID0gZmFsc2U7XG4gICAgICAgICAgcmVwbGFjZVJlY29yZEF0dHJpYnV0ZShcbiAgICAgICAgICAgIHByZXZSZXF1ZXN0LnJlY29yZCxcbiAgICAgICAgICAgIG9wZXJhdGlvbi5hdHRyaWJ1dGUsXG4gICAgICAgICAgICBvcGVyYXRpb24udmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKG9wZXJhdGlvbi5vcCA9PT0gJ3JlcGxhY2VSZWxhdGVkUmVjb3JkJykge1xuICAgICAgICAgIG5ld1JlcXVlc3ROZWVkZWQgPSBmYWxzZTtcbiAgICAgICAgICByZXBsYWNlUmVjb3JkSGFzT25lKFxuICAgICAgICAgICAgcHJldlJlcXVlc3QucmVjb3JkLFxuICAgICAgICAgICAgb3BlcmF0aW9uLnJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGVkUmVjb3JkIGFzIFJlY29yZElkZW50aXR5XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24ub3AgPT09ICdyZXBsYWNlUmVsYXRlZFJlY29yZHMnKSB7XG4gICAgICAgICAgbmV3UmVxdWVzdE5lZWRlZCA9IGZhbHNlO1xuICAgICAgICAgIHJlcGxhY2VSZWNvcmRIYXNNYW55KFxuICAgICAgICAgICAgcHJldlJlcXVlc3QucmVjb3JkLFxuICAgICAgICAgICAgb3BlcmF0aW9uLnJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGVkUmVjb3Jkc1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHByZXZSZXF1ZXN0Lm9wID09PSAnYWRkVG9SZWxhdGVkUmVjb3JkcycgJiZcbiAgICAgICAgb3BlcmF0aW9uLm9wID09PSAnYWRkVG9SZWxhdGVkUmVjb3JkcycgJiZcbiAgICAgICAgKHByZXZSZXF1ZXN0IGFzIEFkZFRvUmVsYXRlZFJlY29yZHNSZXF1ZXN0KS5yZWxhdGlvbnNoaXAgPT09XG4gICAgICAgICAgb3BlcmF0aW9uLnJlbGF0aW9uc2hpcFxuICAgICAgKSB7XG4gICAgICAgIG5ld1JlcXVlc3ROZWVkZWQgPSBmYWxzZTtcbiAgICAgICAgKHByZXZSZXF1ZXN0IGFzIEFkZFRvUmVsYXRlZFJlY29yZHNSZXF1ZXN0KS5yZWxhdGVkUmVjb3Jkcy5wdXNoKFxuICAgICAgICAgIGNsb25lUmVjb3JkSWRlbnRpdHkob3BlcmF0aW9uLnJlbGF0ZWRSZWNvcmQpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBwcmV2UmVxdWVzdC5vcCA9PT0gJ3JlbW92ZUZyb21SZWxhdGVkUmVjb3JkcycgJiZcbiAgICAgICAgb3BlcmF0aW9uLm9wID09PSAncmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzJyAmJlxuICAgICAgICAocHJldlJlcXVlc3QgYXMgUmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzUmVxdWVzdCkucmVsYXRpb25zaGlwID09PVxuICAgICAgICAgIG9wZXJhdGlvbi5yZWxhdGlvbnNoaXBcbiAgICAgICkge1xuICAgICAgICBuZXdSZXF1ZXN0TmVlZGVkID0gZmFsc2U7XG4gICAgICAgIChwcmV2UmVxdWVzdCBhcyBSZW1vdmVGcm9tUmVsYXRlZFJlY29yZHNSZXF1ZXN0KS5yZWxhdGVkUmVjb3Jkcy5wdXNoKFxuICAgICAgICAgIGNsb25lUmVjb3JkSWRlbnRpdHkob3BlcmF0aW9uLnJlbGF0ZWRSZWNvcmQpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG5ld1JlcXVlc3ROZWVkZWQpIHtcbiAgICAgIHJlcXVlc3QgPSBPcGVyYXRpb25Ub1JlcXVlc3RNYXBbb3BlcmF0aW9uLm9wXShvcGVyYXRpb24pO1xuICAgIH1cblxuICAgIGlmIChyZXF1ZXN0KSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gcmVxdWVzdFByb2Nlc3Nvci5tZXJnZVJlcXVlc3RPcHRpb25zKFtcbiAgICAgICAgcmVxdWVzdC5vcHRpb25zLFxuICAgICAgICB0cmFuc2Zvcm0ub3B0aW9ucyxcbiAgICAgICAgb3BlcmF0aW9uLm9wdGlvbnNcbiAgICAgIF0pO1xuICAgICAgaWYgKG9wdGlvbnMpIHJlcXVlc3Qub3B0aW9ucyA9IG9wdGlvbnM7XG5cbiAgICAgIHJlcXVlc3RzLnB1c2gocmVxdWVzdCk7XG4gICAgICBwcmV2UmVxdWVzdCA9IHJlcXVlc3Q7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcXVlc3RzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvblRvUmVxdWVzdENvbnZlcnRlciB7XG4gIChvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbik6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3Q7XG59XG5cbmNvbnN0IE9wZXJhdGlvblRvUmVxdWVzdE1hcDogRGljdDxPcGVyYXRpb25Ub1JlcXVlc3RDb252ZXJ0ZXI+ID0ge1xuICBhZGRSZWNvcmQob3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24pOiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0IHtcbiAgICBjb25zdCBvcCA9IG9wZXJhdGlvbiBhcyBBZGRSZWNvcmRPcGVyYXRpb247XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wOiAnYWRkUmVjb3JkJyxcbiAgICAgIHJlY29yZDogY2xvbmUob3AucmVjb3JkKVxuICAgIH07XG4gIH0sXG5cbiAgcmVtb3ZlUmVjb3JkKG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uKTogUmVjb3JkVHJhbnNmb3JtUmVxdWVzdCB7XG4gICAgY29uc3Qgb3AgPSBvcGVyYXRpb24gYXMgUmVtb3ZlUmVjb3JkT3BlcmF0aW9uO1xuICAgIHJldHVybiB7XG4gICAgICBvcDogJ3JlbW92ZVJlY29yZCcsXG4gICAgICByZWNvcmQ6IGNsb25lUmVjb3JkSWRlbnRpdHkob3AucmVjb3JkKVxuICAgIH07XG4gIH0sXG5cbiAgcmVwbGFjZUF0dHJpYnV0ZShvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbik6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3Qge1xuICAgIGNvbnN0IG9wID0gb3BlcmF0aW9uIGFzIFJlcGxhY2VBdHRyaWJ1dGVPcGVyYXRpb247XG4gICAgY29uc3QgcmVjb3JkID0gY2xvbmVSZWNvcmRJZGVudGl0eShvcC5yZWNvcmQpO1xuXG4gICAgcmVwbGFjZVJlY29yZEF0dHJpYnV0ZShyZWNvcmQsIG9wLmF0dHJpYnV0ZSwgb3AudmFsdWUpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9wOiAndXBkYXRlUmVjb3JkJyxcbiAgICAgIHJlY29yZFxuICAgIH07XG4gIH0sXG5cbiAgdXBkYXRlUmVjb3JkKG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uKTogUmVjb3JkVHJhbnNmb3JtUmVxdWVzdCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wOiAndXBkYXRlUmVjb3JkJyxcbiAgICAgIHJlY29yZDogY2xvbmUob3BlcmF0aW9uLnJlY29yZClcbiAgICB9O1xuICB9LFxuXG4gIGFkZFRvUmVsYXRlZFJlY29yZHMob3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24pOiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0IHtcbiAgICBjb25zdCB7XG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkXG4gICAgfSA9IG9wZXJhdGlvbiBhcyBBZGRUb1JlbGF0ZWRSZWNvcmRzT3BlcmF0aW9uO1xuICAgIHJldHVybiB7XG4gICAgICBvcDogJ2FkZFRvUmVsYXRlZFJlY29yZHMnLFxuICAgICAgcmVjb3JkOiBjbG9uZVJlY29yZElkZW50aXR5KHJlY29yZCksXG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkczogW2Nsb25lUmVjb3JkSWRlbnRpdHkocmVsYXRlZFJlY29yZCldXG4gICAgfSBhcyBBZGRUb1JlbGF0ZWRSZWNvcmRzUmVxdWVzdDtcbiAgfSxcblxuICByZW1vdmVGcm9tUmVsYXRlZFJlY29yZHMob3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24pOiBSZWNvcmRUcmFuc2Zvcm1SZXF1ZXN0IHtcbiAgICBjb25zdCB7XG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3JkXG4gICAgfSA9IG9wZXJhdGlvbiBhcyBSZW1vdmVGcm9tUmVsYXRlZFJlY29yZHNPcGVyYXRpb247XG4gICAgcmV0dXJuIHtcbiAgICAgIG9wOiAncmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzJyxcbiAgICAgIHJlY29yZDogY2xvbmVSZWNvcmRJZGVudGl0eShyZWNvcmQpLFxuICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgcmVsYXRlZFJlY29yZHM6IFtjbG9uZVJlY29yZElkZW50aXR5KHJlbGF0ZWRSZWNvcmQpXVxuICAgIH0gYXMgUmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzUmVxdWVzdDtcbiAgfSxcblxuICByZXBsYWNlUmVsYXRlZFJlY29yZChvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbik6IFJlY29yZFRyYW5zZm9ybVJlcXVlc3Qge1xuICAgIGNvbnN0IHJlY29yZCA9IGNsb25lUmVjb3JkSWRlbnRpdHkob3BlcmF0aW9uLnJlY29yZCk7XG4gICAgY29uc3Qge1xuICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgcmVsYXRlZFJlY29yZFxuICAgIH0gPSBvcGVyYXRpb24gYXMgUmVwbGFjZVJlbGF0ZWRSZWNvcmRPcGVyYXRpb247XG5cbiAgICBkZWVwU2V0KHJlY29yZCwgWydyZWxhdGlvbnNoaXBzJywgcmVsYXRpb25zaGlwLCAnZGF0YSddLCByZWxhdGVkUmVjb3JkKTtcblxuICAgIHJldHVybiB7XG4gICAgICBvcDogJ3VwZGF0ZVJlY29yZCcsXG4gICAgICByZWNvcmRcbiAgICB9IGFzIFVwZGF0ZVJlY29yZFJlcXVlc3Q7XG4gIH0sXG5cbiAgcmVwbGFjZVJlbGF0ZWRSZWNvcmRzKG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uKTogUmVjb3JkVHJhbnNmb3JtUmVxdWVzdCB7XG4gICAgY29uc3QgcmVjb3JkID0gY2xvbmVSZWNvcmRJZGVudGl0eShvcGVyYXRpb24ucmVjb3JkKTtcbiAgICBjb25zdCB7XG4gICAgICByZWxhdGlvbnNoaXAsXG4gICAgICByZWxhdGVkUmVjb3Jkc1xuICAgIH0gPSBvcGVyYXRpb24gYXMgUmVwbGFjZVJlbGF0ZWRSZWNvcmRzT3BlcmF0aW9uO1xuXG4gICAgZGVlcFNldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSwgcmVsYXRlZFJlY29yZHMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9wOiAndXBkYXRlUmVjb3JkJyxcbiAgICAgIHJlY29yZFxuICAgIH0gYXMgVXBkYXRlUmVjb3JkUmVxdWVzdDtcbiAgfVxufTtcblxuZnVuY3Rpb24gcmVwbGFjZVJlY29yZEF0dHJpYnV0ZShcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgYXR0cmlidXRlOiBzdHJpbmcsXG4gIHZhbHVlOiBhbnlcbikge1xuICBkZWVwU2V0KHJlY29yZCwgWydhdHRyaWJ1dGVzJywgYXR0cmlidXRlXSwgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiByZXBsYWNlUmVjb3JkSGFzT25lKFxuICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHlcbikge1xuICBkZWVwU2V0KFxuICAgIHJlY29yZCxcbiAgICBbJ3JlbGF0aW9uc2hpcHMnLCByZWxhdGlvbnNoaXAsICdkYXRhJ10sXG4gICAgcmVsYXRlZFJlY29yZCA/IGNsb25lUmVjb3JkSWRlbnRpdHkocmVsYXRlZFJlY29yZCkgOiBudWxsXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlcGxhY2VSZWNvcmRIYXNNYW55KFxuICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZHM6IFJlY29yZElkZW50aXR5W11cbikge1xuICBkZWVwU2V0KFxuICAgIHJlY29yZCxcbiAgICBbJ3JlbGF0aW9uc2hpcHMnLCByZWxhdGlvbnNoaXAsICdkYXRhJ10sXG4gICAgcmVsYXRlZFJlY29yZHMubWFwKChyKSA9PiBjbG9uZVJlY29yZElkZW50aXR5KHIpKVxuICApO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVDaGFuZ2VzKFxuICByZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLFxuICByZWNvcmREb2M6IFJlY29yZERvY3VtZW50LFxuICBkZXRhaWxzOiBKU09OQVBJUmVzcG9uc2Vcbik6IFRyYW5zZm9ybVJlcXVlc3RQcm9jZXNzb3JSZXNwb25zZSB7XG4gIGxldCB1cGRhdGVkUmVjb3JkOiBJbml0aWFsaXplZFJlY29yZCA9IHJlY29yZERvYy5kYXRhIGFzIEluaXRpYWxpemVkUmVjb3JkO1xuICBsZXQgdHJhbnNmb3JtczogUmVjb3JkVHJhbnNmb3JtW10gPSBbXTtcbiAgbGV0IHVwZGF0ZU9wcyA9IHJlY29yZERpZmZzKHJlY29yZCwgdXBkYXRlZFJlY29yZCk7XG4gIGlmICh1cGRhdGVPcHMubGVuZ3RoID4gMCkge1xuICAgIHRyYW5zZm9ybXMucHVzaChidWlsZFRyYW5zZm9ybSh1cGRhdGVPcHMpKTtcbiAgfVxuICBpZiAocmVjb3JkRG9jLmluY2x1ZGVkICYmIHJlY29yZERvYy5pbmNsdWRlZC5sZW5ndGggPiAwKSB7XG4gICAgbGV0IGluY2x1ZGVkT3BzID0gcmVjb3JkRG9jLmluY2x1ZGVkLm1hcCgocmVjb3JkKSA9PiB7XG4gICAgICByZXR1cm4geyBvcDogJ3VwZGF0ZVJlY29yZCcsIHJlY29yZCB9IGFzIFJlY29yZE9wZXJhdGlvbjtcbiAgICB9KTtcbiAgICB0cmFuc2Zvcm1zLnB1c2goYnVpbGRUcmFuc2Zvcm08UmVjb3JkT3BlcmF0aW9uPihpbmNsdWRlZE9wcykpO1xuICB9XG4gIHJldHVybiB7IHRyYW5zZm9ybXMsIGRhdGE6IHVwZGF0ZWRSZWNvcmQsIGRldGFpbHMgfTtcbn1cbiJdfQ==