UNPKG

react-siesta

Version:
263 lines (256 loc) 31.5 kB
// Just makes the code a tad cleaner if no window.Q available. var FAKE_DEFERRED = {promise: null, reject: function () {}, resolve: function () {}}; var isArray = Array.isArray || function (obj) { return _.toString.call(obj) === '[object Array]'; }; var isString = function (str) { return typeof str == 'string' || str instanceof String; }; /** * Wrap a callback and a deferred in a convienience function. * @param [cb] * @param deferred * @returns {Function} * @private */ function _done(cb, deferred) { return function (err, o) { if (err) { if (cb) cb(err); deferred.reject(err); } else { if (cb) cb(); deferred.resolve(o); } }; } var SiestaMixin = { componentWillMount: function () { this.listeners = []; }, _cancelListeners: function () { for (var i = 0; i < this.listeners.length; i++) { var cancelListener = this.listeners[i]; cancelListener(); } this.listeners = []; }, componentWillUnmount: function () { this._cancelListeners(); }, _listenToModel: function (field, Model, handler, cb) { if (Model.singleton) { Model.one(function (err, instance) { console.log('singleton', instance); if (!err) { if (field) this.listen(field, instance, function (n) {handler(n)}); else this.listen(instance, function (n) {handler(n)}); cb(err, instance); } else { handler(err); } }.bind(this)); } else throw new Error('Cannot listen to a Model if it is not a singleton'); }, wrapCancelListen: function (cancelListen) { var wrappedCancelListen; if (typeof cancelListen == 'function') { wrappedCancelListen = function () { var idx = this.listeners.indexOf(cancelListen); this.listeners.splice(idx, 1); cancelListen(); }.bind(this) } return wrappedCancelListen; }, listen: function () { var field, listenee, handler, cb; if (isString(arguments[0])) { field = arguments[0]; listenee = arguments[1]; handler = arguments[2]; cb = arguments[3]; } else { listenee = arguments[0]; handler = arguments[1]; cb = arguments[2]; } cb = cb || function () {}; var deferred = window.Q ? window.Q.defer() : FAKE_DEFERRED, done = _done(cb, deferred); if (listenee instanceof siesta._internal.Model) { this._listenToModel(field, listenee, handler, done); } else { var cancelListen; if (field) cancelListen = listenee.listen(field, handler); else cancelListen = listenee.listen(handler); this.listeners.push(cancelListen); done(null, listenee); } return deferred.promise; }, query: function (model, query, prop, cb) { cb = cb || function () {}; var deferred = window.Q ? window.Q.defer() : FAKE_DEFERRED, done = _done(cb, deferred); model.query(query, function (err, res) { console.log('_done'); if (!err) { var state = {}; state[prop] = res; this.setState(state, function () { done(null, res); }); } else { done(err); } }.bind(this)); return deferred.promise; }, all: function (model) { var query, prop, cb; if (arguments[1] instanceof String || typeof arguments[1] == 'string') { prop = arguments[1]; cb = arguments[2]; } else { query = arguments[1]; prop = arguments[2]; cb = arguments[3]; } return this.query(model, query, prop, cb); }, isReactiveQuery: function (o) { // TODO: Wishy washy. Do instanceof check instead once ReactiveQuery is available on siesta object return typeof o.terminate == 'function'; }, _listenAndSetStateForModelInstance: function (instance, opts, prop, callback) { var state = {}; opts = opts || {}; if (!opts.fields && !prop) throw Error('Must either specify fields or prop'); if (opts.fields) { var fields; if (isArray(opts.fields)) { fields = {}; opts.fields.forEach(function (f) { if (isString(f)) { fields[f] = f; } else { for (var prop in f) { if (f.hasOwnProperty(prop)) fields[prop] = f[prop]; } } //state[f] = instance[f]; }); } else { fields = opts.fields; } console.log('fields', fields); Object.keys(fields).forEach(function (f) { var custom = fields[f]; state[custom] = instance[f]; }); } else { state[prop] = instance; } console.log('state', state); this.setState(state); this.listen(instance, function (e) { if (opts.fields) { var custom = e.field, doesContain; if (isArray(opts.fields)) { doesContain = opts.fields.indexOf(e.field) > -1; } else { doesContain = e.field in opts.fields; if (doesContain) custom = opts.fields[e.field]; } if (doesContain) { var state = {}; state[custom] = e.new; this.setState(state); } } else { this.setState(); } }.bind(this)); callback(null, instance); }, listenAndSetState: function (o) { var opts, prop, cb; if (typeof arguments[1] == 'object') { opts = arguments[1]; cb = arguments[2]; } else { opts = {}; prop = arguments[1]; cb = arguments[2]; } var deferred = window.Q ? window.Q.defer() : FAKE_DEFERRED; cb = cb || function () {}; var done = _done(cb, deferred); var state = {}; var updateWithResults = function () { state[prop] = o.results; this.setState(state, function () { this.listen(o, function () { if (this.isReactiveQuery(o)) { var state = {}; state[prop] = o.results; this.setState(state); } }.bind(this)); }); }.bind(this); if (this.isReactiveQuery(o)) { if (o.initialised) { updateWithResults.call(this); done(null, o.results); } else { o.init(function () { updateWithResults.call(this); done(null, o.results); }.bind(this)); } } else if (o instanceof siesta._internal.Model) { if (o.singleton) { o.one(function (err, instance) { if (err) { cb(err); deferred.reject(err); } else { this._listenAndSetStateForModelInstance(instance, opts, prop, done); } }.bind(this)); } else { throw new Error('Can only listenAndSetState singleton models'); } } else if (o instanceof siesta._internal.siestaModel) { this._listenAndSetStateForModelInstance(o, opts, prop, done); } else { throw new Error('Cannot listenAndSetState objects of that type'); } return deferred.promise; } }; if (typeof module !== 'undefined') module.exports = {SiestaMixin: SiestaMixin}; if (typeof window !== 'undefined') window.SiestaMixin = SiestaMixin; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDhEQUE4RDtBQUM5RCxJQUFJLGFBQWEsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDOztBQUVyRixJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxJQUFJLFVBQVUsR0FBRyxFQUFFO1FBQ3RDLE9BQU8sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssZ0JBQWdCLENBQUM7QUFDekQsS0FBSyxDQUFDOztBQUVOLElBQUksUUFBUSxHQUFHLFVBQVUsR0FBRyxFQUFFO0lBQzFCLE9BQU8sT0FBTyxHQUFHLElBQUksUUFBUSxJQUFJLEdBQUcsWUFBWSxNQUFNLENBQUM7QUFDM0QsQ0FBQyxDQUFDOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0dBRUc7QUFDSCxTQUFTLEtBQUssQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFO0lBQ3pCLE9BQU8sVUFBVSxHQUFHLEVBQUUsQ0FBQyxFQUFFO1FBQ3JCLElBQUksR0FBRyxFQUFFO1lBQ0wsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hCLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDeEI7YUFDSTtZQUNELElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ2IsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN2QjtLQUNKLENBQUM7QUFDTixDQUFDOztBQUVELElBQUksV0FBVyxHQUFHO0lBQ2Qsa0JBQWtCLEVBQUUsWUFBWTtRQUM1QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztLQUN2QjtJQUNELGdCQUFnQixFQUFFLFlBQVk7UUFDMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxD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QyxDQUFDOztBQUVGLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFDL0UsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsR0FBRyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSnVzdCBtYWtlcyB0aGUgY29kZSBhIHRhZCBjbGVhbmVyIGlmIG5vIHdpbmRvdy5RIGF2YWlsYWJsZS5cbnZhciBGQUtFX0RFRkVSUkVEID0ge3Byb21pc2U6IG51bGwsIHJlamVjdDogZnVuY3Rpb24gKCkge30sIHJlc29sdmU6IGZ1bmN0aW9uICgpIHt9fTtcblxudmFyIGlzQXJyYXkgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgcmV0dXJuIF8udG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xuICAgIH07XG5cbnZhciBpc1N0cmluZyA9IGZ1bmN0aW9uIChzdHIpIHtcbiAgICByZXR1cm4gdHlwZW9mIHN0ciA9PSAnc3RyaW5nJyB8fCBzdHIgaW5zdGFuY2VvZiBTdHJpbmc7XG59O1xuXG4vKipcbiAqIFdyYXAgYSBjYWxsYmFjayBhbmQgYSBkZWZlcnJlZCBpbiBhIGNvbnZpZW5pZW5jZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSBbY2JdXG4gKiBAcGFyYW0gZGVmZXJyZWRcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn1cbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIF9kb25lKGNiLCBkZWZlcnJlZCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoZXJyLCBvKSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChjYikgY2IoZXJyKTtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNiKSBjYigpO1xuICAgICAgICAgICAgZGVmZXJyZWQucmVzb2x2ZShvKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5cbnZhciBTaWVzdGFNaXhpbiA9IHtcbiAgICBjb21wb25lbnRXaWxsTW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMgPSBbXTtcbiAgICB9LFxuICAgIF9jYW5jZWxMaXN0ZW5lcnM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGNhbmNlbExpc3RlbmVyID0gdGhpcy5saXN0ZW5lcnNbaV07XG4gICAgICAgICAgICBjYW5jZWxMaXN0ZW5lcigpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9jYW5jZWxMaXN0ZW5lcnMoKTtcbiAgICB9LFxuICAgIF9saXN0ZW5Ub01vZGVsOiBmdW5jdGlvbiAoZmllbGQsIE1vZGVsLCBoYW5kbGVyLCBjYikge1xuICAgICAgICBpZiAoTW9kZWwuc2luZ2xldG9uKSB7XG4gICAgICAgICAgICBNb2RlbC5vbmUoZnVuY3Rpb24gKGVyciwgaW5zdGFuY2UpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnc2luZ2xldG9uJywgaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgIGlmICghZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWVsZCkgdGhpcy5saXN0ZW4oZmllbGQsIGluc3RhbmNlLCBmdW5jdGlvbiAobikge2hhbmRsZXIobil9KTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB0aGlzLmxpc3RlbihpbnN0YW5jZSwgZnVuY3Rpb24gKG4pIHtoYW5kbGVyKG4pfSk7XG4gICAgICAgICAgICAgICAgICAgIGNiKGVyciwgaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaGFuZGxlcihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBsaXN0ZW4gdG8gYSBNb2RlbCBpZiBpdCBpcyBub3QgYSBzaW5nbGV0b24nKTtcbiAgICB9LFxuICAgIHdyYXBDYW5jZWxMaXN0ZW46IGZ1bmN0aW9uIChjYW5jZWxMaXN0ZW4pIHtcbiAgICAgICAgdmFyIHdyYXBwZWRDYW5jZWxMaXN0ZW47XG4gICAgICAgIGlmICh0eXBlb2YgY2FuY2VsTGlzdGVuID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHdyYXBwZWRDYW5jZWxMaXN0ZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGlkeCA9IHRoaXMubGlzdGVuZXJzLmluZGV4T2YoY2FuY2VsTGlzdGVuKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3RlbmVycy5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgICAgICAgICBjYW5jZWxMaXN0ZW4oKTtcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB3cmFwcGVkQ2FuY2VsTGlzdGVuO1xuICAgIH0sXG4gICAgbGlzdGVuOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmaWVsZCwgbGlzdGVuZWUsIGhhbmRsZXIsIGNiO1xuICAgICAgICBpZiAoaXNTdHJpbmcoYXJndW1lbnRzWzBdKSkge1xuICAgICAgICAgICAgZmllbGQgPSBhcmd1bWVudHNbMF07XG4gICAgICAgICAgICBsaXN0ZW5lZSA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIGhhbmRsZXIgPSBhcmd1bWVudHNbMl07XG4gICAgICAgICAgICBjYiA9IGFyZ3VtZW50c1szXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxpc3RlbmVlID0gYXJndW1lbnRzWzBdO1xuICAgICAgICAgICAgaGFuZGxlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIGNiID0gYXJndW1lbnRzWzJdO1xuICAgICAgICB9XG4gICAgICAgIGNiID0gY2IgfHwgZnVuY3Rpb24gKCkge307XG4gICAgICAgIHZhciBkZWZlcnJlZCA9IHdpbmRvdy5RID8gd2luZG93LlEuZGVmZXIoKSA6IEZBS0VfREVGRVJSRUQsXG4gICAgICAgICAgICBkb25lID0gX2RvbmUoY2IsIGRlZmVycmVkKTtcbiAgICAgICAgaWYgKGxpc3RlbmVlIGluc3RhbmNlb2Ygc2llc3RhLl9pbnRlcm5hbC5Nb2RlbCkge1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuVG9Nb2RlbChmaWVsZCwgbGlzdGVuZWUsIGhhbmRsZXIsIGRvbmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGNhbmNlbExpc3RlbjtcbiAgICAgICAgICAgIGlmIChmaWVsZCkgY2FuY2VsTGlzdGVuID0gbGlzdGVuZWUubGlzdGVuKGZpZWxkLCBoYW5kbGVyKTtcbiAgICAgICAgICAgIGVsc2UgY2FuY2VsTGlzdGVuID0gbGlzdGVuZWUubGlzdGVuKGhhbmRsZXIpO1xuICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMucHVzaChjYW5jZWxMaXN0ZW4pO1xuICAgICAgICAgICAgZG9uZShudWxsLCBsaXN0ZW5lZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlZmVycmVkLnByb21pc2U7XG4gICAgfSxcbiAgICBxdWVyeTogZnVuY3Rpb24gKG1vZGVsLCBxdWVyeSwgcHJvcCwgY2IpIHtcbiAgICAgICAgY2IgPSBjYiB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgdmFyIGRlZmVycmVkID0gd2luZG93LlEgPyB3aW5kb3cuUS5kZWZlcigpIDogRkFLRV9ERUZFUlJFRCxcbiAgICAgICAgICAgIGRvbmUgPSBfZG9uZShjYiwgZGVmZXJyZWQpO1xuICAgICAgICBtb2RlbC5xdWVyeShxdWVyeSwgZnVuY3Rpb24gKGVyciwgcmVzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnX2RvbmUnKTtcbiAgICAgICAgICAgIGlmICghZXJyKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0YXRlID0ge307XG4gICAgICAgICAgICAgICAgc3RhdGVbcHJvcF0gPSByZXM7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBkb25lKG51bGwsIHJlcyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkb25lKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIHJldHVybiBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH0sXG4gICAgYWxsOiBmdW5jdGlvbiAobW9kZWwpIHtcbiAgICAgICAgdmFyIHF1ZXJ5LCBwcm9wLCBjYjtcbiAgICAgICAgaWYgKGFyZ3VtZW50c1sxXSBpbnN0YW5jZW9mIFN0cmluZyB8fCB0eXBlb2YgYXJndW1lbnRzWzFdID09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBwcm9wID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgY2IgPSBhcmd1bWVudHNbMl07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBxdWVyeSA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIHByb3AgPSBhcmd1bWVudHNbMl07XG4gICAgICAgICAgICBjYiA9IGFyZ3VtZW50c1szXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5xdWVyeShtb2RlbCwgcXVlcnksIHByb3AsIGNiKTtcbiAgICB9LFxuICAgIGlzUmVhY3RpdmVRdWVyeTogZnVuY3Rpb24gKG8pIHtcbiAgICAgICAgLy8gVE9ETzogV2lzaHkgd2FzaHkuIERvIGluc3RhbmNlb2YgY2hlY2sgaW5zdGVhZCBvbmNlIFJlYWN0aXZlUXVlcnkgaXMgYXZhaWxhYmxlIG9uIHNpZXN0YSBvYmplY3RcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvLnRlcm1pbmF0ZSA9PSAnZnVuY3Rpb24nO1xuICAgIH0sXG4gICAgX2xpc3RlbkFuZFNldFN0YXRlRm9yTW9kZWxJbnN0YW5jZTogZnVuY3Rpb24gKGluc3RhbmNlLCBvcHRzLCBwcm9wLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgc3RhdGUgPSB7fTtcbiAgICAgICAgb3B0cyA9IG9wdHMgfHwge307XG4gICAgICAgIGlmICghb3B0cy5maWVsZHMgJiYgIXByb3ApIHRocm93IEVycm9yKCdNdXN0IGVpdGhlciBzcGVjaWZ5IGZpZWxkcyBvciBwcm9wJyk7XG4gICAgICAgIGlmIChvcHRzLmZpZWxkcykge1xuICAgICAgICAgICAgdmFyIGZpZWxkcztcbiAgICAgICAgICAgIGlmIChpc0FycmF5KG9wdHMuZmllbGRzKSkge1xuICAgICAgICAgICAgICAgIGZpZWxkcyA9IHt9O1xuICAgICAgICAgICAgICAgIG9wdHMuZmllbGRzLmZvckVhY2goZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RyaW5nKGYpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHNbZl0gPSBmO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGYuaGFzT3duUHJvcGVydHkocHJvcCkpIGZpZWxkc1twcm9wXSA9IGZbcHJvcF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy9zdGF0ZVtmXSA9IGluc3RhbmNlW2ZdO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZmllbGRzID0gb3B0cy5maWVsZHM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnZmllbGRzJywgZmllbGRzKTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKGZpZWxkcykuZm9yRWFjaChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIHZhciBjdXN0b20gPSBmaWVsZHNbZl07XG4gICAgICAgICAgICAgICAgc3RhdGVbY3VzdG9tXSA9IGluc3RhbmNlW2ZdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGF0ZVtwcm9wXSA9IGluc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKCdzdGF0ZScsIHN0YXRlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSk7XG4gICAgICAgIHRoaXMubGlzdGVuKGluc3RhbmNlLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKG9wdHMuZmllbGRzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGN1c3RvbSA9IGUuZmllbGQsXG4gICAgICAgICAgICAgICAgICAgIGRvZXNDb250YWluO1xuICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KG9wdHMuZmllbGRzKSkge1xuICAgICAgICAgICAgICAgICAgICBkb2VzQ29udGFpbiA9IG9wdHMuZmllbGRzLmluZGV4T2YoZS5maWVsZCkgPiAtMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRvZXNDb250YWluID0gZS5maWVsZCBpbiBvcHRzLmZpZWxkcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvZXNDb250YWluKSBjdXN0b20gPSBvcHRzLmZpZWxkc1tlLmZpZWxkXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRvZXNDb250YWluKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzdGF0ZSA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBzdGF0ZVtjdXN0b21dID0gZS5uZXc7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoc3RhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgY2FsbGJhY2sobnVsbCwgaW5zdGFuY2UpO1xuICAgIH0sXG4gICAgbGlzdGVuQW5kU2V0U3RhdGU6IGZ1bmN0aW9uIChvKSB7XG4gICAgICAgIHZhciBvcHRzLCBwcm9wLCBjYjtcbiAgICAgICAgaWYgKHR5cGVvZiBhcmd1bWVudHNbMV0gPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIG9wdHMgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICBjYiA9IGFyZ3VtZW50c1syXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9wdHMgPSB7fTtcbiAgICAgICAgICAgIHByb3AgPSBhcmd1bWVudHNbMV07XG4gICAgICAgICAgICBjYiA9IGFyZ3VtZW50c1syXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZGVmZXJyZWQgPSB3aW5kb3cuUSA/IHdpbmRvdy5RLmRlZmVyKCkgOiBGQUtFX0RFRkVSUkVEO1xuICAgICAgICBjYiA9IGNiIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICB2YXIgZG9uZSA9IF9kb25lKGNiLCBkZWZlcnJlZCk7XG4gICAgICAgIHZhciBzdGF0ZSA9IHt9O1xuXG4gICAgICAgIHZhciB1cGRhdGVXaXRoUmVzdWx0cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHN0YXRlW3Byb3BdID0gby5yZXN1bHRzO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGlzdGVuKG8sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNSZWFjdGl2ZVF1ZXJ5KG8pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdGUgPSB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlW3Byb3BdID0gby5yZXN1bHRzO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZShzdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0uYmluZCh0aGlzKTtcblxuICAgICAgICBpZiAodGhpcy5pc1JlYWN0aXZlUXVlcnkobykpIHtcbiAgICAgICAgICAgIGlmIChvLmluaXRpYWxpc2VkKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlV2l0aFJlc3VsdHMuY2FsbCh0aGlzKTtcbiAgICAgICAgICAgICAgICBkb25lKG51bGwsIG8ucmVzdWx0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvLmluaXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVXaXRoUmVzdWx0cy5jYWxsKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBkb25lKG51bGwsIG8ucmVzdWx0cyk7XG4gICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvIGluc3RhbmNlb2Ygc2llc3RhLl9pbnRlcm5hbC5Nb2RlbCkge1xuICAgICAgICAgICAgaWYgKG8uc2luZ2xldG9uKSB7XG4gICAgICAgICAgICAgICAgby5vbmUoZnVuY3Rpb24gKGVyciwgaW5zdGFuY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2IoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmVycmVkLnJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGlzdGVuQW5kU2V0U3RhdGVGb3JNb2RlbEluc3RhbmNlKGluc3RhbmNlLCBvcHRzLCBwcm9wLCBkb25lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NhbiBvbmx5IGxpc3RlbkFuZFNldFN0YXRlIHNpbmdsZXRvbiBtb2RlbHMnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvIGluc3RhbmNlb2Ygc2llc3RhLl9pbnRlcm5hbC5zaWVzdGFNb2RlbCkge1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuQW5kU2V0U3RhdGVGb3JNb2RlbEluc3RhbmNlKG8sIG9wdHMsIHByb3AsIGRvbmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgbGlzdGVuQW5kU2V0U3RhdGUgb2JqZWN0cyBvZiB0aGF0IHR5cGUnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVmZXJyZWQucHJvbWlzZTtcbiAgICB9XG59O1xuXG5pZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcpIG1vZHVsZS5leHBvcnRzID0ge1NpZXN0YU1peGluOiBTaWVzdGFNaXhpbn07XG5pZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHdpbmRvdy5TaWVzdGFNaXhpbiA9IFNpZXN0YU1peGluOyJdfQ==