@orbit/record-cache
Version:
Orbit base classes used to access and maintain a set of records.
184 lines • 29.4 kB
JavaScript
import { deepGet } from '@orbit/utils';
import { cloneRecordIdentity, equalRecordIdentities, uniqueRecordIdentities } from '@orbit/records';
export function recordAdded(schema, record) {
const ops = [];
if (record.relationships) {
const recordIdentity = cloneRecordIdentity(record);
schema.eachRelationship(record.type, (relationship, relationshipDef) => {
const relationshipData = deepGet(record, [
'relationships',
relationship,
'data'
]);
if (relationshipData) {
const relatedRecords = recordArrayFromData(relationshipData);
Array.prototype.push.apply(ops, addRelatedRecordsOps(schema, recordIdentity, relationshipDef, relatedRecords));
}
});
}
return ops;
}
export 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;
}
export 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;
}
export function relatedRecordReplaced(schema, record, relationship, relatedRecord, currentRelatedRecord) {
const ops = [];
if (!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;
}
export 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 = uniqueRecordIdentities(currentRelatedRecords, relatedRecords);
Array.prototype.push.apply(ops, removeRelatedRecordsOps(schema, record, relationshipDef, removedRecords));
addedRecords = uniqueRecordIdentities(relatedRecords, currentRelatedRecords);
}
else {
addedRecords = relatedRecords;
}
Array.prototype.push.apply(ops, addRelatedRecordsOps(schema, record, relationshipDef, addedRecords));
return ops;
}
export function recordRemoved(schema, record) {
const ops = [];
if (record && record.relationships) {
const recordIdentity = cloneRecordIdentity(record);
schema.eachRelationship(record.type, (relationship, relationshipDef) => {
const relationshipData = deepGet(record, [
'relationships',
relationship,
'data'
]);
if (relationshipData) {
const relatedRecords = recordArrayFromData(relationshipData);
Array.prototype.push.apply(ops, removeRelatedRecordsOps(schema, recordIdentity, relationshipDef, relatedRecords));
}
});
}
return ops;
}
export function recordUpdated(schema, record, currentRecord) {
const ops = [];
if (record.relationships) {
const recordIdentity = cloneRecordIdentity(record);
schema.eachRelationship(record.type, (relationship, relationshipDef) => {
var _a;
const relationshipData = deepGet(record, [
'relationships',
relationship,
'data'
]);
const currentRelationshipData = currentRecord &&
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;
}
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 [];
}
export 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 [];
}
export 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
};
}
export 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
};
}
export function recordArrayFromData(data) {
if (Array.isArray(data)) {
return data;
}
else if (data) {
return [data];
}
else {
return [];
}
}
function removeDependentRecords(relatedRecords) {
return relatedRecords.map((record) => ({
op: 'removeRecord',
record
}));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLWNvbnNpc3RlbmN5LXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL29wZXJhdGlvbi1wcm9jZXNzb3JzL3V0aWxzL3NjaGVtYS1jb25zaXN0ZW5jeS11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIscUJBQXFCLEVBQ3JCLHNCQUFzQixFQU12QixNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE1BQU0sVUFBVSxXQUFXLENBQ3pCLE1BQW9CLEVBQ3BCLE1BQXlCO0lBRXpCLE1BQU0sR0FBRyxHQUFzQixFQUFFLENBQUM7SUFFbEMsSUFBSSxNQUFNLENBQUMsYUFBYSxFQUFFO1FBQ3hCLE1BQU0sY0FBYyxHQUFHLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRW5ELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxFQUFFO1lBQ3JFLE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLE1BQU0sRUFBRTtnQkFDdkMsZUFBZTtnQkFDZixZQUFZO2dCQUNaLE1BQU07YUFDUCxDQUF5RCxDQUFDO1lBRTNELElBQUksZ0JBQWdCLEVBQUU7Z0JBQ3BCLE1BQU0sY0FBYyxHQUFHLG1CQUFtQixDQUN4QyxnQkFBZ0IsQ0FDRyxDQUFDO2dCQUV0QixLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQ3hCLEdBQUcsRUFDSCxvQkFBb0IsQ0FDbEIsTUFBTSxFQUNOLGNBQWMsRUFDZCxlQUFlLEVBQ2YsY0FBYyxDQUNmLENBQ0YsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxDQUFDLENBQUM7S0FDSjtJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsTUFB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SyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUN2QixPQUFPLElBQUksQ0FBQztLQUNiO1NBQU0sSUFBSSxJQUFJLEVBQUU7UUFDZixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7S0FDZjtTQUFNO1FBQ0wsT0FBTyxFQUFFLENBQUM7S0FDWDtBQUNILENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUM3QixjQUFnQztJQUVoQyxPQUFPLGNBQWMsQ0FBQyxHQUFHLENBQ3ZCLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FDVCxDQUFDO1FBQ0MsRUFBRSxFQUFFLGNBQWM7UUFDbEIsTUFBTTtLQUNhLENBQUEsQ0FDeEIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBkZWVwR2V0IH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7XG4gIGNsb25lUmVjb3JkSWRlbnRpdHksXG4gIGVxdWFsUmVjb3JkSWRlbnRpdGllcyxcbiAgdW5pcXVlUmVjb3JkSWRlbnRpdGllcyxcbiAgSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIFJlY29yZElkZW50aXR5LFxuICBSZWNvcmRPcGVyYXRpb24sXG4gIFJlbGF0aW9uc2hpcERlZmluaXRpb24sXG4gIFJlY29yZFNjaGVtYVxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBZGRlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmRcbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgY29uc3Qgb3BzOiBSZWNvcmRPcGVyYXRpb25bXSA9IFtdO1xuXG4gIGlmIChyZWNvcmQucmVsYXRpb25zaGlwcykge1xuICAgIGNvbnN0IHJlY29yZElkZW50aXR5ID0gY2xvbmVSZWNvcmRJZGVudGl0eShyZWNvcmQpO1xuXG4gICAgc2NoZW1hLmVhY2hSZWxhdGlvbnNoaXAocmVjb3JkLnR5cGUsIChyZWxhdGlvbnNoaXAsIHJlbGF0aW9uc2hpcERlZikgPT4ge1xuICAgICAgY29uc3QgcmVsYXRpb25zaGlwRGF0YSA9IGRlZXBHZXQocmVjb3JkLCBbXG4gICAgICAgICdyZWxhdGlvbnNoaXBzJyxcbiAgICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgICAnZGF0YSdcbiAgICAgIF0pIGFzIFJlY29yZElkZW50aXR5IHwgUmVjb3JkSWRlbnRpdHlbXSB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmIChyZWxhdGlvbnNoaXBEYXRhKSB7XG4gICAgICAgIGNvbnN0IHJlbGF0ZWRSZWNvcmRzID0gcmVjb3JkQXJyYXlGcm9tRGF0YShcbiAgICAgICAgICByZWxhdGlvbnNoaXBEYXRhXG4gICAgICAgICkgYXMgUmVjb3JkSWRlbnRpdHlbXTtcblxuICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShcbiAgICAgICAgICBvcHMsXG4gICAgICAgICAgYWRkUmVsYXRlZFJlY29yZHNPcHMoXG4gICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICByZWNvcmRJZGVudGl0eSxcbiAgICAgICAgICAgIHJlbGF0aW9uc2hpcERlZixcbiAgICAgICAgICAgIHJlbGF0ZWRSZWNvcmRzXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG9wcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0ZWRSZWNvcmRBZGRlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHksXG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICByZWxhdGVkUmVjb3JkOiBSZWNvcmRJZGVudGl0eVxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKHJlbGF0ZWRSZWNvcmQpIHtcbiAgICBjb25zdCB7IHR5cGUgfSA9IHJlY29yZDtcbiAgICBjb25zdCByZWxhdGlvbnNoaXBEZWYgPSBzY2hlbWEuZ2V0UmVsYXRpb25zaGlwKHR5cGUsIHJlbGF0aW9uc2hpcCk7XG4gICAgY29uc3QgaW52ZXJzZVJlbGF0aW9uc2hpcCA9IHJlbGF0aW9uc2hpcERlZi5pbnZlcnNlO1xuXG4gICAgaWYgKGludmVyc2VSZWxhdGlvbnNoaXApIHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICBhZGRSZWxhdGlvbnNoaXBPcChzY2hlbWEsIHJlbGF0ZWRSZWNvcmQsIGludmVyc2VSZWxhdGlvbnNoaXAsIHJlY29yZClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9wcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0ZWRSZWNvcmRSZW1vdmVkKFxuICBzY2hlbWE6IFJlY29yZFNjaGVtYSxcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgcmVsYXRpb25zaGlwOiBzdHJpbmcsXG4gIHJlbGF0ZWRSZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICBjdXJyZW50UmVsYXRlZFJlY29yZD86IFJlY29yZElkZW50aXR5IHwgbnVsbFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKGN1cnJlbnRSZWxhdGVkUmVjb3JkKSB7XG4gICAgY29uc3QgeyB0eXBlIH0gPSByZWNvcmQ7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwRGVmID0gc2NoZW1hLmdldFJlbGF0aW9uc2hpcCh0eXBlLCByZWxhdGlvbnNoaXApO1xuICAgIGNvbnN0IGludmVyc2VSZWxhdGlvbnNoaXAgPSByZWxhdGlvbnNoaXBEZWYuaW52ZXJzZTtcblxuICAgIGlmIChpbnZlcnNlUmVsYXRpb25zaGlwKSB7XG4gICAgICBvcHMucHVzaChcbiAgICAgICAgcmVtb3ZlUmVsYXRpb25zaGlwT3Aoc2NoZW1hLCByZWxhdGVkUmVjb3JkLCBpbnZlcnNlUmVsYXRpb25zaGlwLCByZWNvcmQpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWxhdGVkUmVjb3JkUmVwbGFjZWQoXG4gIHNjaGVtYTogUmVjb3JkU2NoZW1hLFxuICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHkgfCBudWxsLFxuICBjdXJyZW50UmVsYXRlZFJlY29yZD86IFJlY29yZElkZW50aXR5IHwgbnVsbFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKFxuICAgICFlcXVhbFJlY29yZElkZW50aXRpZXMoXG4gICAgICByZWxhdGVkUmVjb3JkIGFzIFJlY29yZElkZW50aXR5LFxuICAgICAgY3VycmVudFJlbGF0ZWRSZWNvcmQgYXMgUmVjb3JkSWRlbnRpdHlcbiAgICApXG4gICkge1xuICAgIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuICAgIGNvbnN0IHJlbGF0aW9uc2hpcERlZiA9IHNjaGVtYS5nZXRSZWxhdGlvbnNoaXAodHlwZSwgcmVsYXRpb25zaGlwKTtcbiAgICBjb25zdCBpbnZlcnNlUmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwRGVmLmludmVyc2U7XG5cbiAgICBpZiAoaW52ZXJzZVJlbGF0aW9uc2hpcCkge1xuICAgICAgaWYgKGN1cnJlbnRSZWxhdGVkUmVjb3JkKSB7XG4gICAgICAgIG9wcy5wdXNoKFxuICAgICAgICAgIHJlbW92ZVJlbGF0aW9uc2hpcE9wKFxuICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgY3VycmVudFJlbGF0ZWRSZWNvcmQsXG4gICAgICAgICAgICBpbnZlcnNlUmVsYXRpb25zaGlwLFxuICAgICAgICAgICAgcmVjb3JkXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVsYXRlZFJlY29yZCkge1xuICAgICAgICBvcHMucHVzaChcbiAgICAgICAgICBhZGRSZWxhdGlvbnNoaXBPcChzY2hlbWEsIHJlbGF0ZWRSZWNvcmQsIGludmVyc2VSZWxhdGlvbnNoaXAsIHJlY29yZClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3BzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRlZFJlY29yZHNSZXBsYWNlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHksXG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXSxcbiAgY3VycmVudFJlbGF0ZWRSZWNvcmRzPzogUmVjb3JkSWRlbnRpdHlbXVxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG4gIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuICBjb25zdCByZWxhdGlvbnNoaXBEZWYgPSBzY2hlbWEuZ2V0UmVsYXRpb25zaGlwKHR5cGUsIHJlbGF0aW9uc2hpcCk7XG5cbiAgbGV0IGFkZGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXTtcblxuICBpZiAoY3VycmVudFJlbGF0ZWRSZWNvcmRzICYmIGN1cnJlbnRSZWxhdGVkUmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgbGV0IHJlbW92ZWRSZWNvcmRzID0gdW5pcXVlUmVjb3JkSWRlbnRpdGllcyhcbiAgICAgIGN1cnJlbnRSZWxhdGVkUmVjb3JkcyxcbiAgICAgIHJlbGF0ZWRSZWNvcmRzXG4gICAgKTtcbiAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShcbiAgICAgIG9wcyxcbiAgICAgIHJlbW92ZVJlbGF0ZWRSZWNvcmRzT3BzKHNjaGVtYSwgcmVjb3JkLCByZWxhdGlvbnNoaXBEZWYsIHJlbW92ZWRSZWNvcmRzKVxuICAgICk7XG5cbiAgICBhZGRlZFJlY29yZHMgPSB1bmlxdWVSZWNvcmRJZGVudGl0aWVzKFxuICAgICAgcmVsYXRlZFJlY29yZHMsXG4gICAgICBjdXJyZW50UmVsYXRlZFJlY29yZHNcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIGFkZGVkUmVjb3JkcyA9IHJlbGF0ZWRSZWNvcmRzO1xuICB9XG5cbiAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoXG4gICAgb3BzLFxuICAgIGFkZFJlbGF0ZWRSZWNvcmRzT3BzKHNjaGVtYSwgcmVjb3JkLCByZWxhdGlvbnNoaXBEZWYsIGFkZGVkUmVjb3JkcylcbiAgKTtcblxuICByZXR1cm4gb3BzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkUmVtb3ZlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZD86IEluaXRpYWxpemVkUmVjb3JkXG4pOiBSZWNvcmRPcGVyYXRpb25bXSB7XG4gIGNvbnN0IG9wczogUmVjb3JkT3BlcmF0aW9uW10gPSBbXTtcblxuICBpZiAocmVjb3JkICYmIHJlY29yZC5yZWxhdGlvbnNoaXBzKSB7XG4gICAgY29uc3QgcmVjb3JkSWRlbnRpdHkgPSBjbG9uZVJlY29yZElkZW50aXR5KHJlY29yZCk7XG5cbiAgICBzY2hlbWEuZWFjaFJlbGF0aW9uc2hpcChyZWNvcmQudHlwZSwgKHJlbGF0aW9uc2hpcCwgcmVsYXRpb25zaGlwRGVmKSA9PiB7XG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBEYXRhID0gZGVlcEdldChyZWNvcmQsIFtcbiAgICAgICAgJ3JlbGF0aW9uc2hpcHMnLFxuICAgICAgICByZWxhdGlvbnNoaXAsXG4gICAgICAgICdkYXRhJ1xuICAgICAgXSkgYXMgUmVjb3JkSWRlbnRpdHkgfCBSZWNvcmRJZGVudGl0eVtdIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKHJlbGF0aW9uc2hpcERhdGEpIHtcbiAgICAgICAgY29uc3QgcmVsYXRlZFJlY29yZHMgPSByZWNvcmRBcnJheUZyb21EYXRhKFxuICAgICAgICAgIHJlbGF0aW9uc2hpcERhdGFcbiAgICAgICAgKSBhcyBSZWNvcmRJZGVudGl0eVtdO1xuXG4gICAgICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KFxuICAgICAgICAgIG9wcyxcbiAgICAgICAgICByZW1vdmVSZWxhdGVkUmVjb3Jkc09wcyhcbiAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgIHJlY29yZElkZW50aXR5LFxuICAgICAgICAgICAgcmVsYXRpb25zaGlwRGVmLFxuICAgICAgICAgICAgcmVsYXRlZFJlY29yZHNcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gb3BzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVjb3JkVXBkYXRlZChcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIGN1cnJlbnRSZWNvcmQ/OiBJbml0aWFsaXplZFJlY29yZFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKHJlY29yZC5yZWxhdGlvbnNoaXBzKSB7XG4gICAgY29uc3QgcmVjb3JkSWRlbnRpdHkgPSBjbG9uZVJlY29yZElkZW50aXR5KHJlY29yZCk7XG5cbiAgICBzY2hlbWEuZWFjaFJlbGF0aW9uc2hpcChyZWNvcmQudHlwZSwgKHJlbGF0aW9uc2hpcCwgcmVsYXRpb25zaGlwRGVmKSA9PiB7XG4gICAgICBjb25zdCByZWxhdGlvbnNoaXBEYXRhID0gZGVlcEdldChyZWNvcmQsIFtcbiAgICAgICAgJ3JlbGF0aW9uc2hpcHMnLFxuICAgICAgICByZWxhdGlvbnNoaXAsXG4gICAgICAgICdkYXRhJ1xuICAgICAgXSkgYXMgUmVjb3JkSWRlbnRpdHkgfCBSZWNvcmRJZGVudGl0eVtdIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuICAgICAgY29uc3QgY3VycmVudFJlbGF0aW9uc2hpcERhdGEgPVxuICAgICAgICBjdXJyZW50UmVjb3JkICYmXG4gICAgICAgIChkZWVwR2V0KGN1cnJlbnRSZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSkgYXNcbiAgICAgICAgICB8IFJlY29yZElkZW50aXR5XG4gICAgICAgICAgfCBSZWNvcmRJZGVudGl0eVtdXG4gICAgICAgICAgfCBudWxsXG4gICAgICAgICAgfCB1bmRlZmluZWQpO1xuXG4gICAgICBpZiAocmVsYXRpb25zaGlwRGF0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIFRPRE8gLSByZW1vdmUgZGVwcmVjYXRlZCBgdHlwZWAgY2hlY2tcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChyZWxhdGlvbnNoaXBEZWYua2luZCA/PyAocmVsYXRpb25zaGlwRGVmIGFzIGFueSkudHlwZSkgPT09ICdoYXNNYW55J1xuICAgICAgICApIHtcbiAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShcbiAgICAgICAgICAgIG9wcyxcbiAgICAgICAgICAgIHJlbGF0ZWRSZWNvcmRzUmVwbGFjZWQoXG4gICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgcmVjb3JkSWRlbnRpdHksXG4gICAgICAgICAgICAgIHJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgICAgKHJlbGF0aW9uc2hpcERhdGEgYXMgUmVjb3JkSWRlbnRpdHlbXSkgfHwgW10sXG4gICAgICAgICAgICAgIChjdXJyZW50UmVsYXRpb25zaGlwRGF0YSBhcyBSZWNvcmRJZGVudGl0eVtdKSB8fCBbXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkoXG4gICAgICAgICAgICBvcHMsXG4gICAgICAgICAgICByZWxhdGVkUmVjb3JkUmVwbGFjZWQoXG4gICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgcmVjb3JkSWRlbnRpdHksXG4gICAgICAgICAgICAgIHJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgICAgKHJlbGF0aW9uc2hpcERhdGEgYXMgUmVjb3JkSWRlbnRpdHkpIHx8IG51bGwsXG4gICAgICAgICAgICAgIChjdXJyZW50UmVsYXRpb25zaGlwRGF0YSBhcyBSZWNvcmRJZGVudGl0eSkgfHwgbnVsbFxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBvcHM7XG59XG5cbmZ1bmN0aW9uIGFkZFJlbGF0ZWRSZWNvcmRzT3BzKFxuICBzY2hlbWE6IFJlY29yZFNjaGVtYSxcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgcmVsYXRpb25zaGlwRGVmOiBSZWxhdGlvbnNoaXBEZWZpbml0aW9uLFxuICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXVxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBpZiAocmVsYXRlZFJlY29yZHMubGVuZ3RoID4gMCAmJiByZWxhdGlvbnNoaXBEZWYuaW52ZXJzZSkge1xuICAgIGNvbnN0IGludmVyc2UgPSByZWxhdGlvbnNoaXBEZWYuaW52ZXJzZTtcbiAgICByZXR1cm4gcmVsYXRlZFJlY29yZHMubWFwKChyZWxhdGVkUmVjb3JkKSA9PlxuICAgICAgYWRkUmVsYXRpb25zaGlwT3Aoc2NoZW1hLCByZWxhdGVkUmVjb3JkLCBpbnZlcnNlLCByZWNvcmQpXG4gICAgKTtcbiAgfVxuICByZXR1cm4gW107XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVSZWxhdGVkUmVjb3Jkc09wcyhcbiAgc2NoZW1hOiBSZWNvcmRTY2hlbWEsXG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHksXG4gIHJlbGF0aW9uc2hpcERlZjogUmVsYXRpb25zaGlwRGVmaW5pdGlvbixcbiAgcmVsYXRlZFJlY29yZHM6IFJlY29yZElkZW50aXR5W11cbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgaWYgKHJlbGF0ZWRSZWNvcmRzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAocmVsYXRpb25zaGlwRGVmLmRlcGVuZGVudCA9PT0gJ3JlbW92ZScpIHtcbiAgICAgIHJldHVybiByZW1vdmVEZXBlbmRlbnRSZWNvcmRzKHJlbGF0ZWRSZWNvcmRzKTtcbiAgICB9IGVsc2UgaWYgKHJlbGF0aW9uc2hpcERlZi5pbnZlcnNlKSB7XG4gICAgICBjb25zdCBpbnZlcnNlID0gcmVsYXRpb25zaGlwRGVmLmludmVyc2U7XG4gICAgICByZXR1cm4gcmVsYXRlZFJlY29yZHMubWFwKChyZWxhdGVkUmVjb3JkKSA9PlxuICAgICAgICByZW1vdmVSZWxhdGlvbnNoaXBPcChzY2hlbWEsIHJlbGF0ZWRSZWNvcmQsIGludmVyc2UsIHJlY29yZClcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHJldHVybiBbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFJlbGF0aW9uc2hpcE9wKFxuICBzY2hlbWE6IFJlY29yZFNjaGVtYSxcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eSxcbiAgcmVsYXRpb25zaGlwOiBzdHJpbmcsXG4gIHJlbGF0ZWRSZWNvcmQ6IFJlY29yZElkZW50aXR5XG4pOiBSZWNvcmRPcGVyYXRpb24ge1xuICBjb25zdCB7IHR5cGUgfSA9IHJlY29yZDtcbiAgY29uc3QgcmVsYXRpb25zaGlwRGVmID0gc2NoZW1hLmdldFJlbGF0aW9uc2hpcCh0eXBlLCByZWxhdGlvbnNoaXApO1xuICAvLyBUT0RPIC0gcmVtb3ZlIGRlcHJlY2F0ZWQgYHR5cGVgIGNoZWNrXG4gIGNvbnN0IGlzSGFzTWFueSA9XG4gICAgKHJlbGF0aW9uc2hpcERlZi5raW5kID8/IChyZWxhdGlvbnNoaXBEZWYgYXMgYW55KS50eXBlKSA9PT0gJ2hhc01hbnknO1xuXG4gIHJldHVybiB7XG4gICAgb3A6IGlzSGFzTWFueSA/ICdhZGRUb1JlbGF0ZWRSZWNvcmRzJyA6ICdyZXBsYWNlUmVsYXRlZFJlY29yZCcsXG4gICAgcmVjb3JkLFxuICAgIHJlbGF0aW9uc2hpcCxcbiAgICByZWxhdGVkUmVjb3JkXG4gIH0gYXMgUmVjb3JkT3BlcmF0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlUmVsYXRpb25zaGlwT3AoXG4gIHNjaGVtYTogUmVjb3JkU2NoZW1hLFxuICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHlcbik6IFJlY29yZE9wZXJhdGlvbiB7XG4gIGNvbnN0IHsgdHlwZSB9ID0gcmVjb3JkO1xuICBjb25zdCByZWxhdGlvbnNoaXBEZWYgPSBzY2hlbWEuZ2V0UmVsYXRpb25zaGlwKHR5cGUsIHJlbGF0aW9uc2hpcCk7XG4gIC8vIFRPRE8gLSByZW1vdmUgZGVwcmVjYXRlZCBgdHlwZWAgY2hlY2tcbiAgY29uc3QgaXNIYXNNYW55ID1cbiAgICAocmVsYXRpb25zaGlwRGVmLmtpbmQgPz8gKHJlbGF0aW9uc2hpcERlZiBhcyBhbnkpLnR5cGUpID09PSAnaGFzTWFueSc7XG5cbiAgcmV0dXJuIHtcbiAgICBvcDogaXNIYXNNYW55ID8gJ3JlbW92ZUZyb21SZWxhdGVkUmVjb3JkcycgOiAncmVwbGFjZVJlbGF0ZWRSZWNvcmQnLFxuICAgIHJlY29yZCxcbiAgICByZWxhdGlvbnNoaXAsXG4gICAgcmVsYXRlZFJlY29yZDogaXNIYXNNYW55ID8gcmVsYXRlZFJlY29yZCA6IG51bGxcbiAgfSBhcyBSZWNvcmRPcGVyYXRpb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRBcnJheUZyb21EYXRhKFxuICBkYXRhOiBSZWNvcmRJZGVudGl0eSB8IFJlY29yZElkZW50aXR5W10gfCBudWxsXG4pOiBSZWNvcmRJZGVudGl0eVtdIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfSBlbHNlIGlmIChkYXRhKSB7XG4gICAgcmV0dXJuIFtkYXRhXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlRGVwZW5kZW50UmVjb3JkcyhcbiAgcmVsYXRlZFJlY29yZHM6IFJlY29yZElkZW50aXR5W11cbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgcmV0dXJuIHJlbGF0ZWRSZWNvcmRzLm1hcChcbiAgICAocmVjb3JkKSA9PlxuICAgICAgKHtcbiAgICAgICAgb3A6ICdyZW1vdmVSZWNvcmQnLFxuICAgICAgICByZWNvcmRcbiAgICAgIH0gYXMgUmVjb3JkT3BlcmF0aW9uKVxuICApO1xufVxuIl19