react-static
Version:
A progressive static site generator for React
380 lines (294 loc) • 31.7 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pathJoin = pathJoin;
exports.getRoutePath = getRoutePath;
exports.getCurrentRoutePath = getCurrentRoutePath;
exports.unwrapArray = unwrapArray;
exports.isObject = isObject;
exports.deprecate = deprecate;
exports.removal = removal;
exports.isAbsoluteUrl = isAbsoluteUrl;
exports.makePathAbsolute = makePathAbsolute;
exports.reduceHooks = reduceHooks;
exports.mapHooks = mapHooks;
exports.getHooks = getHooks;
exports.getFullRouteData = getFullRouteData;
exports.is404Path = is404Path;
Object.defineProperty(exports, "poolAll", {
enumerable: true,
get: function get() {
return _swimmer.poolAll;
}
});
Object.defineProperty(exports, "createPool", {
enumerable: true,
get: function get() {
return _swimmer.createPool;
}
});
exports.PATH_404 = exports.cleanSlashes = exports.trimDoubleSlashes = exports.trimTrailingSlashes = exports.trimLeadingSlashes = exports.cutPathToRoot = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _swimmer = require("swimmer");
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var REGEX_TO_CUT_TO_ROOT = /(\..+?)\/.*/g;
var REGEX_TO_REMOVE_LEADING_SLASH = /^\/{1,}/g;
var REGEX_TO_REMOVE_TRAILING_SLASH = /\/{1,}$/g;
var REGEX_TO_REMOVE_DOUBLE_SLASH = /\/{2,}/g;
var cutPathToRoot = function cutPathToRoot() {
var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
return string.replace(REGEX_TO_CUT_TO_ROOT, '$1');
};
exports.cutPathToRoot = cutPathToRoot;
var trimLeadingSlashes = function trimLeadingSlashes() {
var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
return string.replace(REGEX_TO_REMOVE_LEADING_SLASH, '');
};
exports.trimLeadingSlashes = trimLeadingSlashes;
var trimTrailingSlashes = function trimTrailingSlashes() {
var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
return string.replace(REGEX_TO_REMOVE_TRAILING_SLASH, '');
};
exports.trimTrailingSlashes = trimTrailingSlashes;
var trimDoubleSlashes = function trimDoubleSlashes() {
var string = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
if (isAbsoluteUrl(string)) {
var _string$split = string.split('://'),
_string$split2 = (0, _slicedToArray2["default"])(_string$split, 2),
_string$split2$ = _string$split2[0],
scheme = _string$split2$ === void 0 ? '' : _string$split2$,
_string$split2$2 = _string$split2[1],
path = _string$split2$2 === void 0 ? '' : _string$split2$2;
return [scheme, path.replace(REGEX_TO_REMOVE_DOUBLE_SLASH, '/')].join('://');
}
return string.replace(REGEX_TO_REMOVE_DOUBLE_SLASH, '/');
};
exports.trimDoubleSlashes = trimDoubleSlashes;
var cleanSlashes = function cleanSlashes(string) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!string) return '';
var _options$leading = options.leading,
leading = _options$leading === void 0 ? true : _options$leading,
_options$trailing = options.trailing,
trailing = _options$trailing === void 0 ? true : _options$trailing,
_options$double = options["double"],
_double = _options$double === void 0 ? true : _options$double;
var cleanedString = string;
if (leading) {
cleanedString = trimLeadingSlashes(cleanedString);
}
if (trailing) {
cleanedString = trimTrailingSlashes(cleanedString);
}
if (_double) {
cleanedString = trimDoubleSlashes(cleanedString);
}
return cleanedString;
};
exports.cleanSlashes = cleanSlashes;
function pathJoin() {
for (var _len = arguments.length, paths = new Array(_len), _key = 0; _key < _len; _key++) {
paths[_key] = arguments[_key];
}
var newPath = paths.map(cleanSlashes).join('/');
if (!newPath || newPath === '/') {
return '/';
}
newPath = cleanSlashes(newPath);
if (newPath.includes('?')) {
newPath = newPath.substring(0, newPath.indexOf('?'));
}
return newPath;
} // This function is for extracting a routePath from a path or string
// RoutePaths do not have query params, basePaths, and should
// resemble the same string as passed in the static.config.js routes
function getRoutePath(routePath) {
// Detect falsey paths and the root path
if (!routePath || routePath === '/' || routePath === process.env.REACT_STATIC_BASE_PATH) {
return '/';
} // Remove origin, hashes, and query params
if (typeof document !== 'undefined') {
routePath = routePath.replace(window.location.origin, '');
routePath = routePath.replace(/#.*/, '');
routePath = routePath.replace(/\?.*/, '');
} // Be sure to remove the base path
if (process.env.REACT_STATIC_BASE_PATH) {
routePath = routePath.replace(new RegExp("^\\/?".concat(process.env.REACT_STATIC_BASE_PATH, "(\\/|$)")), '');
}
routePath = routePath || '/';
return pathJoin(routePath);
}
function getCurrentRoutePath() {
// If in the browser, use the window
if (typeof document !== 'undefined') {
return getRoutePath(decodeURIComponent(window.location.href));
}
}
function unwrapArray(arg, defaultValue) {
arg = Array.isArray(arg) ? arg[0] : arg;
if (!arg && defaultValue) {
return defaultValue;
}
return arg;
}
function isObject(a) {
return !Array.isArray(a) && (0, _typeof2["default"])(a) === 'object' && a !== null;
}
function deprecate(from, to) {
console.warn("React-Static deprecation notice: ".concat(from, " will be deprecated in favor of ").concat(to, " in the next major release."));
}
function removal(from) {
console.warn("React-Static removal notice: ".concat(from, " is no longer supported in this version of React-Static. Please refer to the CHANGELOG for details."));
}
function isAbsoluteUrl(url) {
if (typeof url !== 'string') {
return false;
}
return /^[a-z][a-z0-9+.-]*:/.test(url);
}
function makePathAbsolute(path) {
if (typeof path !== 'string') {
return '/';
}
if (isAbsoluteUrl(path)) {
return path;
}
return "/".concat(trimLeadingSlashes(path));
}
function reduceHooks(hooks) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
sync = _ref.sync;
// These returns a runner that takes a value (and options) and
// reduces the value through each hook, returning the
// final value
// compare is a function which is used to compare
// the prev and next value and decide which to use.
// By default, if undefined is returned from a reducer, the prev value
// is retained
// If synchronous, things are simple
if (sync) {
return function (value, options) {
return hooks.reduce(function (prev, hook) {
var next = hook(prev, options);
if (next instanceof Promise) {
throw new Error('Expected hook to return a value, but received promise instead. A plugin is attempting to use a sync plugin with an async function!');
}
return typeof next !== 'undefined' ? next : prev;
}, value);
};
} // We create a map of hook handlers that point to the next hook
// in line and reduce the value throughout (or return it if it's done)
return function (startValue, options) {
var hookList = hooks.map(function (hook, index) {
return /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(lastValue) {
var nextValue;
return _regenerator["default"].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return hook(lastValue, options);
case 2:
nextValue = _context.sent;
nextValue = typeof nextValue !== 'undefined' ? nextValue : lastValue;
if (!hookList[index + 1]) {
_context.next = 6;
break;
}
return _context.abrupt("return", hookList[index + 1](nextValue));
case 6:
return _context.abrupt("return", nextValue);
case 7:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref2.apply(this, arguments);
};
}();
});
return hookList.length ? hookList[0](startValue) : startValue;
};
}
function mapHooks(hooks) {
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
sync = _ref3.sync;
// Returns a function that takes state and returns
// a flat array of values mapped from each hook
if (sync) {
return function (state) {
var results = hooks.map(function (hook) {
return hook(state);
});
return results.filter(function (d) {
return typeof d !== 'undefined';
});
};
}
return function (state) {
var results = [];
var hookList = hooks.map(function (hook, index) {
return /*#__PURE__*/(0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2() {
return _regenerator["default"].wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return hook(state);
case 2:
results[index] = _context2.sent;
if (!hookList[index + 1]) {
_context2.next = 5;
break;
}
return _context2.abrupt("return", hookList[index + 1]());
case 5:
return _context2.abrupt("return", results.filter(function (d) {
return typeof d !== 'undefined';
}));
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
});
return hookList.length ? hookList[0]() : [];
};
}
function getHooks(plugins, hook) {
if (!hook) {
throw new Error('A hook ID is required!');
} // The flat hooks
var hooks = []; // Adds a plugin hook to the hook list
var addToHooks = function addToHooks(plugin) {
// Add the hook
hooks.push(plugin.hooks[hook]); // Recurse into sub plugins if needs be
if (plugin.plugins) {
plugin.plugins.forEach(addToHooks);
}
}; // Start with the config plugins
plugins.forEach(addToHooks); // Filter out falsey entries
return hooks.filter(Boolean);
}
function getFullRouteData(routeInfo) {
return _objectSpread(_objectSpread({}, routeInfo.sharedData ? routeInfo.sharedData : {}), routeInfo.data);
}
var PATH_404 = '404';
exports.PATH_404 = PATH_404;
function is404Path(path) {
return path === PATH_404;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL3V0aWxzL2luZGV4LmpzIl0sIm5hbWVzIjpbIlJFR0VYX1RPX0NVVF9UT19ST09UIiwiUkVHRVhfVE9fUkVNT1ZFX0xFQURJTkdfU0xBU0giLCJSRUdFWF9UT19SRU1PVkVfVFJBSUxJTkdfU0xBU0giLCJSRUdFWF9UT19SRU1PVkVfRE9VQkxFX1NMQVNIIiwiY3V0UGF0aFRvUm9vdCIsInN0cmluZyIsInJlcGxhY2UiLCJ0cmltTGVhZGluZ1NsYXNoZXMiLCJ0cmltVHJhaWxpbmdTbGFzaGVzIiwidHJpbURvdWJsZVNsYXNoZXMiLCJpc0Fic29sdXRlVXJsIiwic3BsaXQiLCJzY2hlbWUiLCJwYXRoIiwiam9pbiIsImNsZWFuU2xhc2hlcyIsIm9wdGlvbnMiLCJsZWFkaW5nIiwidHJhaWxpbmciLCJkb3VibGUiLCJjbGVhbmVkU3RyaW5nIiwicGF0aEpvaW4iLCJwYXRocyIsIm5ld1BhdGgiLCJtYXAiLCJpbmNsdWRlcyIsInN1YnN0cmluZyIsImluZGV4T2YiLCJnZXRSb3V0ZVBhdGgiLCJyb3V0ZVBhdGgiLCJwcm9jZXNzIiwiZW52IiwiUkVBQ1RfU1RBVElDX0JBU0VfUEFUSCIsImRvY3VtZW50Iiwid2luZG93IiwibG9jYXRpb24iLCJvcmlnaW4iLCJSZWdFeHAiLCJnZXRDdXJyZW50Um91dGVQYXRoIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiaHJlZiIsInVud3JhcEFycmF5IiwiYXJnIiwiZGVmYXVsdFZhbHVlIiwiQXJyYXkiLCJpc0FycmF5IiwiaXNPYmplY3QiLCJhIiwiZGVwcmVjYXRlIiwiZnJvbSIsInRvIiwiY29uc29sZSIsIndhcm4iLCJyZW1vdmFsIiwidXJsIiwidGVzdCIsIm1ha2VQYXRoQWJzb2x1dGUiLCJyZWR1Y2VIb29rcyIsImhvb2tzIiwic3luYyIsInZhbHVlIiwicmVkdWNlIiwicHJldiIsImhvb2siLCJuZXh0IiwiUHJvbWlzZSIsIkVycm9yIiwic3RhcnRWYWx1ZSIsImhvb2tMaXN0IiwiaW5kZXgiLCJsYXN0VmFsdWUiLCJuZXh0VmFsdWUiLCJsZW5ndGgiLCJtYXBIb29rcyIsInN0YXRlIiwicmVzdWx0cyIsImZpbHRlciIsImQiLCJnZXRIb29rcyIsInBsdWdpbnMiLCJhZGRUb0hvb2tzIiwicGx1Z2luIiwicHVzaCIsImZvckVhY2giLCJCb29sZWFuIiwiZ2V0RnVsbFJvdXRlRGF0YSIsInJvdXRlSW5mbyIsInNoYXJlZERhdGEiLCJkYXRhIiwiUEFUSF80MDQiLCJpczQwNFBhdGgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOzs7Ozs7QUFFQSxJQUFNQSxvQkFBb0IsR0FBRyxjQUE3QjtBQUNBLElBQU1DLDZCQUE2QixHQUFHLFVBQXRDO0FBQ0EsSUFBTUMsOEJBQThCLEdBQUcsVUFBdkM7QUFDQSxJQUFNQyw0QkFBNEIsR0FBRyxTQUFyQzs7QUFFTyxJQUFNQyxhQUFhLEdBQUcsU0FBaEJBLGFBQWdCO0FBQUEsTUFBQ0MsTUFBRCx1RUFBVSxFQUFWO0FBQUEsU0FDM0JBLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlTixvQkFBZixFQUFxQyxJQUFyQyxDQUQyQjtBQUFBLENBQXRCOzs7O0FBR0EsSUFBTU8sa0JBQWtCLEdBQUcsU0FBckJBLGtCQUFxQjtBQUFBLE1BQUNGLE1BQUQsdUVBQVUsRUFBVjtBQUFBLFNBQ2hDQSxNQUFNLENBQUNDLE9BQVAsQ0FBZUwsNkJBQWYsRUFBOEMsRUFBOUMsQ0FEZ0M7QUFBQSxDQUEzQjs7OztBQUdBLElBQU1PLG1CQUFtQixHQUFHLFNBQXRCQSxtQkFBc0I7QUFBQSxNQUFDSCxNQUFELHVFQUFVLEVBQVY7QUFBQSxTQUNqQ0EsTUFBTSxDQUFDQyxPQUFQLENBQWVKLDhCQUFmLEVBQStDLEVBQS9DLENBRGlDO0FBQUEsQ0FBNUI7Ozs7QUFHQSxJQUFNTyxpQkFBaUIsR0FBRyxTQUFwQkEsaUJBQW9CLEdBQWlCO0FBQUEsTUFBaEJKLE1BQWdCLHVFQUFQLEVBQU87O0FBQ2hELE1B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QWEsQ0FBQUMsTUFBTSxFQUFJO0FBQzNCO0FBQ0F2QixJQUFBQSxLQUFLLENBQUN3QixJQUFOLENBQVdELE1BQU0sQ0FBQ3ZCLEtBQVAsQ0FBYUssSUFBYixDQUFYLEVBRjJCLENBSTNCOztBQUNBLFFBQUlrQixNQUFNLENBQUNGLE9BQVgsRUFBb0I7QUFDbEJFLE1BQUFBLE1BQU0sQ0FBQ0YsT0FBUCxDQUFlSSxPQUFmLENBQXVCSCxVQUF2QjtBQUNEO0FBQ0YsR0FSRCxDQVJzQyxDQWlCdEM7OztBQUNBRCxFQUFBQSxPQUFPLENBQUNJLE9BQVIsQ0FBZ0JILFVBQWhCLEVBbEJzQyxDQW9CdEM7O0FBQ0EsU0FBT3RCLEtBQUssQ0FBQ2tCLE1BQU4sQ0FBYVEsT0FBYixDQUFQO0FBQ0Q7O0FBRU0sU0FBU0MsZ0JBQVQsQ0FBMEJDLFNBQTFCLEVBQXFDO0FBQzFDLHlDQUNNQSxTQUFTLENBQUNDLFVBQVYsR0FBdUJELFNBQVMsQ0FBQ0MsVUFBakMsR0FBOEMsRUFEcEQsR0FFS0QsU0FBUyxDQUFDRSxJQUZmO0FBSUQ7O0FBRU0sSUFBTUMsUUFBUSxHQUFHLEtBQWpCOzs7QUFFQSxTQUFTQyxTQUFULENBQW1CN0UsSUFBbkIsRUFBeUI7QUFDOUIsU0FBT0EsSUFBSSxLQUFLNEUsUUFBaEI7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IHBvb2xBbGwsIGNyZWF0ZVBvb2wgfSBmcm9tICdzd2ltbWVyJ1xuXG5jb25zdCBSRUdFWF9UT19DVVRfVE9fUk9PVCA9IC8oXFwuLis/KVxcLy4qL2dcbmNvbnN0IFJFR0VYX1RPX1JFTU9WRV9MRUFESU5HX1NMQVNIID0gL15cXC97MSx9L2dcbmNvbnN0IFJFR0VYX1RPX1JFTU9WRV9UUkFJTElOR19TTEFTSCA9IC9cXC97MSx9JC9nXG5jb25zdCBSRUdFWF9UT19SRU1PVkVfRE9VQkxFX1NMQVNIID0gL1xcL3syLH0vZ1xuXG5leHBvcnQgY29uc3QgY3V0UGF0aFRvUm9vdCA9IChzdHJpbmcgPSAnJykgPT5cbiAgc3RyaW5nLnJlcGxhY2UoUkVHRVhfVE9fQ1VUX1RPX1JPT1QsICckMScpXG5cbmV4cG9ydCBjb25zdCB0cmltTGVhZGluZ1NsYXNoZXMgPSAoc3RyaW5nID0gJycpID0+XG4gIHN0cmluZy5yZXBsYWNlKFJFR0VYX1RPX1JFTU9WRV9MRUFESU5HX1NMQVNILCAnJylcblxuZXhwb3J0IGNvbnN0IHRyaW1UcmFpbGluZ1NsYXNoZXMgPSAoc3RyaW5nID0gJycpID0+XG4gIHN0cmluZy5yZXBsYWNlKFJFR0VYX1RPX1JFTU9WRV9UUkFJTElOR19TTEFTSCwgJycpXG5cbmV4cG9ydCBjb25zdCB0cmltRG91YmxlU2xhc2hlcyA9IChzdHJpbmcgPSAnJykgPT4ge1xuICBpZiAoaXNBYnNvbHV0ZVVybChzdHJpbmcpKSB7XG4gICAgY29uc3QgW3NjaGVtZSA9ICcnLCBwYXRoID0gJyddID0gc3RyaW5nLnNwbGl0KCc6Ly8nKVxuXG4gICAgcmV0dXJuIFtzY2hlbWUsIHBhdGgucmVwbGFjZShSRUdFWF9UT19SRU1PVkVfRE9VQkxFX1NMQVNILCAnLycpXS5qb2luKCc6Ly8nKVxuICB9XG5cbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKFJFR0VYX1RPX1JFTU9WRV9ET1VCTEVfU0xBU0gsICcvJylcbn1cblxuZXhwb3J0IGNvbnN0IGNsZWFuU2xhc2hlcyA9IChzdHJpbmcsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICBpZiAoIXN0cmluZykgcmV0dXJuICcnXG5cbiAgY29uc3QgeyBsZWFkaW5nID0gdHJ1ZSwgdHJhaWxpbmcgPSB0cnVlLCBkb3VibGUgPSB0cnVlIH0gPSBvcHRpb25zXG4gIGxldCBjbGVhbmVkU3RyaW5nID0gc3RyaW5nXG5cbiAgaWYgKGxlYWRpbmcpIHtcbiAgICBjbGVhbmVkU3RyaW5nID0gdHJpbUxlYWRpbmdTbGFzaGVzKGNsZWFuZWRTdHJpbmcpXG4gIH1cblxuICBpZiAodHJhaWxpbmcpIHtcbiAgICBjbGVhbmVkU3RyaW5nID0gdHJpbVRyYWlsaW5nU2xhc2hlcyhjbGVhbmVkU3RyaW5nKVxuICB9XG5cbiAgaWYgKGRvdWJsZSkge1xuICAgIGNsZWFuZWRTdHJpbmcgPSB0cmltRG91YmxlU2xhc2hlcyhjbGVhbmVkU3RyaW5nKVxuICB9XG5cbiAgcmV0dXJuIGNsZWFuZWRTdHJpbmdcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhdGhKb2luKC4uLnBhdGhzKSB7XG4gIGxldCBuZXdQYXRoID0gcGF0aHMubWFwKGNsZWFuU2xhc2hlcykuam9pbignLycpXG4gIGlmICghbmV3UGF0aCB8fCBuZXdQYXRoID09PSAnLycpIHtcbiAgICByZXR1cm4gJy8nXG4gIH1cblxuICBuZXdQYXRoID0gY2xlYW5TbGFzaGVzKG5ld1BhdGgpXG4gIGlmIChuZXdQYXRoLmluY2x1ZGVzKCc/JykpIHtcbiAgICBuZXdQYXRoID0gbmV3UGF0aC5zdWJzdHJpbmcoMCwgbmV3UGF0aC5pbmRleE9mKCc/JykpXG4gIH1cbiAgcmV0dXJuIG5ld1BhdGhcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyBmb3IgZXh0cmFjdGluZyBhIHJvdXRlUGF0aCBmcm9tIGEgcGF0aCBvciBzdHJpbmdcbi8vIFJvdXRlUGF0aHMgZG8gbm90IGhhdmUgcXVlcnkgcGFyYW1zLCBiYXNlUGF0aHMsIGFuZCBzaG91bGRcbi8vIHJlc2VtYmxlIHRoZSBzYW1lIHN0cmluZyBhcyBwYXNzZWQgaW4gdGhlIHN0YXRpYy5jb25maWcuanMgcm91dGVzXG5leHBvcnQgZnVuY3Rpb24gZ2V0Um91dGVQYXRoKHJvdXRlUGF0aCkge1xuICAvLyBEZXRlY3QgZmFsc2V5IHBhdGhzIGFuZCB0aGUgcm9vdCBwYXRoXG4gIGlmIChcbiAgICAhcm91dGVQYXRoIHx8XG4gICAgcm91dGVQYXRoID09PSAnLycgfHxcbiAgICByb3V0ZVBhdGggPT09IHByb2Nlc3MuZW52LlJFQUNUX1NUQVRJQ19CQVNFX1BBVEhcbiAgKSB7XG4gICAgcmV0dXJuICcvJ1xuICB9XG5cbiAgLy8gUmVtb3ZlIG9yaWdpbiwgaGFzaGVzLCBhbmQgcXVlcnkgcGFyYW1zXG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcm91dGVQYXRoID0gcm91dGVQYXRoLnJlcGxhY2Uod2luZG93LmxvY2F0aW9uLm9yaWdpbiwgJycpXG4gICAgcm91dGVQYXRoID0gcm91dGVQYXRoLnJlcGxhY2UoLyMuKi8sICcnKVxuICAgIHJvdXRlUGF0aCA9IHJvdXRlUGF0aC5yZXBsYWNlKC9cXD8uKi8sICcnKVxuICB9XG5cbiAgLy8gQmUgc3VyZSB0byByZW1vdmUgdGhlIGJhc2UgcGF0aFxuICBpZiAocHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0JBU0VfUEFUSCkge1xuICAgIHJvdXRlUGF0aCA9IHJvdXRlUGF0aC5yZXBsYWNlKFxuICAgICAgbmV3IFJlZ0V4cChgXlxcXFwvPyR7cHJvY2Vzcy5lbnYuUkVBQ1RfU1RBVElDX0JBU0VfUEFUSH0oXFxcXC98JClgKSxcbiAgICAgICcnXG4gICAgKVxuICB9XG4gIHJvdXRlUGF0aCA9IHJvdXRlUGF0aCB8fCAnLydcbiAgcmV0dXJuIHBhdGhKb2luKHJvdXRlUGF0aClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRSb3V0ZVBhdGgoKSB7XG4gIC8vIElmIGluIHRoZSBicm93c2VyLCB1c2UgdGhlIHdpbmRvd1xuICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBnZXRSb3V0ZVBhdGgoZGVjb2RlVVJJQ29tcG9uZW50KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSlcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdW53cmFwQXJyYXkoYXJnLCBkZWZhdWx0VmFsdWUpIHtcbiAgYXJnID0gQXJyYXkuaXNBcnJheShhcmcpID8gYXJnWzBdIDogYXJnXG4gIGlmICghYXJnICYmIGRlZmF1bHRWYWx1ZSkge1xuICAgIHJldHVybiBkZWZhdWx0VmFsdWVcbiAgfVxuICByZXR1cm4gYXJnXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdChhKSB7XG4gIHJldHVybiAhQXJyYXkuaXNBcnJheShhKSAmJiB0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiYgYSAhPT0gbnVsbFxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVwcmVjYXRlKGZyb20sIHRvKSB7XG4gIGNvbnNvbGUud2FybihcbiAgICBgUmVhY3QtU3RhdGljIGRlcHJlY2F0aW9uIG5vdGljZTogJHtmcm9tfSB3aWxsIGJlIGRlcHJlY2F0ZWQgaW4gZmF2b3Igb2YgJHt0b30gaW4gdGhlIG5leHQgbWFqb3IgcmVsZWFzZS5gXG4gIClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92YWwoZnJvbSkge1xuICBjb25zb2xlLndhcm4oXG4gICAgYFJlYWN0LVN0YXRpYyByZW1vdmFsIG5vdGljZTogJHtmcm9tfSBpcyBubyBsb25nZXIgc3VwcG9ydGVkIGluIHRoaXMgdmVyc2lvbiBvZiBSZWFjdC1TdGF0aWMuIFBsZWFzZSByZWZlciB0byB0aGUgQ0hBTkdFTE9HIGZvciBkZXRhaWxzLmBcbiAgKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNBYnNvbHV0ZVVybCh1cmwpIHtcbiAgaWYgKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gL15bYS16XVthLXowLTkrLi1dKjovLnRlc3QodXJsKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gbWFrZVBhdGhBYnNvbHV0ZShwYXRoKSB7XG4gIGlmICh0eXBlb2YgcGF0aCAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gJy8nXG4gIH1cblxuICBpZiAoaXNBYnNvbHV0ZVVybChwYXRoKSkge1xuICAgIHJldHVybiBwYXRoXG4gIH1cblxuICByZXR1cm4gYC8ke3RyaW1MZWFkaW5nU2xhc2hlcyhwYXRoKX1gXG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWR1Y2VIb29rcyhob29rcywgeyBzeW5jIH0gPSB7fSkge1xuICAvLyBUaGVzZSByZXR1cm5zIGEgcnVubmVyIHRoYXQgdGFrZXMgYSB2YWx1ZSAoYW5kIG9wdGlvbnMpIGFuZFxuICAvLyByZWR1Y2VzIHRoZSB2YWx1ZSB0aHJvdWdoIGVhY2ggaG9vaywgcmV0dXJuaW5nIHRoZVxuICAvLyBmaW5hbCB2YWx1ZVxuICAvLyBjb21wYXJlIGlzIGEgZnVuY3Rpb24gd2hpY2ggaXMgdXNlZCB0byBjb21wYXJlXG4gIC8vIHRoZSBwcmV2IGFuZCBuZXh0IHZhbHVlIGFuZCBkZWNpZGUgd2hpY2ggdG8gdXNlLlxuICAvLyBCeSBkZWZhdWx0LCBpZiB1bmRlZmluZWQgaXMgcmV0dXJuZWQgZnJvbSBhIHJlZHVjZXIsIHRoZSBwcmV2IHZhbHVlXG4gIC8vIGlzIHJldGFpbmVkXG5cbiAgLy8gSWYgc3luY2hyb25vdXMsIHRoaW5ncyBhcmUgc2ltcGxlXG4gIGlmIChzeW5jKSB7XG4gICAgcmV0dXJuICh2YWx1ZSwgb3B0aW9ucykgPT5cbiAgICAgIGhvb2tzLnJlZHVjZSgocHJldiwgaG9vaykgPT4ge1xuICAgICAgICBjb25zdCBuZXh0ID0gaG9vayhwcmV2LCBvcHRpb25zKVxuICAgICAgICBpZiAobmV4dCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAnRXhwZWN0ZWQgaG9vayB0byByZXR1cm4gYSB2YWx1ZSwgYnV0IHJlY2VpdmVkIHByb21pc2UgaW5zdGVhZC4gQSBwbHVnaW4gaXMgYXR0ZW1wdGluZyB0byB1c2UgYSBzeW5jIHBsdWdpbiB3aXRoIGFuIGFzeW5jIGZ1bmN0aW9uISdcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHR5cGVvZiBuZXh0ICE9PSAndW5kZWZpbmVkJyA/IG5leHQgOiBwcmV2XG4gICAgICB9LCB2YWx1ZSlcbiAgfVxuXG4gIC8vIFdlIGNyZWF0ZSBhIG1hcCBvZiBob29rIGhhbmRsZXJzIHRoYXQgcG9pbnQgdG8gdGhlIG5leHQgaG9va1xuICAvLyBpbiBsaW5lIGFuZCByZWR1Y2UgdGhlIHZhbHVlIHRocm91Z2hvdXQgKG9yIHJldHVybiBpdCBpZiBpdCdzIGRvbmUpXG4gIHJldHVybiAoc3RhcnRWYWx1ZSwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IGhvb2tMaXN0ID0gaG9va3MubWFwKChob29rLCBpbmRleCkgPT4gYXN5bmMgbGFzdFZhbHVlID0+IHtcbiAgICAgIGxldCBuZXh0VmFsdWUgPSBhd2FpdCBob29rKGxhc3RWYWx1ZSwgb3B0aW9ucylcbiAgICAgIG5leHRWYWx1ZSA9IHR5cGVvZiBuZXh0VmFsdWUgIT09ICd1bmRlZmluZWQnID8gbmV4dFZhbHVlIDogbGFzdFZhbHVlXG4gICAgICBpZiAoaG9va0xpc3RbaW5kZXggKyAxXSkge1xuICAgICAgICByZXR1cm4gaG9va0xpc3RbaW5kZXggKyAxXShuZXh0VmFsdWUpXG4gICAgICB9XG4gICAgICByZXR1cm4gbmV4dFZhbHVlXG4gICAgfSlcbiAgICByZXR1cm4gaG9va0xpc3QubGVuZ3RoID8gaG9va0xpc3RbMF0oc3RhcnRWYWx1ZSkgOiBzdGFydFZhbHVlXG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1hcEhvb2tzKGhvb2tzLCB7IHN5bmMgfSA9IHt9KSB7XG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHRha2VzIHN0YXRlIGFuZCByZXR1cm5zXG4gIC8vIGEgZmxhdCBhcnJheSBvZiB2YWx1ZXMgbWFwcGVkIGZyb20gZWFjaCBob29rXG4gIGlmIChzeW5jKSB7XG4gICAgcmV0dXJuIHN0YXRlID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBob29rcy5tYXAoaG9vayA9PiBob29rKHN0YXRlKSlcbiAgICAgIHJldHVybiByZXN1bHRzLmZpbHRlcihkID0+IHR5cGVvZiBkICE9PSAndW5kZWZpbmVkJylcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3RhdGUgPT4ge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXVxuICAgIGNvbnN0IGhvb2tMaXN0ID0gaG9va3MubWFwKChob29rLCBpbmRleCkgPT4gYXN5bmMgKCkgPT4ge1xuICAgICAgcmVzdWx0c1tpbmRleF0gPSBhd2FpdCBob29rKHN0YXRlKVxuXG4gICAgICBpZiAoaG9va0xpc3RbaW5kZXggKyAxXSkge1xuICAgICAgICByZXR1cm4gaG9va0xpc3RbaW5kZXggKyAxXSgpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHRzLmZpbHRlcihkID0+IHR5cGVvZiBkICE9PSAndW5kZWZpbmVkJylcbiAgICB9KVxuICAgIHJldHVybiBob29rTGlzdC5sZW5ndGggPyBob29rTGlzdFswXSgpIDogW11cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SG9va3MocGx1Z2lucywgaG9vaykge1xuICBpZiAoIWhvb2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgaG9vayBJRCBpcyByZXF1aXJlZCEnKVxuICB9XG4gIC8vIFRoZSBmbGF0IGhvb2tzXG4gIGNvbnN0IGhvb2tzID0gW11cblxuICAvLyBBZGRzIGEgcGx1Z2luIGhvb2sgdG8gdGhlIGhvb2sgbGlzdFxuICBjb25zdCBhZGRUb0hvb2tzID0gcGx1Z2luID0+IHtcbiAgICAvLyBBZGQgdGhlIGhvb2tcbiAgICBob29rcy5wdXNoKHBsdWdpbi5ob29rc1tob29rXSlcblxuICAgIC8vIFJlY3Vyc2UgaW50byBzdWIgcGx1Z2lucyBpZiBuZWVkcyBiZVxuICAgIGlmIChwbHVnaW4ucGx1Z2lucykge1xuICAgICAgcGx1Z2luLnBsdWdpbnMuZm9yRWFjaChhZGRUb0hvb2tzKVxuICAgIH1cbiAgfVxuICAvLyBTdGFydCB3aXRoIHRoZSBjb25maWcgcGx1Z2luc1xuICBwbHVnaW5zLmZvckVhY2goYWRkVG9Ib29rcylcblxuICAvLyBGaWx0ZXIgb3V0IGZhbHNleSBlbnRyaWVzXG4gIHJldHVybiBob29rcy5maWx0ZXIoQm9vbGVhbilcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bGxSb3V0ZURhdGEocm91dGVJbmZvKSB7XG4gIHJldHVybiB7XG4gICAgLi4uKHJvdXRlSW5mby5zaGFyZWREYXRhID8gcm91dGVJbmZvLnNoYXJlZERhdGEgOiB7fSksXG4gICAgLi4ucm91dGVJbmZvLmRhdGEsXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IFBBVEhfNDA0ID0gJzQwNCdcblxuZXhwb3J0IGZ1bmN0aW9uIGlzNDA0UGF0aChwYXRoKSB7XG4gIHJldHVybiBwYXRoID09PSBQQVRIXzQwNFxufVxuIl19