unveil
Version:
A React-based Reactive Presentation Framework
277 lines (232 loc) • 23.2 kB
JavaScript
;
var _isNan = require('babel-runtime/core-js/number/is-nan');
var _isNan2 = _interopRequireDefault(_isNan);
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _keys = require('babel-runtime/core-js/object/keys');
var _keys2 = _interopRequireDefault(_keys);
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
Object.defineProperty(exports, "__esModule", {
value: true
});
var _rxjs = require('rxjs');
require('rx-history');
require('../lib/Utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var createRouter = function createRouter(opts) {
// Parametered options
var history = opts.history;
var map = opts.map;
var getDirections = opts.getDirections;
var defaultOptions = {
replaceUri: true
};
var options = (0, _assign2.default)(defaultOptions, opts);
// __internal
var subject = new _rxjs.Subject();
var observables = {};
var fromRouter = function fromRouter(router) {
return subject;
};
_rxjs.Observable.fromRouter = fromRouter;
var Path = {
cleanUp: function cleanUp(path) {
return path.trim();
}
};
var start = function start() {
subject = subject || new _rxjs.Subject();
var outAction = function outAction(action) {
return function (e) {
return e.action !== action;
};
};
observables.history = _rxjs.Observable.fromHistory(history)
//.do((e) => console.log(" history => filter outAction", e))
.filter(outAction('REPLACE'))
//.do((e) => console.log(" history => toPathAndQuery", e))
.map(toPathnameAndQuery)
//.do((e) => console.log(" history => Path.cleanup", e))
.map(stateWith('pathname', Path.cleanUp, 'pathname'))
//.do((e) => console.log(" history => distinct", e))
.distinctUntilChanged()
//.do((e) => console.log(" history => toList", e))
.map(stateWith('keys', toList, 'pathname'))
//.do((e) => console.log(" history => distinct", e))
.distinctUntilChanged()
//.do((e) => console.log(" state => before withIndices", e))
.map(stateWith('indices', toIndices, 'keys'))
//.do((e) => console.log(" state => before withPath", e))
.map(withPath)
//.do((e) => console.log(" state => before withDirections", e))
.map(withDirections)
//.do((e) => console.log(" state => before emitState", e))
.do(emitState)
//.do((e) => console.log(" replaceUri => before toPaths", e))
.distinctUntilChanged()
//.do((e) => console.log(" replaceUri => before replaceUri", e))
.subscribe(replaceUri, function (e) {
console.log("Error", e);
}, function (done) {
console.log("Router successfully unsubscribed from History");
});
};
/*
* Stops all subscriptions.
*/
var stop = function stop() {
subject.complete();
(0, _keys2.default)(observables).map(function (key) {
return observables[key];
}).compact().forEach(function (f) {
return f.complete();
});
};
var asObservable = function asObservable() {
return subject;
};
var go = function go(target) {
var query = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var parts = Array.isArray(target) && target || toList(target);
if (options.replaceUri) parts = toPaths(parts);
history.push(buildUri(buildUriString(parts), query));
};
var stateWith = function stateWith(property, method, paramName) {
return function (state) {
return (0, _assign2.default)(state, (0, _defineProperty3.default)({}, property, method(state[paramName])));
};
};
var emitState = function emitState(state) {
subject.next(state);
};
var toPathnameAndQuery = function toPathnameAndQuery(path) {
return { pathname: path.pathname, query: path.query };
};
/**
* Returns array representation of path.
* Casts numeric path-parts to actual integers.
* in: "hello/1"
* out: ["hello", 1]
*
* @param {string} path path as string
* @returns {*[]} Array of path-parts (split by "/")
*/
var toList = function toList(path) {
return path.split("/").compact().map(function (key) {
var n = Number(key);
return (0, _isNan2.default)(n) && key || n;
});
};
/**
* Recursively goes through lists, checking if
* the key passes the filter, and map that
* with the mapper
* @param {*[]} keys Array of keys related to the
* levels of the list
* @param {*[]} list (Nested) array of routes
* @param {function} filter Filter method used
* for finding the right
* route per level
* @param {function} mapper Mapper method returning
* @param {number[]} result Resulting array
*
* @returns {*[]} Array of mapped entries for each
* level of the routing
*/
var walk = function walk(keys, list, filter, mapper) {
var result = arguments.length <= 4 || arguments[4] === undefined ? [] : arguments[4];
if (keys.length < 1 && list) return walk([0], list, filter, mapper, result);
if (keys.length < 1 || !list) return result;
var element = list.filter(filter(keys[0])).pop() || list[0];
result.push(mapper(element));
return walk(keys.slice(1), element.children, filter, mapper, result);
};
/**
* Builds uri object from pathname and query
*
* @param pathname {string} Pathname
* @param query {object} Object with query params
* @returns {object} Uri object with pathname and query
*/
var buildUri = function buildUri(pathname, query) {
return { pathname: pathname, query: query };
};
/**
* Builds uri string with leading "/" from path array
* by joining path with "/".
* @param {*[]} path path array
* @returns {string} Uri string
*/
var buildUriString = function buildUriString(path) {
return '/' + path.join('/');
};
var withPath = function withPath(state) {
return (0, _assign2.default)(state, {
path: buildUriString(toPaths(state.keys))
});
};
var withDirections = function withDirections(state) {
if (getDirections && typeof getDirections === "function") {
return (0, _assign2.default)(state, {
directions: getDirections(state.indices, map)
});
}
return state;
};
/**
* Returns integer-array representation of path-array.
*
* in: ["hello", 0]
* out: [1, 0]
*
* @param keys *[] Path array
* @returns number[] Index-based path-array
*/
var toIndices = function toIndices(keys) {
var filter = function filter(key) {
return function (entry) {
return entry.name === key || entry.index === key;
};
};
var mapper = function mapper(entry) {
return entry.index;
};
var indices = walk(keys, map, filter, mapper);
return indices.length > 0 && indices || walk([0], map, filter, mapper);
};
/**
* Returns name-based array presentation of path-array
*
* @param keys *[] Path array
* @returns *[] Name-based path-array
*/
var toPaths = function toPaths(keys) {
var filter = function filter(key) {
return function (entry) {
return entry.name === key || entry.index === key;
};
};
var mapper = function mapper(entry) {
return entry.name || entry.index;
};
return walk(keys, map, filter, mapper);
};
/**
* Replaces history with path built with keys
* @param state {object} State object
*/
var replaceUri = function replaceUri(state) {
if (options.replaceUri && state.path !== state.pathname) {
history.replace(buildUri(state.path, state.query));
}
};
return {
start: start,
stop: stop,
go: go,
asObservable: asObservable
};
};
exports.default = createRouter;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21wb25lbnRzL1JvdXRlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFLQSxJQUFJLGVBQWUsU0FBZixZQUFlLENBQVMsSUFBVCxFQUFlOztNQUUxQixVQUFnQyxLQUFoQyxRQUYwQjtNQUVqQixNQUF1QixLQUF2QixJQUZpQjtNQUVaLGdCQUFrQixLQUFsQixjQUZZOztBQUloQyxNQUFJLGlCQUFpQjtBQUNuQixnQkFBWSxJQUFaO0dBREUsQ0FKNEI7QUFPaEMsTUFBSSxVQUFVLHNCQUFjLGNBQWQsRUFBOEIsSUFBOUIsQ0FBVjs7O0FBUDRCLE1BVzVCLFVBQVUsbUJBQVYsQ0FYNEI7QUFZaEMsTUFBSSxjQUFjLEVBQWQsQ0FaNEI7O0FBY2hDLE1BQUksYUFBYSxTQUFiLFVBQWEsQ0FBQyxNQUFELEVBQVk7QUFDM0IsV0FBTyxPQUFQLENBRDJCO0dBQVosQ0FkZTs7QUFrQmhDLG1CQUFXLFVBQVgsR0FBd0IsVUFBeEIsQ0FsQmdDOztBQW9CaEMsTUFBSSxPQUFPO0FBQ1QsYUFBUzthQUFTLEtBQUssSUFBTDtLQUFUO0dBRFAsQ0FwQjRCOztBQXdCaEMsTUFBSSxRQUFRLFNBQVIsS0FBUSxHQUFNO0FBQ2hCLGNBQVUsV0FBVyxtQkFBWCxDQURNOztBQUdoQixRQUFJLFlBQVksU0FBWixTQUFZLENBQUMsTUFBRCxFQUFZO0FBQzFCLGFBQU8sVUFBQyxDQUFEO2VBQU8sRUFBRSxNQUFGLEtBQWEsTUFBYjtPQUFQLENBRG1CO0tBQVosQ0FIQTs7QUFPaEIsZ0JBQVksT0FBWixHQUFzQixpQkFBVyxXQUFYLENBQXVCLE9BQXZCOztLQUVuQixNQUZtQixDQUVaLFVBQVUsU0FBVixDQUZZOztLQUluQixHQUptQixDQUlmLGtCQUplOztLQU1uQixHQU5tQixDQU1mLFVBQVUsVUFBVixFQUFzQixLQUFLLE9BQUwsRUFBYyxVQUFwQyxDQU5lOztLQVFuQixvQkFSbUI7O0tBVW5CLEdB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QVksTUFBTSxLQUFOLENBQXJDLEVBRHNEO0tBQXhEO0dBRGUsQ0FuTmU7O0FBeU5oQyxTQUFPO0FBQ0wsZ0JBREs7QUFFTCxjQUZLO0FBR0wsVUFISztBQUlMLDhCQUpLO0dBQVAsQ0F6TmdDO0NBQWY7O2tCQWlPSiIsImZpbGUiOiJSb3V0ZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgJ3J4LWhpc3RvcnknO1xuXG5pbXBvcnQgJy4uL2xpYi9VdGlscyc7XG5cbmxldCBjcmVhdGVSb3V0ZXIgPSBmdW5jdGlvbihvcHRzKSB7XG4gIC8vIFBhcmFtZXRlcmVkIG9wdGlvbnNcbiAgbGV0IHsgaGlzdG9yeSwgbWFwLCBnZXREaXJlY3Rpb25zIH0gPSBvcHRzO1xuXG4gIGxldCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICByZXBsYWNlVXJpOiB0cnVlXG4gIH07XG4gIGxldCBvcHRpb25zID0gT2JqZWN0LmFzc2lnbihkZWZhdWx0T3B0aW9ucywgb3B0cyk7XG5cblxuICAvLyBfX2ludGVybmFsXG4gIGxldCBzdWJqZWN0ID0gbmV3IFN1YmplY3QoKTtcbiAgbGV0IG9ic2VydmFibGVzID0ge307XG5cbiAgbGV0IGZyb21Sb3V0ZXIgPSAocm91dGVyKSA9PiB7XG4gICAgcmV0dXJuIHN1YmplY3Q7XG4gIH07XG5cbiAgT2JzZXJ2YWJsZS5mcm9tUm91dGVyID0gZnJvbVJvdXRlcjtcblxuICBsZXQgUGF0aCA9IHtcbiAgICBjbGVhblVwOiBwYXRoID0+IChwYXRoLnRyaW0oKSlcbiAgfTtcblxuICBsZXQgc3RhcnQgPSAoKSA9PiB7XG4gICAgc3ViamVjdCA9IHN1YmplY3QgfHwgbmV3IFN1YmplY3QoKTtcblxuICAgIGxldCBvdXRBY3Rpb24gPSAoYWN0aW9uKSA9PiB7XG4gICAgICByZXR1cm4gKGUpID0+IGUuYWN0aW9uICE9PSBhY3Rpb247XG4gICAgfTtcblxuICAgIG9ic2VydmFibGVzLmhpc3RvcnkgPSBPYnNlcnZhYmxlLmZyb21IaXN0b3J5KGhpc3RvcnkpXG4gICAgICAvLy5kbygoZSkgPT4gY29uc29sZS5sb2coXCIgICAgIGhpc3RvcnkgPT4gZmlsdGVyIG91dEFjdGlvblwiLCBlKSlcbiAgICAgIC5maWx0ZXIob3V0QWN0aW9uKCdSRVBMQUNFJykpXG4gICAgICAvLy5kbygoZSkgPT4gY29uc29sZS5sb2coXCIgICAgIGhpc3RvcnkgPT4gdG9QYXRoQW5kUXVlcnlcIiwgZSkpXG4gICAgICAubWFwKHRvUGF0aG5hbWVBbmRRdWVyeSlcbiAgICAgIC8vLmRvKChlKSA9PiBjb25zb2xlLmxvZyhcIiAgICAgaGlzdG9yeSA9PiBQYXRoLmNsZWFudXBcIiwgZSkpXG4gICAgICAubWFwKHN0YXRlV2l0aCgncGF0aG5hbWUnLCBQYXRoLmNsZWFuVXAsICdwYXRobmFtZScpKVxuICAgICAgLy8uZG8oKGUpID0+IGNvbnNvbGUubG9nKFwiICAgICBoaXN0b3J5ID0+IGRpc3RpbmN0XCIsIGUpKVxuICAgICAgLmRpc3RpbmN0VW50aWxDaGFuZ2VkKClcbiAgICAgIC8vLmRvKChlKSA9PiBjb25zb2xlLmxvZyhcIiAgICAgaGlzdG9yeSA9PiB0b0xpc3RcIiwgZSkpXG4gICAgICAubWFwKHN0YXRlV2l0aCgna2V5cycsIHRvTGlzdCwgJ3BhdGhuYW1lJykpXG4gICAgICAvLy5kbygoZSkgPT4gY29uc29sZS5sb2coXCIgICAgIGhpc3RvcnkgPT4gZGlzdGluY3RcIiwgZSkpXG4gICAgICAuZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICAgLy8uZG8oKGUpID0+IGNvbnNvbGUubG9nKFwiICAgICBzdGF0ZSA9PiBiZWZvcmUgd2l0aEluZGljZXNcIiwgZSkpXG4gICAgICAubWFwKHN0YXRlV2l0aCgnaW5kaWNlcycsIHRvSW5kaWNlcywgJ2tleXMnKSlcbiAgICAgIC8vLmRvKChlKSA9PiBjb25zb2xlLmxvZyhcIiAgICAgc3RhdGUgPT4gYmVmb3JlIHdpdGhQYXRoXCIsIGUpKVxuICAgICAgLm1hcCh3aXRoUGF0aClcbiAgICAgIC8vLmRvKChlKSA9PiBjb25zb2xlLmxvZyhcIiAgICAgc3RhdGUgPT4gYmVmb3JlIHdpdGhEaXJlY3Rpb25zXCIsIGUpKVxuICAgICAgLm1hcCh3aXRoRGlyZWN0aW9ucylcbiAgICAgIC8vLmRvKChlKSA9PiBjb25zb2xlLmxvZyhcIiAgICAgc3RhdGUgPT4gYmVmb3JlIGVtaXRTdGF0ZVwiLCBlKSlcbiAgICAgIC5kbyhlbWl0U3RhdGUpXG4gICAgICAvLy5kbygoZSkgPT4gY29uc29sZS5sb2coXCIgICAgIHJlcGxhY2VVcmkgPT4gYmVmb3JlIHRvUGF0aHNcIiwgZSkpXG4gICAgICAuZGlzdGluY3RVbnRpbENoYW5nZWQoKVxuICAgICAgLy8uZG8oKGUpID0+IGNvbnNvbGUubG9nKFwiICAgICByZXBsYWNlVXJpID0+IGJlZm9yZSByZXBsYWNlVXJpXCIsIGUpKVxuICAgICAgLnN1YnNjcmliZShyZXBsYWNlVXJpLCAoZSkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkVycm9yXCIsIGUpO1xuICAgICAgfSwgKGRvbmUpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coXCJSb3V0ZXIgc3VjY2Vzc2Z1bGx5IHVuc3Vic2NyaWJlZCBmcm9tIEhpc3RvcnlcIilcbiAgICAgIH0pO1xuICB9O1xuXG4gIC8qXG4gICAqIFN0b3BzIGFsbCBzdWJzY3JpcHRpb25zLlxuICAgKi9cbiAgbGV0IHN0b3AgPSAoKSA9PiB7XG4gICAgc3ViamVjdC5jb21wbGV0ZSgpO1xuICAgIE9iamVjdC5rZXlzKG9ic2VydmFibGVzKVxuICAgICAgLm1hcCggZnVuY3Rpb24gKGtleSkgeyByZXR1cm4gb2JzZXJ2YWJsZXNba2V5XTsgfSApXG4gICAgICAuY29tcGFjdCgpXG4gICAgICAuZm9yRWFjaCggKGYpID0+IGYuY29tcGxldGUoKSApO1xuICB9O1xuXG4gIGxldCBhc09ic2VydmFibGUgPSAoKSA9PiB7XG4gICAgcmV0dXJuIHN1YmplY3Q7XG4gIH07XG5cbiAgbGV0IGdvID0gKHRhcmdldCwgcXVlcnkgPSB7fSkgPT4ge1xuICAgIGxldCBwYXJ0cyA9IEFycmF5LmlzQXJyYXkodGFyZ2V0KSAmJiB0YXJnZXQgfHwgdG9MaXN0KHRhcmdldCk7XG5cbiAgICBpZiAob3B0aW9ucy5yZXBsYWNlVXJpKVxuICAgICAgcGFydHMgPSB0b1BhdGhzKHBhcnRzKTtcblxuICAgIGhpc3RvcnkucHVzaChidWlsZFVyaShidWlsZFVyaVN0cmluZyhwYXJ0cyksIHF1ZXJ5KSk7XG4gIH07XG5cbiAgbGV0IHN0YXRlV2l0aCA9IChwcm9wZXJ0eSwgbWV0aG9kLCBwYXJhbU5hbWUpID0+IHtcbiAgICByZXR1cm4gKHN0YXRlKSA9PiBPYmplY3QuYXNzaWduKHN0YXRlLCB7W3Byb3BlcnR5XTogbWV0aG9kKHN0YXRlW3BhcmFtTmFtZV0pfSlcbiAgfTtcblxuICBsZXQgZW1pdFN0YXRlID0gKHN0YXRlKSA9PiB7XG4gICAgc3ViamVjdC5uZXh0KHN0YXRlKTtcbiAgfTtcblxuICBsZXQgdG9QYXRobmFtZUFuZFF1ZXJ5ID0gKHBhdGgpID0+IHtcbiAgICByZXR1cm4ge3BhdGhuYW1lOiBwYXRoLnBhdGhuYW1lLCBxdWVyeTogcGF0aC5xdWVyeX07XG4gIH07XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYXJyYXkgcmVwcmVzZW50YXRpb24gb2YgcGF0aC5cbiAgICogQ2FzdHMgbnVtZXJpYyBwYXRoLXBhcnRzIHRvIGFjdHVhbCBpbnRlZ2Vycy5cbiAgICogaW46ICBcImhlbGxvLzFcIlxuICAgKiBvdXQ6IFtcImhlbGxvXCIsIDFdXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIHBhdGggYXMgc3RyaW5nXG4gICAqIEByZXR1cm5zIHsqW119IEFycmF5IG9mIHBhdGgtcGFydHMgKHNwbGl0IGJ5IFwiL1wiKVxuICAgKi9cbiAgbGV0IHRvTGlzdCA9IChwYXRoKSA9PiB7XG4gICAgcmV0dXJuIHBhdGguc3BsaXQoXCIvXCIpLmNvbXBhY3QoKS5tYXAoKGtleSkgPT4ge1xuICAgICAgbGV0IG4gPSBOdW1iZXIoa2V5KTtcbiAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4obikgJiYga2V5IHx8IG47XG4gICAgfSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJlY3Vyc2l2ZWx5IGdvZXMgdGhyb3VnaCBsaXN0cywgY2hlY2tpbmcgaWZcbiAgICogdGhlIGtleSBwYXNzZXMgdGhlIGZpbHRlciwgYW5kIG1hcCB0aGF0XG4gICAqIHdpdGggdGhlIG1hcHBlclxuICAgKiBAcGFyYW0geypbXX0ga2V5cyBBcnJheSBvZiBrZXlzIHJlbGF0ZWQgdG8gdGhlXG4gICAqICAgICAgICAgICAgICAgICAgIGxldmVscyBvZiB0aGUgbGlzdFxuICAgKiBAcGFyYW0geypbXX0gbGlzdCAoTmVzdGVkKSBhcnJheSBvZiByb3V0ZXNcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gZmlsdGVyIEZpbHRlciBtZXRob2QgdXNlZFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGZpbmRpbmcgdGhlIHJpZ2h0XG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICByb3V0ZSBwZXIgbGV2ZWxcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gbWFwcGVyIE1hcHBlciBtZXRob2QgcmV0dXJuaW5nXG4gICAqIEBwYXJhbSB7bnVtYmVyW119IHJlc3VsdCBSZXN1bHRpbmcgYXJyYXlcbiAgICpcbiAgICogQHJldHVybnMgeypbXX0gQXJyYXkgb2YgbWFwcGVkIGVudHJpZXMgZm9yIGVhY2hcbiAgICogICAgICAgICAgICAgICAgbGV2ZWwgb2YgdGhlIHJvdXRpbmdcbiAgICovXG4gIGxldCB3YWxrID0gKGtleXMsIGxpc3QsIGZpbHRlciwgbWFwcGVyLCByZXN1bHQgPSBbXSkgPT4ge1xuICAgIGlmIChrZXlzLmxlbmd0aCA8IDEgJiYgbGlzdCkgcmV0dXJuIHdhbGsoWzBdLCBsaXN0LCBmaWx0ZXIsIG1hcHBlciwgcmVzdWx0KTtcbiAgICBpZiAoa2V5cy5sZW5ndGggPCAxIHx8ICFsaXN0KSByZXR1cm4gcmVzdWx0O1xuXG4gICAgbGV0IGVsZW1lbnQgPSBsaXN0LmZpbHRlcihmaWx0ZXIoa2V5c1swXSkpLnBvcCgpIHx8IGxpc3RbMF07XG4gICAgcmVzdWx0LnB1c2gobWFwcGVyKGVsZW1lbnQpKTtcblxuICAgIHJldHVybiB3YWxrKGtleXMuc2xpY2UoMSksIGVsZW1lbnQuY2hpbGRyZW4sIGZpbHRlciwgbWFwcGVyLCByZXN1bHQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBCdWlsZHMgdXJpIG9iamVjdCBmcm9tIHBhdGhuYW1lIGFuZCBxdWVyeVxuICAgKlxuICAgKiBAcGFyYW0gcGF0aG5hbWUge3N0cmluZ30gUGF0aG5hbWVcbiAgICogQHBhcmFtIHF1ZXJ5IHtvYmplY3R9IE9iamVjdCB3aXRoIHF1ZXJ5IHBhcmFtc1xuICAgKiBAcmV0dXJucyB7b2JqZWN0fSBVcmkgb2JqZWN0IHdpdGggcGF0aG5hbWUgYW5kIHF1ZXJ5XG4gICAqL1xuICBsZXQgYnVpbGRVcmkgPSAocGF0aG5hbWUsIHF1ZXJ5KSA9PiB7XG4gICAgcmV0dXJuIHtwYXRobmFtZTogcGF0aG5hbWUsIHF1ZXJ5OiBxdWVyeX07XG4gIH07XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB1cmkgc3RyaW5nIHdpdGggbGVhZGluZyBcIi9cIiBmcm9tIHBhdGggYXJyYXlcbiAgICogYnkgam9pbmluZyBwYXRoIHdpdGggXCIvXCIuXG4gICAqIEBwYXJhbSB7KltdfSBwYXRoIHBhdGggYXJyYXlcbiAgICogQHJldHVybnMge3N0cmluZ30gVXJpIHN0cmluZ1xuICAgKi9cbiAgbGV0IGJ1aWxkVXJpU3RyaW5nID0gKHBhdGgpID0+IHtcbiAgICByZXR1cm4gYC8ke3BhdGguam9pbignLycpfWBcbiAgfTtcblxuICBsZXQgd2l0aFBhdGggPSAoc3RhdGUpID0+IE9iamVjdC5hc3NpZ24oc3RhdGUsIHtcbiAgICBwYXRoOiBidWlsZFVyaVN0cmluZyh0b1BhdGhzKHN0YXRlLmtleXMpKVxuICB9KTtcblxuICBsZXQgd2l0aERpcmVjdGlvbnMgPSAoc3RhdGUpID0+IHtcbiAgICBpZihnZXREaXJlY3Rpb25zICYmIHR5cGVvZiBnZXREaXJlY3Rpb25zID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHN0YXRlLCB7XG4gICAgICAgIGRpcmVjdGlvbnM6IGdldERpcmVjdGlvbnMoc3RhdGUuaW5kaWNlcywgbWFwKVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfTtcblxuICAvKipcbiAgICogUmV0dXJucyBpbnRlZ2VyLWFycmF5IHJlcHJlc2VudGF0aW9uIG9mIHBhdGgtYXJyYXkuXG4gICAqXG4gICAqIGluOiAgW1wiaGVsbG9cIiwgMF1cbiAgICogb3V0OiBbMSwgMF1cbiAgICpcbiAgICogQHBhcmFtIGtleXMgKltdIFBhdGggYXJyYXlcbiAgICogQHJldHVybnMgbnVtYmVyW10gSW5kZXgtYmFzZWQgcGF0aC1hcnJheVxuICAgKi9cbiAgbGV0IHRvSW5kaWNlcyA9IChrZXlzKSA9PiB7XG4gICAgbGV0IGZpbHRlciA9IChrZXkpID0+IHtcbiAgICAgIHJldHVybiAoZW50cnkpID0+IChlbnRyeS5uYW1lID09PSBrZXkgfHwgZW50cnkuaW5kZXggPT09IGtleSlcblxuICAgIH07XG4gICAgbGV0IG1hcHBlciA9IChlbnRyeSkgPT4gZW50cnkuaW5kZXg7XG4gICAgbGV0IGluZGljZXMgPSB3YWxrKGtleXMsIG1hcCwgZmlsdGVyLCBtYXBwZXIpO1xuICAgIHJldHVybiBpbmRpY2VzLmxlbmd0aCA+IDAgJiYgaW5kaWNlcyB8fCB3YWxrKFswXSwgbWFwLCBmaWx0ZXIsIG1hcHBlcik7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJldHVybnMgbmFtZS1iYXNlZCBhcnJheSBwcmVzZW50YXRpb24gb2YgcGF0aC1hcnJheVxuICAgKlxuICAgKiBAcGFyYW0ga2V5cyAqW10gUGF0aCBhcnJheVxuICAgKiBAcmV0dXJucyAqW10gTmFtZS1iYXNlZCBwYXRoLWFycmF5XG4gICAqL1xuICBsZXQgdG9QYXRocyA9IGZ1bmN0aW9uIChrZXlzKSB7XG4gICAgbGV0IGZpbHRlciA9IChrZXkpID0+IHtcbiAgICAgIHJldHVybiAoZW50cnkpID0+IChlbnRyeS5uYW1lID09PSBrZXkgfHwgZW50cnkuaW5kZXggPT09IGtleSlcbiAgICB9O1xuICAgIGxldCBtYXBwZXIgPSAoZW50cnkpID0+IChlbnRyeS5uYW1lIHx8IGVudHJ5LmluZGV4KTtcbiAgICByZXR1cm4gd2FsayhrZXlzLCBtYXAsIGZpbHRlciwgbWFwcGVyKTtcbiAgfTtcblxuICAvKipcbiAgICogUmVwbGFjZXMgaGlzdG9yeSB3aXRoIHBhdGggYnVpbHQgd2l0aCBrZXlzXG4gICAqIEBwYXJhbSBzdGF0ZSB7b2JqZWN0fSBTdGF0ZSBvYmplY3RcbiAgICovXG4gIGxldCByZXBsYWNlVXJpID0gZnVuY3Rpb24gKHN0YXRlKSB7XG4gICAgaWYob3B0aW9ucy5yZXBsYWNlVXJpICYmIHN0YXRlLnBhdGggIT09IHN0YXRlLnBhdGhuYW1lKSB7XG4gICAgICBoaXN0b3J5LnJlcGxhY2UoYnVpbGRVcmkoc3RhdGUucGF0aCwgc3RhdGUucXVlcnkpKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBzdGFydCxcbiAgICBzdG9wLFxuICAgIGdvLFxuICAgIGFzT2JzZXJ2YWJsZVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjcmVhdGVSb3V0ZXI7XG4iXX0=