@orbit/record-cache
Version:
Orbit base classes used to access and maintain a set of records.
211 lines • 28.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SyncQueryOperators = void 0;
const data_1 = require("@orbit/data");
const records_1 = require("@orbit/records");
const utils_1 = require("@orbit/utils");
exports.SyncQueryOperators = {
findRecord(cache, expression, options) {
const { record } = expression;
const currentRecord = cache.getRecordSync(record);
if (!currentRecord) {
if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) {
throw new records_1.RecordNotFoundException(record.type, record.id);
}
}
return currentRecord;
},
findRecords(cache, expression,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
options) {
let exp = expression;
let results = cache.getRecordsSync(exp.records || exp.type);
if (exp.filter) {
results = filterRecords(results, exp.filter);
}
if (exp.sort) {
results = sortRecords(results, exp.sort);
}
if (exp.page) {
results = paginateRecords(results, exp.page);
}
return results;
},
findRelatedRecords(cache, expression, options) {
const exp = expression;
const { record, relationship } = exp;
const relatedIds = cache.getRelatedRecordsSync(record, relationship);
if (!relatedIds || relatedIds.length === 0) {
if (!cache.getRecordSync(record)) {
if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) {
throw new records_1.RecordNotFoundException(record.type, record.id);
}
else {
return undefined;
}
}
return [];
}
let results = cache.getRecordsSync(relatedIds);
if (exp.filter) {
results = filterRecords(results, exp.filter);
}
if (exp.sort) {
results = sortRecords(results, exp.sort);
}
if (exp.page) {
results = paginateRecords(results, exp.page);
}
return results;
},
findRelatedRecord(cache, expression, options) {
const exp = expression;
const { record, relationship } = exp;
const relatedId = cache.getRelatedRecordSync(record, relationship);
if (relatedId) {
return cache.getRecordSync(relatedId) || null;
}
else {
if (!cache.getRecordSync(record)) {
if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) {
throw new records_1.RecordNotFoundException(record.type, record.id);
}
else {
return undefined;
}
}
return null;
}
}
};
function filterRecords(records, filters) {
return records.filter((record) => {
for (let i = 0, l = filters.length; i < l; i++) {
if (!applyFilter(record, filters[i])) {
return false;
}
}
return true;
});
}
function applyFilter(record, filter) {
if (filter.kind === 'attribute') {
let actual = (0, utils_1.deepGet)(record, ['attributes', filter.attribute]);
if (actual === undefined) {
return false;
}
let expected = filter.value;
switch (filter.op) {
case 'equal':
return actual === expected;
case 'gt':
return actual > expected;
case 'gte':
return actual >= expected;
case 'lt':
return actual < expected;
case 'lte':
return actual <= expected;
default:
throw new data_1.QueryExpressionParseError('Filter operation ${filter.op} not recognized for Store.');
}
}
else if (filter.kind === 'relatedRecords') {
let actual = (0, utils_1.deepGet)(record, [
'relationships',
filter.relation,
'data'
]);
if (actual === undefined) {
return false;
}
let expected = filter.records;
switch (filter.op) {
case 'equal':
return (actual.length === expected.length &&
expected.every((e) => actual.some((a) => a.id === e.id && a.type === e.type)));
case 'all':
return expected.every((e) => actual.some((a) => a.id === e.id && a.type === e.type));
case 'some':
return expected.some((e) => actual.some((a) => a.id === e.id && a.type === e.type));
case 'none':
return !expected.some((e) => actual.some((a) => a.id === e.id && a.type === e.type));
default:
throw new data_1.QueryExpressionParseError('Filter operation ${filter.op} not recognized for Store.');
}
}
else if (filter.kind === 'relatedRecord') {
let actual = (0, utils_1.deepGet)(record, ['relationships', filter.relation, 'data']);
if (actual === undefined) {
return false;
}
let expected = filter.record;
switch (filter.op) {
case 'equal':
if (actual === null) {
return expected === null;
}
else {
if (Array.isArray(expected)) {
return expected.some((e) => actual.type === e.type && actual.id === e.id);
}
else if (expected) {
return actual.type === expected.type && actual.id === expected.id;
}
else {
return false;
}
}
default:
throw new data_1.QueryExpressionParseError('Filter operation ${filter.op} not recognized for Store.');
}
}
return false;
}
function sortRecords(records, sortSpecifiers) {
const comparisonValues = new Map();
records.forEach((record) => {
comparisonValues.set(record, sortSpecifiers.map((sortSpecifier) => {
if (sortSpecifier.kind === 'attribute') {
return (0, utils_1.deepGet)(record, [
'attributes',
sortSpecifier.attribute
]);
}
else {
throw new data_1.QueryExpressionParseError('Sort specifier ${sortSpecifier.kind} not recognized for Store.');
}
}));
});
const comparisonOrders = sortSpecifiers.map((sortExpression) => sortExpression.order === 'descending' ? -1 : 1);
return records.sort((record1, record2) => {
const values1 = comparisonValues.get(record1);
const values2 = comparisonValues.get(record2);
for (let i = 0; i < sortSpecifiers.length; i++) {
if (values1[i] < values2[i]) {
return -comparisonOrders[i];
}
else if (values1[i] > values2[i]) {
return comparisonOrders[i];
}
else if ((0, utils_1.isNone)(values1[i]) && !(0, utils_1.isNone)(values2[i])) {
return comparisonOrders[i];
}
else if ((0, utils_1.isNone)(values2[i]) && !(0, utils_1.isNone)(values1[i])) {
return -comparisonOrders[i];
}
}
return 0;
});
}
function paginateRecords(records, paginationOptions) {
if (paginationOptions.limit !== undefined) {
let offset = paginationOptions.offset === undefined ? 0 : paginationOptions.offset;
let limit = paginationOptions.limit;
return records.slice(offset, offset + limit);
}
else {
throw new data_1.QueryExpressionParseError('Pagination options not recognized for Store. Please specify `offset` and `limit`.');
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1xdWVyeS1vcGVyYXRvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3BlcmF0b3JzL3N5bmMtcXVlcnktb3BlcmF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNDQUF3RTtBQUN4RSw0Q0FZd0I7QUFDeEIsd0NBQXFEO0FBV3hDLFFBQUEsa0JBQWtCLEdBQTRCO0lBQ3pELFVBQVUsQ0FDUixLQUF5QixFQUN6QixVQUFpQyxFQUNqQyxPQUF3QjtRQUV4QixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsVUFBd0IsQ0FBQztRQUM1QyxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWxELElBQUksQ0FBQyxhQUFhLEVBQUU7WUFDbEIsSUFBSSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsdUJBQXVCLEVBQUU7Z0JBQ3BDLE1BQU0sSUFBSSxpQ0FBdUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUMzRDtTQUNGO1FBRUQsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVELFdBQVcsQ0FDVCxLQUF5QixFQUN6QixVQUFpQztJQUNqQyw2REFBNkQ7SUFDN0QsT0FBd0I7UUFFeEIsSUFBSSxHQUFHLEdBQUcsVUFBeUIsQ0FBQztRQUNwQyxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVELElBQUksR0FBRyxDQUFDLE1BQU0sRUFBRTtZQUNkLE9BQU8sR0FBRyxhQUFhLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUM5QztRQUNELElBQUksR0FBRyxDQUFDLElBQUksRUFBRTtZQUNaLE9BQU8sR0FBRyxXQUFXLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxJ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QUF5QixDQUNqQyxtRkFBbUYsQ0FDcEYsQ0FBQztLQUNIO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IsIFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnQG9yYml0L2RhdGEnO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlU29ydFNwZWNpZmllcixcbiAgRmluZFJlY29yZCxcbiAgRmluZFJlY29yZHMsXG4gIEZpbmRSZWxhdGVkUmVjb3JkLFxuICBGaW5kUmVsYXRlZFJlY29yZHMsXG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBSZWNvcmRJZGVudGl0eSxcbiAgUmVjb3JkTm90Rm91bmRFeGNlcHRpb24sXG4gIFJlY29yZFF1ZXJ5RXhwcmVzc2lvbixcbiAgUmVjb3JkUXVlcnlFeHByZXNzaW9uUmVzdWx0LFxuICBTb3J0U3BlY2lmaWVyXG59IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7IGRlZXBHZXQsIERpY3QsIGlzTm9uZSB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBTeW5jUmVjb3JkQWNjZXNzb3IgfSBmcm9tICcuLi9yZWNvcmQtYWNjZXNzb3InO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNRdWVyeU9wZXJhdG9yIHtcbiAgKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBSZWNvcmRRdWVyeUV4cHJlc3Npb25SZXN1bHQ7XG59XG5cbmV4cG9ydCBjb25zdCBTeW5jUXVlcnlPcGVyYXRvcnM6IERpY3Q8U3luY1F1ZXJ5T3BlcmF0b3I+ID0ge1xuICBmaW5kUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBJbml0aWFsaXplZFJlY29yZCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgeyByZWNvcmQgfSA9IGV4cHJlc3Npb24gYXMgRmluZFJlY29yZDtcbiAgICBjb25zdCBjdXJyZW50UmVjb3JkID0gY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpO1xuXG4gICAgaWYgKCFjdXJyZW50UmVjb3JkKSB7XG4gICAgICBpZiAob3B0aW9ucz8ucmFpc2VOb3RGb3VuZEV4Y2VwdGlvbnMpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50UmVjb3JkO1xuICB9LFxuXG4gIGZpbmRSZWNvcmRzKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmRbXSB7XG4gICAgbGV0IGV4cCA9IGV4cHJlc3Npb24gYXMgRmluZFJlY29yZHM7XG4gICAgbGV0IHJlc3VsdHMgPSBjYWNoZS5nZXRSZWNvcmRzU3luYyhleHAucmVjb3JkcyB8fCBleHAudHlwZSk7XG4gICAgaWYgKGV4cC5maWx0ZXIpIHtcbiAgICAgIHJlc3VsdHMgPSBmaWx0ZXJSZWNvcmRzKHJlc3VsdHMsIGV4cC5maWx0ZXIpO1xuICAgIH1cbiAgICBpZiAoZXhwLnNvcnQpIHtcbiAgICAgIHJlc3VsdHMgPSBzb3J0UmVjb3JkcyhyZXN1bHRzLCBleHAuc29ydCk7XG4gICAgfVxuICAgIGlmIChleHAucGFnZSkge1xuICAgICAgcmVzdWx0cyA9IHBhZ2luYXRlUmVjb3JkcyhyZXN1bHRzLCBleHAucGFnZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9LFxuXG4gIGZpbmRSZWxhdGVkUmVjb3JkcyhcbiAgICBjYWNoZTogU3luY1JlY29yZEFjY2Vzc29yLFxuICAgIGV4cHJlc3Npb246IFJlY29yZFF1ZXJ5RXhwcmVzc2lvbixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmRbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZXhwID0gZXhwcmVzc2lvbiBhcyBGaW5kUmVsYXRlZFJlY29yZHM7XG4gICAgY29uc3QgeyByZWNvcmQsIHJlbGF0aW9uc2hpcCB9ID0gZXhwO1xuICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBjYWNoZS5nZXRSZWxhdGVkUmVjb3Jkc1N5bmMocmVjb3JkLCByZWxhdGlvbnNoaXApO1xuICAgIGlmICghcmVsYXRlZElkcyB8fCByZWxhdGVkSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKCFjYWNoZS5nZXRSZWNvcmRTeW5jKHJlY29yZCkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnJhaXNlTm90Rm91bmRFeGNlcHRpb25zKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0cyA9IGNhY2hlLmdldFJlY29yZHNTeW5jKHJlbGF0ZWRJZHMpO1xuXG4gICAgaWYgKGV4cC5maWx0ZXIpIHtcbiAgICAgIHJlc3VsdHMgPSBmaWx0ZXJSZWNvcmRzKHJlc3VsdHMsIGV4cC5maWx0ZXIpO1xuICAgIH1cbiAgICBpZiAoZXhwLnNvcnQpIHtcbiAgICAgIHJlc3VsdHMgPSBzb3J0UmVjb3JkcyhyZXN1bHRzLCBleHAuc29ydCk7XG4gICAgfVxuICAgIGlmIChleHAucGFnZSkge1xuICAgICAgcmVzdWx0cyA9IHBhZ2luYXRlUmVjb3JkcyhyZXN1bHRzLCBleHAucGFnZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9LFxuXG4gIGZpbmRSZWxhdGVkUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBJbml0aWFsaXplZFJlY29yZCB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGV4cCA9IGV4cHJlc3Npb24gYXMgRmluZFJlbGF0ZWRSZWNvcmQ7XG4gICAgY29uc3QgeyByZWNvcmQsIHJlbGF0aW9uc2hpcCB9ID0gZXhwO1xuICAgIGNvbnN0IHJlbGF0ZWRJZCA9IGNhY2hlLmdldFJlbGF0ZWRSZWNvcmRTeW5jKHJlY29yZCwgcmVsYXRpb25zaGlwKTtcblxuICAgIGlmIChyZWxhdGVkSWQpIHtcbiAgICAgIHJldHVybiBjYWNoZS5nZXRSZWNvcmRTeW5jKHJlbGF0ZWRJZCkgfHwgbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjYWNoZS5nZXRSZWNvcmRTeW5jKHJlY29yZCkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnJhaXNlTm90Rm91bmRFeGNlcHRpb25zKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXJSZWNvcmRzKHJlY29yZHM6IEluaXRpYWxpemVkUmVjb3JkW10sIGZpbHRlcnM6IGFueVtdKSB7XG4gIHJldHVybiByZWNvcmRzLmZpbHRlcigocmVjb3JkKSA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBmaWx0ZXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKCFhcHBseUZpbHRlcihyZWNvcmQsIGZpbHRlcnNbaV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhcHBseUZpbHRlcihyZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLCBmaWx0ZXI6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAoZmlsdGVyLmtpbmQgPT09ICdhdHRyaWJ1dGUnKSB7XG4gICAgbGV0IGFjdHVhbCA9IGRlZXBHZXQocmVjb3JkLCBbJ2F0dHJpYnV0ZXMnLCBmaWx0ZXIuYXR0cmlidXRlXSk7XG4gICAgaWYgKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBleHBlY3RlZCA9IGZpbHRlci52YWx1ZTtcbiAgICBzd2l0Y2ggKGZpbHRlci5vcCkge1xuICAgICAgY2FzZSAnZXF1YWwnOlxuICAgICAgICByZXR1cm4gYWN0dWFsID09PSBleHBlY3RlZDtcbiAgICAgIGNhc2UgJ2d0JzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA+IGV4cGVjdGVkO1xuICAgICAgY2FzZSAnZ3RlJzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA+PSBleHBlY3RlZDtcbiAgICAgIGNhc2UgJ2x0JzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA8IGV4cGVjdGVkO1xuICAgICAgY2FzZSAnbHRlJzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA8PSBleHBlY3RlZDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICdGaWx0ZXIgb3BlcmF0aW9uICR7ZmlsdGVyLm9wfSBub3QgcmVjb2duaXplZCBmb3IgU3RvcmUuJ1xuICAgICAgICApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChmaWx0ZXIua2luZCA9PT0gJ3JlbGF0ZWRSZWNvcmRzJykge1xuICAgIGxldCBhY3R1YWw6IFJlY29yZElkZW50aXR5W10gPSBkZWVwR2V0KHJlY29yZCwgW1xuICAgICAgJ3JlbGF0aW9uc2hpcHMnLFxuICAgICAgZmlsdGVyLnJlbGF0aW9uLFxuICAgICAgJ2RhdGEnXG4gICAgXSk7XG4gICAgaWYgKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBleHBlY3RlZDogUmVjb3JkSWRlbnRpdHlbXSA9IGZpbHRlci5yZWNvcmRzO1xuICAgIHN3aXRjaCAoZmlsdGVyLm9wKSB7XG4gICAgICBjYXNlICdlcXVhbCc6XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgYWN0dWFsLmxlbmd0aCA9PT0gZXhwZWN0ZWQubGVuZ3RoICYmXG4gICAgICAgICAgZXhwZWN0ZWQuZXZlcnkoKGUpID0+XG4gICAgICAgICAgICBhY3R1YWwuc29tZSgoYSkgPT4gYS5pZCA9PT0gZS5pZCAmJiBhLnR5cGUgPT09IGUudHlwZSlcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICBjYXNlICdhbGwnOlxuICAgICAgICByZXR1cm4gZXhwZWN0ZWQuZXZlcnkoKGUpID0+XG4gICAgICAgICAgYWN0dWFsLnNvbWUoKGEpID0+IGEuaWQgPT09IGUuaWQgJiYgYS50eXBlID09PSBlLnR5cGUpXG4gICAgICAgICk7XG4gICAgICBjYXNlICdzb21lJzpcbiAgICAgICAgcmV0dXJuIGV4cGVjdGVkLnNvbWUoKGUpID0+XG4gICAgICAgICAgYWN0dWFsLnNvbWUoKGEpID0+IGEuaWQgPT09IGUuaWQgJiYgYS50eXBlID09PSBlLnR5cGUpXG4gICAgICAgICk7XG4gICAgICBjYXNlICdub25lJzpcbiAgICAgICAgcmV0dXJuICFleHBlY3RlZC5zb21lKChlKSA9PlxuICAgICAgICAgIGFjdHVhbC5zb21lKChhKSA9PiBhLmlkID09PSBlLmlkICYmIGEudHlwZSA9PT0gZS50eXBlKVxuICAgICAgICApO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IoXG4gICAgICAgICAgJ0ZpbHRlciBvcGVyYXRpb24gJHtmaWx0ZXIub3B9IG5vdCByZWNvZ25pemVkIGZvciBTdG9yZS4nXG4gICAgICAgICk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGZpbHRlci5raW5kID09PSAncmVsYXRlZFJlY29yZCcpIHtcbiAgICBsZXQgYWN0dWFsID0gZGVlcEdldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIGZpbHRlci5yZWxhdGlvbiwgJ2RhdGEnXSk7XG4gICAgaWYgKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBleHBlY3RlZCA9IGZpbHRlci5yZWNvcmQ7XG4gICAgc3dpdGNoIChmaWx0ZXIub3ApIHtcbiAgICAgIGNhc2UgJ2VxdWFsJzpcbiAgICAgICAgaWYgKGFjdHVhbCA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBleHBlY3RlZCA9PT0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShleHBlY3RlZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBleHBlY3RlZC5zb21lKFxuICAgICAgICAgICAgICAoZSkgPT4gYWN0dWFsLnR5cGUgPT09IGUudHlwZSAmJiBhY3R1YWwuaWQgPT09IGUuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChleHBlY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGFjdHVhbC50eXBlID09PSBleHBlY3RlZC50eXBlICYmIGFjdHVhbC5pZCA9PT0gZXhwZWN0ZWQuaWQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICdGaWx0ZXIgb3BlcmF0aW9uICR7ZmlsdGVyLm9wfSBub3QgcmVjb2duaXplZCBmb3IgU3RvcmUuJ1xuICAgICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHNvcnRSZWNvcmRzKFxuICByZWNvcmRzOiBJbml0aWFsaXplZFJlY29yZFtdLFxuICBzb3J0U3BlY2lmaWVyczogU29ydFNwZWNpZmllcltdXG4pOiBJbml0aWFsaXplZFJlY29yZFtdIHtcbiAgY29uc3QgY29tcGFyaXNvblZhbHVlcyA9IG5ldyBNYXAoKTtcblxuICByZWNvcmRzLmZvckVhY2goKHJlY29yZCkgPT4ge1xuICAgIGNvbXBhcmlzb25WYWx1ZXMuc2V0KFxuICAgICAgcmVjb3JkLFxuICAgICAgc29ydFNwZWNpZmllcnMubWFwKChzb3J0U3BlY2lmaWVyKSA9PiB7XG4gICAgICAgIGlmIChzb3J0U3BlY2lmaWVyLmtpbmQgPT09ICdhdHRyaWJ1dGUnKSB7XG4gICAgICAgICAgcmV0dXJuIGRlZXBHZXQocmVjb3JkLCBbXG4gICAgICAgICAgICAnYXR0cmlidXRlcycsXG4gICAgICAgICAgICAoc29ydFNwZWNpZmllciBhcyBBdHRyaWJ1dGVTb3J0U3BlY2lmaWVyKS5hdHRyaWJ1dGVcbiAgICAgICAgICBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUXVlcnlFeHByZXNzaW9uUGFyc2VFcnJvcihcbiAgICAgICAgICAgICdTb3J0IHNwZWNpZmllciAke3NvcnRTcGVjaWZpZXIua2luZH0gbm90IHJlY29nbml6ZWQgZm9yIFN0b3JlLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH0pO1xuXG4gIGNvbnN0IGNvbXBhcmlzb25PcmRlcnMgPSBzb3J0U3BlY2lmaWVycy5tYXAoKHNvcnRFeHByZXNzaW9uKSA9PlxuICAgIHNvcnRFeHByZXNzaW9uLm9yZGVyID09PSAnZGVzY2VuZGluZycgPyAtMSA6IDFcbiAgKTtcblxuICByZXR1cm4gcmVjb3Jkcy5zb3J0KChyZWNvcmQxLCByZWNvcmQyKSA9PiB7XG4gICAgY29uc3QgdmFsdWVzMSA9IGNvbXBhcmlzb25WYWx1ZXMuZ2V0KHJlY29yZDEpO1xuICAgIGNvbnN0IHZhbHVlczIgPSBjb21wYXJpc29uVmFsdWVzLmdldChyZWNvcmQyKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNvcnRTcGVjaWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodmFsdWVzMVtpXSA8IHZhbHVlczJbaV0pIHtcbiAgICAgICAgcmV0dXJuIC1jb21wYXJpc29uT3JkZXJzW2ldO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZXMxW2ldID4gdmFsdWVzMltpXSkge1xuICAgICAgICByZXR1cm4gY29tcGFyaXNvbk9yZGVyc1tpXTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb25lKHZhbHVlczFbaV0pICYmICFpc05vbmUodmFsdWVzMltpXSkpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmlzb25PcmRlcnNbaV07XG4gICAgICB9IGVsc2UgaWYgKGlzTm9uZSh2YWx1ZXMyW2ldKSAmJiAhaXNOb25lKHZhbHVlczFbaV0pKSB7XG4gICAgICAgIHJldHVybiAtY29tcGFyaXNvbk9yZGVyc1tpXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBwYWdpbmF0ZVJlY29yZHMoXG4gIHJlY29yZHM6IEluaXRpYWxpemVkUmVjb3JkW10sXG4gIHBhZ2luYXRpb25PcHRpb25zOiBhbnlcbik6IEluaXRpYWxpemVkUmVjb3JkW10ge1xuICBpZiAocGFnaW5hdGlvbk9wdGlvbnMubGltaXQgIT09IHVuZGVmaW5lZCkge1xuICAgIGxldCBvZmZzZXQgPVxuICAgICAgcGFnaW5hdGlvbk9wdGlvbnMub2Zmc2V0ID09PSB1bmRlZmluZWQgPyAwIDogcGFnaW5hdGlvbk9wdGlvbnMub2Zmc2V0O1xuICAgIGxldCBsaW1pdCA9IHBhZ2luYXRpb25PcHRpb25zLmxpbWl0O1xuXG4gICAgcmV0dXJuIHJlY29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBsaW1pdCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IoXG4gICAgICAnUGFnaW5hdGlvbiBvcHRpb25zIG5vdCByZWNvZ25pemVkIGZvciBTdG9yZS4gUGxlYXNlIHNwZWNpZnkgYG9mZnNldGAgYW5kIGBsaW1pdGAuJ1xuICAgICk7XG4gIH1cbn1cbiJdfQ==