UNPKG

pretur.sync

Version:

Front-end back-end communication infrastructure

305 lines 42.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var lodash_1 = require("lodash"); var fetch_1 = require("./fetch"); function buildRequester(endPoint, options) { var uid = 0; function uniqueId() { return ++uid; } var _a = options.wait, wait = _a === void 0 ? 200 : _a, _b = options.maxWait, maxWait = _b === void 0 ? 2000 : _b, cancelError = options.cancelError, networkError = options.networkError; var currBatch = undefined; var queue = []; var requestRunning = false; var congested = false; var debouncedSend = lodash_1.debounce(send, wait, { maxWait: maxWait }); function send() { return tslib_1.__awaiter(this, void 0, void 0, function () { var pendingQueue, response, _loop_1, _i, pendingQueue_1, item, error_1, _a, pendingQueue_2, item; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: if (requestRunning) { congested = true; return [2 /*return*/]; } pendingQueue = lodash_1.compact(queue); queue = []; requestRunning = true; _b.label = 1; case 1: _b.trys.push([1, 3, 4, 5]); return [4 /*yield*/, fetch_1.fetch({ body: pendingQueue.map(function (item) { return item.request; }), json: true, method: 'POST', url: endPoint, })]; case 2: response = _b.sent(); _loop_1 = function (item) { var target = response.body.find(function (res) { return res.requestId === item.request.requestId; }); if (!target) { item.resolve({ errors: networkError({ ok: false, code: 0, text: 'UNKNOWN' }, new Error("Request's response was not found.")), requestId: item.request.requestId, type: item.request.type, }); } else { item.resolve(target); } }; for (_i = 0, pendingQueue_1 = pendingQueue; _i < pendingQueue_1.length; _i++) { item = pendingQueue_1[_i]; _loop_1(item); } return [3 /*break*/, 5]; case 3: error_1 = _b.sent(); for (_a = 0, pendingQueue_2 = pendingQueue; _a < pendingQueue_2.length; _a++) { item = pendingQueue_2[_a]; item.resolve({ errors: networkError({ ok: false, code: 0, text: 'UNKNOWN' }, error_1), requestId: item.request.requestId, type: item.request.type, }); } return [3 /*break*/, 5]; case 4: requestRunning = false; if (congested) { congested = false; debouncedSend(); } return [7 /*endfinally*/]; case 5: return [2 /*return*/]; } }); }); } function select(scope, model, query) { return new Promise(function (resolve) { var requestId = uniqueId(); var request = { scope: scope, model: model, query: query, requestId: requestId, type: 'select' }; var item = { request: request, resolve: function (_a) { var _ = _a.requestId, response = tslib_1.__rest(_a, ["requestId"]); return resolve(response); }, cancel: function () { return resolve({ count: 0, data: [], errors: cancelError(request), type: 'select' }); }, }; queue.push(item); debouncedSend(); }); } function operate(name, data) { return new Promise(function (resolve) { var requestId = uniqueId(); var request = { data: data, name: name, requestId: requestId, type: 'operate' }; var item = { request: request, resolve: function (_a) { var _ = _a.requestId, response = tslib_1.__rest(_a, ["requestId"]); return resolve(response); }, cancel: function () { resolve({ name: name, errors: cancelError(request), type: 'operate' }); }, }; queue.push(item); debouncedSend(); }); } function insert(scopeOrOpts, model, data) { return new Promise(function (resolve) { var requestId = uniqueId(); var request = { action: 'insert', data: typeof scopeOrOpts === 'string' ? data || {} : scopeOrOpts.data, scope: typeof scopeOrOpts === 'string' ? scopeOrOpts : scopeOrOpts.scope, model: typeof scopeOrOpts === 'string' ? model : scopeOrOpts.model, requestId: requestId, type: 'mutate', }; var item = { request: request, resolve: function (_a) { var _ = _a.requestId, response = tslib_1.__rest(_a, ["requestId"]); return resolve(response); }, cancel: function () { return resolve({ action: 'insert', errors: cancelError(request), type: 'mutate' }); }, }; if (currBatch) { currBatch.queue.push(item); } else { queue.push(item); debouncedSend(); } }); } function update(scopeOrOpts, model, data) { return new Promise(function (resolve) { var requestId = uniqueId(); var request = { action: 'update', data: typeof scopeOrOpts === 'string' ? data || {} : scopeOrOpts.data, scope: typeof scopeOrOpts === 'string' ? scopeOrOpts : scopeOrOpts.scope, model: typeof scopeOrOpts === 'string' ? model : scopeOrOpts.model, requestId: requestId, type: 'mutate', }; var item = { request: request, resolve: function (_a) { var _ = _a.requestId, response = tslib_1.__rest(_a, ["requestId"]); return resolve(response); }, cancel: function () { return resolve({ action: 'update', errors: cancelError(request), type: 'mutate' }); }, }; if (currBatch) { currBatch.queue.push(item); } else { queue.push(item); debouncedSend(); } }); } function remove(scopeOrOpts, model, identifiers) { return new Promise(function (resolve) { var requestId = uniqueId(); var request = { action: 'remove', identifiers: typeof scopeOrOpts === 'string' ? identifiers || {} : scopeOrOpts.identifiers, scope: typeof scopeOrOpts === 'string' ? scopeOrOpts : scopeOrOpts.scope, model: typeof scopeOrOpts === 'string' ? model : scopeOrOpts.model, requestId: requestId, type: 'mutate', }; var item = { request: request, resolve: function (_a) { var _ = _a.requestId, response = tslib_1.__rest(_a, ["requestId"]); return resolve(response); }, cancel: function () { return resolve({ action: 'remove', errors: cancelError(request), type: 'mutate' }); }, }; if (currBatch) { currBatch.queue.push(item); } else { queue.push(item); debouncedSend(); } }); } function validate(name, data) { return new Promise(function (resolve) { var requestId = uniqueId(); var request = { data: data, name: name, requestId: requestId, type: 'validate' }; var item = { request: request, resolve: function (_a) { var _ = _a.requestId, response = tslib_1.__rest(_a, ["requestId"]); return resolve(response); }, cancel: function () { return resolve({ name: name, errors: cancelError(request), type: 'validate' }); }, }; queue.push(item); debouncedSend(); }); } function batchMutateStart() { if (!currBatch) { currBatch = { queue: [], requestId: uniqueId(), }; } } function batchMutateEnd() { if (currBatch) { var prevBatch_1 = currBatch; currBatch = undefined; var request = { queue: prevBatch_1.queue.map(function (i) { return i.request; }), requestId: prevBatch_1.requestId, type: 'batchMutate', }; var item = { request: request, resolve: function (_a) { var batchQueue = _a.queue, errors = _a.errors; var _loop_2 = function (action, requestId, type, resolve) { var target = batchQueue.find(function (res) { return res.requestId === requestId; }); if (errors.length > 0) { resolve({ action: action, errors: errors, requestId: requestId, type: type }); } else if (!target) { resolve({ action: action, errors: networkError({ ok: false, code: 0, text: 'UNKNOWN' }, new Error("Request's response was not found.")), requestId: requestId, type: type, }); } else { resolve(target); } }; for (var _i = 0, _b = prevBatch_1.queue; _i < _b.length; _i++) { var _c = _b[_i], _d = _c.request, action = _d.action, requestId = _d.requestId, type = _d.type, resolve = _c.resolve; _loop_2(action, requestId, type, resolve); } }, cancel: function () { for (var _i = 0, _a = prevBatch_1.queue; _i < _a.length; _i++) { var batchItem = _a[_i]; batchItem.cancel(); } }, }; queue.push(item); debouncedSend(); } } function cancel() { congested = false; debouncedSend.cancel(); queue.forEach(function (item) { return item.cancel(); }); queue = []; if (currBatch) { currBatch.queue.forEach(function (item) { return item.cancel(); }); currBatch = undefined; } } function flush() { if (currBatch) { batchMutateEnd(); } if (!requestRunning) { debouncedSend.flush(); } else { congested = true; } } return { batchMutateEnd: batchMutateEnd, batchMutateStart: batchMutateStart, cancel: cancel, flush: flush, insert: insert, operate: operate, remove: remove, select: select, update: update, validate: validate, }; } exports.buildRequester = buildRequester; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlcXVlc3Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpQ0FBMkM7QUFFM0MsaUNBQTZDO0FBNkY3Qyx3QkFBK0IsUUFBZ0IsRUFBRSxPQUE4QjtJQUM3RSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDWjtRQUNFLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQztJQUNmLENBQUM7SUFFTyxJQUFBLGlCQUFVLEVBQVYsK0JBQVUsRUFBRSxvQkFBYyxFQUFkLG1DQUFjLEVBQUUsaUNBQVcsRUFBRSxtQ0FBWSxDQUFhO0lBRTFFLElBQUksU0FBUyxHQUFxQyxTQUFTLENBQUM7SUFFNUQsSUFBSSxLQUFLLEdBQWlDLEVBQUUsQ0FBQztJQUM3QyxJQUFJLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFDM0IsSUFBSSxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBRXRCLElBQU0sYUFBYSxHQUFHLGlCQUFRLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLE9BQU8sU0FBQSxFQUFFLENBQUMsQ0FBQztJQUV4RDs7Ozs7O3dCQUNFLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7NEJBQ25CLFNBQVMsR0FBRyxJQUFJLENBQUM7NEJBQ2pCLE1BQU0sZ0JBQUM7d0JBQ1QsQ0FBQzt3QkFFSyxZQUFZLEdBQUcsZ0JBQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDcEMsS0FBSyxHQUFHLEVBQUUsQ0FBQzt3QkFDWCxjQUFjLEdBQUcsSUFBSSxDQUFDOzs7O3dCQUdILHFCQUFNLGFBQUssQ0FBYTtnQ0FDdkMsSUFBSSxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsVUFBQSxJQUFJLElBQUksT0FBQSxJQUFJLENBQUMsT0FBTyxFQUFaLENBQVksQ0FBQztnQ0FDNUMsSUFBSSxFQUFFLElBQUk7Z0NBQ1YsTUFBTSxFQUFFLE1BQU07Z0NBQ2QsR0FBRyxFQUFF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QUM7SUFFRCxNQUFNLENBQUM7UUFDTCxjQUFjLGdCQUFBO1FBQ2QsZ0JBQWdCLGtCQUFBO1FBQ2hCLE1BQU0sUUFBQTtRQUNOLEtBQUssT0FBQTtRQUNMLE1BQU0sUUFBQTtRQUNOLE9BQU8sU0FBQTtRQUNQLE1BQU0sUUFBQTtRQUNOLE1BQU0sUUFBQTtRQUNOLE1BQU0sUUFBQTtRQUNOLFFBQVEsVUFBQTtLQUNULENBQUM7QUFDSixDQUFDO0FBOVRELHdDQThUQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNwZWNUeXBlLCBNb2RlbCwgQW55U3BlYyB9IGZyb20gJ3ByZXR1ci5zcGVjJztcclxuaW1wb3J0IHsgQnVuZGxlIH0gZnJvbSAncHJldHVyLmkxOG4nO1xyXG5pbXBvcnQgeyBkZWJvdW5jZSwgY29tcGFjdCB9IGZyb20gJ2xvZGFzaCc7XHJcbmltcG9ydCB7IFF1ZXJ5IH0gZnJvbSAnLi9xdWVyeSc7XHJcbmltcG9ydCB7IGZldGNoLCBGZXRjaFN0YXR1cyB9IGZyb20gJy4vZmV0Y2gnO1xyXG5pbXBvcnQge1xyXG4gIFNlbGVjdFJlcXVlc3QsXHJcbiAgT3BlcmF0ZVJlcXVlc3QsXHJcbiAgTXV0YXRlUmVxdWVzdCxcclxuICBWYWxpZGF0ZVJlcXVlc3QsXHJcbiAgQmF0Y2hNdXRhdGVSZXF1ZXN0LFxyXG4gIFJlcXVlc3QsXHJcbn0gZnJvbSAnLi9yZXF1ZXN0JztcclxuaW1wb3J0IHsgU2VsZWN0UmVzdWx0LCBPcGVyYXRlUmVzdWx0LCBNdXRhdGVSZXN1bHQsIFZhbGlkYXRlUmVzdWx0IH0gZnJvbSAnLi9yZXN1bHQnO1xyXG5pbXBvcnQge1xyXG4gIFJlc3BvbnNlLFxyXG4gIFNlbGVjdFJlc3BvbnNlLFxyXG4gIE9wZXJhdGVSZXNwb25zZSxcclxuICBNdXRhdGVSZXNwb25zZSxcclxuICBWYWxpZGF0ZVJlc3BvbnNlLFxyXG4gIEJhdGNoTXV0YXRlUmVzcG9uc2UsXHJcbn0gZnJvbSAnLi9yZXNwb25zZSc7XHJcblxyXG5leHBvcnQgdHlwZSBJbnNlcnRPcHRpb25zPFQgZXh0ZW5kcyBTcGVjVHlwZT4gPSB7XHJcbiAgZGF0YTogUGFydGlhbDxNb2RlbDxUPj47XHJcbiAgc2NvcGU6IHN0cmluZyxcclxuICBtb2RlbDogVFsnbmFtZSddO1xyXG59O1xyXG5cclxuZXhwb3J0IHR5cGUgVXBkYXRlT3B0aW9uczxUIGV4dGVuZHMgU3BlY1R5cGU+ID0ge1xyXG4gIGRhdGE6IFBhcnRpYWw8VFsnZmllbGRzJ10+O1xyXG4gIHNjb3BlOiBzdHJpbmcsXHJcbiAgbW9kZWw6IFRbJ25hbWUnXTtcclxufTtcclxuXHJcbmV4cG9ydCB0eXBlIFJlbW92ZU9wdGlvbnM8VCBleHRlbmRzIFNwZWNUeXBlPiA9IHtcclxuICBpZGVudGlmaWVyczogUGFydGlhbDxUWydmaWVsZHMnXT47XHJcbiAgc2NvcGU6IHN0cmluZyxcclxuICBtb2RlbDogVFsnbmFtZSddO1xyXG59O1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0ZXIge1xyXG4gIHNlbGVjdDxUIGV4dGVuZHMgU3BlY1R5cGU+KFxyXG4gICAgc2NvcGU6IHN0cmluZyxcclxuICAgIG1vZGVsOiBUWyduYW1lJ10sXHJcbiAgICBxdWVyeTogUXVlcnk8VD4sXHJcbiAgKTogUHJvbWlzZTxTZWxlY3RSZXN1bHQ8VD4+O1xyXG4gIG9wZXJhdGU8VERhdGEsIFRSZXN1bHQ+KG5hbWU6IHN0cmluZywgZGF0YT86IFREYXRhKTogUHJvbWlzZTxPcGVyYXRlUmVzdWx0PFRSZXN1bHQ+PjtcclxuICBpbnNlcnQ8VCBleHRlbmRzIFNwZWNUeXBlPihvcHRpb25zOiBJbnNlcnRPcHRpb25zPFQ+KTogUHJvbWlzZTxNdXRhdGVSZXN1bHQ8VD4+O1xyXG4gIGluc2VydDxUIGV4dGVuZHMgU3BlY1R5cGU+KFxyXG4gICAgc2NvcGU6IHN0cmluZyxcclxuICAgIG1vZGVsOiBUWyduYW1lJ10sXHJcbiAgICBkYXRhOiBQYXJ0aWFsPE1vZGVsPFQ+PixcclxuICApOiBQcm9taXNlPE11dGF0ZVJlc3VsdDxUPj47XHJcbiAgdXBkYXRlPFQgZXh0ZW5kcyBTcGVjVHlwZT4ob3B0aW9uczogVXBkYXRlT3B0aW9uczxUPik6IFByb21pc2U8TXV0YXRlUmVzdWx0PjtcclxuICB1cGRhdGU8VCBleHRlbmRzIFNwZWNUeXBlPihcclxuICAgIHNjb3BlOiBzdHJpbmcsXHJcbiAgICBtb2RlbDogVFsnbmFtZSddLFxyXG4gICAgZGF0YTogUGFydGlhbDxUWydmaWVsZHMnXT4sXHJcbiAgKTogUHJvbWlzZTxNdXRhdGVSZXN1bHQ+O1xyXG4gIHJlbW92ZTxUIGV4dGVuZHMgU3BlY1R5cGU+KG9wdGlvbnM6IFJlbW92ZU9wdGlvbnM8VD4pOiBQcm9taXNlPE11dGF0ZVJlc3VsdD47XHJcbiAgcmVtb3ZlPFQgZXh0ZW5kcyBTcGVjVHlwZT4oXHJcbiAgICBzY29wZTogc3RyaW5nLFxyXG4gICAgbW9kZWw6IFRbJ25hbWUnXSxcclxuICAgIGlkZW50aWZpZXJzOiBQYXJ0aWFsPFRbJ2ZpZWxkcyddPixcclxuICApOiBQcm9taXNlPE11dGF0ZVJlc3VsdD47XHJcbiAgdmFsaWRhdGU8VD4obmFtZTogc3RyaW5nLCBkYXRhOiBUKTogUHJvbWlzZTxWYWxpZGF0ZVJlc3VsdD47XHJcbiAgYmF0Y2hNdXRhdGVTdGFydCgpOiB2b2lkO1xyXG4gIGJhdGNoTXV0YXRlRW5kKCk6IHZvaWQ7XHJcbiAgZmx1c2goKTogdm9pZDtcclxuICBjYW5jZWwoKTogdm9pZDtcclxufVxyXG5cclxuaW50ZXJmYWNlIFJlcXVlc3RRdWV1ZUl0ZW08VCBleHRlbmRzIFJlc3BvbnNlPiB7XHJcbiAgcmVxdWVzdDogUmVxdWVzdDtcclxuICByZXNvbHZlKHJlc3VsdDogVCk6IHZvaWQ7XHJcbiAgY2FuY2VsKCk6IHZvaWQ7XHJcbn1cclxuXHJcbmludGVyZmFjZSBCYXRjaGFibGVSZXF1ZXN0UXVldWVJdGVtPFQgZXh0ZW5kcyBTcGVjVHlwZT4ge1xyXG4gIHJlcXVlc3Q6IE11dGF0ZVJlcXVlc3Q8VD47XHJcbiAgcmVzb2x2ZShyZXN1bHQ6IE11dGF0ZVJlc3BvbnNlPFQ+KTogdm9pZDtcclxuICBjYW5jZWwoKTogdm9pZDtcclxufVxyXG5cclxuaW50ZXJmYWNlIEJhdGNoUmVxdWVzdE1ldGFkYXRhIHtcclxuICBxdWV1ZTogQmF0Y2hhYmxlUmVxdWVzdFF1ZXVlSXRlbTxBbnlTcGVjPltdO1xyXG4gIHJlcXVlc3RJZDogbnVtYmVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWxkUmVxdWVzdGVyT3B0aW9ucyB7XHJcbiAgd2FpdD86IG51bWJlcjtcclxuICBtYXhXYWl0PzogbnVtYmVyO1xyXG4gIGNhbmNlbEVycm9yOiAocmVxdWVzdDogUmVxdWVzdCkgPT4gQnVuZGxlW107XHJcbiAgbmV0d29ya0Vycm9yOiAoc3RhdHVzOiBGZXRjaFN0YXR1cywgZXJyb3I/OiBhbnkpID0+IEJ1bmRsZVtdO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSZXF1ZXN0ZXIoZW5kUG9pbnQ6IHN0cmluZywgb3B0aW9uczogQnVpbGRSZXF1ZXN0ZXJPcHRpb25zKTogUmVxdWVzdGVyIHtcclxuICBsZXQgdWlkID0gMDtcclxuICBmdW5jdGlvbiB1bmlxdWVJZCgpIHtcclxuICAgIHJldHVybiArK3VpZDtcclxuICB9XHJcblxyXG4gIGNvbnN0IHsgd2FpdCA9IDIwMCwgbWF4V2FpdCA9IDIwMDAsIGNhbmNlbEVycm9yLCBuZXR3b3JrRXJyb3IgfSA9IG9wdGlvbnM7XHJcblxyXG4gIGxldCBjdXJyQmF0Y2g6IEJhdGNoUmVxdWVzdE1ldGFkYXRhIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xyXG5cclxuICBsZXQgcXVldWU6IFJlcXVlc3RRdWV1ZUl0ZW08UmVzcG9uc2U+W10gPSBbXTtcclxuICBsZXQgcmVxdWVzdFJ1bm5pbmcgPSBmYWxzZTtcclxuICBsZXQgY29uZ2VzdGVkID0gZmFsc2U7XHJcblxyXG4gIGNvbnN0IGRlYm91bmNlZFNlbmQgPSBkZWJvdW5jZShzZW5kLCB3YWl0LCB7IG1heFdhaXQgfSk7XHJcblxyXG4gIGFzeW5jIGZ1bmN0aW9uIHNlbmQoKSB7XHJcbiAgICBpZiAocmVxdWVzdFJ1bm5pbmcpIHtcclxuICAgICAgY29uZ2VzdGVkID0gdHJ1ZTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHBlbmRpbmdRdWV1ZSA9IGNvbXBhY3QocXVldWUpO1xyXG4gICAgcXVldWUgPSBbXTtcclxuICAgIHJlcXVlc3RSdW5uaW5nID0gdHJ1ZTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoPFJlc3BvbnNlW10+KHtcclxuICAgICAgICBib2R5OiBwZW5kaW5nUXVldWUubWFwKGl0ZW0gPT4gaXRlbS5yZXF1ZXN0KSxcclxuICAgICAgICBqc29uOiB0cnVlLFxyXG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxyXG4gICAgICAgIHVybDogZW5kUG9pbnQsXHJcbiAgICAgIH0pO1xyXG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgcGVuZGluZ1F1ZXVlKSB7XHJcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gcmVzcG9uc2UuYm9keS5maW5kKHJlcyA9PiByZXMucmVxdWVzdElkID09PSBpdGVtLnJlcXVlc3QucmVxdWVzdElkKTtcclxuICAgICAgICBpZiAoIXRhcmdldCkge1xyXG4gICAgICAgICAgaXRlbS5yZXNvbHZlKDxSZXNwb25zZT57XHJcbiAgICAgICAgICAgIGVycm9yczogbmV0d29ya0Vycm9yKFxyXG4gICAgICAgICAgICAgIHsgb2s6IGZhbHNlLCBjb2RlOiAwLCB0ZXh0OiAnVU5LTk9XTicgfSxcclxuICAgICAgICAgICAgICBuZXcgRXJyb3IoYFJlcXVlc3QncyByZXNwb25zZSB3YXMgbm90IGZvdW5kLmApLFxyXG4gICAgICAgICAgICApLFxyXG4gICAgICAgICAgICByZXF1ZXN0SWQ6IGl0ZW0ucmVxdWVzdC5yZXF1ZXN0SWQsXHJcbiAgICAgICAgICAgIHR5cGU6IGl0ZW0ucmVxdWVzdC50eXBlLFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGl0ZW0ucmVzb2x2ZSh0YXJnZXQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHBlbmRpbmdRdWV1ZSkge1xyXG4gICAgICAgIGl0ZW0ucmVzb2x2ZSg8UmVzcG9uc2U+e1xyXG4gICAgICAgICAgZXJyb3JzOiBuZXR3b3JrRXJyb3IoeyBvazogZmFsc2UsIGNvZGU6IDAsIHRleHQ6ICdVTktOT1dOJyB9LCBlcnJvciksXHJcbiAgICAgICAgICByZXF1ZXN0SWQ6IGl0ZW0ucmVxdWVzdC5yZXF1ZXN0SWQsXHJcbiAgICAgICAgICB0eXBlOiBpdGVtLnJlcXVlc3QudHlwZSxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgcmVxdWVzdFJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgaWYgKGNvbmdlc3RlZCkge1xyXG4gICAgICAgIGNvbmdlc3RlZCA9IGZhbHNlO1xyXG4gICAgICAgIGRlYm91bmNlZFNlbmQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gc2VsZWN0PFQgZXh0ZW5kcyBTcGVjVHlwZT4oXHJcbiAgICBzY29wZTogc3RyaW5nLFxyXG4gICAgbW9kZWw6IFRbJ25hbWUnXSxcclxuICAgIHF1ZXJ5OiBRdWVyeTxUPixcclxuICApOiBQcm9taXNlPFNlbGVjdFJlc3VsdDxUPj4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPFNlbGVjdFJlc3VsdDxUPj4ocmVzb2x2ZSA9PiB7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3RJZCA9IHVuaXF1ZUlkKCk7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3Q6IFNlbGVjdFJlcXVlc3Q8VD4gPSB7IHNjb3BlLCBtb2RlbCwgcXVlcnksIHJlcXVlc3RJZCwgdHlwZTogJ3NlbGVjdCcgfTtcclxuXHJcbiAgICAgIGNvbnN0IGl0ZW06IFJlcXVlc3RRdWV1ZUl0ZW08U2VsZWN0UmVzcG9uc2U8VD4+ID0ge1xyXG4gICAgICAgIHJlcXVlc3QsXHJcbiAgICAgICAgcmVzb2x2ZTogKHsgcmVxdWVzdElkOiBfLCAuLi5yZXNwb25zZSB9KSA9PiByZXNvbHZlKHJlc3BvbnNlKSxcclxuICAgICAgICBjYW5jZWw6ICgpID0+IHJlc29sdmUoeyBjb3VudDogMCwgZGF0YTogW10sIGVycm9yczogY2FuY2VsRXJyb3IocmVxdWVzdCksIHR5cGU6ICdzZWxlY3QnIH0pLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcXVldWUucHVzaChpdGVtKTtcclxuICAgICAgZGVib3VuY2VkU2VuZCgpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBvcGVyYXRlPFREYXRhLCBUUmVzdWx0PihuYW1lOiBzdHJpbmcsIGRhdGE/OiBURGF0YSk6IFByb21pc2U8T3BlcmF0ZVJlc3VsdDxUUmVzdWx0Pj4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE9wZXJhdGVSZXN1bHQ8VFJlc3VsdD4+KHJlc29sdmUgPT4ge1xyXG4gICAgICBjb25zdCByZXF1ZXN0SWQgPSB1bmlxdWVJZCgpO1xyXG4gICAgICBjb25zdCByZXF1ZXN0OiBPcGVyYXRlUmVxdWVzdDxURGF0YT4gPSB7IGRhdGEsIG5hbWUsIHJlcXVlc3RJZCwgdHlwZTogJ29wZXJhdGUnIH07XHJcblxyXG4gICAgICBjb25zdCBpdGVtOiBSZXF1ZXN0UXVldWVJdGVtPE9wZXJhdGVSZXNwb25zZTxUUmVzdWx0Pj4gPSB7XHJcbiAgICAgICAgcmVxdWVzdCxcclxuICAgICAgICByZXNvbHZlOiAoeyByZXF1ZXN0SWQ6IF8sIC4uLnJlc3BvbnNlIH0pID0+IHJlc29sdmUocmVzcG9uc2UpLFxyXG4gICAgICAgIGNhbmNlbCgpIHtcclxuICAgICAgICAgIHJlc29sdmUoeyBuYW1lLCBlcnJvcnM6IGNhbmNlbEVycm9yKHJlcXVlc3QpLCB0eXBlOiAnb3BlcmF0ZScgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHF1ZXVlLnB1c2goaXRlbSk7XHJcbiAgICAgIGRlYm91bmNlZFNlbmQoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gaW5zZXJ0PFQgZXh0ZW5kcyBTcGVjVHlwZT4ob3B0aW9uczogSW5zZXJ0T3B0aW9uczxUPik6IFByb21pc2U8TXV0YXRlUmVzdWx0PFQ+PjtcclxuICBmdW5jdGlvbiBpbnNlcnQ8VCBleHRlbmRzIFNwZWNUeXBlPihcclxuICAgIHNjb3BlOiBzdHJpbmcsXHJcbiAgICBtb2RlbDogVFsnbmFtZSddLFxyXG4gICAgZGF0YTogUGFydGlhbDxNb2RlbDxUPj4sXHJcbiAgKTogUHJvbWlzZTxNdXRhdGVSZXN1bHQ8VD4+O1xyXG4gIGZ1bmN0aW9uIGluc2VydDxUIGV4dGVuZHMgU3BlY1R5cGU+KFxyXG4gICAgc2NvcGVPck9wdHM6IHN0cmluZyB8IEluc2VydE9wdGlvbnM8VD4sXHJcbiAgICBtb2RlbD86IFRbJ25hbWUnXSxcclxuICAgIGRhdGE/OiBQYXJ0aWFsPE1vZGVsPFQ+PixcclxuICApOiBQcm9taXNlPE11dGF0ZVJlc3VsdDxUPj4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE11dGF0ZVJlc3VsdDxUPj4ocmVzb2x2ZSA9PiB7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3RJZCA9IHVuaXF1ZUlkKCk7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3Q6IE11dGF0ZVJlcXVlc3Q8VD4gPSB7XHJcbiAgICAgICAgYWN0aW9uOiAnaW5zZXJ0JyxcclxuICAgICAgICBkYXRhOiB0eXBlb2Ygc2NvcGVPck9wdHMgPT09ICdzdHJpbmcnID8gZGF0YSB8fCB7fSA6IHNjb3BlT3JPcHRzLmRhdGEsXHJcbiAgICAgICAgc2NvcGU6IHR5cGVvZiBzY29wZU9yT3B0cyA9PT0gJ3N0cmluZycgPyBzY29wZU9yT3B0cyA6IHNjb3BlT3JPcHRzLnNjb3BlLFxyXG4gICAgICAgIG1vZGVsOiB0eXBlb2Ygc2NvcGVPck9wdHMgPT09ICdzdHJpbmcnID8gbW9kZWwhIDogc2NvcGVPck9wdHMubW9kZWwsXHJcbiAgICAgICAgcmVxdWVzdElkLFxyXG4gICAgICAgIHR5cGU6ICdtdXRhdGUnLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgaXRlbTogQmF0Y2hhYmxlUmVxdWVzdFF1ZXVlSXRlbTxUPiA9IHtcclxuICAgICAgICByZXF1ZXN0LFxyXG4gICAgICAgIHJlc29sdmU6ICh7IHJlcXVlc3RJZDogXywgLi4ucmVzcG9uc2UgfSkgPT4gcmVzb2x2ZShyZXNwb25zZSksXHJcbiAgICAgICAgY2FuY2VsOiAoKSA9PiByZXNvbHZlKHsgYWN0aW9uOiAnaW5zZXJ0JywgZXJyb3JzOiBjYW5jZWxFcnJvcihyZXF1ZXN0KSwgdHlwZTogJ211dGF0ZScgfSksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoY3VyckJhdGNoKSB7XHJcbiAgICAgICAgY3VyckJhdGNoLnF1ZXVlLnB1c2goaXRlbSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcXVldWUucHVzaChpdGVtKTtcclxuICAgICAgICBkZWJvdW5jZWRTZW5kKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlPFQgZXh0ZW5kcyBTcGVjVHlwZT4ob3B0aW9uczogVXBkYXRlT3B0aW9uczxUPik6IFByb21pc2U8TXV0YXRlUmVzdWx0PFQ+PjtcclxuICBmdW5jdGlvbiB1cGRhdGU8VCBleHRlbmRzIFNwZWNUeXBlPihcclxuICAgIHNjb3BlOiBzdHJpbmcsXHJcbiAgICBtb2RlbDogVFsnbmFtZSddLFxyXG4gICAgZGF0YTogUGFydGlhbDxUWydmaWVsZHMnXT4sXHJcbiAgKTogUHJvbWlzZTxNdXRhdGVSZXN1bHQ8VD4+O1xyXG4gIGZ1bmN0aW9uIHVwZGF0ZTxUIGV4dGVuZHMgU3BlY1R5cGU+KFxyXG4gICAgc2NvcGVPck9wdHM6IHN0cmluZyB8IFVwZGF0ZU9wdGlvbnM8VD4sXHJcbiAgICBtb2RlbD86IFRbJ25hbWUnXSxcclxuICAgIGRhdGE/OiBQYXJ0aWFsPFRbJ2ZpZWxkcyddPixcclxuICApOiBQcm9taXNlPE11dGF0ZVJlc3VsdDxUPj4ge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlPE11dGF0ZVJlc3VsdDxUPj4ocmVzb2x2ZSA9PiB7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3RJZCA9IHVuaXF1ZUlkKCk7XHJcbiAgICAgIGNvbnN0IHJlcXVlc3Q6IE11dGF0ZVJlcXVlc3Q8VD4gPSB7XHJcbiAgICAgICAgYWN0aW9uOiAndXBkYXRlJyxcclxuICAgICAgICBkYXRhOiB0eXBlb2Ygc2NvcGVPck9wdHMgPT09ICdzdHJpbmcnID8gZGF0YSB8fCB7fSA6IHNjb3BlT3JPcHRzLmRhdGEsXHJcbiAgICAgICAgc2NvcGU6IHR5cGVvZiBzY29wZU9yT3B0cyA9PT0gJ3N0cmluZycgPyBzY29wZU9yT3B0cyA6IHNjb3BlT3JPcHRzLnNjb3BlLFxyXG4gICAgICAgIG1vZGVsOiB0eXBlb2Ygc2NvcGVPck9wdHMgPT09ICdzdHJpbmcnID8gbW9kZWwhIDogc2NvcGVPck9wdHMubW9kZWwsXHJcbiAgICAgICAgcmVxdWVzdElkLFxyXG4gICAgICAgIHR5cGU6ICdtdXRhdGUnLFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgaXRlbTogQmF0Y2hhYmxlUmVxdWVzdFF1ZXVlSXRlbTxUPiA9IHtcclxuICAgICAgICByZXF1ZXN0LFxyXG4gICAgICAgIHJlc29sdmU6ICh7IHJlcXVlc3RJZDogXywgLi4ucmVzcG9uc2UgfSkgPT4gcmVzb2x2ZShyZXNwb25zZSksXHJcbiAgICAgICAgY2FuY2VsOiAoKSA9PiByZXNvbHZlKHsgYWN0aW9uOiAndXBkYXRlJywgZXJyb3JzOiBjYW5jZWxFcnJvcihyZXF1ZXN0KSwgdHlwZTogJ211dGF0ZScgfSksXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoY3VyckJhdGNoKSB7XHJcbiAgICAgICAgY3VyckJhdGNoLnF1ZXVlLnB1c2goaXRlbSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcXVldWUucHVzaChpdGVtKTtcclxuICAgICAgICBkZWJvdW5jZWRTZW5kKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gcmVtb3ZlPFQgZXh0ZW5kcyBTcGVjVHlwZT4ob3B0aW9uczogUmVtb3ZlT3B0aW9uczxUPik6IFByb21pc2U8TXV0YXRlUmVzdWx0PFQ+PjtcclxuICBmdW5jdGlvbiByZW1vdmU8VCBleHRlbmRzIFNwZWNUeXBlPihcclxuICAgIHNjb3BlOiBzdHJpbmcsXHJcbiAgICBtb2RlbDogVFsnbmFtZSddLFxyXG4gICAgaWRlbnRpZmllcnM6IFBhcnRpYWw8VFsnZmllbGRzJ10+LFxyXG4gICk6IFByb21pc2U8TXV0YXRlUmVzdWx0PFQ+PjtcclxuICBmdW5jdGlvbiByZW1vdmU8VCBleHRlbmRzIFNwZWNUeXBlPihcclxuICAgIHNjb3BlT3JPcHRzOiBzdHJpbmcgfCBSZW1vdmVPcHRpb25zPFQ+LFxyXG4gICAgbW9kZWw/OiBUWyduYW1lJ10sXHJcbiAgICBpZGVudGlmaWVycz86IFBhcnRpYWw8VFsnZmllbGRzJ10+LFxyXG4gICk6IFByb21pc2U8TXV0YXRlUmVzdWx0PFQ+PiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8TXV0YXRlUmVzdWx0PFQ+PihyZXNvbHZlID0+IHtcclxuICAgICAgY29uc3QgcmVxdWVzdElkID0gdW5pcXVlSWQoKTtcclxuICAgICAgY29uc3QgcmVxdWVzdDogTXV0YXRlUmVxdWVzdDxUPiA9IHtcclxuICAgICAgICBhY3Rpb246ICdyZW1vdmUnLFxyXG4gICAgICAgIGlkZW50aWZpZXJzOiB0eXBlb2Ygc2NvcGVPck9wdHMgPT09ICdzdHJpbmcnID8gaWRlbnRpZmllcnMgfHwge30gOiBzY29wZU9yT3B0cy5pZGVudGlmaWVycyxcclxuICAgICAgICBzY29wZTogdHlwZW9mIHNjb3BlT3JPcHRzID09PSAnc3RyaW5nJyA/IHNjb3BlT3JPcHRzIDogc2NvcGVPck9wdHMuc2NvcGUsXHJcbiAgICAgICAgbW9kZWw6IHR5cGVvZiBzY29wZU9yT3B0cyA9PT0gJ3N0cmluZycgPyBtb2RlbCEgOiBzY29wZU9yT3B0cy5tb2RlbCxcclxuICAgICAgICByZXF1ZXN0SWQsXHJcbiAgICAgICAgdHlwZTogJ211dGF0ZScsXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBjb25zdCBpdGVtOiBCYXRjaGFibGVSZXF1ZXN0UXVldWVJdGVtPFQ+ID0ge1xyXG4gICAgICAgIHJlcXVlc3QsXHJcbiAgICAgICAgcmVzb2x2ZTogKHsgcmVxdWVzdElkOiBfLCAuLi5yZXNwb25zZSB9KSA9PiByZXNvbHZlKHJlc3BvbnNlKSxcclxuICAgICAgICBjYW5jZWw6ICgpID0+IHJlc29sdmUoeyBhY3Rpb246ICdyZW1vdmUnLCBlcnJvcnM6IGNhbmNlbEVycm9yKHJlcXVlc3QpLCB0eXBlOiAnbXV0YXRlJyB9KSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChjdXJyQmF0Y2gpIHtcclxuICAgICAgICBjdXJyQmF0Y2gucXVldWUucHVzaChpdGVtKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBxdWV1ZS5wdXNoKGl0ZW0pO1xyXG4gICAgICAgIGRlYm91bmNlZFNlbmQoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiB2YWxpZGF0ZTxUPihuYW1lOiBzdHJpbmcsIGRhdGE6IFQpOiBQcm9taXNlPFZhbGlkYXRlUmVzdWx0PiB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2U8VmFsaWRhdGVSZXN1bHQ+KHJlc29sdmUgPT4ge1xyXG4gICAgICBjb25zdCByZXF1ZXN0SWQgPSB1bmlxdWVJZCgpO1xyXG4gICAgICBjb25zdCByZXF1ZXN0OiBWYWxpZGF0ZVJlcXVlc3Q8VD4gPSB7IGRhdGEsIG5hbWUsIHJlcXVlc3RJZCwgdHlwZTogJ3ZhbGlkYXRlJyB9O1xyXG5cclxuICAgICAgY29uc3QgaXRlbTogUmVxdWVzdFF1ZXVlSXRlbTxWYWxpZGF0ZVJlc3BvbnNlPiA9IHtcclxuICAgICAgICByZXF1ZXN0LFxyXG4gICAgICAgIHJlc29sdmU6ICh7IHJlcXVlc3RJZDogXywgLi4ucmVzcG9uc2UgfSkgPT4gcmVzb2x2ZShyZXNwb25zZSksXHJcbiAgICAgICAgY2FuY2VsOiAoKSA9PiByZXNvbHZlKHsgbmFtZSwgZXJyb3JzOiBjYW5jZWxFcnJvcihyZXF1ZXN0KSwgdHlwZTogJ3ZhbGlkYXRlJyB9KSxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHF1ZXVlLnB1c2goaXRlbSk7XHJcbiAgICAgIGRlYm91bmNlZFNlbmQoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gYmF0Y2hNdXRhdGVTdGFydCgpIHtcclxuICAgIGlmICghY3VyckJhdGNoKSB7XHJcbiAgICAgIGN1cnJCYXRjaCA9IHtcclxuICAgICAgICBxdWV1ZTogW10sXHJcbiAgICAgICAgcmVxdWVzdElkOiB1bmlxdWVJZCgpLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gYmF0Y2hNdXRhdGVFbmQoKSB7XHJcbiAgICBpZiAoY3VyckJhdGNoKSB7XHJcbiAgICAgIGNvbnN0IHByZXZCYXRjaCA9IGN1cnJCYXRjaDtcclxuICAgICAgY3VyckJhdGNoID0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgY29uc3QgcmVxdWVzdDogQmF0Y2hNdXRhdGVSZXF1ZXN0ID0ge1xyXG4gICAgICAgIHF1ZXVlOiBwcmV2QmF0Y2gucXVldWUubWFwKGkgPT4gaS5yZXF1ZXN0KSxcclxuICAgICAgICByZXF1ZXN0SWQ6IHByZXZCYXRjaC5yZXF1ZXN0SWQsXHJcbiAgICAgICAgdHlwZTogJ2JhdGNoTXV0YXRlJyxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IGl0ZW06IFJlcXVlc3RRdWV1ZUl0ZW08QmF0Y2hNdXRhdGVSZXNwb25zZT4gPSB7XHJcbiAgICAgICAgcmVxdWVzdCxcclxuICAgICAgICByZXNvbHZlKHsgcXVldWU6IGJhdGNoUXVldWUsIGVycm9ycyB9KSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IHsgcmVxdWVzdDogeyBhY3Rpb24sIHJlcXVlc3RJZCwgdHlwZSB9LCByZXNvbHZlIH0gb2YgcHJldkJhdGNoLnF1ZXVlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGJhdGNoUXVldWUuZmluZChyZXMgPT4gcmVzLnJlcXVlc3RJZCA9PT0gcmVxdWVzdElkKTtcclxuICAgICAgICAgICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgcmVzb2x2ZSh7IGFjdGlvbiwgZXJyb3JzLCByZXF1ZXN0SWQsIHR5cGUgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRhcmdldCkge1xyXG4gICAgICAgICAgICAgIHJlc29sdmUoe1xyXG4gICAgICAgICAgICAgICAgYWN0aW9uLFxyXG4gICAgICAgICAgICAgICAgZXJyb3JzOiBuZXR3b3JrRXJyb3IoXHJcbiAgICAgICAgICAgICAgICAgIHsgb2s6IGZhbHNlLCBjb2RlOiAwLCB0ZXh0OiAnVU5LTk9XTicgfSxcclxuICAgICAgICAgICAgICAgICAgbmV3IEVycm9yKGBSZXF1ZXN0J3MgcmVzcG9uc2Ugd2FzIG5vdCBmb3VuZC5gKSxcclxuICAgICAgICAgICAgICAgICksXHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0SWQsXHJcbiAgICAgICAgICAgICAgICB0eXBlLFxyXG4gICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJlc29sdmUodGFyZ2V0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY2FuY2VsKCkge1xyXG4gICAgICAgICAgZm9yIChjb25zdCBiYXRjaEl0ZW0gb2YgcHJldkJhdGNoLnF1ZXVlKSB7XHJcbiAgICAgICAgICAgIGJhdGNoSXRlbS5jYW5jZWwoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcXVldWUucHVzaChpdGVtKTtcclxuICAgICAgZGVib3VuY2VkU2VuZCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gY2FuY2VsKCkge1xyXG4gICAgY29uZ2VzdGVkID0gZmFsc2U7XHJcbiAgICBkZWJvdW5jZWRTZW5kLmNhbmNlbCgpO1xyXG4gICAgcXVldWUuZm9yRWFjaChpdGVtID0+IGl0ZW0uY2FuY2VsKCkpO1xyXG4gICAgcXVldWUgPSBbXTtcclxuICAgIGlmIChjdXJyQmF0Y2gpIHtcclxuICAgICAgY3VyckJhdGNoLnF1ZXVlLmZvckVhY2goaXRlbSA9PiBpdGVtLmNhbmNlbCgpKTtcclxuICAgICAgY3VyckJhdGNoID0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZmx1c2goKSB7XHJcbiAgICBpZiAoY3VyckJhdGNoKSB7XHJcbiAgICAgIGJhdGNoTXV0YXRlRW5kKCk7XHJcbiAgICB9XHJcbiAgICBpZiAoIXJlcXVlc3RSdW5uaW5nKSB7XHJcbiAgICAgIGRlYm91bmNlZFNlbmQuZmx1c2goKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvbmdlc3RlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgYmF0Y2hNdXRhdGVFbmQsXHJcbiAgICBiYXRjaE11dGF0ZVN0YXJ0LFxyXG4gICAgY2FuY2VsLFxyXG4gICAgZmx1c2gsXHJcbiAgICBpbnNlcnQsXHJcbiAgICBvcGVyYXRlLFxyXG4gICAgcmVtb3ZlLFxyXG4gICAgc2VsZWN0LFxyXG4gICAgdXBkYXRlLFxyXG4gICAgdmFsaWRhdGUsXHJcbiAgfTtcclxufVxyXG4iXX0=