loopback-softdelete-mixin-with-count
Version:
A mixin to provide soft deletes by adding a deletedAt attribute for loopback Models
218 lines (171 loc) • 22.4 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
var _promise = require('babel-runtime/core-js/promise');
var _promise2 = _interopRequireDefault(_promise);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _extends7 = require('babel-runtime/helpers/extends');
var _extends8 = _interopRequireDefault(_extends7);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _debug2 = require('./debug');
var _debug3 = _interopRequireDefault(_debug2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var debug = (0, _debug3.default)();
exports.default = function (Model, _ref) {
var _ref$deletedAt = _ref.deletedAt,
deletedAt = _ref$deletedAt === undefined ? 'deletedAt' : _ref$deletedAt,
_ref$scrub = _ref.scrub,
scrub = _ref$scrub === undefined ? false : _ref$scrub;
debug('SoftDelete mixin for Model %s', Model.modelName);
debug('options', { deletedAt: deletedAt, scrub: scrub });
var properties = Model.definition.properties;
var idName = Model.dataSource.idName(Model.modelName);
var scrubbed = {};
if (scrub !== false) {
var propertiesToScrub = scrub;
if (!Array.isArray(propertiesToScrub)) {
propertiesToScrub = (0, _keys2.default)(properties).filter(function (prop) {
return !properties[prop][idName] && prop !== deletedAt;
});
}
scrubbed = propertiesToScrub.reduce(function (obj, prop) {
return (0, _extends8.default)({}, obj, (0, _defineProperty3.default)({}, prop, null));
}, {});
}
Model.defineProperty(deletedAt, { type: Date, required: false });
Model.destroyAll = function softDestroyAll(where, cb) {
var context = {
Model: Model,
where: where,
hookState: {},
options: {}
};
var deleted = void 0;
return Model.notifyObserversOf('before delete', context).then(function () {
return Model.find({ where: where, fields: ['id'] }, (0, _extends8.default)({}, scrubbed, (0, _defineProperty3.default)({}, deletedAt, new Date())));
}).then(function (instances) {
deleted = instances.map(function (instance) {
return instance.id;
});
return Model.updateAll(where, (0, _extends8.default)({}, scrubbed, (0, _defineProperty3.default)({}, deletedAt, new Date())));
}).then(function (result) {
return Model.notifyObserversOf('after delete', (0, _extends8.default)({}, context, { deleted: deleted })).then(function () {
if (typeof cb === 'function') {
cb(null, result);
}
return _promise2.default.resolve(result);
});
}).catch(function (error) {
if (typeof cb === 'function') {
cb(error);
}
});
};
Model.remove = Model.destroyAll;
Model.deleteAll = Model.destroyAll;
Model.destroyById = function softDestroyById(id, cb) {
var context = {
Model: Model,
where: { id: id },
hookState: {},
options: {}
};
return Model.notifyObserversOf('before delete', context).then(function () {
return Model.updateAll((0, _defineProperty3.default)({}, idName, id), (0, _extends8.default)({}, scrubbed, (0, _defineProperty3.default)({}, deletedAt, new Date())));
}).then(function (result) {
return Model.notifyObserversOf('after delete', (0, _extends8.default)({}, context, { deleted: [id] })).then(function () {
if (typeof cb === 'function') {
cb(null, result);
}
return _promise2.default.resolve(result);
});
}).catch(function (error) {
if (typeof cb === 'function') {
cb(error);
}
});
};
Model.removeById = Model.destroyById;
Model.deleteById = Model.destroyById;
Model.prototype.destroy = function softDestroy(options, cb) {
var callback = cb === undefined && typeof options === 'function' ? options : cb;
return this.updateAttributes((0, _extends8.default)({}, scrubbed, (0, _defineProperty3.default)({}, deletedAt, new Date()))).then(function (result) {
return typeof cb === 'function' ? callback(null, result) : result;
}).catch(function (error) {
return typeof cb === 'function' ? callback(error) : _promise2.default.reject(error);
});
};
Model.prototype.remove = Model.prototype.destroy;
Model.prototype.delete = Model.prototype.destroy;
// Emulate default scope but with more flexibility.
var queryNonDeleted = (0, _defineProperty3.default)({}, deletedAt, null);
var _findOrCreate = Model.findOrCreate;
Model.findOrCreate = function findOrCreateDeleted() {
var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!query.deleted) {
if (!query.where || (0, _keys2.default)(query.where).length === 0) {
query.where = queryNonDeleted;
} else {
query.where = { and: [query.where, queryNonDeleted] };
}
}
for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
rest[_key - 1] = arguments[_key];
}
return _findOrCreate.call.apply(_findOrCreate, [Model, query].concat(rest));
};
var _find = Model.find;
Model.find = function findDeleted() {
var query = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!query.deleted) {
if (!query.where || (0, _keys2.default)(query.where).length === 0) {
query.where = queryNonDeleted;
} else {
query.where = { and: [query.where, queryNonDeleted] };
}
}
for (var _len2 = arguments.length, rest = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
rest[_key2 - 1] = arguments[_key2];
}
return _find.call.apply(_find, [Model, query].concat(rest));
};
var _count = Model.count;
Model.count = function countDeleted() {
var where = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var newWhere = void 0;
if (!where || (0, _keys2.default)(where).length === 0) {
newWhere = queryNonDeleted;
} else {
if (where.deleted) {
delete where.deleted;
newWhere = where;
} else {
newWhere = { and: [where, queryNonDeleted] };
}
}
for (var _len3 = arguments.length, rest = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
rest[_key3 - 1] = arguments[_key3];
}
return _count.call.apply(_count, [Model, newWhere].concat(rest));
};
var _update = Model.update;
Model.update = Model.updateAll = function updateDeleted() {
var where = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
// Because update/updateAll only receives a 'where', there's nowhere to ask for the deleted entities.
var whereNotDeleted = void 0;
if (!where || (0, _keys2.default)(where).length === 0) {
whereNotDeleted = queryNonDeleted;
} else {
whereNotDeleted = { and: [where, queryNonDeleted] };
}
for (var _len4 = arguments.length, rest = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
rest[_key4 - 1] = arguments[_key4];
}
return _update.call.apply(_update, [Model, whereNotDeleted].concat(rest));
};
};
module.exports = exports['default'];
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvZnQtZGVsZXRlLmpzIl0sIm5hbWVzIjpbImRlYnVnIiwiTW9kZWwiLCJkZWxldGVkQXQiLCJzY3J1YiIsIm1vZGVsTmFtZSIsInByb3BlcnRpZXMiLCJkZWZpbml0aW9uIiwiaWROYW1lIiwiZGF0YVNvdXJjZSIsInNjcnViYmVkIiwicHJvcGVydGllc1RvU2NydWIiLCJBcnJheSIsImlzQXJyYXkiLCJmaWx0ZXIiLCJwcm9wIiwicmVkdWNlIiwib2JqIiwiZGVmaW5lUHJvcGVydHkiLCJ0eXBlIiwiRGF0ZSIsInJlcXVpcmVkIiwiZGVzdHJveUFsbCIsInNvZnREZXN0cm95QWxsIiwid2hlcmUiLCJjYiIsImNvbnRleHQiLCJob29rU3RhdGUiLCJvcHRpb25zIiwiZGVsZXRlZCIsIm5vdGlmeU9ic2VydmVyc09mIiwidGhlbiIsImZpbmQiLCJmaWVsZHMiLCJpbnN0YW5jZXMiLCJtYXAiLCJpbnN0YW5jZSIsImlkIiwidXBkYXRlQWxsIiwicmVzdWx0IiwicmVzb2x2ZSIsImNhdGNoIiwiZXJyb3IiLCJyZW1vdmUiLCJkZWxldGVBbGwiLCJkZXN0cm95QnlJZCIsInNvZnREZXN0cm95QnlJZCIsInJlbW92ZUJ5SWQiLCJkZWxldGVCeUlkIiwicHJvdG90eXBlIiwiZGVzdHJveSIsInNvZnREZXN0cm95IiwiY2FsbGJhY2siLCJ1bmRlZmluZWQiLCJ1cGRhdGVBdHRyaWJ1dGVzIiwicmVqZWN0IiwiZGVsZXRlIiwicXVlcnlOb25EZWxldGVkIiwiX2ZpbmRPckNyZWF0ZSIsImZpbmRPckNyZWF0ZSIsImZpbmRPckNyZWF0ZURlbGV0ZWQiLCJxdWVyeSIsImxlbmd0aCIsImFuZCIsInJlc3QiLCJjYWxsIiwiX2ZpbmQiLCJmaW5kRGVsZXRlZCIsIl9jb3VudCIsImNvdW50IiwiY291bnREZWxldGVkIiwibmV3V2hlcmUiLCJfdXBkYXRlIiwidXBkYXRlIiwidXBkYXRlRGVsZXRlZCIsIndoZXJlTm90RGVsZXRlZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7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QixDQUE1QyxFQUErQztBQUM3Q1MsaUJBQVdkLGVBQVg7QUFDRCxLQUZELE1BRU87QUFDTCxVQUFJakMsTUFBTUssT0FBVixFQUFtQjtBQUNqQixlQUFPTCxNQUFNSyxPQUFiO0FBQ0EwQyxtQkFBVy9DLEtBQVg7QUFDRCxPQUhELE1BR087QUFDTCtDLG1CQUFXLEVBQUVSLEtBQUssQ0FBRXZDLEtBQUYsRUFBU2lDLGVBQVQsQ0FBUCxFQUFYO0FBQ0Q7QUFDRjs7QUFYc0QsdUNBQU5PLElBQU07QUFBTkEsVUFBTTtBQUFBOztBQVl2RCxXQUFPSSxPQUFPSCxJQUFQLGdCQUFZL0QsS0FBWixFQUFtQnFFLFFBQW5CLFNBQWdDUCxJQUFoQyxFQUFQO0FBQ0QsR0FiRDs7QUFlQSxNQUFNUSxVQUFVdEUsTUFBTXVFLE1BQXRCO0FBQ0F2RSxRQUFNdUUsTUFBTixHQUFldkUsTUFBTW9DLFNBQU4sR0FBa0IsU0FBU29DLGFBQVQsR0FBNEM7QUFBQSxRQUFyQmxELEtBQXFCLHVFQUFiLEVBQWE7O0FBQzNFO0FBQ0EsUUFBSW1ELHdCQUFKO0FBQ0EsUUFBSSxDQUFDbkQsS0FBRCxJQUFVLG9CQUFZQSxLQUFaLEVBQW1Cc0MsTUFBbkIsS0FBOEIsQ0FBNUMsRUFBK0M7QUFDN0NhLHdCQUFrQmxCLGVBQWxCO0FBQ0QsS0FGRCxNQUVPO0FBQ0xrQix3QkFBa0IsRUFBRVosS0FBSyxDQUFFdkMsS0FBRixFQUFTaUMsZUFBVCxDQUFQLEVBQWxCO0FBQ0Q7O0FBUDBFLHVDQUFOTyxJQUFNO0FBQU5BLFVBQU07QUFBQTs7QUFRM0UsV0FBT1EsUUFBUVAsSUFBUixpQkFBYS9ELEtBQWIsRUFBb0J5RSxlQUFwQixTQUF3Q1gsSUFBeEMsRUFBUDtBQUNELEdBVEQ7QUFVRCxDIiwiZmlsZSI6InNvZnQtZGVsZXRlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IF9kZWJ1ZyBmcm9tICcuL2RlYnVnJztcbmNvbnN0IGRlYnVnID0gX2RlYnVnKCk7XG5cbmV4cG9ydCBkZWZhdWx0IChNb2RlbCwgeyBkZWxldGVkQXQgPSAnZGVsZXRlZEF0Jywgc2NydWIgPSBmYWxzZSB9KSA9PiB7XG4gIGRlYnVnKCdTb2Z0RGVsZXRlIG1peGluIGZvciBNb2RlbCAlcycsIE1vZGVsLm1vZGVsTmFtZSk7XG5cbiAgZGVidWcoJ29wdGlvbnMnLCB7IGRlbGV0ZWRBdCwgc2NydWIgfSk7XG5cbiAgY29uc3QgcHJvcGVydGllcyA9IE1vZGVsLmRlZmluaXRpb24ucHJvcGVydGllcztcbiAgY29uc3QgaWROYW1lID0gTW9kZWwuZGF0YVNvdXJjZS5pZE5hbWUoTW9kZWwubW9kZWxOYW1lKTtcblxuICBsZXQgc2NydWJiZWQgPSB7fTtcbiAgaWYgKHNjcnViICE9PSBmYWxzZSkge1xuICAgIGxldCBwcm9wZXJ0aWVzVG9TY3J1YiA9IHNjcnViO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShwcm9wZXJ0aWVzVG9TY3J1YikpIHtcbiAgICAgIHByb3BlcnRpZXNUb1NjcnViID0gT2JqZWN0LmtleXMocHJvcGVydGllcylcbiAgICAgICAgLmZpbHRlcihwcm9wID0+ICFwcm9wZXJ0aWVzW3Byb3BdW2lkTmFtZV0gJiYgcHJvcCAhPT0gZGVsZXRlZEF0KTtcbiAgICB9XG4gICAgc2NydWJiZWQgPSBwcm9wZXJ0aWVzVG9TY3J1Yi5yZWR1Y2UoKG9iaiwgcHJvcCkgPT4gKHsgLi4ub2JqLCBbcHJvcF06IG51bGwgfSksIHt9KTtcbiAgfVxuXG4gIE1vZGVsLmRlZmluZVByb3BlcnR5KGRlbGV0ZWRBdCwge3R5cGU6IERhdGUsIHJlcXVpcmVkOiBmYWxzZX0pO1xuXG4gIE1vZGVsLmRlc3Ryb3lBbGwgPSBmdW5jdGlvbiBzb2Z0RGVzdHJveUFsbCh3aGVyZSwgY2IpIHtcbiAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgTW9kZWwsXG4gICAgICB3aGVyZSxcbiAgICAgIGhvb2tTdGF0ZToge30sXG4gICAgICBvcHRpb25zOiB7fSxcbiAgICB9O1xuXG4gICAgbGV0IGRlbGV0ZWQ7XG4gICAgcmV0dXJuIE1vZGVsLm5vdGlmeU9ic2VydmVyc09mKCdiZWZvcmUgZGVsZXRlJywgY29udGV4dClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIE1vZGVsLmZpbmQoeyB3aGVyZSwgZmllbGRzOiBbJ2lkJ119LCB7IC4uLnNjcnViYmVkLCBbZGVsZXRlZEF0XTogbmV3IERhdGUoKSB9KTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoaW5zdGFuY2VzKSA9PiB7XG4gICAgICAgIGRlbGV0ZWQgPSBpbnN0YW5jZXMubWFwKGluc3RhbmNlID0+IGluc3RhbmNlLmlkKTtcbiAgICAgICAgcmV0dXJuIE1vZGVsLnVwZGF0ZUFsbCh3aGVyZSwgeyAuLi5zY3J1YmJlZCwgW2RlbGV0ZWRBdF06IG5ldyBEYXRlKCkgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICByZXR1cm4gTW9kZWwubm90aWZ5T2JzZXJ2ZXJzT2YoJ2FmdGVyIGRlbGV0ZScsIHsgLi4uY29udGV4dCwgZGVsZXRlZCB9KS50aGVuKCgpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYihudWxsLCByZXN1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBjYihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9O1xuXG4gIE1vZGVsLnJlbW92ZSA9IE1vZGVsLmRlc3Ryb3lBbGw7XG4gIE1vZGVsLmRlbGV0ZUFsbCA9IE1vZGVsLmRlc3Ryb3lBbGw7XG5cbiAgTW9kZWwuZGVzdHJveUJ5SWQgPSBmdW5jdGlvbiBzb2Z0RGVzdHJveUJ5SWQoaWQsIGNiKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIE1vZGVsOiBNb2RlbCxcbiAgICAgIHdoZXJlOiB7IGlkIH0sXG4gICAgICBob29rU3RhdGU6IHt9LFxuICAgICAgb3B0aW9uczoge30sXG4gICAgfTtcblxuICAgIHJldHVybiBNb2RlbC5ub3RpZnlPYnNlcnZlcnNPZignYmVmb3JlIGRlbGV0ZScsIGNvbnRleHQpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBNb2RlbC51cGRhdGVBbGwoeyBbaWROYW1lXTogaWQgfSwgeyAuLi5zY3J1YmJlZCwgW2RlbGV0ZWRBdF06IG5ldyBEYXRlKCkgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICByZXR1cm4gTW9kZWwubm90aWZ5T2JzZXJ2ZXJzT2YoJ2FmdGVyIGRlbGV0ZScsIHsgLi4uY29udGV4dCwgZGVsZXRlZDogW2lkXSB9KS50aGVuKCgpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBjYihudWxsLCByZXN1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgY2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBjYihlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9O1xuXG4gIE1vZGVsLnJlbW92ZUJ5SWQgPSBNb2RlbC5kZXN0cm95QnlJZDtcbiAgTW9kZWwuZGVsZXRlQnlJZCA9IE1vZGVsLmRlc3Ryb3lCeUlkO1xuXG4gIE1vZGVsLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gc29mdERlc3Ryb3kob3B0aW9ucywgY2IpIHtcbiAgICBjb25zdCBjYWxsYmFjayA9IChjYiA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSA/IG9wdGlvbnMgOiBjYjtcblxuICAgIHJldHVybiB0aGlzLnVwZGF0ZUF0dHJpYnV0ZXMoeyAuLi5zY3J1YmJlZCwgW2RlbGV0ZWRBdF06IG5ldyBEYXRlKCkgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiAodHlwZW9mIGNiID09PSAnZnVuY3Rpb24nKSA/IGNhbGxiYWNrKG51bGwsIHJlc3VsdCkgOiByZXN1bHQpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4gKHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykgPyBjYWxsYmFjayhlcnJvcikgOiBQcm9taXNlLnJlamVjdChlcnJvcikpO1xuICB9O1xuXG4gIE1vZGVsLnByb3RvdHlwZS5yZW1vdmUgPSBNb2RlbC5wcm90b3R5cGUuZGVzdHJveTtcbiAgTW9kZWwucHJvdG90eXBlLmRlbGV0ZSA9IE1vZGVsLnByb3RvdHlwZS5kZXN0cm95O1xuXG4gIC8vIEVtdWxhdGUgZGVmYXVsdCBzY29wZSBidXQgd2l0aCBtb3JlIGZsZXhpYmlsaXR5LlxuICBjb25zdCBxdWVyeU5vbkRlbGV0ZWQgPSB7W2RlbGV0ZWRBdF06IG51bGx9O1xuXG4gIGNvbnN0IF9maW5kT3JDcmVhdGUgPSBNb2RlbC5maW5kT3JDcmVhdGU7XG4gIE1vZGVsLmZpbmRPckNyZWF0ZSA9IGZ1bmN0aW9uIGZpbmRPckNyZWF0ZURlbGV0ZWQocXVlcnkgPSB7fSwgLi4ucmVzdCkge1xuICAgIGlmICghcXVlcnkuZGVsZXRlZCkge1xuICAgICAgaWYgKCFxdWVyeS53aGVyZSB8fCBPYmplY3Qua2V5cyhxdWVyeS53aGVyZSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlID0gcXVlcnlOb25EZWxldGVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnkud2hlcmUgPSB7IGFuZDogWyBxdWVyeS53aGVyZSwgcXVlcnlOb25EZWxldGVkIF0gfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX2ZpbmRPckNyZWF0ZS5jYWxsKE1vZGVsLCBxdWVyeSwgLi4ucmVzdCk7XG4gIH07XG5cbiAgY29uc3QgX2ZpbmQgPSBNb2RlbC5maW5kO1xuICBNb2RlbC5maW5kID0gZnVuY3Rpb24gZmluZERlbGV0ZWQocXVlcnkgPSB7fSwgLi4ucmVzdCkge1xuICAgIGlmICghcXVlcnkuZGVsZXRlZCkge1xuICAgICAgaWYgKCFxdWVyeS53aGVyZSB8fCBPYmplY3Qua2V5cyhxdWVyeS53aGVyZSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlID0gcXVlcnlOb25EZWxldGVkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnkud2hlcmUgPSB7IGFuZDogWyBxdWVyeS53aGVyZSwgcXVlcnlOb25EZWxldGVkIF0gfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gX2ZpbmQuY2FsbChNb2RlbCwgcXVlcnksIC4uLnJlc3QpO1xuICB9O1xuXG4gIGNvbnN0IF9jb3VudCA9IE1vZGVsLmNvdW50O1xuICBNb2RlbC5jb3VudCA9IGZ1bmN0aW9uIGNvdW50RGVsZXRlZCh3aGVyZSA9IHt9LCAuLi5yZXN0KSB7XG4gICAgbGV0IG5ld1doZXJlO1xuICAgIGlmICghd2hlcmUgfHwgT2JqZWN0LmtleXMod2hlcmUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbmV3V2hlcmUgPSBxdWVyeU5vbkRlbGV0ZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh3aGVyZS5kZWxldGVkKSB7XG4gICAgICAgIGRlbGV0ZSB3aGVyZS5kZWxldGVkO1xuICAgICAgICBuZXdXaGVyZSA9IHdoZXJlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3V2hlcmUgPSB7IGFuZDogWyB3aGVyZSwgcXVlcnlOb25EZWxldGVkIF0gfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIF9jb3VudC5jYWxsKE1vZGVsLCBuZXdXaGVyZSwgLi4ucmVzdCk7XG4gIH07XG5cbiAgY29uc3QgX3VwZGF0ZSA9IE1vZGVsLnVwZGF0ZTtcbiAgTW9kZWwudXBkYXRlID0gTW9kZWwudXBkYXRlQWxsID0gZnVuY3Rpb24gdXBkYXRlRGVsZXRlZCh3aGVyZSA9IHt9LCAuLi5yZXN0KSB7XG4gICAgLy8gQmVjYXVzZSB1cGRhdGUvdXBkYXRlQWxsIG9ubHkgcmVjZWl2ZXMgYSAnd2hlcmUnLCB0aGVyZSdzIG5vd2hlcmUgdG8gYXNrIGZvciB0aGUgZGVsZXRlZCBlbnRpdGllcy5cbiAgICBsZXQgd2hlcmVOb3REZWxldGVkO1xuICAgIGlmICghd2hlcmUgfHwgT2JqZWN0LmtleXMod2hlcmUpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgd2hlcmVOb3REZWxldGVkID0gcXVlcnlOb25EZWxldGVkO1xuICAgIH0gZWxzZSB7XG4gICAgICB3aGVyZU5vdERlbGV0ZWQgPSB7IGFuZDogWyB3aGVyZSwgcXVlcnlOb25EZWxldGVkIF0gfTtcbiAgICB9XG4gICAgcmV0dXJuIF91cGRhdGUuY2FsbChNb2RlbCwgd2hlcmVOb3REZWxldGVkLCAuLi5yZXN0KTtcbiAgfTtcbn07XG4iXX0=
;