@orbit/record-cache
Version:
Orbit base classes used to access and maintain a set of records.
198 lines • 30.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.recordArrayFromData = exports.removeRelationshipOp = exports.addRelationshipOp = exports.removeRelatedRecordsOps = exports.recordUpdated = exports.recordRemoved = exports.relatedRecordsReplaced = exports.relatedRecordReplaced = exports.relatedRecordRemoved = exports.relatedRecordAdded = exports.recordAdded = void 0;
const utils_1 = require("@orbit/utils");
const records_1 = require("@orbit/records");
function recordAdded(schema, record) {
const ops = [];
if (record.relationships) {
const recordIdentity = (0, records_1.cloneRecordIdentity)(record);
schema.eachRelationship(record.type, (relationship, relationshipDef) => {
const relationshipData = (0, utils_1.deepGet)(record, [
'relationships',
relationship,
'data'
]);
if (relationshipData) {
const relatedRecords = recordArrayFromData(relationshipData);
Array.prototype.push.apply(ops, addRelatedRecordsOps(schema, recordIdentity, relationshipDef, relatedRecords));
}
});
}
return ops;
}
exports.recordAdded = recordAdded;
function relatedRecordAdded(schema, record, relationship, relatedRecord) {
const ops = [];
if (relatedRecord) {
const { type } = record;
const relationshipDef = schema.getRelationship(type, relationship);
const inverseRelationship = relationshipDef.inverse;
if (inverseRelationship) {
ops.push(addRelationshipOp(schema, relatedRecord, inverseRelationship, record));
}
}
return ops;
}
exports.relatedRecordAdded = relatedRecordAdded;
function relatedRecordRemoved(schema, record, relationship, relatedRecord, currentRelatedRecord) {
const ops = [];
if (currentRelatedRecord) {
const { type } = record;
const relationshipDef = schema.getRelationship(type, relationship);
const inverseRelationship = relationshipDef.inverse;
if (inverseRelationship) {
ops.push(removeRelationshipOp(schema, relatedRecord, inverseRelationship, record));
}
}
return ops;
}
exports.relatedRecordRemoved = relatedRecordRemoved;
function relatedRecordReplaced(schema, record, relationship, relatedRecord, currentRelatedRecord) {
const ops = [];
if (!(0, records_1.equalRecordIdentities)(relatedRecord, currentRelatedRecord)) {
const { type } = record;
const relationshipDef = schema.getRelationship(type, relationship);
const inverseRelationship = relationshipDef.inverse;
if (inverseRelationship) {
if (currentRelatedRecord) {
ops.push(removeRelationshipOp(schema, currentRelatedRecord, inverseRelationship, record));
}
if (relatedRecord) {
ops.push(addRelationshipOp(schema, relatedRecord, inverseRelationship, record));
}
}
}
return ops;
}
exports.relatedRecordReplaced = relatedRecordReplaced;
function relatedRecordsReplaced(schema, record, relationship, relatedRecords, currentRelatedRecords) {
const ops = [];
const { type } = record;
const relationshipDef = schema.getRelationship(type, relationship);
let addedRecords;
if (currentRelatedRecords && currentRelatedRecords.length > 0) {
let removedRecords = (0, records_1.uniqueRecordIdentities)(currentRelatedRecords, relatedRecords);
Array.prototype.push.apply(ops, removeRelatedRecordsOps(schema, record, relationshipDef, removedRecords));
addedRecords = (0, records_1.uniqueRecordIdentities)(relatedRecords, currentRelatedRecords);
}
else {
addedRecords = relatedRecords;
}
Array.prototype.push.apply(ops, addRelatedRecordsOps(schema, record, relationshipDef, addedRecords));
return ops;
}
exports.relatedRecordsReplaced = relatedRecordsReplaced;
function recordRemoved(schema, record) {
const ops = [];
if (record && record.relationships) {
const recordIdentity = (0, records_1.cloneRecordIdentity)(record);
schema.eachRelationship(record.type, (relationship, relationshipDef) => {
const relationshipData = (0, utils_1.deepGet)(record, [
'relationships',
relationship,
'data'
]);
if (relationshipData) {
const relatedRecords = recordArrayFromData(relationshipData);
Array.prototype.push.apply(ops, removeRelatedRecordsOps(schema, recordIdentity, relationshipDef, relatedRecords));
}
});
}
return ops;
}
exports.recordRemoved = recordRemoved;
function recordUpdated(schema, record, currentRecord) {
const ops = [];
if (record.relationships) {
const recordIdentity = (0, records_1.cloneRecordIdentity)(record);
schema.eachRelationship(record.type, (relationship, relationshipDef) => {
var _a;
const relationshipData = (0, utils_1.deepGet)(record, [
'relationships',
relationship,
'data'
]);
const currentRelationshipData = currentRecord &&
(0, utils_1.deepGet)(currentRecord, ['relationships', relationship, 'data']);
if (relationshipData !== undefined) {
// TODO - remove deprecated `type` check
if (((_a = relationshipDef.kind) !== null && _a !== void 0 ? _a : relationshipDef.type) === 'hasMany') {
Array.prototype.push.apply(ops, relatedRecordsReplaced(schema, recordIdentity, relationship, relationshipData || [], currentRelationshipData || []));
}
else {
Array.prototype.push.apply(ops, relatedRecordReplaced(schema, recordIdentity, relationship, relationshipData || null, currentRelationshipData || null));
}
}
});
}
return ops;
}
exports.recordUpdated = recordUpdated;
function addRelatedRecordsOps(schema, record, relationshipDef, relatedRecords) {
if (relatedRecords.length > 0 && relationshipDef.inverse) {
const inverse = relationshipDef.inverse;
return relatedRecords.map((relatedRecord) => addRelationshipOp(schema, relatedRecord, inverse, record));
}
return [];
}
function removeRelatedRecordsOps(schema, record, relationshipDef, relatedRecords) {
if (relatedRecords.length > 0) {
if (relationshipDef.dependent === 'remove') {
return removeDependentRecords(relatedRecords);
}
else if (relationshipDef.inverse) {
const inverse = relationshipDef.inverse;
return relatedRecords.map((relatedRecord) => removeRelationshipOp(schema, relatedRecord, inverse, record));
}
}
return [];
}
exports.removeRelatedRecordsOps = removeRelatedRecordsOps;
function addRelationshipOp(schema, record, relationship, relatedRecord) {
var _a;
const { type } = record;
const relationshipDef = schema.getRelationship(type, relationship);
// TODO - remove deprecated `type` check
const isHasMany = ((_a = relationshipDef.kind) !== null && _a !== void 0 ? _a : relationshipDef.type) === 'hasMany';
return {
op: isHasMany ? 'addToRelatedRecords' : 'replaceRelatedRecord',
record,
relationship,
relatedRecord
};
}
exports.addRelationshipOp = addRelationshipOp;
function removeRelationshipOp(schema, record, relationship, relatedRecord) {
var _a;
const { type } = record;
const relationshipDef = schema.getRelationship(type, relationship);
// TODO - remove deprecated `type` check
const isHasMany = ((_a = relationshipDef.kind) !== null && _a !== void 0 ? _a : relationshipDef.type) === 'hasMany';
return {
op: isHasMany ? 'removeFromRelatedRecords' : 'replaceRelatedRecord',
record,
relationship,
relatedRecord: isHasMany ? relatedRecord : null
};
}
exports.removeRelationshipOp = removeRelationshipOp;
function recordArrayFromData(data) {
if (Array.isArray(data)) {
return data;
}
else if (data) {
return [data];
}
else {
return [];
}
}
exports.recordArrayFromData = recordArrayFromData;
function removeDependentRecords(relatedRecords) {
return relatedRecords.map((record) => ({
op: 'removeRecord',
record
}));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLWNvbnNpc3RlbmN5LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL29wZXJhdGlvbi1wcm9jZXNzb3JzL3V0aWxzL3NjaGVtYS1jb25zaXN0ZW5jeS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3Q0FBdUM7QUFDdkMsNENBU3dCO0FBRXhCLFNBQWdCLFdBQVcsQ0FDekIsTUFBb0IsRUFDcEIsTUFBeUI7SUFFekIsTUFBTSxHQUFHLEdBQXNCLEVBQUUsQ0FBQztJQUVsQyxJQUFJLE1BQU0sQ0FBQyxhQUFhLEVBQUU7UUFDeEIsTUFBTSxjQUFjLEdBQUcsSUFBQSw2QkFBbUIsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUVuRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLFlBQVksRUFBRSxlQUFlLEVBQUUsRUFBRTtZQUNyRSxNQUFNLGdCQUFnQixHQUFHLElBQUEsZUFBTyxFQUFDLE1BQU0sRUFBRTtnQkFDdkMsZUFBZTtnQkFDZixZQUFZO2dCQUNaLE1BQU07YUFDUCxDQUF5RCxDQUFDO1lBRTNELElBQUksZ0JBQWdCLEVBQUU7Z0JBQ3BCLE1BQU0sY0FBYyxHQUFHLG1CQUFtQixDQUN4QyxnQkFBZ0IsQ0FDRyxDQUFDO2dCQUV0QixLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQ3hCLEdBQUcsRUFDSCxvQkFBb0IsQ0FDbEIsTUFBTSxFQUNOLGNBQWMsRUFDZCxlQUFlLEVBQ2YsY0FBYyxDQUNmLENBQ0YsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxDQUFDLENBQUM7S0FDSjtJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQW5DRCxrQ0FtQ0M7QUFFRCxTQUFnQixrQkFBa0IsQ0FDaEMsTUFBb0IsRUFDcEIsTUFBc0IsRUFDdEIsWUFBb0IsRUFDcEIsYUFBNkI7SUFFN0IsTUFBTSxHQUFHLEdBQXNCLEVBQUUsQ0FB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LG9EQWtCQztBQUVELFNBQWdCLG1CQUFtQixDQUNqQyxJQUE4QztJQUU5QyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDdkIsT0FBTyxJQUFJLENBQUM7S0FDYjtTQUFNLElBQUksSUFBSSxFQUFFO1FBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2Y7U0FBTTtRQUNMLE9BQU8sRUFBRSxDQUFDO0tBQ1g7QUFDSCxDQUFDO0FBVkQsa0RBVUM7QUFFRCxTQUFTLHNCQUFzQixDQUM3QixjQUFnQztJQUVoQyxPQUFPLGNBQWMsQ0FBQyxHQUFHLENBQ3ZCLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FDVCxDQUFDO1FBQ0MsRUFBRSxFQUFFLGNBQWM7UUFDbEIsTUFBTTtLQUNhLENBQUEsQ0FDeEIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBkZWVwR2V0IH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7XG4gIGNsb25lUmVjb3JkSWRlbnRpdHksXG4gIGVxdWFsUmVjb3JkSWRlbnRpdGllcyxcbiAgdW5pcXVlUmVjb3JkSWRlbnRpdGllcyxcbiAgSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIFJlY29yZElkZW50aXR5LFxuICBSZWNvcmRPcGVyYXRpb24sXG4gIFJlbGF0aW9uc2hpcERlZmluaXRpb24sXG4gIFJlY29yZFNjaGVtYVxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBZGRlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmRcbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgY29uc3Qgb3BzOiBSZWNvcmRPcGVyYXRpb25bXSA9IFtdO1xuXG4gIGlmIChyZWNvcmQucmVsYXRpb25zaGlwcykge1xuICAgIGNvbnN0IHJlY29yZElkZW50aXR5ID0gY2xvbmVSZWNvcmRJZGVudGl0eShyZWNvcmQpO1xuXG4gICAgc2NoZW1hLmVhY2hSZWxhdGlvbnNoaXAocmVjb3JkLnR5cGUsIChyZWxhdGlvbnNoaXAsIHJlbGF0aW9uc2hpcERlZikgPT4ge1xuICAgICAgY29uc3QgcmVsYXRpb25zaGlwRGF0YSA9IGRlZXBHZXQocmVjb3JkLCBbXG4gICAgICAgICdyZWxhdGlvbnNoaXBzJyxcbiAgICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgICAnZGF0YSdcbiAgICAgIF0pIGFzIFJlY29yZElkZW50aXR5IHwgUmVjb3JkSWRlbnRpdHlbXSB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChyZWxhdGlvbnNoaXBEYXRhKSB7XG4gICAgICAgIGNvbnN0IHJlbGF0ZWRSZWNvcmRzID0gcmVjb3JkQXJyYXlGcm9tRGF0YShcbiAgICAgICAgICByZWxhdGlvbnNoaXBEYXRhXG4gICAgICAgICkgYXMgUmVjb3JkSWRlbnRpdHlbXTtcblxuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShcbiAgICAgICAgICBvcHMsXG4gICAgICAgICAgYWRkUmVsYXRlZFJlY29yZHNPcHMoXG4gICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICByZWNvcmRJZGVudGl0eSxcbiAgICAgICAgICAgIHJlbGF0aW9uc2hpcERlZixcbiAgICAgICAgICAgIHJlbGF0ZWRSZWNvcmRzXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG9wcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0ZWRSZWNvcmRBZGRlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHksXG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICByZWxhdGVkUmVjb3JkOiBSZWNvcmRJZGVudGl0eVxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKHJlbGF0ZWRSZWNvcmQpIHtcbiAgICBjb25zdCB7IHR5cGUgfSA9IHJlY29yZDtcbiAgICBjb25zdCByZWxhdGlvbnNoaXBEZWYgPSBzY2hlbWEuZ2V0UmVsYXRpb25zaGlwKHR5cGUsIHJlbGF0aW9uc2hpcCk7XG4gICAgY29uc3QgaW52ZXJzZVJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcERlZi5pbnZlcnNlO1xuXG4gICAgaWYgKGludmVyc2VSZWxhdGlvbnNoaXApIHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICBhZGRSZWxhdGlvbnNoaXBPcChzY2hlbWEsIHJlbGF0ZWRSZWNvcmQsIGludmVyc2VSZWxhdGlvbnNoaXAsIHJlY29yZClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9wcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0ZWRSZWNvcmRSZW1vdmVkKFxuICBzY2hlbWE6IFJlY29yZFNjaGVtYSxcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgcmVsYXRpb25zaGlwOiBzdHJpbmcsXG4gIHJlbGF0ZWRSZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICBjdXJyZW50UmVsYXRlZFJlY29yZD86IFJlY29yZElkZW50aXR5IHwgbnVsbFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKGN1cnJlbnRSZWxhdGVkUmVjb3JkKSB7XG4gICAgY29uc3QgeyB0eXBlIH0gPSByZWNvcmQ7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwRGVmID0gc2NoZW1hLmdldFJlbGF0aW9uc2hpcCh0eXBlLCByZWxhdGlvbnNoaXApO1xuICAgIGNvbnN0IGludmVyc2VSZWxhdGlvbnNoaXAgPSByZWxhdGlvbnNoaXBEZWYuaW52ZXJzZTtcblxuICAgIGlmIChpbnZlcnNlUmVsYXRpb25zaGlwKSB7XG4gICAgICBvcHMucHVzaChcbiAgICAgICAgcmVtb3ZlUmVsYXRpb25zaGlwT3Aoc2NoZW1hLCByZWxhdGVkUmVjb3JkLCBpbnZlcnNlUmVsYXRpb25zaGlwLCByZWNvcmQpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWxhdGVkUmVjb3JkUmVwbGFjZWQoXG4gIHNjaGVtYTogUmVjb3JkU2NoZW1hLFxuICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHkgfCBudWxsLFxuICBjdXJyZW50UmVsYXRlZFJlY29yZD86IFJlY29yZElkZW50aXR5IHwgbnVsbFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKFxuICAgICFlcXVhbFJlY29yZElkZW50aXRpZXMoXG4gICAgICByZWxhdGVkUmVjb3JkIGFzIFJlY29yZElkZW50aXR5LFxuICAgICAgY3VycmVudFJlbGF0ZWRSZWNvcmQgYXMgUmVjb3JkSWRlbnRpdHlcbiAgICApXG4gICkge1xuICAgIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuICAgIGNvbnN0IHJlbGF0aW9uc2hpcERlZiA9IHNjaGVtYS5nZXRSZWxhdGlvbnNoaXAodHlwZSwgcmVsYXRpb25zaGlwKTtcbiAgICBjb25zdCBpbnZlcnNlUmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwRGVmLmludmVyc2U7XG5cbiAgICBpZiAoaW52ZXJzZVJlbGF0aW9uc2hpcCkge1xuICAgICAgaWYgKGN1cnJlbnRSZWxhdGVkUmVjb3JkKSB7XG4gICAgICAgIG9wcy5wdXNoKFxuICAgICAgICAgIHJlbW92ZVJlbGF0aW9uc2hpcE9wKFxuICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgY3VycmVudFJlbGF0ZWRSZWNvcmQsXG4gICAgICAgICAgICBpbnZlcnNlUmVsYXRpb25zaGlwLFxuICAgICAgICAgICAgcmVjb3JkXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVsYXRlZFJlY29yZCkge1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICBhZGRSZWxhdGlvbnNoaXBPcChzY2hlbWEsIHJlbGF0ZWRSZWNvcmQsIGludmVyc2VSZWxhdGlvbnNoaXAsIHJlY29yZClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3BzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRlZFJlY29yZHNSZXBsYWNlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHksXG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXSxcbiAgY3VycmVudFJlbGF0ZWRSZWNvcmRzPzogUmVjb3JkSWRlbnRpdHlbXVxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG4gIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuICBjb25zdCByZWxhdGlvbnNoaXBEZWYgPSBzY2hlbWEuZ2V0UmVsYXRpb25zaGlwKHR5cGUsIHJlbGF0aW9uc2hpcCk7XG5cbiAgbGV0IGFkZGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXTtcblxuICBpZiAoY3VycmVudFJlbGF0ZWRSZWNvcmRzICYmIGN1cnJlbnRSZWxhdGVkUmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgbGV0IHJlbW92ZWRSZWNvcmRzID0gdW5pcXVlUmVjb3JkSWRlbnRpdGllcyhcbiAgICAgIGN1cnJlbnRSZWxhdGVkUmVjb3JkcyxcbiAgICAgIHJlbGF0ZWRSZWNvcmRzXG4gICAgKTtcbiAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShcbiAgICAgIG9wcyxcbiAgICAgIHJlbW92ZVJlbGF0ZWRSZWNvcmRzT3BzKHNjaGVtYSwgcmVjb3JkLCByZWxhdGlvbnNoaXBEZWYsIHJlbW92ZWRSZWNvcmRzKVxuICAgICk7XG5cbiAgICBhZGRlZFJlY29yZHMgPSB1bmlxdWVSZWNvcmRJZGVudGl0aWVzKFxuICAgICAgcmVsYXRlZFJlY29yZHMsXG4gICAgICBjdXJyZW50UmVsYXRlZFJlY29yZHNcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGFkZGVkUmVjb3JkcyA9IHJlbGF0ZWRSZWNvcmRzO1xuICB9XG5cbiAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoXG4gICAgb3BzLFxuICAgIGFkZFJlbGF0ZWRSZWNvcmRzT3BzKHNjaGVtYSwgcmVjb3JkLCByZWxhdGlvbnNoaXBEZWYsIGFkZGVkUmVjb3JkcylcbiAgKTtcblxuICByZXR1cm4gb3BzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkUmVtb3ZlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZD86IEluaXRpYWxpemVkUmVjb3JkXG4pOiBSZWNvcmRPcGVyYXRpb25bXSB7XG4gIGNvbnN0IG9wczogUmVjb3JkT3BlcmF0aW9uW10gPSBbXTtcblxuICBpZiAocmVjb3JkICYmIHJlY29yZC5yZWxhdGlvbnNoaXBzKSB7XG4gICAgY29uc3QgcmVjb3JkSWRlbnRpdHkgPSBjbG9uZVJlY29yZElkZW50aXR5KHJlY29yZCk7XG5cbiAgICBzY2hlbWEuZWFjaFJlbGF0aW9uc2hpcChyZWNvcmQudHlwZSwgKHJlbGF0aW9uc2hpcCwgcmVsYXRpb25zaGlwRGVmKSA9PiB7XG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBEYXRhID0gZGVlcEdldChyZWNvcmQsIFtcbiAgICAgICAgJ3JlbGF0aW9uc2hpcHMnLFxuICAgICAgICByZWxhdGlvbnNoaXAsXG4gICAgICAgICdkYXRhJ1xuICAgICAgXSkgYXMgUmVjb3JkSWRlbnRpdHkgfCBSZWNvcmRJZGVudGl0eVtdIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKHJlbGF0aW9uc2hpcERhdGEpIHtcbiAgICAgICAgY29uc3QgcmVsYXRlZFJlY29yZHMgPSByZWNvcmRBcnJheUZyb21EYXRhKFxuICAgICAgICAgIHJlbGF0aW9uc2hpcERhdGFcbiAgICAgICAgKSBhcyBSZWNvcmRJZGVudGl0eVtdO1xuXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KFxuICAgICAgICAgIG9wcyxcbiAgICAgICAgICByZW1vdmVSZWxhdGVkUmVjb3Jkc09wcyhcbiAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgIHJlY29yZElkZW50aXR5LFxuICAgICAgICAgICAgcmVsYXRpb25zaGlwRGVmLFxuICAgICAgICAgICAgcmVsYXRlZFJlY29yZHNcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gb3BzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkVXBkYXRlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIGN1cnJlbnRSZWNvcmQ/OiBJbml0aWFsaXplZFJlY29yZFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKHJlY29yZC5yZWxhdGlvbnNoaXBzKSB7XG4gICAgY29uc3QgcmVjb3JkSWRlbnRpdHkgPSBjbG9uZVJlY29yZElkZW50aXR5KHJlY29yZCk7XG5cbiAgICBzY2hlbWEuZWFjaFJlbGF0aW9uc2hpcChyZWNvcmQudHlwZSwgKHJlbGF0aW9uc2hpcCwgcmVsYXRpb25zaGlwRGVmKSA9PiB7XG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBEYXRhID0gZGVlcEdldChyZWNvcmQsIFtcbiAgICAgICAgJ3JlbGF0aW9uc2hpcHMnLFxuICAgICAgICByZWxhdGlvbnNoaXAsXG4gICAgICAgICdkYXRhJ1xuICAgICAgXSkgYXMgUmVjb3JkSWRlbnRpdHkgfCBSZWNvcmRJZGVudGl0eVtdIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgY3VycmVudFJlbGF0aW9uc2hpcERhdGEgPVxuICAgICAgICBjdXJyZW50UmVjb3JkICYmXG4gICAgICAgIChkZWVwR2V0KGN1cnJlbnRSZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSkgYXNcbiAgICAgICAgICB8IFJlY29yZElkZW50aXR5XG4gICAgICAgICAgfCBSZWNvcmRJZGVudGl0eVtdXG4gICAgICAgICAgfCBudWxsXG4gICAgICAgICAgfCB1bmRlZmluZWQpO1xuXG4gICAgICBpZiAocmVsYXRpb25zaGlwRGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFRPRE8gLSByZW1vdmUgZGVwcmVjYXRlZCBgdHlwZWAgY2hlY2tcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChyZWxhdGlvbnNoaXBEZWYua2luZCA/PyAocmVsYXRpb25zaGlwRGVmIGFzIGFueSkudHlwZSkgPT09ICdoYXNNYW55J1xuICAgICAgICApIHtcbiAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShcbiAgICAgICAgICAgIG9wcyxcbiAgICAgICAgICAgIHJlbGF0ZWRSZWNvcmRzUmVwbGFjZWQoXG4gICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgcmVjb3JkSWRlbnRpdHksXG4gICAgICAgICAgICAgIHJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgICAgKHJlbGF0aW9uc2hpcERhdGEgYXMgUmVjb3JkSWRlbnRpdHlbXSkgfHwgW10sXG4gICAgICAgICAgICAgIChjdXJyZW50UmVsYXRpb25zaGlwRGF0YSBhcyBSZWNvcmRJZGVudGl0eVtdKSB8fCBbXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoXG4gICAgICAgICAgICBvcHMsXG4gICAgICAgICAgICByZWxhdGVkUmVjb3JkUmVwbGFjZWQoXG4gICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgcmVjb3JkSWRlbnRpdHksXG4gICAgICAgICAgICAgIHJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgICAgKHJlbGF0aW9uc2hpcERhdGEgYXMgUmVjb3JkSWRlbnRpdHkpIHx8IG51bGwsXG4gICAgICAgICAgICAgIChjdXJyZW50UmVsYXRpb25zaGlwRGF0YSBhcyBSZWNvcmRJZGVudGl0eSkgfHwgbnVsbFxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBvcHM7XG59XG5cbmZ1bmN0aW9uIGFkZFJlbGF0ZWRSZWNvcmRzT3BzKFxuICBzY2hlbWE6IFJlY29yZFNjaGVtYSxcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgcmVsYXRpb25zaGlwRGVmOiBSZWxhdGlvbnNoaXBEZWZpbml0aW9uLFxuICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXVxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBpZiAocmVsYXRlZFJlY29yZHMubGVuZ3RoID4gMCAmJiByZWxhdGlvbnNoaXBEZWYuaW52ZXJzZSkge1xuICAgIGNvbnN0IGludmVyc2UgPSByZWxhdGlvbnNoaXBEZWYuaW52ZXJzZTtcbiAgICByZXR1cm4gcmVsYXRlZFJlY29yZHMubWFwKChyZWxhdGVkUmVjb3JkKSA9PlxuICAgICAgYWRkUmVsYXRpb25zaGlwT3Aoc2NoZW1hLCByZWxhdGVkUmVjb3JkLCBpbnZlcnNlLCByZWNvcmQpXG4gICAgKTtcbiAgfVxuICByZXR1cm4gW107XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVSZWxhdGVkUmVjb3Jkc09wcyhcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHksXG4gIHJlbGF0aW9uc2hpcERlZjogUmVsYXRpb25zaGlwRGVmaW5pdGlvbixcbiAgcmVsYXRlZFJlY29yZHM6IFJlY29yZElkZW50aXR5W11cbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgaWYgKHJlbGF0ZWRSZWNvcmRzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAocmVsYXRpb25zaGlwRGVmLmRlcGVuZGVudCA9PT0gJ3JlbW92ZScpIHtcbiAgICAgIHJldHVybiByZW1vdmVEZXBlbmRlbnRSZWNvcmRzKHJlbGF0ZWRSZWNvcmRzKTtcbiAgICB9IGVsc2UgaWYgKHJlbGF0aW9uc2hpcERlZi5pbnZlcnNlKSB7XG4gICAgICBjb25zdCBpbnZlcnNlID0gcmVsYXRpb25zaGlwRGVmLmludmVyc2U7XG4gICAgICByZXR1cm4gcmVsYXRlZFJlY29yZHMubWFwKChyZWxhdGVkUmVjb3JkKSA9PlxuICAgICAgICByZW1vdmVSZWxhdGlvbnNoaXBPcChzY2hlbWEsIHJlbGF0ZWRSZWNvcmQsIGludmVyc2UsIHJlY29yZClcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHJldHVybiBbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFJlbGF0aW9uc2hpcE9wKFxuICBzY2hlbWE6IFJlY29yZFNjaGVtYSxcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgcmVsYXRpb25zaGlwOiBzdHJpbmcsXG4gIHJlbGF0ZWRSZWNvcmQ6IFJlY29yZElkZW50aXR5XG4pOiBSZWNvcmRPcGVyYXRpb24ge1xuICBjb25zdCB7IHR5cGUgfSA9IHJlY29yZDtcbiAgY29uc3QgcmVsYXRpb25zaGlwRGVmID0gc2NoZW1hLmdldFJlbGF0aW9uc2hpcCh0eXBlLCByZWxhdGlvbnNoaXApO1xuICAvLyBUT0RPIC0gcmVtb3ZlIGRlcHJlY2F0ZWQgYHR5cGVgIGNoZWNrXG4gIGNvbnN0IGlzSGFzTWFueSA9XG4gICAgKHJlbGF0aW9uc2hpcERlZi5raW5kID8/IChyZWxhdGlvbnNoaXBEZWYgYXMgYW55KS50eXBlKSA9PT0gJ2hhc01hbnknO1xuXG4gIHJldHVybiB7XG4gICAgb3A6IGlzSGFzTWFueSA/ICdhZGRUb1JlbGF0ZWRSZWNvcmRzJyA6ICdyZXBsYWNlUmVsYXRlZFJlY29yZCcsXG4gICAgcmVjb3JkLFxuICAgIHJlbGF0aW9uc2hpcCxcbiAgICByZWxhdGVkUmVjb3JkXG4gIH0gYXMgUmVjb3JkT3BlcmF0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlUmVsYXRpb25zaGlwT3AoXG4gIHNjaGVtYTogUmVjb3JkU2NoZW1hLFxuICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHlcbik6IFJlY29yZE9wZXJhdGlvbiB7XG4gIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuICBjb25zdCByZWxhdGlvbnNoaXBEZWYgPSBzY2hlbWEuZ2V0UmVsYXRpb25zaGlwKHR5cGUsIHJlbGF0aW9uc2hpcCk7XG4gIC8vIFRPRE8gLSByZW1vdmUgZGVwcmVjYXRlZCBgdHlwZWAgY2hlY2tcbiAgY29uc3QgaXNIYXNNYW55ID1cbiAgICAocmVsYXRpb25zaGlwRGVmLmtpbmQgPz8gKHJlbGF0aW9uc2hpcERlZiBhcyBhbnkpLnR5cGUpID09PSAnaGFzTWFueSc7XG5cbiAgcmV0dXJuIHtcbiAgICBvcDogaXNIYXNNYW55ID8gJ3JlbW92ZUZyb21SZWxhdGVkUmVjb3JkcycgOiAncmVwbGFjZVJlbGF0ZWRSZWNvcmQnLFxuICAgIHJlY29yZCxcbiAgICByZWxhdGlvbnNoaXAsXG4gICAgcmVsYXRlZFJlY29yZDogaXNIYXNNYW55ID8gcmVsYXRlZFJlY29yZCA6IG51bGxcbiAgfSBhcyBSZWNvcmRPcGVyYXRpb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBcnJheUZyb21EYXRhKFxuICBkYXRhOiBSZWNvcmRJZGVudGl0eSB8IFJlY29yZElkZW50aXR5W10gfCBudWxsXG4pOiBSZWNvcmRJZGVudGl0eVtdIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfSBlbHNlIGlmIChkYXRhKSB7XG4gICAgcmV0dXJuIFtkYXRhXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGVwZW5kZW50UmVjb3JkcyhcbiAgcmVsYXRlZFJlY29yZHM6IFJlY29yZElkZW50aXR5W11cbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgcmV0dXJuIHJlbGF0ZWRSZWNvcmRzLm1hcChcbiAgICAocmVjb3JkKSA9PlxuICAgICAgKHtcbiAgICAgICAgb3A6ICdyZW1vdmVSZWNvcmQnLFxuICAgICAgICByZWNvcmRcbiAgICAgIH0gYXMgUmVjb3JkT3BlcmF0aW9uKVxuICApO1xufVxuIl19