UNPKG

@orbit/records

Version:

A flexible data access and synchronization layer.

317 lines 50.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.recordsReferencedByOperations = exports.recordDiffs = exports.coalesceRecordOperations = void 0; const utils_1 = require("@orbit/utils"); const record_1 = require("./record"); function markOperationToDelete(operation) { const o = operation; o._deleted = true; } function isOperationMarkedToDelete(operation) { const o = operation; return o._deleted === true; } function mergeOperations(superceded, superceding, consecutiveOps) { var _a, _b, _c, _d; if (superceded.options || superceding.options) { // do not merge if one of the operations have options return; } else if ((0, record_1.equalRecordIdentities)(superceded.record, superceding.record)) { if (superceding.op === 'removeRecord') { markOperationToDelete(superceded); if (superceded.op === 'addRecord') { markOperationToDelete(superceding); } } else if (!isOperationMarkedToDelete(superceding) && (consecutiveOps || superceding.op === 'replaceAttribute')) { if (isReplaceFieldOp(superceded.op) && isReplaceFieldOp(superceding.op)) { if (superceded.op === 'replaceAttribute' && superceding.op === 'replaceAttribute' && superceded.attribute === superceding.attribute) { markOperationToDelete(superceded); } else if (superceded.op === 'replaceRelatedRecord' && superceding.op === 'replaceRelatedRecord' && superceded.relationship === superceding.relationship) { markOperationToDelete(superceded); } else if (superceded.op === 'replaceRelatedRecords' && superceding.op === 'replaceRelatedRecords' && superceded.relationship === superceding.relationship) { markOperationToDelete(superceded); } else { if (superceded.op === 'replaceAttribute') { updateRecordReplaceAttribute(superceded.record, superceded.attribute, superceded.value); delete superceded.attribute; delete superceded.value; } else if (superceded.op === 'replaceRelatedRecord') { updateRecordReplaceHasOne(superceded.record, superceded.relationship, superceded.relatedRecord); delete superceded.relationship; delete superceded.relatedRecord; } else if (superceded.op === 'replaceRelatedRecords') { updateRecordReplaceHasMany(superceded.record, superceded.relationship, superceded.relatedRecords); delete superceded.relationship; delete superceded.relatedRecords; } if (superceding.op === 'replaceAttribute') { updateRecordReplaceAttribute(superceded.record, superceding.attribute, superceding.value); } else if (superceding.op === 'replaceRelatedRecord') { updateRecordReplaceHasOne(superceded.record, superceding.relationship, superceding.relatedRecord); } else if (superceding.op === 'replaceRelatedRecords') { updateRecordReplaceHasMany(superceded.record, superceding.relationship, superceding.relatedRecords); } superceded.op = 'updateRecord'; markOperationToDelete(superceding); } } else if ((superceded.op === 'addRecord' || superceded.op === 'updateRecord' || superceded.op === 'replaceRecord') && (superceding.op === 'updateRecord' || superceding.op === 'replaceRecord')) { superceded.record = (0, record_1.mergeRecords)(superceded.record, superceding.record); markOperationToDelete(superceding); } else if ((superceded.op === 'addRecord' || superceded.op === 'updateRecord' || superceded.op === 'replaceRecord') && isReplaceFieldOp(superceding.op)) { if (superceding.op === 'replaceAttribute') { updateRecordReplaceAttribute(superceded.record, superceding.attribute, superceding.value); } else if (superceding.op === 'replaceRelatedRecord') { updateRecordReplaceHasOne(superceded.record, superceding.relationship, superceding.relatedRecord); } else if (superceding.op === 'replaceRelatedRecords') { updateRecordReplaceHasMany(superceded.record, superceding.relationship, superceding.relatedRecords); } markOperationToDelete(superceding); } else if (superceding.op === 'addToRelatedRecords') { if (superceded.op === 'addRecord') { updateRecordAddToHasMany(superceded.record, superceding.relationship, superceding.relatedRecord); markOperationToDelete(superceding); } else if (superceded.op === 'updateRecord' || superceded.op === 'replaceRecord') { let record = superceded.record; if ((_b = (_a = record.relationships) === null || _a === void 0 ? void 0 : _a[superceding.relationship]) === null || _b === void 0 ? void 0 : _b.data) { updateRecordAddToHasMany(superceded.record, superceding.relationship, superceding.relatedRecord); markOperationToDelete(superceding); } } } else if (superceding.op === 'removeFromRelatedRecords') { if (superceded.op === 'addToRelatedRecords' && superceded.relationship === superceding.relationship && (0, record_1.equalRecordIdentities)(superceded.relatedRecord, superceding.relatedRecord)) { markOperationToDelete(superceded); markOperationToDelete(superceding); } else if (superceded.op === 'addRecord' || superceded.op === 'updateRecord' || superceded.op === 'replaceRecord') { let record = superceded.record; if ((_d = (_c = record.relationships) === null || _c === void 0 ? void 0 : _c[superceding.relationship]) === null || _d === void 0 ? void 0 : _d.data) { updateRecordRemoveFromHasMany(superceded.record, superceding.relationship, superceding.relatedRecord); markOperationToDelete(superceding); } } } } } else if (superceding.record && superceding.op === 'removeRecord') { if (superceded.relatedRecord && (0, record_1.equalRecordIdentities)(superceded .relatedRecord, superceding.record)) { markOperationToDelete(superceded); } } } function isReplaceFieldOp(op) { return (op === 'replaceAttribute' || op === 'replaceRelatedRecord' || op === 'replaceRelatedRecords'); } function updateRecordReplaceAttribute(record, attribute, value) { (0, utils_1.deepSet)(record, ['attributes', attribute], value); } function updateRecordReplaceHasOne(record, relationship, relatedRecord) { (0, utils_1.deepSet)(record, ['relationships', relationship, 'data'], relatedRecord ? (0, record_1.cloneRecordIdentity)(relatedRecord) : null); } function updateRecordReplaceHasMany(record, relationship, relatedRecords) { (0, utils_1.deepSet)(record, ['relationships', relationship, 'data'], relatedRecords.map(record_1.cloneRecordIdentity)); } function updateRecordAddToHasMany(record, relationship, relatedRecord) { const data = (0, utils_1.deepGet)(record, ['relationships', relationship, 'data']) || []; data.push((0, record_1.cloneRecordIdentity)(relatedRecord)); (0, utils_1.deepSet)(record, ['relationships', relationship, 'data'], data); } function updateRecordRemoveFromHasMany(record, relationship, relatedRecord) { const data = (0, utils_1.deepGet)(record, [ 'relationships', relationship, 'data' ]); if (data) { for (let i = 0, l = data.length; i < l; i++) { let r = data[i]; if ((0, record_1.equalRecordIdentities)(r, relatedRecord)) { data.splice(i, 1); break; } } } } /** * Coalesces operations into a minimal set of equivalent operations. * * This method respects the order of the operations array and does not allow * reordering of operations that affect relationships. */ function coalesceRecordOperations(operations) { for (let i = 0, l = operations.length; i < l; i++) { let currentOp = operations[i]; let consecutiveOps = true; for (let j = i + 1; j < l; j++) { let nextOp = operations[j]; mergeOperations(currentOp, nextOp, consecutiveOps); if (isOperationMarkedToDelete(currentOp)) { break; } else if (!isOperationMarkedToDelete(nextOp)) { consecutiveOps = false; } } } return operations.filter((o) => !isOperationMarkedToDelete(o)); } exports.coalesceRecordOperations = coalesceRecordOperations; /** * Determine the differences between a record and its updated version in terms * of a set of operations. */ function recordDiffs(record, updatedRecord) { var _a; const ops = []; if (record && updatedRecord) { let fullRecordUpdate = false; const recordIdentity = (0, record_1.cloneRecordIdentity)(record); const diffRecord = { ...recordIdentity }; for (let member in updatedRecord) { if (member !== 'id' && member !== 'type') { let value; let updatedValue; switch (member) { case 'attributes': case 'keys': case 'relationships': for (let field in updatedRecord[member]) { value = (_a = record[member]) === null || _a === void 0 ? void 0 : _a[field]; updatedValue = updatedRecord[member][field]; if (!(0, utils_1.eq)(value, updatedValue)) { if (member === 'relationships') { fullRecordUpdate = true; } (0, utils_1.deepSet)(diffRecord, [member, field], updatedValue); } } break; default: value = record[member]; updatedValue = updatedRecord[member]; if (!(0, utils_1.eq)(updatedValue, value)) { diffRecord[member] = updatedValue; fullRecordUpdate = true; } } } } // If updates consist solely of attributes and keys, update fields // with individual operations. Otherwise, update the record as a // whole. if (fullRecordUpdate) { let op = { op: 'updateRecord', record: diffRecord }; ops.push(op); } else { if (diffRecord.attributes) { for (let attribute in diffRecord.attributes) { let value = diffRecord.attributes[attribute]; let op = { op: 'replaceAttribute', record: recordIdentity, attribute, value }; ops.push(op); } } if (diffRecord.keys) { for (let key in diffRecord.keys) { let value = diffRecord.keys[key]; let op = { op: 'replaceKey', record: recordIdentity, key, value }; ops.push(op); } } } } return ops; } exports.recordDiffs = recordDiffs; /** * Returns the deduped identities of all the records directly referenced by an * array of operations. */ function recordsReferencedByOperations(operations) { const records = []; for (let operation of operations) { if (operation.record) { records.push(operation.record); if (operation.op === 'addRecord' || operation.op === 'updateRecord') { let record = operation.record; if (record.relationships) { for (let relName in record.relationships) { let rel = record.relationships[relName]; if (rel === null || rel === void 0 ? void 0 : rel.data) { if (Array.isArray(rel.data)) { Array.prototype.push.apply(records, rel.data); } else { records.push(rel.data); } } } } } } if (operation.op === 'addToRelatedRecords' || operation.op === 'removeFromRelatedRecords' || operation.op === 'replaceRelatedRecord') { if (operation.relatedRecord) { records.push(operation.relatedRecord); } } else if (operation.op === 'replaceRelatedRecords') { Array.prototype.push.apply(records, operation.relatedRecords); } } return (0, record_1.dedupeRecordIdentities)(records); } exports.recordsReferencedByOperations = recordsReferencedByOperations; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLW9wZXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWNvcmQtb3BlcmF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHdDQUFvRDtBQUVwRCxxQ0FPa0I7QUFnSGxCLFNBQVMscUJBQXFCLENBQUMsU0FBb0I7SUFDakQsTUFBTSxDQUFDLEdBQVEsU0FBUyxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3BCLENBQUM7QUFFRCxTQUFTLHlCQUF5QixDQUFDLFNBQW9CO0lBQ3JELE1BQU0sQ0FBQyxHQUFRLFNBQVMsQ0FBQztJQUN6QixPQUFPLENBQUMsQ0FBQyxRQUFRLEtBQUssSUFBSSxDQUFDO0FBQzdCLENBQUM7QUFFRCxTQUFTLGVBQWUsQ0FDdEIsVUFBMkIsRUFDM0IsV0FBNEIsRUFDNUIsY0FBdUI7O0lBRXZCLElBQUksVUFBVSxDQUFDLE9BQU8sSUFBSSxXQUFXLENBQUMsT0FBTyxFQUFFO1FBQzdDLHFEQUFxRDtRQUNyRCxPQUFPO0tBQ1I7U0FBTSxJQUFJLElBQUEsOEJBQXFCLEVBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUU7UUFDdkUsSUFBSSxXQUFXLENBQUMsRUFBRSxLQUFLLGNBQWMsRUFBRTtZQUNyQyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNsQyxJQUFJLFVBQVUsQ0FBQyxFQUFFLEtBQUssV0FBVyxFQUFFO2dCQUNqQyxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsQ0FBQzthQUNwQztTQUNGO2FBQU0sSUFDTCxDQUFDLHlCQUF5QixDQUFDLFdBQVcsQ0FBQztZQUN2QyxDQUFDLGNBQWMsSUFBSSxXQUFXLENBQUMsRUFBRSxLQUFLLGtCQUFrQixDQUFDLEVBQ3pEO1lBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLElBQUksZ0JBQWdCLENBQUMsV0FBVyxDQUFD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RjtJQUVELE9BQU8sSUFBQSwrQkFBc0IsRUFBQyxPQUFPLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBdkNELHNFQXVDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVxLCBkZWVwR2V0LCBkZWVwU2V0IH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7IE9wZXJhdGlvbiB9IGZyb20gJ0BvcmJpdC9kYXRhJztcbmltcG9ydCB7XG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBSZWNvcmRJZGVudGl0eSxcbiAgY2xvbmVSZWNvcmRJZGVudGl0eSxcbiAgZXF1YWxSZWNvcmRJZGVudGl0aWVzLFxuICBtZXJnZVJlY29yZHMsXG4gIGRlZHVwZVJlY29yZElkZW50aXRpZXNcbn0gZnJvbSAnLi9yZWNvcmQnO1xuXG4vKipcbiAqIEFkZCByZWNvcmQgb3BlcmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFkZFJlY29yZE9wZXJhdGlvbiBleHRlbmRzIE9wZXJhdGlvbiB7XG4gIG9wOiAnYWRkUmVjb3JkJztcbiAgcmVjb3JkOiBJbml0aWFsaXplZFJlY29yZDtcbn1cblxuLyoqXG4gKiBVcGRhdGUgcmVjb3JkIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBVcGRhdGVSZWNvcmRPcGVyYXRpb24gZXh0ZW5kcyBPcGVyYXRpb24ge1xuICBvcDogJ3VwZGF0ZVJlY29yZCc7XG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQ7XG59XG5cbi8qKlxuICogUmVtb3ZlIHJlY29yZCBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3ZlUmVjb3JkT3BlcmF0aW9uIGV4dGVuZHMgT3BlcmF0aW9uIHtcbiAgb3A6ICdyZW1vdmVSZWNvcmQnO1xuICByZWNvcmQ6IFJlY29yZElkZW50aXR5O1xufVxuXG4vKipcbiAqIFJlcGxhY2Uga2V5IG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXBsYWNlS2V5T3BlcmF0aW9uIGV4dGVuZHMgT3BlcmF0aW9uIHtcbiAgb3A6ICdyZXBsYWNlS2V5JztcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eTtcbiAga2V5OiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVwbGFjZSBhdHRyaWJ1dGUgb3BlcmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcGxhY2VBdHRyaWJ1dGVPcGVyYXRpb24gZXh0ZW5kcyBPcGVyYXRpb24ge1xuICBvcDogJ3JlcGxhY2VBdHRyaWJ1dGUnO1xuICByZWNvcmQ6IFJlY29yZElkZW50aXR5O1xuICBhdHRyaWJ1dGU6IHN0cmluZztcbiAgdmFsdWU6IHVua25vd247XG59XG5cbi8qKlxuICogQWRkIHRvIGhhcy1tYW55IHJlbGF0aW9uc2hpcCBvcGVyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWRkVG9SZWxhdGVkUmVjb3Jkc09wZXJhdGlvbiBleHRlbmRzIE9wZXJhdGlvbiB7XG4gIG9wOiAnYWRkVG9SZWxhdGVkUmVjb3Jkcyc7XG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHk7XG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nO1xuICByZWxhdGVkUmVjb3JkOiBSZWNvcmRJZGVudGl0eTtcbn1cblxuLyoqXG4gKiBSZW1vdmUgZnJvbSBoYXMtbWFueSByZWxhdGlvbnNoaXAgb3BlcmF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc09wZXJhdGlvbiBleHRlbmRzIE9wZXJhdGlvbiB7XG4gIG9wOiAncmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzJztcbiAgcmVjb3JkOiBSZWNvcmRJZGVudGl0eTtcbiAgcmVsYXRpb25zaGlwOiBzdHJpbmc7XG4gIHJlbGF0ZWRSZWNvcmQ6IFJlY29yZElkZW50aXR5O1xufVxuXG4vKipcbiAqIFJlcGxhY2UgaGFzLW1hbnkgcmVsYXRpb25zaGlwIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXBsYWNlUmVsYXRlZFJlY29yZHNPcGVyYXRpb24gZXh0ZW5kcyBPcGVyYXRpb24ge1xuICBvcDogJ3JlcGxhY2VSZWxhdGVkUmVjb3Jkcyc7XG4gIHJlY29yZDogUmVjb3JkSWRlbnRpdHk7XG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nO1xuICByZWxhdGVkUmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlIGhhcy1vbmUgcmVsYXRpb25zaGlwIG9wZXJhdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXBsYWNlUmVsYXRlZFJlY29yZE9wZXJhdGlvbiBleHRlbmRzIE9wZXJhdGlvbiB7XG4gIG9wOiAncmVwbGFjZVJlbGF0ZWRSZWNvcmQnO1xuICByZWNvcmQ6IFJlY29yZElkZW50aXR5O1xuICByZWxhdGlvbnNoaXA6IHN0cmluZztcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHkgfCBudWxsO1xufVxuXG4vKipcbiAqIFVuaW9uIG9mIGFsbCByZWNvcmQtcmVsYXRlZCBvcGVyYXRpb25zLlxuICovXG5leHBvcnQgdHlwZSBSZWNvcmRPcGVyYXRpb24gPVxuICB8IEFkZFJlY29yZE9wZXJhdGlvblxuICB8IFVwZGF0ZVJlY29yZE9wZXJhdGlvblxuICB8IFJlbW92ZVJlY29yZE9wZXJhdGlvblxuICB8IFJlcGxhY2VLZXlPcGVyYXRpb25cbiAgfCBSZXBsYWNlQXR0cmlidXRlT3BlcmF0aW9uXG4gIHwgQWRkVG9SZWxhdGVkUmVjb3Jkc09wZXJhdGlvblxuICB8IFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc09wZXJhdGlvblxuICB8IFJlcGxhY2VSZWxhdGVkUmVjb3Jkc09wZXJhdGlvblxuICB8IFJlcGxhY2VSZWxhdGVkUmVjb3JkT3BlcmF0aW9uO1xuXG5leHBvcnQgdHlwZSBBZGRSZWNvcmRPcGVyYXRpb25SZXN1bHQgPSBJbml0aWFsaXplZFJlY29yZDtcbmV4cG9ydCB0eXBlIFVwZGF0ZVJlY29yZE9wZXJhdGlvblJlc3VsdCA9IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIFJlbW92ZVJlY29yZE9wZXJhdGlvblJlc3VsdCA9IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIFJlcGxhY2VLZXlPcGVyYXRpb25SZXN1bHQgPSB1bmRlZmluZWQ7XG5leHBvcnQgdHlwZSBSZXBsYWNlQXR0cmlidXRlT3BlcmF0aW9uUmVzdWx0ID0gdW5kZWZpbmVkO1xuZXhwb3J0IHR5cGUgQWRkVG9SZWxhdGVkUmVjb3Jkc09wZXJhdGlvblJlc3VsdCA9IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc09wZXJhdGlvblJlc3VsdCA9IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIFJlcGxhY2VSZWxhdGVkUmVjb3Jkc09wZXJhdGlvblJlc3VsdCA9IHVuZGVmaW5lZDtcbmV4cG9ydCB0eXBlIFJlcGxhY2VSZWxhdGVkUmVjb3JkT3BlcmF0aW9uUmVzdWx0ID0gdW5kZWZpbmVkO1xuXG5leHBvcnQgdHlwZSBSZWNvcmRPcGVyYXRpb25SZXN1bHQ8VCA9IEluaXRpYWxpemVkUmVjb3JkPiA9IFQgfCB1bmRlZmluZWQ7XG5cbmZ1bmN0aW9uIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShvcGVyYXRpb246IE9wZXJhdGlvbik6IHZvaWQge1xuICBjb25zdCBvOiBhbnkgPSBvcGVyYXRpb247XG4gIG8uX2RlbGV0ZWQgPSB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc09wZXJhdGlvbk1hcmtlZFRvRGVsZXRlKG9wZXJhdGlvbjogT3BlcmF0aW9uKTogYm9vbGVhbiB7XG4gIGNvbnN0IG86IGFueSA9IG9wZXJhdGlvbjtcbiAgcmV0dXJuIG8uX2RlbGV0ZWQgPT09IHRydWU7XG59XG5cbmZ1bmN0aW9uIG1lcmdlT3BlcmF0aW9ucyhcbiAgc3VwZXJjZWRlZDogUmVjb3JkT3BlcmF0aW9uLFxuICBzdXBlcmNlZGluZzogUmVjb3JkT3BlcmF0aW9uLFxuICBjb25zZWN1dGl2ZU9wczogYm9vbGVhblxuKTogdm9pZCB7XG4gIGlmIChzdXBlcmNlZGVkLm9wdGlvbnMgfHwgc3VwZXJjZWRpbmcub3B0aW9ucykge1xuICAgIC8vIGRvIG5vdCBtZXJnZSBpZiBvbmUgb2YgdGhlIG9wZXJhdGlvbnMgaGF2ZSBvcHRpb25zXG4gICAgcmV0dXJuO1xuICB9IGVsc2UgaWYgKGVxdWFsUmVjb3JkSWRlbnRpdGllcyhzdXBlcmNlZGVkLnJlY29yZCwgc3VwZXJjZWRpbmcucmVjb3JkKSkge1xuICAgIGlmIChzdXBlcmNlZGluZy5vcCA9PT0gJ3JlbW92ZVJlY29yZCcpIHtcbiAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGVkKTtcbiAgICAgIGlmIChzdXBlcmNlZGVkLm9wID09PSAnYWRkUmVjb3JkJykge1xuICAgICAgICBtYXJrT3BlcmF0aW9uVG9EZWxldGUoc3VwZXJjZWRpbmcpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXG4gICAgICAhaXNPcGVyYXRpb25NYXJrZWRUb0RlbGV0ZShzdXBlcmNlZGluZykgJiZcbiAgICAgIChjb25zZWN1dGl2ZU9wcyB8fCBzdXBlcmNlZGluZy5vcCA9PT0gJ3JlcGxhY2VBdHRyaWJ1dGUnKVxuICAgICkge1xuICAgICAgaWYgKGlzUmVwbGFjZUZpZWxkT3Aoc3VwZXJjZWRlZC5vcCkgJiYgaXNSZXBsYWNlRmllbGRPcChzdXBlcmNlZGluZy5vcCkpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHN1cGVyY2VkZWQub3AgPT09ICdyZXBsYWNlQXR0cmlidXRlJyAmJlxuICAgICAgICAgIHN1cGVyY2VkaW5nLm9wID09PSAncmVwbGFjZUF0dHJpYnV0ZScgJiZcbiAgICAgICAgICBzdXBlcmNlZGVkLmF0dHJpYnV0ZSA9PT0gc3VwZXJjZWRpbmcuYXR0cmlidXRlXG4gICAgICAgICkge1xuICAgICAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGVkKTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzdXBlcmNlZGVkLm9wID09PSAncmVwbGFjZVJlbGF0ZWRSZWNvcmQnICYmXG4gICAgICAgICAgc3VwZXJjZWRpbmcub3AgPT09ICdyZXBsYWNlUmVsYXRlZFJlY29yZCcgJiZcbiAgICAgICAgICBzdXBlcmNlZGVkLnJlbGF0aW9uc2hpcCA9PT0gc3VwZXJjZWRpbmcucmVsYXRpb25zaGlwXG4gICAgICAgICkge1xuICAgICAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGVkKTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzdXBlcmNlZGVkLm9wID09PSAncmVwbGFjZVJlbGF0ZWRSZWNvcmRzJyAmJlxuICAgICAgICAgIHN1cGVyY2VkaW5nLm9wID09PSAncmVwbGFjZVJlbGF0ZWRSZWNvcmRzJyAmJlxuICAgICAgICAgIHN1cGVyY2VkZWQucmVsYXRpb25zaGlwID09PSBzdXBlcmNlZGluZy5yZWxhdGlvbnNoaXBcbiAgICAgICAgKSB7XG4gICAgICAgICAgbWFya09wZXJhdGlvblRvRGVsZXRlKHN1cGVyY2VkZWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChzdXBlcmNlZGVkLm9wID09PSAncmVwbGFjZUF0dHJpYnV0ZScpIHtcbiAgICAgICAgICAgIHVwZGF0ZVJlY29yZFJlcGxhY2VBdHRyaWJ1dGUoXG4gICAgICAgICAgICAgIHN1cGVyY2VkZWQucmVjb3JkLFxuICAgICAgICAgICAgICBzdXBlcmNlZGVkLmF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgc3VwZXJjZWRlZC52YWx1ZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGRlbGV0ZSAoc3VwZXJjZWRlZCBhcyBhbnkpLmF0dHJpYnV0ZTtcbiAgICAgICAgICAgIGRlbGV0ZSBzdXBlcmNlZGVkLnZhbHVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc3VwZXJjZWRlZC5vcCA9PT0gJ3JlcGxhY2VSZWxhdGVkUmVjb3JkJykge1xuICAgICAgICAgICAgdXBkYXRlUmVjb3JkUmVwbGFjZUhhc09uZShcbiAgICAgICAgICAgICAgc3VwZXJjZWRlZC5yZWNvcmQsXG4gICAgICAgICAgICAgIHN1cGVyY2VkZWQucmVsYXRpb25zaGlwLFxuICAgICAgICAgICAgICBzdXBlcmNlZGVkLnJlbGF0ZWRSZWNvcmRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBkZWxldGUgKHN1cGVyY2VkZWQgYXMgYW55KS5yZWxhdGlvbnNoaXA7XG4gICAgICAgICAgICBkZWxldGUgKHN1cGVyY2VkZWQgYXMgYW55KS5yZWxhdGVkUmVjb3JkO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc3VwZXJjZWRlZC5vcCA9PT0gJ3JlcGxhY2VSZWxhdGVkUmVjb3JkcycpIHtcbiAgICAgICAgICAgIHVwZGF0ZVJlY29yZFJlcGxhY2VIYXNNYW55KFxuICAgICAgICAgICAgICBzdXBlcmNlZGVkLnJlY29yZCxcbiAgICAgICAgICAgICAgc3VwZXJjZWRlZC5yZWxhdGlvbnNoaXAsXG4gICAgICAgICAgICAgIHN1cGVyY2VkZWQucmVsYXRlZFJlY29yZHNcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBkZWxldGUgKHN1cGVyY2VkZWQgYXMgYW55KS5yZWxhdGlvbnNoaXA7XG4gICAgICAgICAgICBkZWxldGUgKHN1cGVyY2VkZWQgYXMgYW55KS5yZWxhdGVkUmVjb3JkcztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHN1cGVyY2VkaW5nLm9wID09PSAncmVwbGFjZUF0dHJpYnV0ZScpIHtcbiAgICAgICAgICAgIHVwZGF0ZVJlY29yZFJlcGxhY2VBdHRyaWJ1dGUoXG4gICAgICAgICAgICAgIHN1cGVyY2VkZWQucmVjb3JkLFxuICAgICAgICAgICAgICBzdXBlcmNlZGluZy5hdHRyaWJ1dGUsXG4gICAgICAgICAgICAgIHN1cGVyY2VkaW5nLnZhbHVlXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAoc3VwZXJjZWRpbmcub3AgPT09ICdyZXBsYWNlUmVsYXRlZFJlY29yZCcpIHtcbiAgICAgICAgICAgIHVwZGF0ZVJlY29yZFJlcGxhY2VIYXNPbmUoXG4gICAgICAgICAgICAgIHN1cGVyY2VkZWQucmVjb3JkLFxuICAgICAgICAgICAgICBzdXBlcmNlZGluZy5yZWxhdGlvbnNoaXAsXG4gICAgICAgICAgICAgIHN1cGVyY2VkaW5nLnJlbGF0ZWRSZWNvcmRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChzdXBlcmNlZGluZy5vcCA9PT0gJ3JlcGxhY2VSZWxhdGVkUmVjb3JkcycpIHtcbiAgICAgICAgICAgIHVwZGF0ZVJlY29yZFJlcGxhY2VIYXNNYW55KFxuICAgICAgICAgICAgICBzdXBlcmNlZGVkLnJlY29yZCxcbiAgICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRpb25zaGlwLFxuICAgICAgICAgICAgICBzdXBlcmNlZGluZy5yZWxhdGVkUmVjb3Jkc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc3VwZXJjZWRlZC5vcCA9ICd1cGRhdGVSZWNvcmQnO1xuICAgICAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGluZyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIChzdXBlcmNlZGVkLm9wID09PSAnYWRkUmVjb3JkJyB8fFxuICAgICAgICAgIHN1cGVyY2VkZWQub3AgPT09ICd1cGRhdGVSZWNvcmQnIHx8XG4gICAgICAgICAgKHN1cGVyY2VkZWQgYXMgYW55KS5vcCA9PT0gJ3JlcGxhY2VSZWNvcmQnKSAmJlxuICAgICAgICAoc3VwZXJjZWRpbmcub3AgPT09ICd1cGRhdGVSZWNvcmQnIHx8XG4gICAgICAgICAgKHN1cGVyY2VkaW5nIGFzIGFueSkub3AgPT09ICdyZXBsYWNlUmVjb3JkJylcbiAgICAgICkge1xuICAgICAgICBzdXBlcmNlZGVkLnJlY29yZCA9IG1lcmdlUmVjb3JkcyhzdXBlcmNlZGVkLnJlY29yZCwgc3VwZXJjZWRpbmcucmVjb3JkKTtcbiAgICAgICAgbWFya09wZXJhdGlvblRvRGVsZXRlKHN1cGVyY2VkaW5nKTtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIChzdXBlcmNlZGVkLm9wID09PSAnYWRkUmVjb3JkJyB8fFxuICAgICAgICAgIHN1cGVyY2VkZWQub3AgPT09ICd1cGRhdGVSZWNvcmQnIHx8XG4gICAgICAgICAgKHN1cGVyY2VkZWQgYXMgYW55KS5vcCA9PT0gJ3JlcGxhY2VSZWNvcmQnKSAmJlxuICAgICAgICBpc1JlcGxhY2VGaWVsZE9wKHN1cGVyY2VkaW5nLm9wKVxuICAgICAgKSB7XG4gICAgICAgIGlmIChzdXBlcmNlZGluZy5vcCA9PT0gJ3JlcGxhY2VBdHRyaWJ1dGUnKSB7XG4gICAgICAgICAgdXBkYXRlUmVjb3JkUmVwbGFjZUF0dHJpYnV0ZShcbiAgICAgICAgICAgIHN1cGVyY2VkZWQucmVjb3JkLFxuICAgICAgICAgICAgc3VwZXJjZWRpbmcuYXR0cmlidXRlLFxuICAgICAgICAgICAgc3VwZXJjZWRpbmcudmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHN1cGVyY2VkaW5nLm9wID09PSAncmVwbGFjZVJlbGF0ZWRSZWNvcmQnKSB7XG4gICAgICAgICAgdXBkYXRlUmVjb3JkUmVwbGFjZUhhc09uZShcbiAgICAgICAgICAgIHN1cGVyY2VkZWQucmVjb3JkLFxuICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRpb25zaGlwLFxuICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRlZFJlY29yZFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3VwZXJjZWRpbmcub3AgPT09ICdyZXBsYWNlUmVsYXRlZFJlY29yZHMnKSB7XG4gICAgICAgICAgdXBkYXRlUmVjb3JkUmVwbGFjZUhhc01hbnkoXG4gICAgICAgICAgICBzdXBlcmNlZGVkLnJlY29yZCxcbiAgICAgICAgICAgIHN1cGVyY2VkaW5nLnJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgIHN1cGVyY2VkaW5nLnJlbGF0ZWRSZWNvcmRzXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBtYXJrT3BlcmF0aW9uVG9EZWxldGUoc3VwZXJjZWRpbmcpO1xuICAgICAgfSBlbHNlIGlmIChzdXBlcmNlZGluZy5vcCA9PT0gJ2FkZFRvUmVsYXRlZFJlY29yZHMnKSB7XG4gICAgICAgIGlmIChzdXBlcmNlZGVkLm9wID09PSAnYWRkUmVjb3JkJykge1xuICAgICAgICAgIHVwZGF0ZVJlY29yZEFkZFRvSGFzTWFueShcbiAgICAgICAgICAgIHN1cGVyY2VkZWQucmVjb3JkLFxuICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRpb25zaGlwLFxuICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRlZFJlY29yZFxuICAgICAgICAgICk7XG4gICAgICAgICAgbWFya09wZXJhdGlvblRvRGVsZXRlKHN1cGVyY2VkaW5nKTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzdXBlcmNlZGVkLm9wID09PSAndXBkYXRlUmVjb3JkJyB8fFxuICAgICAgICAgIChzdXBlcmNlZGVkIGFzIGFueSkub3AgPT09ICdyZXBsYWNlUmVjb3JkJ1xuICAgICAgICApIHtcbiAgICAgICAgICBsZXQgcmVjb3JkOiBJbml0aWFsaXplZFJlY29yZCA9IHN1cGVyY2VkZWQucmVjb3JkO1xuICAgICAgICAgIGlmIChyZWNvcmQucmVsYXRpb25zaGlwcz8uW3N1cGVyY2VkaW5nLnJlbGF0aW9uc2hpcF0/LmRhdGEpIHtcbiAgICAgICAgICAgIHVwZGF0ZVJlY29yZEFkZFRvSGFzTWFueShcbiAgICAgICAgICAgICAgc3VwZXJjZWRlZC5yZWNvcmQsXG4gICAgICAgICAgICAgIHN1cGVyY2VkaW5nLnJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRlZFJlY29yZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHN1cGVyY2VkaW5nLm9wID09PSAncmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzJykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgc3VwZXJjZWRlZC5vcCA9PT0gJ2FkZFRvUmVsYXRlZFJlY29yZHMnICYmXG4gICAgICAgICAgc3VwZXJjZWRlZC5yZWxhdGlvbnNoaXAgPT09IHN1cGVyY2VkaW5nLnJlbGF0aW9uc2hpcCAmJlxuICAgICAgICAgIGVxdWFsUmVjb3JkSWRlbnRpdGllcyhcbiAgICAgICAgICAgIHN1cGVyY2VkZWQucmVsYXRlZFJlY29yZCxcbiAgICAgICAgICAgIHN1cGVyY2VkaW5nLnJlbGF0ZWRSZWNvcmRcbiAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGVkKTtcbiAgICAgICAgICBtYXJrT3BlcmF0aW9uVG9EZWxldGUoc3VwZXJjZWRpbmcpO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHN1cGVyY2VkZWQub3AgPT09ICdhZGRSZWNvcmQnIHx8XG4gICAgICAgICAgc3VwZXJjZWRlZC5vcCA9PT0gJ3VwZGF0ZVJlY29yZCcgfHxcbiAgICAgICAgICAoc3VwZXJjZWRlZCBhcyBhbnkpLm9wID09PSAncmVwbGFjZVJlY29yZCdcbiAgICAgICAgKSB7XG4gICAgICAgICAgbGV0IHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQgPSBzdXBlcmNlZGVkLnJlY29yZDtcbiAgICAgICAgICBpZiAocmVjb3JkLnJlbGF0aW9uc2hpcHM/LltzdXBlcmNlZGluZy5yZWxhdGlvbnNoaXBdPy5kYXRhKSB7XG4gICAgICAgICAgICB1cGRhdGVSZWNvcmRSZW1vdmVGcm9tSGFzTWFueShcbiAgICAgICAgICAgICAgc3VwZXJjZWRlZC5yZWNvcmQsXG4gICAgICAgICAgICAgIHN1cGVyY2VkaW5nLnJlbGF0aW9uc2hpcCxcbiAgICAgICAgICAgICAgc3VwZXJjZWRpbmcucmVsYXRlZFJlY29yZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIG1hcmtPcGVyYXRpb25Ub0RlbGV0ZShzdXBlcmNlZGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKHN1cGVyY2VkaW5nLnJlY29yZCAmJiBzdXBlcmNlZGluZy5vcCA9PT0gJ3JlbW92ZVJlY29yZCcpIHtcbiAgICBpZiAoXG4gICAgICAoc3VwZXJjZWRlZCBhcyBSZXBsYWNlUmVsYXRlZFJlY29yZE9wZXJhdGlvbikucmVsYXRlZFJlY29yZCAmJlxuICAgICAgZXF1YWxSZWNvcmRJZGVudGl0aWVzKFxuICAgICAgICAoc3VwZXJjZWRlZCBhcyBSZXBsYWNlUmVsYXRlZFJlY29yZE9wZXJhdGlvbilcbiAgICAgICAgICAucmVsYXRlZFJlY29yZCBhcyBSZWNvcmRJZGVudGl0eSxcbiAgICAgICAgc3VwZXJjZWRpbmcucmVjb3JkXG4gICAgICApXG4gICAgKSB7XG4gICAgICBtYXJrT3BlcmF0aW9uVG9EZWxldGUoc3VwZXJjZWRlZCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzUmVwbGFjZUZpZWxkT3Aob3A6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIG9wID09PSAncmVwbGFjZUF0dHJpYnV0ZScgfHxcbiAgICBvcCA9PT0gJ3JlcGxhY2VSZWxhdGVkUmVjb3JkJyB8fFxuICAgIG9wID09PSAncmVwbGFjZVJlbGF0ZWRSZWNvcmRzJ1xuICApO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVSZWNvcmRSZXBsYWNlQXR0cmlidXRlKFxuICByZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLFxuICBhdHRyaWJ1dGU6IHN0cmluZyxcbiAgdmFsdWU6IHVua25vd25cbikge1xuICBkZWVwU2V0KHJlY29yZCwgWydhdHRyaWJ1dGVzJywgYXR0cmlidXRlXSwgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVSZWNvcmRSZXBsYWNlSGFzT25lKFxuICByZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLFxuICByZWxhdGlvbnNoaXA6IHN0cmluZyxcbiAgcmVsYXRlZFJlY29yZDogUmVjb3JkSWRlbnRpdHkgfCBudWxsXG4pIHtcbiAgZGVlcFNldChcbiAgICByZWNvcmQsXG4gICAgWydyZWxhdGlvbnNoaXBzJywgcmVsYXRpb25zaGlwLCAnZGF0YSddLFxuICAgIHJlbGF0ZWRSZWNvcmQgPyBjbG9uZVJlY29yZElkZW50aXR5KHJlbGF0ZWRSZWNvcmQpIDogbnVsbFxuICApO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVSZWNvcmRSZXBsYWNlSGFzTWFueShcbiAgcmVjb3JkOiBJbml0aWFsaXplZFJlY29yZCxcbiAgcmVsYXRpb25zaGlwOiBzdHJpbmcsXG4gIHJlbGF0ZWRSZWNvcmRzOiBSZWNvcmRJZGVudGl0eVtdXG4pIHtcbiAgZGVlcFNldChcbiAgICByZWNvcmQsXG4gICAgWydyZWxhdGlvbnNoaXBzJywgcmVsYXRpb25zaGlwLCAnZGF0YSddLFxuICAgIHJlbGF0ZWRSZWNvcmRzLm1hcChjbG9uZVJlY29yZElkZW50aXR5KVxuICApO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVSZWNvcmRBZGRUb0hhc01hbnkoXG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICByZWxhdGVkUmVjb3JkOiBSZWNvcmRJZGVudGl0eVxuKSB7XG4gIGNvbnN0IGRhdGEgPSBkZWVwR2V0KHJlY29yZCwgWydyZWxhdGlvbnNoaXBzJywgcmVsYXRpb25zaGlwLCAnZGF0YSddKSB8fCBbXTtcbiAgZGF0YS5wdXNoKGNsb25lUmVjb3JkSWRlbnRpdHkocmVsYXRlZFJlY29yZCkpO1xuICBkZWVwU2V0KHJlY29yZCwgWydyZWxhdGlvbnNoaXBzJywgcmVsYXRpb25zaGlwLCAnZGF0YSddLCBkYXRhKTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlUmVjb3JkUmVtb3ZlRnJvbUhhc01hbnkoXG4gIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIHJlbGF0aW9uc2hpcDogc3RyaW5nLFxuICByZWxhdGVkUmVjb3JkOiBSZWNvcmRJZGVudGl0eVxuKSB7XG4gIGNvbnN0IGRhdGEgPSBkZWVwR2V0KHJlY29yZCwgW1xuICAgICdyZWxhdGlvbnNoaXBzJyxcbiAgICByZWxhdGlvbnNoaXAsXG4gICAgJ2RhdGEnXG4gIF0pIGFzIFJlY29yZElkZW50aXR5W107XG4gIGlmIChkYXRhKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBkYXRhLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgbGV0IHIgPSBkYXRhW2ldO1xuICAgICAgaWYgKGVxdWFsUmVjb3JkSWRlbnRpdGllcyhyLCByZWxhdGVkUmVjb3JkKSkge1xuICAgICAgICBkYXRhLnNwbGljZShpLCAxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29hbGVzY2VzIG9wZXJhdGlvbnMgaW50byBhIG1pbmltYWwgc2V0IG9mIGVxdWl2YWxlbnQgb3BlcmF0aW9ucy5cbiAqXG4gKiBUaGlzIG1ldGhvZCByZXNwZWN0cyB0aGUgb3JkZXIgb2YgdGhlIG9wZXJhdGlvbnMgYXJyYXkgYW5kIGRvZXMgbm90IGFsbG93XG4gKiByZW9yZGVyaW5nIG9mIG9wZXJhdGlvbnMgdGhhdCBhZmZlY3QgcmVsYXRpb25zaGlwcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvYWxlc2NlUmVjb3JkT3BlcmF0aW9ucyhcbiAgb3BlcmF0aW9uczogUmVjb3JkT3BlcmF0aW9uW11cbik6IFJlY29yZE9wZXJhdGlvbltdIHtcbiAgZm9yIChsZXQgaSA9IDAsIGwgPSBvcGVyYXRpb25zLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGxldCBjdXJyZW50T3AgPSBvcGVyYXRpb25zW2ldO1xuICAgIGxldCBjb25zZWN1dGl2ZU9wcyA9IHRydWU7XG5cbiAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBsOyBqKyspIHtcbiAgICAgIGxldCBuZXh0T3AgPSBvcGVyYXRpb25zW2pdO1xuXG4gICAgICBtZXJnZU9wZXJhdGlvbnMoY3VycmVudE9wLCBuZXh0T3AsIGNvbnNlY3V0aXZlT3BzKTtcblxuICAgICAgaWYgKGlzT3BlcmF0aW9uTWFya2VkVG9EZWxldGUoY3VycmVudE9wKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH0gZWxzZSBpZiAoIWlzT3BlcmF0aW9uTWFya2VkVG9EZWxldGUobmV4dE9wKSkge1xuICAgICAgICBjb25zZWN1dGl2ZU9wcyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvcGVyYXRpb25zLmZpbHRlcigobykgPT4gIWlzT3BlcmF0aW9uTWFya2VkVG9EZWxldGUobykpO1xufVxuXG4vKipcbiAqIERldGVybWluZSB0aGUgZGlmZmVyZW5jZXMgYmV0d2VlbiBhIHJlY29yZCBhbmQgaXRzIHVwZGF0ZWQgdmVyc2lvbiBpbiB0ZXJtc1xuICogb2YgYSBzZXQgb2Ygb3BlcmF0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZERpZmZzKFxuICByZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLFxuICB1cGRhdGVkUmVjb3JkOiBJbml0aWFsaXplZFJlY29yZFxuKTogUmVjb3JkT3BlcmF0aW9uW10ge1xuICBjb25zdCBvcHM6IFJlY29yZE9wZXJhdGlvbltdID0gW107XG5cbiAgaWYgKHJlY29yZCAmJiB1cGRhdGVkUmVjb3JkKSB7XG4gICAgbGV0IGZ1bGxSZWNvcmRVcGRhdGUgPSBmYWxzZTtcbiAgICBjb25zdCByZWNvcmRJZGVudGl0eSA9IGNsb25lUmVjb3JkSWRlbnRpdHkocmVjb3JkKTtcbiAgICBjb25zdCBkaWZmUmVjb3JkOiBJbml0aWFsaXplZFJlY29yZCA9IHsgLi4ucmVjb3JkSWRlbnRpdHkgfTtcblxuICAgIGZvciAobGV0IG1lbWJlciBpbiB1cGRhdGVkUmVjb3JkKSB7XG4gICAgICBpZiAobWVtYmVyICE9PSAnaWQnICYmIG1lbWJlciAhPT0gJ3R5cGUnKSB7XG4gICAgICAgIGxldCB2YWx1ZTogdW5rbm93bjtcbiAgICAgICAgbGV0IHVwZGF0ZWRWYWx1ZTogdW5rbm93bjtcblxuICAgICAgICBzd2l0Y2ggKG1lbWJlcikge1xuICAgICAgICAgIGNhc2UgJ2F0dHJpYnV0ZXMnOlxuICAgICAgICAgIGNhc2UgJ2tleXMnOlxuICAgICAgICAgIGNhc2UgJ3JlbGF0aW9uc2hpcHMnOlxuICAgICAgICAgICAgZm9yIChsZXQgZmllbGQgaW4gdXBkYXRlZFJlY29yZFttZW1iZXJdKSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gcmVjb3JkW21lbWJlcl0/LltmaWVsZF07XG4gICAgICAgICAgICAgIHVwZGF0ZWRWYWx1ZSA9ICh1cGRhdGVkUmVjb3JkW21lbWJlcl0gYXMgYW55KVtmaWVsZF07XG5cbiAgICAgICAgICAgICAgaWYgKCFlcSh2YWx1ZSwgdXBkYXRlZFZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmIChtZW1iZXIgPT09ICdyZWxhdGlvbnNoaXBzJykge1xuICAgICAgICAgICAgICAgICAgZnVsbFJlY29yZFVwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZXBTZXQoZGlmZlJlY29yZCwgW21lbWJlciwgZmllbGRdLCB1cGRhdGVkVmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB2YWx1ZSA9IChyZWNvcmQgYXMgYW55KVttZW1iZXJdO1xuICAgICAgICAgICAgdXBkYXRlZFZhbHVlID0gKHVwZGF0ZWRSZWNvcmQgYXMgYW55KVttZW1iZXJdO1xuXG4gICAgICAgICAgICBpZiAoIWVxKHVwZGF0ZWRWYWx1ZSwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgIChkaWZmUmVjb3JkIGFzIGFueSlbbWVtYmVyXSA9IHVwZGF0ZWRWYWx1ZTtcbiAgICAgICAgICAgICAgZnVsbFJlY29yZFVwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBJZiB1cGRhdGVzIGNvbnNpc3Qgc29sZWx5IG9mIGF0dHJpYnV0ZXMgYW5kIGtleXMsIHVwZGF0ZSBmaWVsZHNcbiAgICAvLyB3aXRoIGluZGl2aWR1YWwgb3BlcmF0aW9ucy4gT3RoZXJ3aXNlLCB1cGRhdGUgdGhlIHJlY29yZCBhcyBhXG4gICAgLy8gd2hvbGUuXG4gICAgaWYgKGZ1bGxSZWNvcmRVcGRhdGUpIHtcbiAgICAgIGxldCBvcDogVXBkYXRlUmVjb3JkT3BlcmF0aW9uID0ge1xuICAgICAgICBvcDogJ3VwZGF0ZVJlY29yZCcsXG4gICAgICAgIHJlY29yZDogZGlmZlJlY29yZFxuICAgICAgfTtcbiAgICAgIG9wcy5wdXNoKG9wKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRpZmZSZWNvcmQuYXR0cmlidXRlcykge1xuICAgICAgICBmb3IgKGxldCBhdHRyaWJ1dGUgaW4gZGlmZlJlY29yZC5hdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgbGV0IHZhbHVlID0gZGlmZlJlY29yZC5hdHRyaWJ1dGVzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgbGV0IG9wOiBSZXBsYWNlQXR0cmlidXRlT3BlcmF0aW9uID0ge1xuICAgICAgICAgICAgb3A6ICdyZXBsYWNlQXR0cmlidXRlJyxcbiAgICAgICAgICAgIHJlY29yZDogcmVjb3JkSWRlbnRpdHksXG4gICAgICAgICAgICBhdHRyaWJ1dGUsXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgIH07XG4gICAgICAgICAgb3BzLnB1c2gob3ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZGlmZlJlY29yZC5rZXlzKSB7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBkaWZmUmVjb3JkLmtleXMpIHtcbiAgICAgICAgICBsZXQgdmFsdWUgPSBkaWZmUmVjb3JkLmtleXNba2V5XTtcbiAgICAgICAgICBsZXQgb3A6IFJlcGxhY2VLZXlPcGVyYXRpb24gPSB7XG4gICAgICAgICAgICBvcDogJ3JlcGxhY2VLZXknLFxuICAgICAgICAgICAgcmVjb3JkOiByZWNvcmRJZGVudGl0eSxcbiAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgfTtcbiAgICAgICAgICBvcHMucHVzaChvcCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gb3BzO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlZHVwZWQgaWRlbnRpdGllcyBvZiBhbGwgdGhlIHJlY29yZHMgZGlyZWN0bHkgcmVmZXJlbmNlZCBieSBhblxuICogYXJyYXkgb2Ygb3BlcmF0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZHNSZWZlcmVuY2VkQnlPcGVyYXRpb25zKFxuICBvcGVyYXRpb25zOiBSZWNvcmRPcGVyYXRpb25bXVxuKTogUmVjb3JkSWRlbnRpdHlbXSB7XG4gIGNvbnN0IHJlY29yZHMgPSBbXTtcblxuICBmb3IgKGxldCBvcGVyYXRpb24gb2Ygb3BlcmF0aW9ucykge1xuICAgIGlmIChvcGVyYXRpb24ucmVjb3JkKSB7XG4gICAgICByZWNvcmRzLnB1c2gob3BlcmF0aW9uLnJlY29yZCk7XG5cbiAgICAgIGlmIChvcGVyYXRpb24ub3AgPT09ICdhZGRSZWNvcmQnIHx8IG9wZXJhdGlvbi5vcCA9PT0gJ3VwZGF0ZVJlY29yZCcpIHtcbiAgICAgICAgbGV0IHJlY29yZCA9IG9wZXJhdGlvbi5yZWNvcmQ7XG4gICAgICAgIGlmIChyZWNvcmQucmVsYXRpb25zaGlwcykge1xuICAgICAgICAgIGZvciAobGV0IHJlbE5hbWUgaW4gcmVjb3JkLnJlbGF0aW9uc2hpcHMpIHtcbiAgICAgICAgICAgIGxldCByZWwgPSByZWNvcmQucmVsYXRpb25zaGlwc1tyZWxOYW1lXTtcbiAgICAgICAgICAgIGlmIChyZWw/LmRhdGEpIHtcbiAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVsLmRhdGEpKSB7XG4gICAgICAgICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkocmVjb3JkcywgcmVsLmRhdGEpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlY29yZHMucHVzaChyZWwuZGF0YSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKFxuICAgICAgb3BlcmF0aW9uLm9wID09PSAnYWRkVG9SZWxhdGVkUmVjb3JkcycgfHxcbiAgICAgIG9wZXJhdGlvbi5vcCA9PT0gJ3JlbW92ZUZyb21SZWxhdGVkUmVjb3JkcycgfHxcbiAgICAgIG9wZXJhdGlvbi5vcCA9PT0gJ3JlcGxhY2VSZWxhdGVkUmVjb3JkJ1xuICAgICkge1xuICAgICAgaWYgKG9wZXJhdGlvbi5yZWxhdGVkUmVjb3JkKSB7XG4gICAgICAgIHJlY29yZHMucHVzaChvcGVyYXRpb24ucmVsYXRlZFJlY29yZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvcGVyYXRpb24ub3AgPT09ICdyZXBsYWNlUmVsYXRlZFJlY29yZHMnKSB7XG4gICAgICBBcnJheS5wcm90b3R5cGUucHVz