to better match corresponding pre-rendered DOM), and calls reset()\n * method of the parent SplitRoute when unmounted. This allows to reset\n * SplitRoute to the initial state, which is necessary for its proper\n * functioning.\n */\n\nvar ContentWrapper = function (_React$Component) {\n (0, _inherits3.default)(ContentWrapper, _React$Component);\n\n function ContentWrapper() {\n (0, _classCallCheck3.default)(this, ContentWrapper);\n return (0, _possibleConstructorReturn3.default)(this, (ContentWrapper.__proto__ || (0, _getPrototypeOf2.default)(ContentWrapper)).apply(this, arguments));\n }\n\n (0, _createClass3.default)(ContentWrapper, [{\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n var parent = this.props.parent;\n\n parent.reset();\n }\n }, {\n key: 'render',\n value: function render() {\n var content = this.props.content;\n\n return content;\n }\n }, {\n key: '__reactstandin__regenerateByEval',\n // @ts-ignore\n value: function __reactstandin__regenerateByEval(key, code) {\n // @ts-ignore\n this[key] = eval(code);\n }\n }]);\n return ContentWrapper;\n}(_react2.default.Component);\n\nvar _default = ContentWrapper;\nexports.default = _default;\n\n\nContentWrapper.propTypes = {\n content: _propTypes2.default.element.isRequired,\n parent: _propTypes2.default.shape({\n reset: _propTypes2.default.func.isRequired\n }).isRequired\n};\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(ContentWrapper, 'ContentWrapper', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/containers/AppChunk/ContentWrapper.jsx');\n reactHotLoader.register(_default, 'default', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/containers/AppChunk/ContentWrapper.jsx');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/containers/AppChunk/ContentWrapper.jsx?");
+
+/***/ }),
+
+/***/ "./src/shared/containers/AppChunk/index.jsx":
+/*!**************************************************!*\
+ !*** ./src/shared/containers/AppChunk/index.jsx ***!
+ \**************************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module, global) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _getPrototypeOf = __webpack_require__(/*! babel-runtime/core-js/object/get-prototype-of */ \"babel-runtime/core-js/object/get-prototype-of\");\n\nvar _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);\n\nvar _classCallCheck2 = __webpack_require__(/*! babel-runtime/helpers/classCallCheck */ \"babel-runtime/helpers/classCallCheck\");\n\nvar _classCallCheck3 = _interopRequireDefault(_classCallCheck2);\n\nvar _createClass2 = __webpack_require__(/*! babel-runtime/helpers/createClass */ \"babel-runtime/helpers/createClass\");\n\nvar _createClass3 = _interopRequireDefault(_createClass2);\n\nvar _possibleConstructorReturn2 = __webpack_require__(/*! babel-runtime/helpers/possibleConstructorReturn */ \"babel-runtime/helpers/possibleConstructorReturn\");\n\nvar _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);\n\nvar _inherits2 = __webpack_require__(/*! babel-runtime/helpers/inherits */ \"babel-runtime/helpers/inherits\");\n\nvar _inherits3 = _interopRequireDefault(_inherits2);\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _moment = __webpack_require__(/*! moment */ \"moment\");\n\nvar _moment2 = _interopRequireDefault(_moment);\n\nvar _propTypes = __webpack_require__(/*! prop-types */ \"prop-types\");\n\nvar _propTypes2 = _interopRequireDefault(_propTypes);\n\nvar _react = __webpack_require__(/*! react */ \"react\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _server = __webpack_require__(/*! react-dom/server */ \"react-dom/server\");\n\nvar _server2 = _interopRequireDefault(_server);\n\nvar _shortid = __webpack_require__(/*! shortid */ \"shortid\");\n\nvar _shortid2 = _interopRequireDefault(_shortid);\n\nvar _reactRedux = __webpack_require__(/*! react-redux */ \"react-redux\");\n\nvar _reactRouterDom = __webpack_require__(/*! react-router-dom */ \"react-router-dom\");\n\nvar _isomorphy = __webpack_require__(/*! ../../utils/isomorphy */ \"./src/shared/utils/isomorphy.js\");\n\nvar _ContentWrapper = __webpack_require__(/*! ./ContentWrapper */ \"./src/shared/containers/AppChunk/ContentWrapper.jsx\");\n\nvar _ContentWrapper2 = _interopRequireDefault(_ContentWrapper);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})(); /**\n * A custom component for code splitting support, with react-router routes\n * serving as the split points. Because it is quite complex, here are only\n * some technical comments in the code. For instructions on how to use it\n * refer to\n * https://github.com/topcoder-platform/community-app/blob/develop/docs/code-splitting.md\n */\n\n/* global document, window */\n\n/* Specifies the maximal number of unused CSS stylesheets to be kept in memory.\n */\nvar MAX_UNUSED_STYLESHEETS = 10;\n\nvar unusedCssStamp = 0;\n\nvar SplitRoute = function (_React$Component) {\n (0, _inherits3.default)(SplitRoute, _React$Component);\n\n function SplitRoute(props) {\n (0, _classCallCheck3.default)(this, SplitRoute);\n\n var _this = (0, _possibleConstructorReturn3.default)(this, (SplitRoute.__proto__ || (0, _getPrototypeOf2.default)(SplitRoute)).call(this, props));\n\n _this.state = { component: null };\n return _this;\n }\n\n (0, _createClass3.default)(SplitRoute, [{\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n this.unmounted = true;\n }\n }, {\n key: 'reset',\n value: function reset() {\n /* Marking chunk's stylesheet as unused.\n * This works properly only when styling does not depend on the ordering\n * of loaded stylesheets, which is how our CSS should be written. */\n var chunkName = this.props.chunkName;\n\n var link = document.querySelector('link[data-chunk=\"' + chunkName + '\"]');\n if (link) link.setAttribute('data-chunk-unused', unusedCssStamp += 1);\n\n /* Reset to the initial state. */\n this.setState({ component: null });\n }\n }, {\n key: 'render',\n value: function render() {\n var _this2 = this;\n\n var _props = this.props,\n chunkName = _props.chunkName,\n exact = _props.exact,\n location = _props.location,\n path = _props.path,\n renderClientAsync = _props.renderClientAsync,\n renderPlaceholder = _props.renderPlaceholder,\n renderServer = _props.renderServer,\n strict = _props.strict;\n\n\n var PUBLIC_PATH = global.TRU_BUILD_INFO.publicPath;\n var CROSS_ORIGIN_LOADING = global.TRU_BUILD_INFO.crossOriginLoading;\n\n var timestamp = (0, _moment2.default)((0, _isomorphy.buildTimestamp)()).valueOf();\n\n var component = this.state.component;\n\n\n return _react2.default.createElement(_reactRouterDom.Route, {\n component: component,\n exact: exact,\n location: location,\n path: path,\n render: function render(props) {\n var res = null;\n if ((0, _isomorphy.isServerSide)()) {\n /* Server-side rendering */\n\n /* 1. The component or its placeholder is rendered into HTML\n * string. And, yes, just in case we have to wrap it into\n * Provider, otherwise containers in the render will break\n * the code. */\n var render = renderServer || renderPlaceholder || function () {\n return _react2.default.createElement('div', null);\n };\n var html = _server2.default.renderToString(_react2.default.createElement(\n _reactRedux.Provider,\n { store: props.staticContext.store },\n _react2.default.createElement(\n _reactRouterDom.StaticRouter,\n {\n context: props.staticContext,\n location: props.location\n },\n render(props)\n )\n ));\n\n /* 2. The rendered HTML string is added to the router context,\n * to be injected by server/renderer.jsx into the rendered HTML\n * document as a field of window.SPLITS object. We also check\n * that route ID is unique among all matched SplitRoutes. */\n /* eslint-disable react/prop-types */\n var splits = props.staticContext.splits;\n /* eslint-enable react/prop-types */\n\n if (splits[chunkName]) throw new Error('SplitRoute: IDs clash!');else splits[chunkName] = html;\n\n /* 3. The stylesheet links are injected via links elements in the\n * header of the document, to have a better control over styles\n * (re-)loading, independent of ReactJS mechanics of\n * the document updates. */\n props.staticContext.chunks.push(chunkName);\n\n /* 4. We also render the mounted component, or the placeholder,\n * into the document, using dangerouslySetInnerHTML to inject\n * previously rendered HTML string into the main body of the doc.\n * Thanks to (2) and (3), at the client side we will be able to\n * perform exactly the same rendering even before the splitted\n * code is loaded, thus not breaking the result of server-side\n * rendering. */\n /* eslint-disable react/no-danger */\n res = _react2.default.createElement('div', { dangerouslySetInnerHTML: { __html: html } });\n /* eslint-enable react/no-danger */\n } else {\n /* Client side rendering */\n if (window.SPLITS[chunkName]) {\n /* If the page has been pre-rendered at the server-side, we render\n * exactly the same until the splitted code is loaded. */\n /* eslint-disable react/no-danger */\n res = _react2.default.createElement('div', {\n dangerouslySetInnerHTML: {\n __html: window.SPLITS[chunkName]\n }\n });\n /* eslint-disable react/no-danger */\n\n /* We remove the pre-rendered HTML string from window.SPLITS,\n * because if the vistor navigates around the app and comes back\n * to this route, we want to re-render the page from scratch in\n * that case (because the state of app has changed). */\n delete window.SPLITS[chunkName];\n } else if (renderPlaceholder) {\n /* If the page has not been pre-rendered, the best we can do prior\n * the loading of split code, is to render the placeholder, if\n * provided.\n *\n * NOTE: The
wrappings here and in other places below may\n * look unnecessary, but they are important: we want to be sure\n * that all render options produce the same markup, thus helping\n * ReactJS to be efficient.\n */\n res = _react2.default.createElement(\n 'div',\n null,\n renderPlaceholder(props)\n );\n }\n\n /* The links to stylesheets are injected into document header using\n * browser's API, rather than ReactJS rendering mechanism, because\n * it gives a better control over reloading of the stylesheets and\n * helps to avoid some unnecessary flickering when the app loads a\n * page already pre-rendered at the server side. */\n var link = document.querySelector('link[data-chunk=\"' + chunkName + '\"]');\n if (link) {\n /* Marking the chunk being used again. */\n link.removeAttribute('data-chunk-unused');\n } else {\n link = document.createElement('link');\n link.setAttribute('data-chunk', chunkName);\n link.setAttribute('href', PUBLIC_PATH + '/' + chunkName + '-' + timestamp + '.css');\n if (CROSS_ORIGIN_LOADING) {\n link.setAttribute('crossorigin', CROSS_ORIGIN_LOADING);\n }\n link.setAttribute('id', 'tru-style');\n link.setAttribute('rel', 'stylesheet');\n var head = document.getElementsByTagName('head')[0];\n head.appendChild(link);\n\n /* Unloads unused CSS stylesheets, if too many of them are\n * loaded. */\n var unused = head.querySelectorAll('link[data-chunk-unused]');\n if (unused.length > MAX_UNUSED_STYLESHEETS) {\n var arr = [];\n unused.forEach(function (x) {\n /* eslint-disable no-param-reassign */\n x.chunkOrder = Number(x.getAttribute('data-chunk-unused'));\n /* eslint-enable no-param-reassign */\n arr.push(x);\n });\n arr.sort(function (a, b) {\n return a.chunkOrder - b.chunkOrder;\n });\n arr.slice(0, unused.length - MAX_UNUSED_STYLESHEETS).forEach(function (x) {\n return head.removeChild(x);\n });\n }\n }\n\n /* Checking, whether we need to trigger async rendering process,\n * as it might be already launched before and we can end up with\n * a deadlock. We want to re-trigger it only if some props having\n * impact on the rendering result have been changed. */\n var shouldReRender = !_this2.pendingRender;\n if (!shouldReRender) {\n shouldReRender = _this2.pendingRender !== renderClientAsync;\n _lodash2.default.forIn(_this2.pendingRenderProps, function (value, key) {\n shouldReRender = shouldReRender || value !== props[key];\n });\n }\n if (!shouldReRender) return res;\n\n var renderUUID = (0, _shortid2.default)();\n _this2.pendingRenderUUID = renderUUID;\n _this2.pendingRender = renderClientAsync;\n _this2.pendingRenderProps = props;\n\n /* Finally, we call the async renderer and once the promise it\n * returns is resolved, we set the resulting component to the state,\n * which causes it to be set on this route via \"component\" props,\n * that has a higher precedence that \"render\". The component is\n * wrapped by ContentWrapper helper, which takes care about\n * removing it from the state once it is unmounted, to ensure\n * that the next time the route is matched, its content will\n * be re-rendered from scratch. */\n renderClientAsync(props).then(function (component2) {\n if (renderUUID !== _this2.pendingRenderUUID) return;\n _this2.pendingRenderUUID = null;\n _this2.pendingRender = null;\n _this2.pendingRenderProps = null;\n _this2.setState({\n component: function component() {\n return _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(_ContentWrapper2.default, {\n chunkName: chunkName,\n content: component2,\n parent: _this2\n })\n );\n }\n });\n });\n }\n\n return res;\n },\n strict: strict\n });\n }\n }, {\n key: '__reactstandin__regenerateByEval',\n // @ts-ignore\n value: function __reactstandin__regenerateByEval(key, code) {\n // @ts-ignore\n this[key] = eval(code);\n }\n }]);\n return SplitRoute;\n}(_react2.default.Component);\n\nvar _default = SplitRoute;\nexports.default = _default;\n\n\nSplitRoute.defaultProps = {\n exact: false,\n location: null,\n path: null,\n renderPlaceholder: null,\n renderServer: null,\n strict: false\n};\n\nSplitRoute.propTypes = {\n chunkName: _propTypes2.default.string.isRequired,\n exact: _propTypes2.default.bool,\n location: _propTypes2.default.shape(),\n path: _propTypes2.default.string,\n renderClientAsync: _propTypes2.default.func.isRequired,\n renderPlaceholder: _propTypes2.default.func,\n renderServer: _propTypes2.default.func,\n strict: _propTypes2.default.bool\n};\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(MAX_UNUSED_STYLESHEETS, 'MAX_UNUSED_STYLESHEETS', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/containers/AppChunk/index.jsx');\n reactHotLoader.register(unusedCssStamp, 'unusedCssStamp', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/containers/AppChunk/index.jsx');\n reactHotLoader.register(SplitRoute, 'SplitRoute', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/containers/AppChunk/index.jsx');\n reactHotLoader.register(_default, 'default', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/containers/AppChunk/index.jsx');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module), __webpack_require__(/*! ./../../../../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/containers/AppChunk/index.jsx?");
+
+/***/ }),
+
+/***/ "./src/shared/reducers/collection.js":
+/*!*******************************************!*\
+ !*** ./src/shared/reducers/collection.js ***!
+ \*******************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _extends3 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends4 = _interopRequireDefault(_extends3);\n\nvar _redux$handleActions; /**\n * Proof-of-concept code. Will be documented once stable. In case of any\n * questions before that, feel free to contact `birdofpreyru`.\n */\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _collection = __webpack_require__(/*! ../actions/collection */ \"./src/shared/actions/collection.js\");\n\nvar _collection2 = _interopRequireDefault(_collection);\n\nvar _redux = __webpack_require__(/*! ../utils/redux */ \"./src/shared/utils/redux.js\");\n\nvar redux = _interopRequireWildcard(_redux);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})();\n\n/**\n * Inits, or replaces by its clone, the slot indexed under the specified id.\n * Returns the new slot indexed by that id.\n *\n * BEWARE: It mutates the index.\n *\n * @param {Object} index\n * @param {String} id\n * @return {Object}\n */\nfunction prepare(index, id) {\n var slot = index[id];\n slot = slot ? _lodash2.default.clone(slot) : {\n item: null,\n loadingOperationId: '',\n numRefs: 0,\n timestamp: 0\n };\n index[id] = slot; // eslint-disable-line no-param-reassign\n return slot;\n}\n\nfunction onAddItems(state, action) {\n var _action$payload = action.payload,\n index = _action$payload.index,\n timestamp = _action$payload.timestamp;\n\n var result = _lodash2.default.clone(state);\n _lodash2.default.forOwn(index, function (item, id) {\n var slot = prepare(result, id);\n slot.timestamp = timestamp;\n slot.item = item;\n });\n return result;\n}\n\nfunction onBookItems(state, _ref) {\n var _ref$payload = _ref.payload,\n factor = _ref$payload.factor,\n ids = _ref$payload.ids;\n\n var result = _lodash2.default.clone(state);\n ids.forEach(function (id) {\n prepare(result, id).numRefs += factor;\n });\n return result;\n}\n\nfunction onClean(state, _ref2) {\n var payload = _ref2.payload;\n\n var result = _lodash2.default.clone(state);\n _lodash2.default.forOwn(state, function (item, id) {\n var slot = state[id];\n if (slot.numRefs || slot.loadingOperationId || slot.timestamp > payload) return;\n delete result[id];\n });\n return result;\n}\n\nfunction onFreeItems(state, _ref3) {\n var _ref3$payload = _ref3.payload,\n factor = _ref3$payload.factor,\n ids = _ref3$payload.ids;\n\n var result = _lodash2.default.clone(state);\n ids.forEach(function (id) {\n prepare(result, id).numRefs -= factor;\n });\n return result;\n}\n\nfunction onLoadItemInit(state, _ref4) {\n var payload = _ref4.payload;\n var itemId = payload.itemId,\n operationId = payload.operationId;\n\n var result = _lodash2.default.clone(state);\n var slot = prepare(result, itemId);\n slot.loadingOperationId = operationId;\n return result;\n}\n\nfunction onLoadItemDone(state, _ref5) {\n var payload = _ref5.payload;\n var item = payload.item,\n itemId = payload.itemId,\n operationId = payload.operationId,\n timestamp = payload.timestamp;\n\n var slot = state[itemId];\n if (!slot || slot.loadingOperationId !== operationId) return state;\n return (0, _extends4.default)({}, state, (0, _defineProperty3.default)({}, itemId, (0, _extends4.default)({}, slot, {\n item: item,\n loadingOperationId: '',\n timestamp: timestamp\n })));\n}\n\nvar a = _collection2.default.collection;\n\nvar _default = redux.handleActions((_redux$handleActions = {}, (0, _defineProperty3.default)(_redux$handleActions, a.addItems, onAddItems), (0, _defineProperty3.default)(_redux$handleActions, a.bookItems, onBookItems), (0, _defineProperty3.default)(_redux$handleActions, a.clean, onClean), (0, _defineProperty3.default)(_redux$handleActions, a.freeItems, onFreeItems), (0, _defineProperty3.default)(_redux$handleActions, a.loadItemInit, onLoadItemInit), (0, _defineProperty3.default)(_redux$handleActions, a.loadItemDone, onLoadItemDone), _redux$handleActions), {});\n\nexports.default = _default;\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(prepare, 'prepare', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(onAddItems, 'onAddItems', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(onBookItems, 'onBookItems', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(onClean, 'onClean', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(onFreeItems, 'onFreeItems', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(onLoadItemInit, 'onLoadItemInit', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(onLoadItemDone, 'onLoadItemDone', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(a, 'a', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n reactHotLoader.register(_default, 'default', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/collection.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/reducers/collection.js?");
+
+/***/ }),
+
+/***/ "./src/shared/reducers/index.js":
+/*!**************************************!*\
+ !*** ./src/shared/reducers/index.js ***!
+ \**************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _collection = __webpack_require__(/*! ./collection */ \"./src/shared/reducers/collection.js\");\n\nvar _collection2 = _interopRequireDefault(_collection);\n\nvar _item = __webpack_require__(/*! ./item */ \"./src/shared/reducers/item.js\");\n\nvar _item2 = _interopRequireDefault(_item);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})();\n\nvar _default = {\n collection: _collection2.default,\n item: _item2.default\n};\nexports.default = _default;\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(_default, 'default', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/index.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/reducers/index.js?");
+
+/***/ }),
+
+/***/ "./src/shared/reducers/item.js":
+/*!*************************************!*\
+ !*** ./src/shared/reducers/item.js ***!
+ \*************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\nvar _redux$handleActions; /**\n * @module \"reducers.item\"\n * @desc Reducer for {@link module:actions.item} actions.\n *\n * State segment managed by this reducer has the following structure:\n * @param {Any} data=null Actual item data.\n * @param {Number|String} loadingOperationId=null `null` when no loading\n * operation is happening; unique identifier of the ongoing loading operation\n * otherwise (expected to be a truly value).\n * @param {Number} numRefs=0 Number of references to this item from the code.\n * @param {Number} timestamp=0 Timestamp of the most recent moment when item\n * data were loaded or set.\n */\n\nvar _item = __webpack_require__(/*! ../actions/item */ \"./src/shared/actions/item.js\");\n\nvar _item2 = _interopRequireDefault(_item);\n\nvar _redux = __webpack_require__(/*! ../utils/redux */ \"./src/shared/utils/redux.js\");\n\nvar redux = _interopRequireWildcard(_redux);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})();\n\nfunction onDropData(state, _ref) {\n var olderThan = _ref.payload;\n\n if (state.numRefs > 0 || state.timestamp > olderThan) return state;\n return (0, _extends3.default)({}, state, { data: null, timestamp: 0 });\n}\n\nfunction onLoadDataInit(state, _ref2) {\n var loadingOperationId = _ref2.payload;\n\n return (0, _extends3.default)({}, state, { loadingOperationId: loadingOperationId });\n}\n\nfunction onLoadDataDone(state, action) {\n var _action$payload = action.payload,\n data = _action$payload.data,\n loadingOperationId = _action$payload.loadingOperationId,\n timestamp = _action$payload.timestamp;\n\n if (loadingOperationId !== state.loadingOperationId) return state;\n return (0, _extends3.default)({}, state, {\n data: data,\n loadingOperationId: null,\n timestamp: timestamp\n });\n}\n\nfunction onSetData(state, _ref3) {\n var payload = _ref3.payload;\n\n return (0, _extends3.default)({}, state, payload);\n}\n\nfunction onUpdateReferenceCounter(state, _ref4) {\n var shift = _ref4.payload;\n\n var numRefs = state.numRefs + shift;\n return (0, _extends3.default)({}, state, { numRefs: numRefs });\n}\n\nvar a = _item2.default.item;\n\nvar _default = redux.handleActions((_redux$handleActions = {}, (0, _defineProperty3.default)(_redux$handleActions, a.dropData, onDropData), (0, _defineProperty3.default)(_redux$handleActions, a.loadDataInit, onLoadDataInit), (0, _defineProperty3.default)(_redux$handleActions, a.loadDataDone, onLoadDataDone), (0, _defineProperty3.default)(_redux$handleActions, a.setData, onSetData), (0, _defineProperty3.default)(_redux$handleActions, a.updateReferenceCounter, onUpdateReferenceCounter), _redux$handleActions), {\n data: null,\n loadingOperationId: null,\n numRefs: 0,\n timestamp: 0\n});\n\nexports.default = _default;\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(onDropData, 'onDropData', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n reactHotLoader.register(onLoadDataInit, 'onLoadDataInit', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n reactHotLoader.register(onLoadDataDone, 'onLoadDataDone', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n reactHotLoader.register(onSetData, 'onSetData', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n reactHotLoader.register(onUpdateReferenceCounter, 'onUpdateReferenceCounter', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n reactHotLoader.register(a, 'a', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n reactHotLoader.register(_default, 'default', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/reducers/item.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/reducers/item.js?");
+
+/***/ }),
+
+/***/ "./src/shared/utils/config.js":
+/*!************************************!*\
+ !*** ./src/shared/utils/config.js ***!
+ \************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("\n\nvar _isomorphy = __webpack_require__(/*! ./isomorphy */ \"./src/shared/utils/isomorphy.js\");\n\nvar _webpack = __webpack_require__(/*! ./webpack */ \"./src/shared/utils/webpack/index.js\");\n\n/* eslint-disable global-require */\n// console.log('IS CLIENT SIDE', isClientSide());\n/**\n * This module provides isomorphic configuration. At the client-side it serves\n * cofiguration object from the global CONFIG variable, injected into the page\n * during the server-side rendering; at the server side it is fetched directly\n * from node-config.\n */\n\n/* global window */\n\nmodule.exports = (0, _isomorphy.isClientSide)() ? window.CONFIG : (0, _webpack.requireWeak)('config');\n/* eslint-enable global-require */\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/utils/config.js?");
+
+/***/ }),
+
+/***/ "./src/shared/utils/index.js":
+/*!***********************************!*\
+ !*** ./src/shared/utils/index.js ***!
+ \***********************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.webpack = exports.redux = exports.JU = exports.isomorphy = exports.config = undefined;\n\nvar _config = __webpack_require__(/*! ./config */ \"./src/shared/utils/config.js\");\n\nvar _config2 = _interopRequireDefault(_config);\n\nvar _isomorphy = __webpack_require__(/*! ./isomorphy */ \"./src/shared/utils/isomorphy.js\");\n\nvar isomorphy = _interopRequireWildcard(_isomorphy);\n\nvar _redux = __webpack_require__(/*! ./redux */ \"./src/shared/utils/redux.js\");\n\nvar redux = _interopRequireWildcard(_redux);\n\nvar _webpack = __webpack_require__(/*! ./webpack */ \"./src/shared/utils/webpack/index.js\");\n\nvar webpack = _interopRequireWildcard(_webpack);\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})();\n\nvar juUrl = isomorphy.isProdBuild() ? 'prod' : 'dev';\njuUrl = 'topcoder-react-utils/dist/' + juUrl + '/shared/utils/jest';\n\nvar JU = isomorphy.isServerSide() ? webpack.requireWeak(juUrl) : null;\n\nexports.config = _config2.default;\nexports.isomorphy = isomorphy;\nexports.JU = JU;\nexports.redux = redux;\nexports.webpack = webpack;\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(juUrl, 'juUrl', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/index.js');\n reactHotLoader.register(JU, 'JU', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/index.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/utils/index.js?");
+
+/***/ }),
+
+/***/ "./src/shared/utils/isomorphy.js":
+/*!***************************************!*\
+ !*** ./src/shared/utils/isomorphy.js ***!
+ \***************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module, global) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.isClientSide = isClientSide;\nexports.isServerSide = isServerSide;\nexports.isDevBuild = isDevBuild;\nexports.isProdBuild = isProdBuild;\nexports.buildTimestamp = buildTimestamp;\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})();\n\n/**\n * Collection of helpers to deal with isomorphic aspects of the code.\n */\n\n/* global window */\n\n/**\n * Returns `true` when executed at the front end side; `false` otherwise.\n * @return {Boolean}\n */\nfunction isClientSide() {\n return typeof window !== 'undefined' && Boolean(window.TRU_FRONT_END);\n}\n\n/**\n * Returns `true` if executed at the server side; `false` otherwise.\n * @return {Boolean}\n */\nfunction isServerSide() {\n return typeof window === 'undefined' || !window.TRU_FRONT_END;\n}\n\n/**\n * @return {String} Code mode: \"development\" or \"production\".\n */\nfunction getMode() {\n return \"development\";\n}\n\n/**\n * Returns `true` if development version of the code is running;\n * `false` otherwise.\n * @return {Boolean}\n */\nfunction isDevBuild() {\n return getMode() === 'development';\n}\n\n/**\n * Returns `true` if production build of the code is running;\n * `false` otherwise.\n * @return {Boolean}\n */\nfunction isProdBuild() {\n return getMode() === 'production';\n}\n\n/**\n * Returns build timestamp of the front-end JS bundle.\n * @return {String} ISO date/time string.\n */\nfunction buildTimestamp() {\n return (isClientSide() ? window : global).TRU_BUILD_INFO.timestamp;\n}\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(isClientSide, 'isClientSide', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/isomorphy.js');\n reactHotLoader.register(isServerSide, 'isServerSide', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/isomorphy.js');\n reactHotLoader.register(getMode, 'getMode', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/isomorphy.js');\n reactHotLoader.register(isDevBuild, 'isDevBuild', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/isomorphy.js');\n reactHotLoader.register(isProdBuild, 'isProdBuild', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/isomorphy.js');\n reactHotLoader.register(buildTimestamp, 'buildTimestamp', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/isomorphy.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module), __webpack_require__(/*! ./../../../node_modules/webpack/buildin/global.js */ \"./node_modules/webpack/buildin/global.js\")))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/utils/isomorphy.js?");
+
+/***/ }),
+
+/***/ "./src/shared/utils/redux.js":
+/*!***********************************!*\
+ !*** ./src/shared/utils/redux.js ***!
+ \***********************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.storeFactory = undefined;\n\nvar _regenerator = __webpack_require__(/*! babel-runtime/regenerator */ \"babel-runtime/regenerator\");\n\nvar _regenerator2 = _interopRequireDefault(_regenerator);\n\nvar _asyncToGenerator2 = __webpack_require__(/*! babel-runtime/helpers/asyncToGenerator */ \"babel-runtime/helpers/asyncToGenerator\");\n\nvar _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\nvar _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _keys = __webpack_require__(/*! babel-runtime/core-js/object/keys */ \"babel-runtime/core-js/object/keys\");\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nvar _assign = __webpack_require__(/*! babel-runtime/core-js/object/assign */ \"babel-runtime/core-js/object/assign\");\n\nvar _assign2 = _interopRequireDefault(_assign);\n\n/**\n * Creates a new Redux store.\n * @param {Function} getReducerFactory Function that returns reducer factory.\n * For HMR to work, it should require the JS module of the factory each time it\n * is called.\n * @param {Object} httpRequest Optional. ExpressJS HTTP request. It should be\n * passed in at the server side to support server-side rendering.\n * @param {Object} intialState Optional. Initial state of Redux store. It should\n * be passed in at the client side to support server-side rendering.\n * @param {Object} moduleHot Optional. `module.hot` object from the module that\n * imports storeFactory(..).\n * @param {Object} reducerFactoryModulePath Optional. Path of the root module of\n * the reducer factory. It is necessary for proper HMR support.\n * @return {Promise} Resolves to the new Redux store.\n */\nvar storeFactory = exports.storeFactory = function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(_ref2) {\n var _this = this;\n\n var getReducerFactory = _ref2.getReducerFactory,\n httpRequest = _ref2.httpRequest,\n initialState = _ref2.initialState,\n moduleHot = _ref2.moduleHot,\n reducerFactoryModulePath = _ref2.reducerFactoryModulePath;\n var reducer, enhancer, store;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return getReducerFactory()(httpRequest);\n\n case 2:\n reducer = _context2.sent;\n enhancer = (0, _redux.applyMiddleware)(_reduxPromise2.default);\n\n if ((0, _isomorphy.isDevBuild)()) enhancer = (0, _redux.compose)(enhancer, _DevTools2.default.instrument());\n store = (0, _redux.createStore)(reducer, initialState || {}, enhancer);\n\n if (moduleHot && reducerFactoryModulePath) {\n moduleHot.accept(reducerFactoryModulePath, (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {\n var newReducer;\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _context.next = 2;\n return getReducerFactory()();\n\n case 2:\n newReducer = _context.sent;\n\n store.replaceReducer(newReducer);\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n })));\n }\n return _context2.abrupt('return', store);\n\n case 8:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n return function storeFactory(_x) {\n return _ref.apply(this, arguments);\n };\n}();\n\nexports.combineReducers = combineReducers;\nexports.proxyAction = proxyAction;\nexports.proxyReducer = proxyReducer;\nexports.resolveAction = resolveAction;\nexports.resolveReducers = resolveReducers;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _DevTools = __webpack_require__(/*! ../components/DevTools */ \"./src/shared/components/DevTools.jsx\");\n\nvar _DevTools2 = _interopRequireDefault(_DevTools);\n\nvar _reduxPromise = __webpack_require__(/*! redux-promise */ \"redux-promise\");\n\nvar _reduxPromise2 = _interopRequireDefault(_reduxPromise);\n\nvar _redux = __webpack_require__(/*! redux */ \"redux\");\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _reactRedux = __webpack_require__(/*! react-redux */ \"react-redux\");\n\nvar _isomorphy = __webpack_require__(/*! ./isomorphy */ \"./src/shared/utils/isomorphy.js\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})(); /**\n * Redux-related helpers.\n */\n\n/* Auxiliary aliases. */\nmodule.exports.connect = _reactRedux.connect;\nmodule.exports.createActions = _reduxActions.createActions;\nmodule.exports.handleActions = _reduxActions.handleActions;\n\n/**\n * Reduce multiple reducers into a single reducer from left to right.\n * Function-type reducers will be called directly with current state, and action\n * Object type reducers (eg: `{submissions: (state, action) => {}}`)\n * will be called with the state's slice corresponding to object's key\n * eg: `{submissions}` will be called with `submissions(state.submissions, action)`\n *\n * @params {function|Object} the reducers to be combined\n * @return function the unified reducer\n */\n/* TODO: Can we simplify this function? */\nfunction combineReducers() {\n for (var _len = arguments.length, reducers = Array(_len), _key = 0; _key < _len; _key++) {\n reducers[_key] = arguments[_key];\n }\n\n return function (state, action) {\n var nextState = {};\n var mergeState = _assign2.default.bind(Object, nextState);\n\n reducers.forEach(function (reducer) {\n if (typeof reducer === 'function') {\n return mergeState(reducer(state, action));\n }\n\n (0, _keys2.default)(reducer).forEach(function (slice) {\n mergeState((0, _defineProperty3.default)({}, slice, reducer[slice]((state || {})[slice], action)));\n });\n return undefined;\n });\n\n return nextState;\n };\n}\n\n/**\n * Helps to proxy actions. This function has two modes:\n *\n * 1. **When no `action` is given:** it re-generates payload creator used by\n * `actionCreator`; i.e. it returns a function that passes its arguments\n * to the given `actionCreator`, and then returns `payload` of the\n * created action.\n *\n * 2. **When `action` is given:** it returns a copy of `action` with its type\n * replaced by the type of `actionCreator`.\n *\n * @param {Function} actionCreator Creator of the proxied action. It is assumed\n * that it creates a Flux Standard Action.\n * @param {Action} action Optional. Action to map.\n * @return {Function|Action} Payload creator, or the mapped action.\n */\nfunction proxyAction(actionCreator, action) {\n if (action) return (0, _extends3.default)({}, action, { type: actionCreator.toString() });\n return function () {\n return actionCreator.apply(undefined, arguments).payload;\n };\n}\n\n/**\n * Wraps given reducer with a piece of code that changes the type of incoming\n * action to the type of action created by the given `actionCreator`.\n * @param {Function} reducer\n * @param {Function} actionCreator\n * @return {Reducer}\n */\nfunction proxyReducer(reducer, actionCreator) {\n return function (state, action) {\n return reducer(state, proxyAction(actionCreator, action));\n };\n}\n\n/**\n * Given any Flux Standard Action (FSA) with promise as the payload, it returns\n * a promise which resolves into the FSA result object.\n * @param {Object} action\n * @return Promise which resolves to the operation result.\n */\nfunction resolveAction(action) {\n return action.payload.then(function (data) {\n return (0, _extends3.default)({}, action, {\n payload: data\n });\n }, function (error) {\n return (0, _extends3.default)({}, action, {\n payload: error,\n error: true\n });\n });\n}\n\n/**\n * Given a mapping between reducer names and their promises, this function\n * waits till resolution of all promises and returns the mapping between\n * reducer names and the resolved reducers.\n * @param {Object} promises Object with promises of reducers.\n * @return Object with reducers.\n */\nfunction resolveReducers(promises) {\n return _promise2.default.all(_lodash2.default.values(promises)).then(function (reducers) {\n var map = {};\n _lodash2.default.keys(promises).forEach(function (key, index) {\n map[key] = reducers[index];\n });\n return map;\n });\n};\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(combineReducers, 'combineReducers', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/redux.js');\n reactHotLoader.register(proxyAction, 'proxyAction', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/redux.js');\n reactHotLoader.register(proxyReducer, 'proxyReducer', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/redux.js');\n reactHotLoader.register(resolveAction, 'resolveAction', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/redux.js');\n reactHotLoader.register(resolveReducers, 'resolveReducers', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/redux.js');\n reactHotLoader.register(storeFactory, 'storeFactory', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/redux.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/utils/redux.js?");
+
+/***/ }),
+
+/***/ "./src/shared/utils/webpack/index.js":
+/*!*******************************************!*\
+ !*** ./src/shared/utils/webpack/index.js ***!
+ \*******************************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+"use strict";
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.requireWeak = requireWeak;\nexports.resolveWeak = resolveWeak;\n\n(function () {\n var enterModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").enterModule;\n\n enterModule && enterModule(module);\n})();\n\n/**\n * Requires the specified module without including it into the bundle during\n * Webpack build. This function should be executed only server-side.\n *\n * WARNING: Beware to pass in relative paths: they will be resolved relative\n * to the library distribution function, this is not what you want in most of\n * cases. To convert a relative path to the absolute one, do in the caller code\n * ```\n * import path from 'path';\n * const p = path.resolve(__dirname, './relative/path');\n * const module = requireWeak(p);\n * ```\n * In case you use an absolute path that relies on Babel module resolver,\n * pass it through resolveWeak function below.\n *\n * @param {String} modulePath\n * @return Required module.\n */\nfunction requireWeak(modulePath) {\n /* eslint-disable global-require, import/no-dynamic-require */\n var mod = __webpack_require__(/*! ./require */ \"./src/shared/utils/webpack/require.js\")(modulePath);\n /* eslint-enable global-require, import/no-dynamic-require */\n return mod.default || mod;\n}\n\n/**\n * Resolves specified module path with help of Babel's module resolver.\n * Yes, the function itself just returns its argument to the caller, but Babel\n * is configured to resolve the first argument of resolveWeak(..) function, thus\n * the result will be the resolved path.\n * @param {String} modulePath\n * @return {String} Absolute or relative path to the module.\n */\nfunction resolveWeak(modulePath) {\n return modulePath;\n}\n;\n\n(function () {\n var reactHotLoader = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").default;\n\n var leaveModule = __webpack_require__(/*! react-hot-loader */ \"react-hot-loader\").leaveModule;\n\n if (!reactHotLoader) {\n return;\n }\n\n reactHotLoader.register(requireWeak, 'requireWeak', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/webpack/index.js');\n reactHotLoader.register(resolveWeak, 'resolveWeak', '/home/jmgasper/Documents/Git/topcoder-react-utils/src/shared/utils/webpack/index.js');\n leaveModule(module);\n})();\n\n;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../../node_modules/webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/utils/webpack/index.js?");
+
+/***/ }),
+
+/***/ "./src/shared/utils/webpack/require.js":
+/*!*********************************************!*\
+ !*** ./src/shared/utils/webpack/require.js ***!
+ \*********************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("\"use strict\";\n\n/**\n * This helper module is a part of requireWeak(..) implementation. Webpack is\n * configured to ignore this file, thus the code:\n *\n * const m = require('utils/router/require')('my-module-path');\n *\n * will load the module at the specified path, when exectuted at the server\n * side, and will crush, if executed at the client side. Though, the crush at\n * the client side can be easily prevented by adding condition:\n *\n * import { isServerSide } from 'utils/isomorphy';\n *\n * if (isServerSide()) {\n * const m = require('utils/router/require')('my-module-path');\n * // Some client-side only code.\n * }\n *\n * The key point here is that the module at 'my-module-path' will not be bundled\n * by Webpack if required this way. Thus, this way we can use static resolution\n * of the module at the server-side, while using alternative code at the client\n * side (dynamic module loading from the server).\n */\n\n/* eslint-disable global-require */\n/* eslint-disable import/no-dynamic-require */\n\nmodule.exports = require;\n\n//# sourceURL=webpack://topcoder-react-utils/./src/shared/utils/webpack/require.js?");
+
+/***/ }),
+
+/***/ "./src/styles/global.scss":
+/*!********************************!*\
+ !*** ./src/styles/global.scss ***!
+ \********************************/
+/*! no static exports found */
+/***/ (function(module, exports, __webpack_require__) {
+
+eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack://topcoder-react-utils/./src/styles/global.scss?");
+
+/***/ }),
+
+/***/ "babel-runtime/core-js/object/assign":
+/*!******************************************************!*\
+ !*** external "babel-runtime/core-js/object/assign" ***!
+ \******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_core_js_object_assign__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/core-js/object/assign%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/core-js/object/get-prototype-of":
+/*!****************************************************************!*\
+ !*** external "babel-runtime/core-js/object/get-prototype-of" ***!
+ \****************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_core_js_object_get_prototype_of__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/core-js/object/get-prototype-of%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/core-js/object/keys":
+/*!****************************************************!*\
+ !*** external "babel-runtime/core-js/object/keys" ***!
+ \****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_core_js_object_keys__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/core-js/object/keys%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/core-js/promise":
+/*!************************************************!*\
+ !*** external "babel-runtime/core-js/promise" ***!
+ \************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_core_js_promise__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/core-js/promise%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/asyncToGenerator":
+/*!*********************************************************!*\
+ !*** external "babel-runtime/helpers/asyncToGenerator" ***!
+ \*********************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_asyncToGenerator__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/asyncToGenerator%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/classCallCheck":
+/*!*******************************************************!*\
+ !*** external "babel-runtime/helpers/classCallCheck" ***!
+ \*******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_classCallCheck__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/classCallCheck%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/createClass":
+/*!****************************************************!*\
+ !*** external "babel-runtime/helpers/createClass" ***!
+ \****************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_createClass__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/createClass%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/defineProperty":
+/*!*******************************************************!*\
+ !*** external "babel-runtime/helpers/defineProperty" ***!
+ \*******************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_defineProperty__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/defineProperty%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/extends":
+/*!************************************************!*\
+ !*** external "babel-runtime/helpers/extends" ***!
+ \************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_extends__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/extends%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/inherits":
+/*!*************************************************!*\
+ !*** external "babel-runtime/helpers/inherits" ***!
+ \*************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_inherits__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/inherits%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/helpers/possibleConstructorReturn":
+/*!******************************************************************!*\
+ !*** external "babel-runtime/helpers/possibleConstructorReturn" ***!
+ \******************************************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_helpers_possibleConstructorReturn__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/helpers/possibleConstructorReturn%22?");
+
+/***/ }),
+
+/***/ "babel-runtime/regenerator":
+/*!********************************************!*\
+ !*** external "babel-runtime/regenerator" ***!
+ \********************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_babel_runtime_regenerator__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22babel-runtime/regenerator%22?");
+
+/***/ }),
+
+/***/ "lodash":
+/*!*************************!*\
+ !*** external "lodash" ***!
+ \*************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_lodash__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22lodash%22?");
+
+/***/ }),
+
+/***/ "moment":
+/*!*************************!*\
+ !*** external "moment" ***!
+ \*************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_moment__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22moment%22?");
+
+/***/ }),
+
+/***/ "prop-types":
+/*!*****************************!*\
+ !*** external "prop-types" ***!
+ \*****************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_prop_types__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22prop-types%22?");
+
+/***/ }),
+
+/***/ "react":
+/*!************************!*\
+ !*** external "react" ***!
+ \************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react%22?");
+
+/***/ }),
+
+/***/ "react-css-super-themr":
+/*!****************************************!*\
+ !*** external "react-css-super-themr" ***!
+ \****************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_css_super_themr__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-css-super-themr%22?");
+
+/***/ }),
+
+/***/ "react-dom":
+/*!****************************!*\
+ !*** external "react-dom" ***!
+ \****************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_dom__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-dom%22?");
+
+/***/ }),
+
+/***/ "react-dom/server":
+/*!***********************************!*\
+ !*** external "react-dom/server" ***!
+ \***********************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_dom_server__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-dom/server%22?");
+
+/***/ }),
+
+/***/ "react-helmet":
+/*!*******************************!*\
+ !*** external "react-helmet" ***!
+ \*******************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_helmet__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-helmet%22?");
+
+/***/ }),
+
+/***/ "react-hot-loader":
+/*!***********************************!*\
+ !*** external "react-hot-loader" ***!
+ \***********************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_hot_loader__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-hot-loader%22?");
+
+/***/ }),
+
+/***/ "react-redux":
+/*!******************************!*\
+ !*** external "react-redux" ***!
+ \******************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_redux__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-redux%22?");
+
+/***/ }),
+
+/***/ "react-router-dom":
+/*!***********************************!*\
+ !*** external "react-router-dom" ***!
+ \***********************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_react_router_dom__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22react-router-dom%22?");
+
+/***/ }),
+
+/***/ "redux":
+/*!************************!*\
+ !*** external "redux" ***!
+ \************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_redux__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22redux%22?");
+
+/***/ }),
+
+/***/ "redux-actions":
+/*!********************************!*\
+ !*** external "redux-actions" ***!
+ \********************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_redux_actions__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22redux-actions%22?");
+
+/***/ }),
+
+/***/ "redux-devtools":
+/*!*********************************!*\
+ !*** external "redux-devtools" ***!
+ \*********************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_redux_devtools__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22redux-devtools%22?");
+
+/***/ }),
+
+/***/ "redux-devtools-dock-monitor":
+/*!**********************************************!*\
+ !*** external "redux-devtools-dock-monitor" ***!
+ \**********************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_redux_devtools_dock_monitor__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22redux-devtools-dock-monitor%22?");
+
+/***/ }),
+
+/***/ "redux-devtools-log-monitor":
+/*!*********************************************!*\
+ !*** external "redux-devtools-log-monitor" ***!
+ \*********************************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_redux_devtools_log_monitor__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22redux-devtools-log-monitor%22?");
+
+/***/ }),
+
+/***/ "redux-promise":
+/*!********************************!*\
+ !*** external "redux-promise" ***!
+ \********************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_redux_promise__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22redux-promise%22?");
+
+/***/ }),
+
+/***/ "shortid":
+/*!**************************!*\
+ !*** external "shortid" ***!
+ \**************************/
+/*! no static exports found */
+/***/ (function(module, exports) {
+
+eval("module.exports = __WEBPACK_EXTERNAL_MODULE_shortid__;\n\n//# sourceURL=webpack://topcoder-react-utils/external_%22shortid%22?");
+
+/***/ })
+
+/******/ });
+});
\ No newline at end of file
diff --git a/dist/dev/server/index.js b/dist/dev/server/index.js
new file mode 100644
index 00000000..5c87d584
--- /dev/null
+++ b/dist/dev/server/index.js
@@ -0,0 +1,151 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _regenerator = require('babel-runtime/regenerator');
+
+var _regenerator2 = _interopRequireDefault(_regenerator);
+
+var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
+
+var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
+
+var _lodash = require('lodash');
+
+var _lodash2 = _interopRequireDefault(_lodash);
+
+var _http = require('http');
+
+var _http2 = _interopRequireDefault(_http);
+
+require('raf/polyfill');
+
+var _server = require('./server');
+
+var _server2 = _interopRequireDefault(_server);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Normalizes a port into a number, string, or false.
+ * @param {String} value Port name or number.
+ * @return Port number (Number), name (String), or false.
+ */
+
+
+/* Polyfill required by ReactJS. */
+/**
+ * Standard web servers.
+ */
+
+function normalizePort(value) {
+ var port = _lodash2.default.toNumber(value);
+ if (_lodash2.default.isFinite(port)) return port; /* port number */
+ if (!_lodash2.default.isNumber(port)) return value; /* named pipe */
+ return false;
+}
+
+/**
+ * Creates and starts a new webserver.
+ * @param {Object} webpackConfig The Webpack config that was used to build the
+ * frontend bundle.
+ * @param {config} options Additional options:
+ * - Application {Function} - Optional. The root ReactJS component of the app
+ * to use for server-side rendering;
+ * - devMode {Boolean} - Whether the server should be started in dev mode;
+ * - favicon {String} - Path of the favicon to be used by the server;
+ * - logger {Object} - Optional. The logger to use. By default, the console
+ * is used (which is not a good decision performancewise, but it will be
+ * changed soon);
+ * - beforeRender {Function} - The hook into server-side rendering. It will get
+ * incoming request as the argument and it should return a promise that will
+ * resolve to the object with the following fields all optional:
+ * - config {Object} - Config object to be injected into the page;
+ * - extraScripts {Array} - Any additional scripts to be injected into
+ * HTML template;
+ * - store {Object} - Redux store, which state should be used for server-side
+ * rendering, if it is performed, and also injected into HTML template as
+ * the initial state.
+ * - onExpressJsSetup {Function} - Custom setup of ExpressJS server.
+ * - port {String} - Optional. The port to listen (number or name). If not
+ * specified the value will be taken from PORT environmental variable, or
+ * default to 3000 otherwise.
+ * @return {Promise} Resolves to the result object has two fields:
+ * - express {Object} - ExpressJS server;
+ * - http {Object} - NodeJS HTTP server.
+ */
+
+exports.default = function () {
+ var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(webpackConfig, options) {
+ var ops, expressServer, httpServer;
+ return _regenerator2.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ /* Options normalization. */
+ ops = options ? _lodash2.default.clone(options) : {};
+
+ ops.port = normalizePort(ops.port || process.env.PORT || 3000);
+ _lodash2.default.defaults(ops, {
+ logger: console
+ });
+
+ /* Creates servers, resolves and sets the port. */
+ _context.next = 5;
+ return (0, _server2.default)(webpackConfig, ops);
+
+ case 5:
+ expressServer = _context.sent;
+ httpServer = _http2.default.createServer(expressServer);
+
+ /* Sets error handler for HTTP server. */
+
+ httpServer.on('error', function (error) {
+ if (error.syscall !== 'listen') throw error;
+ var bind = _lodash2.default.isString(ops.port) ? 'Pipe ' + ops.port : 'Port ' + ops.port;
+
+ /* Human-readable message for some specific listen errors. */
+ switch (error.code) {
+ case 'EACCES':
+ ops.logger.error(bind + ' requires elevated privileges');
+ process.exit(1);
+ break;
+ case 'EADDRINUSE':
+ ops.logger.error(bind + ' is already in use');
+ process.exit(1);
+ break;
+ default:
+ throw error;
+ }
+ });
+
+ /* Listening event handler for HTTP server. */
+ httpServer.on('listening', function () {
+ var addr = httpServer.address();
+ var bind = _lodash2.default.isString(addr) ? 'pipe ' + addr : 'port ' + addr.port;
+ ops.logger.info('Server listening on ' + bind + ' in ' + process.env.NODE_ENV + ' mode');
+ });
+
+ httpServer.listen(ops.port);
+
+ return _context.abrupt('return', {
+ expressServer: expressServer,
+ httpServer: httpServer
+ });
+
+ case 11:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function launch(_x, _x2) {
+ return _ref.apply(this, arguments);
+ }
+
+ return launch;
+}();
\ No newline at end of file
diff --git a/dist/dev/server/renderer.js b/dist/dev/server/renderer.js
new file mode 100644
index 00000000..8013be87
--- /dev/null
+++ b/dist/dev/server/renderer.js
@@ -0,0 +1,286 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _regenerator = require('babel-runtime/regenerator');
+
+var _regenerator2 = _interopRequireDefault(_regenerator);
+
+var _stringify = require('babel-runtime/core-js/json/stringify');
+
+var _stringify2 = _interopRequireDefault(_stringify);
+
+var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
+
+var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
+
+var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
+
+var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
+
+var _promise = require('babel-runtime/core-js/promise');
+
+var _promise2 = _interopRequireDefault(_promise);
+
+exports.default = factory;
+
+var _lodash = require('lodash');
+
+var _lodash2 = _interopRequireDefault(_lodash);
+
+var _config = require('config');
+
+var _config2 = _interopRequireDefault(_config);
+
+var _nodeForge = require('node-forge');
+
+var _nodeForge2 = _interopRequireDefault(_nodeForge);
+
+var _fs = require('fs');
+
+var _fs2 = _interopRequireDefault(_fs);
+
+var _moment = require('moment');
+
+var _moment2 = _interopRequireDefault(_moment);
+
+var _path = require('path');
+
+var _path2 = _interopRequireDefault(_path);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _server = require('react-dom/server');
+
+var _server2 = _interopRequireDefault(_server);
+
+var _serializeJavascript = require('serialize-javascript');
+
+var _serializeJavascript2 = _interopRequireDefault(_serializeJavascript);
+
+var _reactHelmet = require('react-helmet');
+
+var _reactRedux = require('react-redux');
+
+var _reactRouterDom = require('react-router-dom');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * ExpressJS middleware for server-side rendering of a ReactJS app.
+ */
+
+var sanitizedConfig = _lodash2.default.omit(_config2.default, 'SECRET');
+
+/**
+ * Reads build-time information about the app. This information is generated
+ * by our standard Webpack config for apps, and it is written into
+ * ".build-info" file in the context folder specified in Webpack config.
+ * At the moment, that file contains build timestamp and a random 32-bit key,
+ * suitable for cryptographical use.
+ * @param {String} context Webpack context path used during the build.
+ * @return {Object} Resolves to the build-time information.
+ */
+function getBuildInfo(context) {
+ var url = _path2.default.resolve(context, '.build-info');
+ return JSON.parse(_fs2.default.readFileSync(url));
+}
+
+/**
+ * Attempts to read from the disk Webpack stats generated during the build.
+ * It will not work for development builds, where these stats should be captured
+ * via compilator callback.
+ * @param {String} buildDir
+ * @return {Object} Resolves to the stats, or null, if cannot be read.
+ */
+function getWebpackStats(buildDir) {
+ var url = _path2.default.resolve(buildDir, '__stats__.json');
+ var res = void 0;
+ try {
+ res = JSON.parse(_fs2.default.readFileSync(url));
+ } catch (err) {
+ res = null;
+ }
+ return res;
+}
+
+/**
+ * Prepares a new Cipher for data encryption.
+ * @param {String} key Encryption key (32-bit random key is expected, see
+ * node-forge documentation, in case of doubts).
+ * @return {Promise} Resolves to the object with two fields:
+ * 1. cipher - a new Cipher, ready for encryption;
+ * 2. iv - initial vector used by the cipher.
+ */
+function prepareCipher(key) {
+ return new _promise2.default(function (resolve, reject) {
+ _nodeForge2.default.random.getBytes(32, function (err, iv) {
+ if (err) reject(err);else {
+ // console.log('KEY', key);
+ var cipher = _nodeForge2.default.cipher.createCipher('AES-CBC', key);
+ cipher.start({ iv: iv });
+ resolve({ cipher: cipher, iv: iv });
+ }
+ });
+ });
+}
+
+/**
+ * Creates the middleware.
+ * @param {Object} webpackConfig
+ * @param {Object} options Additional options:
+ * @return {Function} Created middleware.
+ */
+function factory(webpackConfig, options) {
+ var _this = this;
+
+ var buildInfo = getBuildInfo(webpackConfig.context);
+
+ global.TRU_BUILD_INFO = buildInfo;
+
+ var WEBPACK_STATS = getWebpackStats(webpackConfig.output.path);
+
+ var ops = _lodash2.default.defaults(_lodash2.default.clone(options), {
+ beforeRender: function beforeRender() {
+ return _promise2.default.resolve({});
+ }
+ });
+
+ return function () {
+ var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(req, res, next) {
+ var _ref2, _ref3, _ref3$, configToInject, extraScripts, store, _ref3$2, cipher, iv, context, helmet, App, INJ, _webpackConfig$output, publicPath, crossOriginLoading, crossorigin, assetsByChunkName, webpackStats, _webpackStats$toJson, timestamp, styles;
+
+ return _regenerator2.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ _context.prev = 0;
+ _context.next = 3;
+ return _promise2.default.all([ops.beforeRender(req, sanitizedConfig), prepareCipher(buildInfo.key)]);
+
+ case 3:
+ _ref2 = _context.sent;
+ _ref3 = (0, _slicedToArray3.default)(_ref2, 2);
+ _ref3$ = _ref3[0];
+ configToInject = _ref3$.configToInject;
+ extraScripts = _ref3$.extraScripts;
+ store = _ref3$.store;
+ _ref3$2 = _ref3[1];
+ cipher = _ref3$2.cipher;
+ iv = _ref3$2.iv;
+
+
+ /* Context for react-router and collection of data related to server-side
+ * rendering (this will be moved into separate place in future). */
+ context = {
+ /* Array of chunk names, to use for stylesheet links injection. */
+ chunks: [],
+
+ /* Pre-rendered HTML markup for dynamic chunks. */
+ splits: {},
+
+ store: store
+ };
+ helmet = void 0;
+
+ /* Optional server-side rendering. */
+
+ App = options.Application;
+
+ if (App) {
+ App = _react2.default.createElement(
+ _reactRouterDom.StaticRouter,
+ {
+ context: context,
+ location: req.url
+ },
+ _react2.default.createElement(App, null)
+ );
+
+ if (store) {
+ App = _react2.default.createElement(
+ _reactRedux.Provider,
+ { store: store },
+ App
+ );
+ }
+
+ App = _server2.default.renderToString(App);
+
+ /* This takes care about server-side rendering of page title and meta tags
+ * (still demands injection into HTML template, which happens below). */
+ helmet = _reactHelmet.Helmet.renderStatic();
+ }
+
+ /* Encrypts data to be injected into HTML.
+ * Keep in mind, that this encryption is no way secure: as the JS bundle
+ * contains decryption key and is able to decode it at the client side.
+ * Hovewer, for a number of reasons, encryption of injected data is still
+ * better than injection of a plain text. */
+ cipher.update(_nodeForge2.default.util.createBuffer((0, _stringify2.default)({
+ CONFIG: configToInject || sanitizedConfig,
+ ISTATE: store ? store.getState() : null
+ }), 'utf8'));
+ cipher.finish();
+ INJ = _nodeForge2.default.util.encode64('' + iv + cipher.output.data);
+
+ /* It is supposed to end with '/' symbol as path separator. */
+
+ _webpackConfig$output = webpackConfig.output, publicPath = _webpackConfig$output.publicPath, crossOriginLoading = _webpackConfig$output.crossOriginLoading;
+ crossorigin = crossOriginLoading ? 'crossorigin="' + crossOriginLoading + '"' : '';
+ assetsByChunkName = void 0;
+ webpackStats = res.locals.webpackStats;
+
+ if (webpackStats) {
+ _webpackStats$toJson = webpackStats.toJson();
+ assetsByChunkName = _webpackStats$toJson.assetsByChunkName;
+ } else if (WEBPACK_STATS) {
+ ;
+ assetsByChunkName = WEBPACK_STATS.assetsByChunkName;
+ } else assetsByChunkName = {};
+
+ timestamp = (0, _moment2.default)(buildInfo.timestamp).valueOf();
+
+
+ if (context.status) res.status(context.status);
+ styles = [];
+
+ context.chunks.forEach(function (chunk) {
+ var assets = assetsByChunkName[chunk];
+ if (!assets) return;
+ if (!_lodash2.default.isArray(assets)) assets = [assets];
+ assets = assets.filter(function (asset) {
+ return asset.endsWith('.css');
+ });
+ assets.forEach(function (asset) {
+ styles.push('
');
+ });
+ });
+
+ res.send('\n \n \n ' + (helmet ? helmet.title.toString() : '') + '\n ' + (helmet ? helmet.meta.toString() : '') + '\n
\n
\n
\n ' + styles.join('') + '\n
\n
\n
\n \n \n
' + (App || '') + '
\n \n \n ' + (extraScripts ? extraScripts.join('') : '') + '\n \n \n ');
+ _context.next = 34;
+ break;
+
+ case 31:
+ _context.prev = 31;
+ _context.t0 = _context['catch'](0);
+
+ next(_context.t0);
+
+ case 34:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, _this, [[0, 31]]);
+ }));
+
+ return function (_x, _x2, _x3) {
+ return _ref.apply(this, arguments);
+ };
+ }();
+}
\ No newline at end of file
diff --git a/dist/dev/server/server.js b/dist/dev/server/server.js
new file mode 100644
index 00000000..5fc41cec
--- /dev/null
+++ b/dist/dev/server/server.js
@@ -0,0 +1,199 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _regenerator = require('babel-runtime/regenerator');
+
+var _regenerator2 = _interopRequireDefault(_regenerator);
+
+var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
+
+var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
+
+var _lodash = require('lodash');
+
+var _lodash2 = _interopRequireDefault(_lodash);
+
+var _bodyParser = require('body-parser');
+
+var _bodyParser2 = _interopRequireDefault(_bodyParser);
+
+var _compression = require('compression');
+
+var _compression2 = _interopRequireDefault(_compression);
+
+var _cookieParser = require('cookie-parser');
+
+var _cookieParser2 = _interopRequireDefault(_cookieParser);
+
+var _express = require('express');
+
+var _express2 = _interopRequireDefault(_express);
+
+var _serveFavicon = require('serve-favicon');
+
+var _serveFavicon2 = _interopRequireDefault(_serveFavicon);
+
+var _helmet = require('helmet');
+
+var _helmet2 = _interopRequireDefault(_helmet);
+
+var _morgan = require('morgan');
+
+var _morgan2 = _interopRequireDefault(_morgan);
+
+var _requestIp = require('request-ip');
+
+var _requestIp2 = _interopRequireDefault(_requestIp);
+
+var _stream = require('stream');
+
+var _stream2 = _interopRequireDefault(_stream);
+
+var _renderer = require('./renderer');
+
+var _renderer2 = _interopRequireDefault(_renderer);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = function () {
+ var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(webpackConfig, options) {
+ var renderer, publicPath, server, FORMAT, exludeSW, webpack, webpackDevMiddleware, webpackHotMiddleware, compiler;
+ return _regenerator2.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ renderer = (0, _renderer2.default)(webpackConfig, options);
+ publicPath = webpackConfig.output.publicPath;
+ server = (0, _express2.default)();
+
+ server.use((0, _compression2.default)());
+ server.use((0, _helmet2.default)());
+
+ if (options.favicon) {
+ server.use((0, _serveFavicon2.default)(options.favicon));
+ }
+
+ server.use(_bodyParser2.default.json({ limit: '300kb' }));
+ server.use(_bodyParser2.default.urlencoded({ extended: false }));
+ server.use((0, _cookieParser2.default)());
+ server.use(_requestIp2.default.mw());
+
+ _morgan2.default.token('ip', function (req) {
+ return req.clientIp;
+ });
+ FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';
+
+ server.use((0, _morgan2.default)(FORMAT, {
+ stream: new _stream2.default.Writable({
+ decodeStrings: false,
+ write: function write(chunk, encoding, cb) {
+ options.logger.log(chunk);
+ cb();
+ }
+ })
+ }));
+
+ exludeSW = function exludeSW(middleware) {
+ return function (req, res, next) {
+ if (req.url.indexOf('/sw.js') > -1) {
+ next();
+ return;
+ }
+ middleware(req, res, next);
+ };
+ };
+
+ /* Setup of Hot Module Reloading for development environment.
+ * These dependencies are not used, nor installed for production use,
+ * hence we should violate some import-related lint rules. */
+ /* eslint-disable global-require */
+ /* eslint-disable import/no-extraneous-dependencies */
+ /* eslint-disable import/no-unresolved */
+
+
+ if (options.devMode) {
+ webpack = require('webpack');
+ webpackDevMiddleware = require('webpack-dev-middleware');
+ webpackHotMiddleware = require('webpack-hot-middleware');
+ compiler = webpack(webpackConfig);
+
+ compiler.apply(new webpack.ProgressPlugin());
+ server.use(exludeSW(webpackDevMiddleware(compiler, {
+ name: 'main.js',
+ publicPath: publicPath,
+ serverSideRender: true
+ })));
+ server.use(exludeSW(webpackHotMiddleware(compiler)));
+ }
+ /* eslint-enable global-require */
+ /* eslint-enable import/no-extraneous-dependencies */
+ /* eslint-enable import/no-unresolved */
+
+ server.use(publicPath, exludeSW(_express2.default.static(webpackConfig.output.path)));
+
+ if (!options.onExpressJsSetup) {
+ _context.next = 19;
+ break;
+ }
+
+ _context.next = 19;
+ return options.onExpressJsSetup(server);
+
+ case 19:
+ server.use(renderer);
+
+ /* Detects 404 errors, and forwards them to the error handler. */
+ server.use(function (req, res, next) {
+ var err = new Error('Not Found');
+ err.status = 404;
+ next(err);
+ });
+
+ /* Error handler. */
+ server.use(function (err, req, res, next) {
+ // eslint-disable-line no-unused-vars
+ var errorResponse = null;
+ var status = err.isJoi ? 400 : err.httpStatus || err.status || 500;
+
+ if (err.isJoi && _lodash2.default.isArray(err.details)) {
+ _lodash2.default.map(err.details, function (e) {
+ if (e.message) {
+ if (!errorResponse) errorResponse = e.message;else errorResponse += ', ' + e.message;
+ }
+ });
+ }
+ errorResponse = errorResponse || err.message || 'Internal Server Error';
+
+ /* Sets locals. The actual errors are exposed only in dev. */
+ _lodash2.default.assign(res, {
+ locals: {
+ error: req.app.get('env') === 'development' ? err : {},
+ message: err.message
+ }
+ });
+
+ /* Finally, the error response. */
+ res.status(status).send(errorResponse);
+ });
+
+ return _context.abrupt('return', server);
+
+ case 23:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function factory(_x, _x2) {
+ return _ref.apply(this, arguments);
+ }
+
+ return factory;
+}(); /**
+ * Creation of standard ExpressJS server for ReactJS apps.
+ */
\ No newline at end of file
diff --git a/dist/dev/shared/utils/jest.js b/dist/dev/shared/utils/jest.js
new file mode 100644
index 00000000..4181f8f1
--- /dev/null
+++ b/dist/dev/shared/utils/jest.js
@@ -0,0 +1,181 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.simulate = undefined;
+
+var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
+
+var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
+
+var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
+
+var _inherits2 = require('babel-runtime/helpers/inherits');
+
+var _inherits3 = _interopRequireDefault(_inherits2);
+
+exports.findInDomByClass = findInDomByClass;
+exports.findInDomManyByClass = findInDomManyByClass;
+exports.render = render;
+exports.renderDom = renderDom;
+exports.shallowRender = shallowRender;
+exports.shallowSnapshot = shallowSnapshot;
+exports.snapshot = snapshot;
+
+var _propTypes = require('prop-types');
+
+var _propTypes2 = _interopRequireDefault(_propTypes);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _testUtils = require('react-dom/test-utils');
+
+var _testUtils2 = _interopRequireDefault(_testUtils);
+
+var _reactTestRenderer = require('react-test-renderer');
+
+var _reactTestRenderer2 = _interopRequireDefault(_reactTestRenderer);
+
+var _shallow = require('react-test-renderer/shallow');
+
+var _shallow2 = _interopRequireDefault(_shallow);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/* eslint-enable import/no-extraneous-dependencies */
+
+/**
+ * Just an alias for TU.findRenderedDOMComponentWithClass(..).
+ * @param {Object} dom
+ * @param {String} className
+ * @return {Object}
+ */
+
+
+/* eslint-disable import/no-extraneous-dependencies */
+function findInDomByClass(dom, className) {
+ return _testUtils2.default.findRenderedDOMComponentWithClass(dom, className);
+}
+
+/**
+ * Just an alias for TU.scryRenderedDOMComponentsWithClass(..).
+ * @param {Object} dom
+ * @param {Stirng} className
+ * @return {Array}
+ */
+/**
+ * Utilities for Jest tests.
+ */
+
+/* NOTE: At the moment here is no intention to use this module for runtime
+ * execution, only for tests; thus we depend on Jest environment and dev
+ * dependencies. */
+
+/* global expect */
+
+function findInDomManyByClass(dom, className) {
+ return _testUtils2.default.scryRenderedDOMComponentsWithClass(dom, className);
+}
+
+/**
+ * Auxiliary wrapper around ReactJS Test Renderer.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON representation of the rendered tree.
+ */
+function render(component) {
+ return _reactTestRenderer2.default.create(component).toJSON();
+}
+
+/* The Wrapper is necessary for the "renderDom(..)" function, because
+ * the "renderIntoDocument(..)" function from "react-dom/test-utils" works
+ * only with state components, so we have to wrap our ReactJS components into
+ * such Wrapper. */
+
+var Wrapper = function (_React$Component) {
+ (0, _inherits3.default)(Wrapper, _React$Component);
+
+ function Wrapper() {
+ (0, _classCallCheck3.default)(this, Wrapper);
+ return (0, _possibleConstructorReturn3.default)(this, (Wrapper.__proto__ || (0, _getPrototypeOf2.default)(Wrapper)).apply(this, arguments));
+ }
+
+ (0, _createClass3.default)(Wrapper, [{
+ key: 'componentDidMount',
+ value: function componentDidMount() {}
+ }, {
+ key: 'render',
+ value: function render() {
+ var children = this.props.children;
+
+ return children;
+ }
+ }]);
+ return Wrapper;
+}(_react2.default.Component);
+
+Wrapper.propTypes = {
+ children: _propTypes2.default.node.isRequired
+};
+
+/**
+ * Renders given component into DOM, using "react-dom/test-utils".
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} Rendered DOM.
+ */
+function renderDom(component) {
+ return _testUtils2.default.renderIntoDocument(_react2.default.createElement(
+ Wrapper,
+ null,
+ component
+ ));
+}
+
+/**
+ * Auxiliary wrapper around ReactJS Shallow Test Renderer.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON representation of the shallow component's render tree.
+ */
+function shallowRender(component) {
+ var renderer = new _shallow2.default();
+ renderer.render(component);
+ return renderer.getRenderOutput();
+}
+
+/**
+ * Renders provided ReactJS component with ReactJS Shallow Test Renderer,
+ * creates/tests its snapshot, and returns the render result.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON representation of shallow render.
+ */
+function shallowSnapshot(component) {
+ var res = shallowRender(component);
+ expect(res).toMatchSnapshot();
+ return res;
+}
+
+/**
+ * Renders provided ReactJS component with ReactJS Test Renderer,
+ * creates/tests the snapshot, and returns the render.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON render of the component.
+ */
+function snapshot(component) {
+ var res = render(component);
+ expect(res).toMatchSnapshot();
+ return res;
+}
+
+var simulate = exports.simulate = _testUtils2.default.Simulate;
diff --git a/dist/dev/style.css b/dist/dev/style.css
new file mode 100644
index 00000000..96b18157
--- /dev/null
+++ b/dist/dev/style.css
@@ -0,0 +1,246 @@
+/* Global styles. */
+
+/* Eric Meyer's "Reset CSS" 2.0 */
+
+/* http://meyerweb.com/eric/tools/css/reset/
+ v2.0 | 20110126
+ License: none (public domain)
+*/
+
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+}
+
+ol,
+ul {
+ list-style: none;
+}
+
+blockquote,
+q {
+ quotes: none;
+}
+
+blockquote:before,
+blockquote:after,
+q:before,
+q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+html,
+body {
+ text-rendering: geometricPrecision;
+}
+/* Collection of standard mixins, being used all around. */
+
+/* Auxiliary mixins for fonts inclusion. */
+
+/**
+ * Includes a font, provided as a set of alternative files in EOT, WOFF, TTF,
+ * SVG formats into the app.
+ * $font-name {String}
+ * $font-weight {Number}
+ * $font-style {String}
+ * $font-url {String} Path to the font file, without the filename itself.
+ * $font-file {String} Font filename, without extension (should be the same for
+ * each version of the font in different formats.
+ */
+
+/**
+ * Includes a font, provided in the TTF format only.
+ * $font-name {String}
+ * $font-weight {Number}
+ * $font-style {String}
+ * $font-url {String}
+ */
+
+/**
+ * Mixins for different layout sizes: xs, sm, md, lg.
+ * Breaking points are defined in _variables.scss
+ * The range mixins A-to-B all means "for the sizes from A to B, both
+ * inclusive", in particular it means that mixin A-to-lg is equivalent to
+ * all sizes from A (inclusive) and larger.
+ *
+ * NOTE: For convenience, these mixins are sorted not alphabetically, but,
+ * first, by increase of the first size; second, by increase of the second size.
+ */
+
+/* Break points. */
+
+/* XS */
+
+/* XS */
+
+/* MD */
+
+/* LG */
+
+/* XL */
+
+body.scrolling-disabled-by-modal {
+ overflow: hidden;
+}
+
+.src-shared-components-Modal-style___overlay___X12tn9 {
+ background: #ebebeb;
+ border: none;
+ height: 100%;
+ left: 0;
+ opacity: 0.8;
+ outline: none;
+ position: fixed;
+ top: 0;
+ width: 100%;
+ z-index: 998;
+}
+
+.src-shared-components-Modal-style___container___1SoeQl {
+ background: #fff;
+ box-shadow: 0 0 14px 1px rgba(38, 38, 40, 0.15);
+ border-radius: 4;
+ max-height: 95vh;
+ max-width: 1024px;
+ overflow: hidden;
+ padding: 40;
+ width: 480px;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ z-index: 999;
+}
+
+@media (max-width: 1280px) {
+ .src-shared-components-Modal-style___container___1SoeQl {
+ max-width: 95vw;
+ }
+}
+
+@media (max-width: 768px) {
+ .src-shared-components-Modal-style___container___1SoeQl {
+ padding: 40px 10px;
+ }
+}
+.src-shared-components-ScalableRect-style___container___3YhfNf {
+ position: relative;
+ width: 100%;
+}
+
+.src-shared-components-ScalableRect-style___wrapper___3qZoWe {
+ height: 100%;
+ position: absolute;
+ width: 100%;
+}
diff --git a/dist/prod/client/init.js b/dist/prod/client/init.js
new file mode 100644
index 00000000..4ad48938
--- /dev/null
+++ b/dist/prod/client/init.js
@@ -0,0 +1,32 @@
+'use strict';
+
+var _nodeForge = require('node-forge');
+
+var _nodeForge2 = _interopRequireDefault(_nodeForge);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+window.TRU_BUILD_INFO = BUILD_INFO; /**
+ * Initialization of client-side environment.
+ */
+
+/* global BUILD_INFO, document, window */
+
+window.TRU_FRONT_END = true;
+
+/* Removes data injection script out of the document. */
+var block = document.querySelector('script[id="inj"]');
+document.getElementsByTagName('body')[0].removeChild(block);
+
+/* Decodes data injected at the server side. */
+var key = window.TRU_BUILD_INFO.key;
+
+var data = _nodeForge2.default.util.decode64(window.INJ);
+var decipher = _nodeForge2.default.cipher.createDecipher('AES-CBC', key);
+decipher.start({ iv: data.slice(0, 32) });
+decipher.update(_nodeForge2.default.util.createBuffer(data.slice(32)));
+decipher.finish();
+data = JSON.parse(_nodeForge2.default.util.decodeUtf8(decipher.output.data));
+
+window.CONFIG = data.CONFIG;
+window.ISTATE = data.ISTATE;
diff --git a/dist/prod/index.js b/dist/prod/index.js
new file mode 100644
index 00000000..4815b349
--- /dev/null
+++ b/dist/prod/index.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("prop-types"),require("babel-runtime/helpers/extends"),require("lodash"),require("react-router-dom"),require("react-redux"),require("babel-runtime/helpers/inherits"),require("babel-runtime/helpers/possibleConstructorReturn"),require("babel-runtime/helpers/createClass"),require("babel-runtime/helpers/classCallCheck"),require("babel-runtime/core-js/object/get-prototype-of"),require("babel-runtime/helpers/defineProperty"),require("react-dom"),require("shortid"),require("babel-runtime/helpers/asyncToGenerator"),require("babel-runtime/regenerator"),require("react-css-super-themr"),require("react-helmet"),require("react-dom/server"),require("moment"),require("redux-actions"),require("redux"),require("redux-promise"),require("redux-devtools-log-monitor"),require("redux-devtools-dock-monitor"),require("redux-devtools"),require("babel-runtime/core-js/object/assign"),require("babel-runtime/core-js/object/keys"),require("babel-runtime/core-js/promise")):"function"==typeof define&&define.amd?define(["react","prop-types","babel-runtime/helpers/extends","lodash","react-router-dom","react-redux","babel-runtime/helpers/inherits","babel-runtime/helpers/possibleConstructorReturn","babel-runtime/helpers/createClass","babel-runtime/helpers/classCallCheck","babel-runtime/core-js/object/get-prototype-of","babel-runtime/helpers/defineProperty","react-dom","shortid","babel-runtime/helpers/asyncToGenerator","babel-runtime/regenerator","react-css-super-themr","react-helmet","react-dom/server","moment","redux-actions","redux","redux-promise","redux-devtools-log-monitor","redux-devtools-dock-monitor","redux-devtools","babel-runtime/core-js/object/assign","babel-runtime/core-js/object/keys","babel-runtime/core-js/promise"],t):"object"==typeof exports?exports["topcoder-react-utils"]=t(require("react"),require("prop-types"),require("babel-runtime/helpers/extends"),require("lodash"),require("react-router-dom"),require("react-redux"),require("babel-runtime/helpers/inherits"),require("babel-runtime/helpers/possibleConstructorReturn"),require("babel-runtime/helpers/createClass"),require("babel-runtime/helpers/classCallCheck"),require("babel-runtime/core-js/object/get-prototype-of"),require("babel-runtime/helpers/defineProperty"),require("react-dom"),require("shortid"),require("babel-runtime/helpers/asyncToGenerator"),require("babel-runtime/regenerator"),require("react-css-super-themr"),require("react-helmet"),require("react-dom/server"),require("moment"),require("redux-actions"),require("redux"),require("redux-promise"),require("redux-devtools-log-monitor"),require("redux-devtools-dock-monitor"),require("redux-devtools"),require("babel-runtime/core-js/object/assign"),require("babel-runtime/core-js/object/keys"),require("babel-runtime/core-js/promise")):e["topcoder-react-utils"]=t(e.react,e["prop-types"],e["babel-runtime/helpers/extends"],e.lodash,e["react-router-dom"],e["react-redux"],e["babel-runtime/helpers/inherits"],e["babel-runtime/helpers/possibleConstructorReturn"],e["babel-runtime/helpers/createClass"],e["babel-runtime/helpers/classCallCheck"],e["babel-runtime/core-js/object/get-prototype-of"],e["babel-runtime/helpers/defineProperty"],e["react-dom"],e.shortid,e["babel-runtime/helpers/asyncToGenerator"],e["babel-runtime/regenerator"],e["react-css-super-themr"],e["react-helmet"],e["react-dom/server"],e.moment,e["redux-actions"],e.redux,e["redux-promise"],e["redux-devtools-log-monitor"],e["redux-devtools-dock-monitor"],e["redux-devtools"],e["babel-runtime/core-js/object/assign"],e["babel-runtime/core-js/object/keys"],e["babel-runtime/core-js/promise"])}("undefined"!=typeof self?self:this,function(e,t,r,n,u,o,a,l,i,d,c,s,f,p,m,b,v,h,y,_,g,x,q,M,O,E,k,w,j){return function(e){var t={};function r(n){if(t[n])return t[n].exports;var u=t[n]={i:n,l:!1,exports:{}};return e[n].call(u.exports,u,u.exports,r),u.l=!0,u.exports}return r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var u in e)r.d(n,u,function(t){return e[t]}.bind(null,u));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=60)}([function(t,r){t.exports=e},function(e,r){e.exports=t},function(e,t){e.exports=r},function(e,t){e.exports=n},function(e,t,r){"use strict";(function(e){function r(){return"undefined"!=typeof window&&Boolean(window.TRU_FRONT_END)}Object.defineProperty(t,"__esModule",{value:!0}),t.isClientSide=r,t.isServerSide=function(){return"undefined"==typeof window||!window.TRU_FRONT_END},t.isDevBuild=function(){return!1},t.isProdBuild=function(){return!0},t.buildTimestamp=function(){return(r()?window:e).TRU_BUILD_INFO.timestamp}}).call(this,r(20))},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.storeFactory=void 0;var n=h(r(23)),u=h(r(22)),o=h(r(56)),a=h(r(2)),l=h(r(14)),i=h(r(55)),d=h(r(54));t.storeFactory=function(){var e=(0,u.default)(n.default.mark(function e(t){var r,o,a,l=this,i=t.getReducerFactory,d=t.httpRequest,c=t.initialState,m=t.moduleHot,b=t.reducerFactoryModulePath;return n.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,i()(d);case 2:return r=e.sent,o=(0,p.applyMiddleware)(f.default),(0,v.isDevBuild)()&&(o=(0,p.compose)(o,s.default.instrument())),a=(0,p.createStore)(r,c||{},o),m&&b&&m.accept(b,(0,u.default)(n.default.mark(function e(){var t;return n.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,i()();case 2:t=e.sent,a.replaceReducer(t);case 4:case"end":return e.stop()}},e,l)}))),e.abrupt("return",a);case 8:case"end":return e.stop()}},e,this)}));return function(t){return e.apply(this,arguments)}}();t.combineReducers=function(){for(var e=arguments.length,t=Array(e),r=0;r
0&&void 0!==arguments[0]?arguments[0]:Number.MAX_VALUE},LOAD_DATA_INIT:function(e){return e},LOAD_DATA_DONE:function(e,t){return{data:t,loadingOperationId:e,timestamp:Date.now()}},SET_DATA:function(e){return{data:e,timestamp:Date.now()}},UPDATE_REFERENCE_COUNTER:function(e){return e}}})},function(e,t){var r;r=function(){return this}();try{r=r||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(r=window)}e.exports=r},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=l(r(0)),u=r(53),o=l(r(52)),a=l(r(51));function l(e){return e&&e.__esModule?e:{default:e}}t.default=(0,u.createDevTools)(n.default.createElement(o.default,{changePositionKey:"ctrl-p",toggleVisibilityKey:"ctrl-m"},n.default.createElement(a.default,null)))},function(e,t){e.exports=m},function(e,t){e.exports=b},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=function(e){return e&&e.__esModule?e:{default:e}}(r(3)),u=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(5));t.default=u.createActions({COLLECTION:{ADD_ITEMS:function(e){return{index:e,timestamp:Date.now()}},BOOK_ITEMS:function(e){return{factor:arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,ids:n.default.isArray(e)?e:[e]}},CLEAN:function(){return arguments.length>0&&void 0!==arguments[0]?arguments[0]:Number.MAX_VALUE},FREE_ITEMS:function(e){return{factor:arguments.length>1&&void 0!==arguments[1]?arguments[1]:1,ids:n.default.isArray(e)?e:[e]}},LOAD_ITEM_INIT:function(e,t){return{itemId:t,operationId:e}},LOAD_ITEM_DONE:function(e,t,r){return{item:r,itemId:t,operationId:e,timestamp:Date.now()}}}})},function(e,t){"use strict";e.exports=require},function(e,t,r){"use strict";var n=r(4),u=r(8);e.exports=(0,n.isClientSide)()?window.CONFIG:(0,u.requireWeak)("config")},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.webpack=t.redux=t.JU=t.isomorphy=t.config=void 0;var n=function(e){return e&&e.__esModule?e:{default:e}}(r(26)),u=l(r(4)),o=l(r(5)),a=l(r(8));function l(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}var i=u.isProdBuild()?"prod":"dev";i="topcoder-react-utils/dist/"+i+"/shared/utils/jest";var d=u.isServerSide()?a.requireWeak(i):null;t.config=n.default,t.isomorphy=u,t.JU=d,t.redux=o,t.webpack=a},,function(e,t,r){e.exports={container:"_3YhfNf",wrapper:"_3qZoWe"}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=a;var n=o(r(1)),u=o(r(0));function o(e){return e&&e.__esModule?e:{default:e}}function a(e){var t=e.children,r=e.className,n=e.ratio.split(":"),o=100*n[1]/n[0]+"%",a=u.default.createElement("div",{style:{paddingBottom:o},className:"_3YhfNf"},u.default.createElement("div",{className:"_3qZoWe"},t));return r?u.default.createElement("div",{className:r},a):a}r(29),a.defaultProps={children:null,className:null,ratio:"1:1"},a.propTypes={children:n.default.node,className:n.default.string,ratio:n.default.string}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,u=i(r(14)),o=i(r(2)),a=i(r(19)),l=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(5));function i(e){return e&&e.__esModule?e:{default:e}}var d=a.default.item;t.default=l.handleActions((n={},(0,u.default)(n,d.dropData,function(e,t){var r=t.payload;return e.numRefs>0||e.timestamp>r?e:(0,o.default)({},e,{data:null,timestamp:0})}),(0,u.default)(n,d.loadDataInit,function(e,t){var r=t.payload;return(0,o.default)({},e,{loadingOperationId:r})}),(0,u.default)(n,d.loadDataDone,function(e,t){var r=t.payload,n=r.data,u=r.loadingOperationId,a=r.timestamp;return u!==e.loadingOperationId?e:(0,o.default)({},e,{data:n,loadingOperationId:null,timestamp:a})}),(0,u.default)(n,d.setData,function(e,t){var r=t.payload;return(0,o.default)({},e,r)}),(0,u.default)(n,d.updateReferenceCounter,function(e,t){var r=t.payload,n=e.numRefs+r;return(0,o.default)({},e,{numRefs:n})}),n),{data:null,loadingOperationId:null,numRefs:0,timestamp:0})},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n,u=d(r(14)),o=d(r(2)),a=d(r(3)),l=d(r(24)),i=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(5));function d(e){return e&&e.__esModule?e:{default:e}}function c(e,t){var r=e[t];return r=r?a.default.clone(r):{item:null,loadingOperationId:"",numRefs:0,timestamp:0},e[t]=r,r}var s=l.default.collection;t.default=i.handleActions((n={},(0,u.default)(n,s.addItems,function(e,t){var r=t.payload,n=r.index,u=r.timestamp,o=a.default.clone(e);return a.default.forOwn(n,function(e,t){var r=c(o,t);r.timestamp=u,r.item=e}),o}),(0,u.default)(n,s.bookItems,function(e,t){var r=t.payload,n=r.factor,u=r.ids,o=a.default.clone(e);return u.forEach(function(e){c(o,e).numRefs+=n}),o}),(0,u.default)(n,s.clean,function(e,t){var r=t.payload,n=a.default.clone(e);return a.default.forOwn(e,function(t,u){var o=e[u];o.numRefs||o.loadingOperationId||o.timestamp>r||delete n[u]}),n}),(0,u.default)(n,s.freeItems,function(e,t){var r=t.payload,n=r.factor,u=r.ids,o=a.default.clone(e);return u.forEach(function(e){c(o,e).numRefs-=n}),o}),(0,u.default)(n,s.loadItemInit,function(e,t){var r=t.payload,n=r.itemId,u=r.operationId,o=a.default.clone(e);return c(o,n).loadingOperationId=u,o}),(0,u.default)(n,s.loadItemDone,function(e,t){var r=t.payload,n=r.item,a=r.itemId,l=r.operationId,i=r.timestamp,d=e[a];return d&&d.loadingOperationId===l?(0,o.default)({},e,(0,u.default)({},a,(0,o.default)({},d,{item:n,loadingOperationId:"",timestamp:i}))):e}),n),{})},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=o(r(32)),u=o(r(31));function o(e){return e&&e.__esModule?e:{default:e}}t.default={collection:n.default,item:u.default}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=l(r(2));t.default=function(e){return u.default.createElement(a.default,(0,n.default)({},e,{routerLinkType:o.NavLink}))};var u=l(r(0)),o=r(6),a=l(r(16));function l(e){return e&&e.__esModule?e:{default:e}}},,function(e,t,r){e.exports={overlay:"X12tn9",container:"_1SoeQl"}},function(e,t){e.exports=v},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BaseModal=void 0;var n=m(r(13)),u=m(r(12)),o=m(r(11)),a=m(r(10)),l=m(r(9)),i=m(r(3)),d=m(r(0)),c=m(r(15)),s=m(r(1)),f=r(37),p=m(r(36));function m(e){return e&&e.__esModule?e:{default:e}}var b=function(e){function t(e){(0,u.default)(this,t);var r=(0,a.default)(this,(t.__proto__||(0,n.default)(t)).call(this,e));return r.portal=document.createElement("div"),r}return(0,l.default)(t,e),(0,o.default)(t,[{key:"componentDidMount",value:function(){document.body.classList.add("scrolling-disabled-by-modal"),document.body.appendChild(this.portal)}},{key:"componentWillUnmount",value:function(){document.body.classList.remove("scrolling-disabled-by-modal"),document.body.removeChild(this.portal)}},{key:"render",value:function(){var e=this.props,t=e.children,r=e.onCancel,n=e.theme;return c.default.createPortal(d.default.createElement(d.default.Fragment,null,d.default.createElement("div",{className:n.container,onWheel:function(e){return e.stopPropagation()}},t),d.default.createElement("button",{onClick:function(){return r()},className:n.overlay,type:"button"})),this.portal)}}]),t}(d.default.Component);b.defaultProps={onCancel:i.default.noop,children:null,theme:{}},b.propTypes={onCancel:s.default.func,children:s.default.node,theme:s.default.shape()},t.BaseModal=b,t.default=(0,f.themr)("Modal",p.default)(b)},function(e,t){e.exports=h},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=l(r(1)),u=l(r(0)),o=r(7),a=r(39);function l(e){return e&&e.__esModule?e:{default:e}}function i(e){var t=e.description,r=e.domain,n=e.image,o=e.siteName,l=e.socialDescription,i=e.socialTitle,d=e.title,c=e.url,s=""+r+n,f=i||d,p=l||t;return u.default.createElement(a.Helmet,null,u.default.createElement("title",null,d),u.default.createElement("meta",{property:"description",content:t}),u.default.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),u.default.createElement("meta",{name:"twitter:title",content:f}),u.default.createElement("meta",{name:"twitter:description",content:p}),n?u.default.createElement("meta",{name:"twitter:image",content:s}):null,o?u.default.createElement("meta",{name:"twitter:site",content:"@"+o}):null,u.default.createElement("meta",{property:"og:title",content:f}),n?u.default.createElement("meta",{property:"og:image",content:s}):null,n?u.default.createElement("meta",{property:"og:image:alt",content:f}):null,u.default.createElement("meta",{property:"og:description",content:p}),o?u.default.createElement("meta",{property:"og:sitename",content:o}):null,c?u.default.createElement("meta",{property:"og:url",content:c}):null)}i.defaultProps={image:null,siteName:null,socialDescription:null,socialTitle:null,url:null},i.propTypes={description:n.default.string.isRequired,domain:n.default.string.isRequired,image:n.default.string,siteName:n.default.string,socialDescription:n.default.string,socialTitle:n.default.string,title:n.default.string.isRequired,url:n.default.string},t.default=(0,o.connect)(function(e){return{domain:e.domain}})(i)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=c(r(23)),u=c(r(22)),o=c(r(0)),a=c(r(15)),l=c(r(18)),i=r(7),d=r(6);function c(e){return e&&e.__esModule?e:{default:e}}function s(e,t){var r=o.default.createElement(d.BrowserRouter,null,o.default.createElement(e,null));t&&(r=o.default.createElement(i.Provider,{store:t},r)),a.default.hydrate(r,document.getElementById("react-view"))}t.default=function(){var e=(0,u.default)(n.default.mark(function e(t){var r,u=t.applicationModulePath,o=t.getApplication,a=t.moduleHot,i=t.storeFactory;return n.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(r=void 0,!i){e.next=5;break}return e.next=4,i(window.ISTATE);case 4:r=e.sent;case 5:s(o(),r),a&&u&&(a.accept(u,function(){return s(o(),r)}),a.addStatusHandler(function(e){if("ready"===e)for(var t=(0,l.default)(),r=document.querySelectorAll('link[rel=stylesheet][id="tru-style"]'),n=0;n10){var O=[];M.forEach(function(e){e.chunkOrder=Number(e.getAttribute("data-chunk-unused")),O.push(e)}),O.sort(function(e,t){return e.chunkOrder-t.chunkOrder}),O.slice(0,M.length-10).forEach(function(e){return _.removeChild(e)})}}var E=!t.pendingRender;if(E||(E=t.pendingRender!==l,i.default.forIn(t.pendingRenderProps,function(t,r){E=E||t!==e[r]})),!E)return r;var k=(0,p.default)();t.pendingRenderUUID=k,t.pendingRender=l,t.pendingRenderProps=e,l(e).then(function(e){k===t.pendingRenderUUID&&(t.pendingRenderUUID=null,t.pendingRender=null,t.pendingRenderProps=null,t.setState({component:function(){return s.default.createElement("div",null,s.default.createElement(h.default,{chunkName:n,content:e,parent:t}))}}))})}return r},strict:_})}}]),r}(s.default.Component);t.default=g,g.defaultProps={exact:!1,location:null,path:null,renderPlaceholder:null,renderServer:null,strict:!1},g.propTypes={chunkName:c.default.string.isRequired,exact:c.default.bool,location:c.default.shape(),path:c.default.string,renderClientAsync:c.default.func.isRequired,renderPlaceholder:c.default.func,renderServer:c.default.func,strict:c.default.bool}}).call(this,r(20))},function(e,t){e.exports=g},function(e,t){e.exports=x},function(e,t){e.exports=q},function(e,t){e.exports=M},function(e,t){e.exports=O},function(e,t){e.exports=E},function(e,t){e.exports=k},function(e,t){e.exports=w},function(e,t){e.exports=j},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=a(r(2)),u=a(r(24)),o=a(r(19));function a(e){return e&&e.__esModule?e:{default:e}}t.default=(0,n.default)({},u.default,o.default)},,function(e,t,r){},function(e,t,r){"use strict";var n=g(r(2));r(59);var u=g(r(57)),o=g(r(47)),a=g(r(43)),l=g(r(42)),i=g(r(41)),d=g(r(21)),c=g(r(17)),s=g(r(40)),f=r(38),p=g(f),m=g(r(34)),b=g(r(33)),v=g(r(30)),h=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r]);return t.default=e,t}(r(27)),y=r(4),_=r(8);function g(e){return e&&e.__esModule?e:{default:e}}var x=(0,y.isProdBuild)()?"prod":"dev";x="topcoder-react-utils/dist/"+x+"/server";var q=h.isomorphy.isServerSide()?(0,_.requireWeak)(x):null;e.exports=(0,n.default)({actions:u.default,AppChunk:o.default,Avatar:a.default,BaseModal:f.BaseModal,Button:l.default,client:i.default,DevTools:d.default,Link:c.default,NavLink:m.default,MetaTags:s.default,Modal:p.default,ScalableRect:v.default,reducers:b.default,server:q},h)}])});
\ No newline at end of file
diff --git a/dist/prod/server/index.js b/dist/prod/server/index.js
new file mode 100644
index 00000000..5c87d584
--- /dev/null
+++ b/dist/prod/server/index.js
@@ -0,0 +1,151 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _regenerator = require('babel-runtime/regenerator');
+
+var _regenerator2 = _interopRequireDefault(_regenerator);
+
+var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
+
+var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
+
+var _lodash = require('lodash');
+
+var _lodash2 = _interopRequireDefault(_lodash);
+
+var _http = require('http');
+
+var _http2 = _interopRequireDefault(_http);
+
+require('raf/polyfill');
+
+var _server = require('./server');
+
+var _server2 = _interopRequireDefault(_server);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Normalizes a port into a number, string, or false.
+ * @param {String} value Port name or number.
+ * @return Port number (Number), name (String), or false.
+ */
+
+
+/* Polyfill required by ReactJS. */
+/**
+ * Standard web servers.
+ */
+
+function normalizePort(value) {
+ var port = _lodash2.default.toNumber(value);
+ if (_lodash2.default.isFinite(port)) return port; /* port number */
+ if (!_lodash2.default.isNumber(port)) return value; /* named pipe */
+ return false;
+}
+
+/**
+ * Creates and starts a new webserver.
+ * @param {Object} webpackConfig The Webpack config that was used to build the
+ * frontend bundle.
+ * @param {config} options Additional options:
+ * - Application {Function} - Optional. The root ReactJS component of the app
+ * to use for server-side rendering;
+ * - devMode {Boolean} - Whether the server should be started in dev mode;
+ * - favicon {String} - Path of the favicon to be used by the server;
+ * - logger {Object} - Optional. The logger to use. By default, the console
+ * is used (which is not a good decision performancewise, but it will be
+ * changed soon);
+ * - beforeRender {Function} - The hook into server-side rendering. It will get
+ * incoming request as the argument and it should return a promise that will
+ * resolve to the object with the following fields all optional:
+ * - config {Object} - Config object to be injected into the page;
+ * - extraScripts {Array} - Any additional scripts to be injected into
+ * HTML template;
+ * - store {Object} - Redux store, which state should be used for server-side
+ * rendering, if it is performed, and also injected into HTML template as
+ * the initial state.
+ * - onExpressJsSetup {Function} - Custom setup of ExpressJS server.
+ * - port {String} - Optional. The port to listen (number or name). If not
+ * specified the value will be taken from PORT environmental variable, or
+ * default to 3000 otherwise.
+ * @return {Promise} Resolves to the result object has two fields:
+ * - express {Object} - ExpressJS server;
+ * - http {Object} - NodeJS HTTP server.
+ */
+
+exports.default = function () {
+ var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(webpackConfig, options) {
+ var ops, expressServer, httpServer;
+ return _regenerator2.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ /* Options normalization. */
+ ops = options ? _lodash2.default.clone(options) : {};
+
+ ops.port = normalizePort(ops.port || process.env.PORT || 3000);
+ _lodash2.default.defaults(ops, {
+ logger: console
+ });
+
+ /* Creates servers, resolves and sets the port. */
+ _context.next = 5;
+ return (0, _server2.default)(webpackConfig, ops);
+
+ case 5:
+ expressServer = _context.sent;
+ httpServer = _http2.default.createServer(expressServer);
+
+ /* Sets error handler for HTTP server. */
+
+ httpServer.on('error', function (error) {
+ if (error.syscall !== 'listen') throw error;
+ var bind = _lodash2.default.isString(ops.port) ? 'Pipe ' + ops.port : 'Port ' + ops.port;
+
+ /* Human-readable message for some specific listen errors. */
+ switch (error.code) {
+ case 'EACCES':
+ ops.logger.error(bind + ' requires elevated privileges');
+ process.exit(1);
+ break;
+ case 'EADDRINUSE':
+ ops.logger.error(bind + ' is already in use');
+ process.exit(1);
+ break;
+ default:
+ throw error;
+ }
+ });
+
+ /* Listening event handler for HTTP server. */
+ httpServer.on('listening', function () {
+ var addr = httpServer.address();
+ var bind = _lodash2.default.isString(addr) ? 'pipe ' + addr : 'port ' + addr.port;
+ ops.logger.info('Server listening on ' + bind + ' in ' + process.env.NODE_ENV + ' mode');
+ });
+
+ httpServer.listen(ops.port);
+
+ return _context.abrupt('return', {
+ expressServer: expressServer,
+ httpServer: httpServer
+ });
+
+ case 11:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function launch(_x, _x2) {
+ return _ref.apply(this, arguments);
+ }
+
+ return launch;
+}();
\ No newline at end of file
diff --git a/dist/prod/server/renderer.js b/dist/prod/server/renderer.js
new file mode 100644
index 00000000..8013be87
--- /dev/null
+++ b/dist/prod/server/renderer.js
@@ -0,0 +1,286 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _regenerator = require('babel-runtime/regenerator');
+
+var _regenerator2 = _interopRequireDefault(_regenerator);
+
+var _stringify = require('babel-runtime/core-js/json/stringify');
+
+var _stringify2 = _interopRequireDefault(_stringify);
+
+var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
+
+var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
+
+var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
+
+var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
+
+var _promise = require('babel-runtime/core-js/promise');
+
+var _promise2 = _interopRequireDefault(_promise);
+
+exports.default = factory;
+
+var _lodash = require('lodash');
+
+var _lodash2 = _interopRequireDefault(_lodash);
+
+var _config = require('config');
+
+var _config2 = _interopRequireDefault(_config);
+
+var _nodeForge = require('node-forge');
+
+var _nodeForge2 = _interopRequireDefault(_nodeForge);
+
+var _fs = require('fs');
+
+var _fs2 = _interopRequireDefault(_fs);
+
+var _moment = require('moment');
+
+var _moment2 = _interopRequireDefault(_moment);
+
+var _path = require('path');
+
+var _path2 = _interopRequireDefault(_path);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _server = require('react-dom/server');
+
+var _server2 = _interopRequireDefault(_server);
+
+var _serializeJavascript = require('serialize-javascript');
+
+var _serializeJavascript2 = _interopRequireDefault(_serializeJavascript);
+
+var _reactHelmet = require('react-helmet');
+
+var _reactRedux = require('react-redux');
+
+var _reactRouterDom = require('react-router-dom');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * ExpressJS middleware for server-side rendering of a ReactJS app.
+ */
+
+var sanitizedConfig = _lodash2.default.omit(_config2.default, 'SECRET');
+
+/**
+ * Reads build-time information about the app. This information is generated
+ * by our standard Webpack config for apps, and it is written into
+ * ".build-info" file in the context folder specified in Webpack config.
+ * At the moment, that file contains build timestamp and a random 32-bit key,
+ * suitable for cryptographical use.
+ * @param {String} context Webpack context path used during the build.
+ * @return {Object} Resolves to the build-time information.
+ */
+function getBuildInfo(context) {
+ var url = _path2.default.resolve(context, '.build-info');
+ return JSON.parse(_fs2.default.readFileSync(url));
+}
+
+/**
+ * Attempts to read from the disk Webpack stats generated during the build.
+ * It will not work for development builds, where these stats should be captured
+ * via compilator callback.
+ * @param {String} buildDir
+ * @return {Object} Resolves to the stats, or null, if cannot be read.
+ */
+function getWebpackStats(buildDir) {
+ var url = _path2.default.resolve(buildDir, '__stats__.json');
+ var res = void 0;
+ try {
+ res = JSON.parse(_fs2.default.readFileSync(url));
+ } catch (err) {
+ res = null;
+ }
+ return res;
+}
+
+/**
+ * Prepares a new Cipher for data encryption.
+ * @param {String} key Encryption key (32-bit random key is expected, see
+ * node-forge documentation, in case of doubts).
+ * @return {Promise} Resolves to the object with two fields:
+ * 1. cipher - a new Cipher, ready for encryption;
+ * 2. iv - initial vector used by the cipher.
+ */
+function prepareCipher(key) {
+ return new _promise2.default(function (resolve, reject) {
+ _nodeForge2.default.random.getBytes(32, function (err, iv) {
+ if (err) reject(err);else {
+ // console.log('KEY', key);
+ var cipher = _nodeForge2.default.cipher.createCipher('AES-CBC', key);
+ cipher.start({ iv: iv });
+ resolve({ cipher: cipher, iv: iv });
+ }
+ });
+ });
+}
+
+/**
+ * Creates the middleware.
+ * @param {Object} webpackConfig
+ * @param {Object} options Additional options:
+ * @return {Function} Created middleware.
+ */
+function factory(webpackConfig, options) {
+ var _this = this;
+
+ var buildInfo = getBuildInfo(webpackConfig.context);
+
+ global.TRU_BUILD_INFO = buildInfo;
+
+ var WEBPACK_STATS = getWebpackStats(webpackConfig.output.path);
+
+ var ops = _lodash2.default.defaults(_lodash2.default.clone(options), {
+ beforeRender: function beforeRender() {
+ return _promise2.default.resolve({});
+ }
+ });
+
+ return function () {
+ var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(req, res, next) {
+ var _ref2, _ref3, _ref3$, configToInject, extraScripts, store, _ref3$2, cipher, iv, context, helmet, App, INJ, _webpackConfig$output, publicPath, crossOriginLoading, crossorigin, assetsByChunkName, webpackStats, _webpackStats$toJson, timestamp, styles;
+
+ return _regenerator2.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ _context.prev = 0;
+ _context.next = 3;
+ return _promise2.default.all([ops.beforeRender(req, sanitizedConfig), prepareCipher(buildInfo.key)]);
+
+ case 3:
+ _ref2 = _context.sent;
+ _ref3 = (0, _slicedToArray3.default)(_ref2, 2);
+ _ref3$ = _ref3[0];
+ configToInject = _ref3$.configToInject;
+ extraScripts = _ref3$.extraScripts;
+ store = _ref3$.store;
+ _ref3$2 = _ref3[1];
+ cipher = _ref3$2.cipher;
+ iv = _ref3$2.iv;
+
+
+ /* Context for react-router and collection of data related to server-side
+ * rendering (this will be moved into separate place in future). */
+ context = {
+ /* Array of chunk names, to use for stylesheet links injection. */
+ chunks: [],
+
+ /* Pre-rendered HTML markup for dynamic chunks. */
+ splits: {},
+
+ store: store
+ };
+ helmet = void 0;
+
+ /* Optional server-side rendering. */
+
+ App = options.Application;
+
+ if (App) {
+ App = _react2.default.createElement(
+ _reactRouterDom.StaticRouter,
+ {
+ context: context,
+ location: req.url
+ },
+ _react2.default.createElement(App, null)
+ );
+
+ if (store) {
+ App = _react2.default.createElement(
+ _reactRedux.Provider,
+ { store: store },
+ App
+ );
+ }
+
+ App = _server2.default.renderToString(App);
+
+ /* This takes care about server-side rendering of page title and meta tags
+ * (still demands injection into HTML template, which happens below). */
+ helmet = _reactHelmet.Helmet.renderStatic();
+ }
+
+ /* Encrypts data to be injected into HTML.
+ * Keep in mind, that this encryption is no way secure: as the JS bundle
+ * contains decryption key and is able to decode it at the client side.
+ * Hovewer, for a number of reasons, encryption of injected data is still
+ * better than injection of a plain text. */
+ cipher.update(_nodeForge2.default.util.createBuffer((0, _stringify2.default)({
+ CONFIG: configToInject || sanitizedConfig,
+ ISTATE: store ? store.getState() : null
+ }), 'utf8'));
+ cipher.finish();
+ INJ = _nodeForge2.default.util.encode64('' + iv + cipher.output.data);
+
+ /* It is supposed to end with '/' symbol as path separator. */
+
+ _webpackConfig$output = webpackConfig.output, publicPath = _webpackConfig$output.publicPath, crossOriginLoading = _webpackConfig$output.crossOriginLoading;
+ crossorigin = crossOriginLoading ? 'crossorigin="' + crossOriginLoading + '"' : '';
+ assetsByChunkName = void 0;
+ webpackStats = res.locals.webpackStats;
+
+ if (webpackStats) {
+ _webpackStats$toJson = webpackStats.toJson();
+ assetsByChunkName = _webpackStats$toJson.assetsByChunkName;
+ } else if (WEBPACK_STATS) {
+ ;
+ assetsByChunkName = WEBPACK_STATS.assetsByChunkName;
+ } else assetsByChunkName = {};
+
+ timestamp = (0, _moment2.default)(buildInfo.timestamp).valueOf();
+
+
+ if (context.status) res.status(context.status);
+ styles = [];
+
+ context.chunks.forEach(function (chunk) {
+ var assets = assetsByChunkName[chunk];
+ if (!assets) return;
+ if (!_lodash2.default.isArray(assets)) assets = [assets];
+ assets = assets.filter(function (asset) {
+ return asset.endsWith('.css');
+ });
+ assets.forEach(function (asset) {
+ styles.push('');
+ });
+ });
+
+ res.send('\n \n \n ' + (helmet ? helmet.title.toString() : '') + '\n ' + (helmet ? helmet.meta.toString() : '') + '\n \n \n \n ' + styles.join('') + '\n \n \n \n \n \n ' + (App || '') + '
\n \n \n ' + (extraScripts ? extraScripts.join('') : '') + '\n \n \n ');
+ _context.next = 34;
+ break;
+
+ case 31:
+ _context.prev = 31;
+ _context.t0 = _context['catch'](0);
+
+ next(_context.t0);
+
+ case 34:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, _this, [[0, 31]]);
+ }));
+
+ return function (_x, _x2, _x3) {
+ return _ref.apply(this, arguments);
+ };
+ }();
+}
\ No newline at end of file
diff --git a/dist/prod/server/server.js b/dist/prod/server/server.js
new file mode 100644
index 00000000..5fc41cec
--- /dev/null
+++ b/dist/prod/server/server.js
@@ -0,0 +1,199 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _regenerator = require('babel-runtime/regenerator');
+
+var _regenerator2 = _interopRequireDefault(_regenerator);
+
+var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
+
+var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
+
+var _lodash = require('lodash');
+
+var _lodash2 = _interopRequireDefault(_lodash);
+
+var _bodyParser = require('body-parser');
+
+var _bodyParser2 = _interopRequireDefault(_bodyParser);
+
+var _compression = require('compression');
+
+var _compression2 = _interopRequireDefault(_compression);
+
+var _cookieParser = require('cookie-parser');
+
+var _cookieParser2 = _interopRequireDefault(_cookieParser);
+
+var _express = require('express');
+
+var _express2 = _interopRequireDefault(_express);
+
+var _serveFavicon = require('serve-favicon');
+
+var _serveFavicon2 = _interopRequireDefault(_serveFavicon);
+
+var _helmet = require('helmet');
+
+var _helmet2 = _interopRequireDefault(_helmet);
+
+var _morgan = require('morgan');
+
+var _morgan2 = _interopRequireDefault(_morgan);
+
+var _requestIp = require('request-ip');
+
+var _requestIp2 = _interopRequireDefault(_requestIp);
+
+var _stream = require('stream');
+
+var _stream2 = _interopRequireDefault(_stream);
+
+var _renderer = require('./renderer');
+
+var _renderer2 = _interopRequireDefault(_renderer);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.default = function () {
+ var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(webpackConfig, options) {
+ var renderer, publicPath, server, FORMAT, exludeSW, webpack, webpackDevMiddleware, webpackHotMiddleware, compiler;
+ return _regenerator2.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ renderer = (0, _renderer2.default)(webpackConfig, options);
+ publicPath = webpackConfig.output.publicPath;
+ server = (0, _express2.default)();
+
+ server.use((0, _compression2.default)());
+ server.use((0, _helmet2.default)());
+
+ if (options.favicon) {
+ server.use((0, _serveFavicon2.default)(options.favicon));
+ }
+
+ server.use(_bodyParser2.default.json({ limit: '300kb' }));
+ server.use(_bodyParser2.default.urlencoded({ extended: false }));
+ server.use((0, _cookieParser2.default)());
+ server.use(_requestIp2.default.mw());
+
+ _morgan2.default.token('ip', function (req) {
+ return req.clientIp;
+ });
+ FORMAT = ':ip > :status :method :url :response-time ms :res[content-length] :referrer :user-agent';
+
+ server.use((0, _morgan2.default)(FORMAT, {
+ stream: new _stream2.default.Writable({
+ decodeStrings: false,
+ write: function write(chunk, encoding, cb) {
+ options.logger.log(chunk);
+ cb();
+ }
+ })
+ }));
+
+ exludeSW = function exludeSW(middleware) {
+ return function (req, res, next) {
+ if (req.url.indexOf('/sw.js') > -1) {
+ next();
+ return;
+ }
+ middleware(req, res, next);
+ };
+ };
+
+ /* Setup of Hot Module Reloading for development environment.
+ * These dependencies are not used, nor installed for production use,
+ * hence we should violate some import-related lint rules. */
+ /* eslint-disable global-require */
+ /* eslint-disable import/no-extraneous-dependencies */
+ /* eslint-disable import/no-unresolved */
+
+
+ if (options.devMode) {
+ webpack = require('webpack');
+ webpackDevMiddleware = require('webpack-dev-middleware');
+ webpackHotMiddleware = require('webpack-hot-middleware');
+ compiler = webpack(webpackConfig);
+
+ compiler.apply(new webpack.ProgressPlugin());
+ server.use(exludeSW(webpackDevMiddleware(compiler, {
+ name: 'main.js',
+ publicPath: publicPath,
+ serverSideRender: true
+ })));
+ server.use(exludeSW(webpackHotMiddleware(compiler)));
+ }
+ /* eslint-enable global-require */
+ /* eslint-enable import/no-extraneous-dependencies */
+ /* eslint-enable import/no-unresolved */
+
+ server.use(publicPath, exludeSW(_express2.default.static(webpackConfig.output.path)));
+
+ if (!options.onExpressJsSetup) {
+ _context.next = 19;
+ break;
+ }
+
+ _context.next = 19;
+ return options.onExpressJsSetup(server);
+
+ case 19:
+ server.use(renderer);
+
+ /* Detects 404 errors, and forwards them to the error handler. */
+ server.use(function (req, res, next) {
+ var err = new Error('Not Found');
+ err.status = 404;
+ next(err);
+ });
+
+ /* Error handler. */
+ server.use(function (err, req, res, next) {
+ // eslint-disable-line no-unused-vars
+ var errorResponse = null;
+ var status = err.isJoi ? 400 : err.httpStatus || err.status || 500;
+
+ if (err.isJoi && _lodash2.default.isArray(err.details)) {
+ _lodash2.default.map(err.details, function (e) {
+ if (e.message) {
+ if (!errorResponse) errorResponse = e.message;else errorResponse += ', ' + e.message;
+ }
+ });
+ }
+ errorResponse = errorResponse || err.message || 'Internal Server Error';
+
+ /* Sets locals. The actual errors are exposed only in dev. */
+ _lodash2.default.assign(res, {
+ locals: {
+ error: req.app.get('env') === 'development' ? err : {},
+ message: err.message
+ }
+ });
+
+ /* Finally, the error response. */
+ res.status(status).send(errorResponse);
+ });
+
+ return _context.abrupt('return', server);
+
+ case 23:
+ case 'end':
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function factory(_x, _x2) {
+ return _ref.apply(this, arguments);
+ }
+
+ return factory;
+}(); /**
+ * Creation of standard ExpressJS server for ReactJS apps.
+ */
\ No newline at end of file
diff --git a/dist/prod/shared/utils/jest.js b/dist/prod/shared/utils/jest.js
new file mode 100644
index 00000000..4181f8f1
--- /dev/null
+++ b/dist/prod/shared/utils/jest.js
@@ -0,0 +1,181 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.simulate = undefined;
+
+var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
+
+var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
+
+var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
+
+var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
+
+var _createClass2 = require('babel-runtime/helpers/createClass');
+
+var _createClass3 = _interopRequireDefault(_createClass2);
+
+var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
+
+var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
+
+var _inherits2 = require('babel-runtime/helpers/inherits');
+
+var _inherits3 = _interopRequireDefault(_inherits2);
+
+exports.findInDomByClass = findInDomByClass;
+exports.findInDomManyByClass = findInDomManyByClass;
+exports.render = render;
+exports.renderDom = renderDom;
+exports.shallowRender = shallowRender;
+exports.shallowSnapshot = shallowSnapshot;
+exports.snapshot = snapshot;
+
+var _propTypes = require('prop-types');
+
+var _propTypes2 = _interopRequireDefault(_propTypes);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _testUtils = require('react-dom/test-utils');
+
+var _testUtils2 = _interopRequireDefault(_testUtils);
+
+var _reactTestRenderer = require('react-test-renderer');
+
+var _reactTestRenderer2 = _interopRequireDefault(_reactTestRenderer);
+
+var _shallow = require('react-test-renderer/shallow');
+
+var _shallow2 = _interopRequireDefault(_shallow);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/* eslint-enable import/no-extraneous-dependencies */
+
+/**
+ * Just an alias for TU.findRenderedDOMComponentWithClass(..).
+ * @param {Object} dom
+ * @param {String} className
+ * @return {Object}
+ */
+
+
+/* eslint-disable import/no-extraneous-dependencies */
+function findInDomByClass(dom, className) {
+ return _testUtils2.default.findRenderedDOMComponentWithClass(dom, className);
+}
+
+/**
+ * Just an alias for TU.scryRenderedDOMComponentsWithClass(..).
+ * @param {Object} dom
+ * @param {Stirng} className
+ * @return {Array}
+ */
+/**
+ * Utilities for Jest tests.
+ */
+
+/* NOTE: At the moment here is no intention to use this module for runtime
+ * execution, only for tests; thus we depend on Jest environment and dev
+ * dependencies. */
+
+/* global expect */
+
+function findInDomManyByClass(dom, className) {
+ return _testUtils2.default.scryRenderedDOMComponentsWithClass(dom, className);
+}
+
+/**
+ * Auxiliary wrapper around ReactJS Test Renderer.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON representation of the rendered tree.
+ */
+function render(component) {
+ return _reactTestRenderer2.default.create(component).toJSON();
+}
+
+/* The Wrapper is necessary for the "renderDom(..)" function, because
+ * the "renderIntoDocument(..)" function from "react-dom/test-utils" works
+ * only with state components, so we have to wrap our ReactJS components into
+ * such Wrapper. */
+
+var Wrapper = function (_React$Component) {
+ (0, _inherits3.default)(Wrapper, _React$Component);
+
+ function Wrapper() {
+ (0, _classCallCheck3.default)(this, Wrapper);
+ return (0, _possibleConstructorReturn3.default)(this, (Wrapper.__proto__ || (0, _getPrototypeOf2.default)(Wrapper)).apply(this, arguments));
+ }
+
+ (0, _createClass3.default)(Wrapper, [{
+ key: 'componentDidMount',
+ value: function componentDidMount() {}
+ }, {
+ key: 'render',
+ value: function render() {
+ var children = this.props.children;
+
+ return children;
+ }
+ }]);
+ return Wrapper;
+}(_react2.default.Component);
+
+Wrapper.propTypes = {
+ children: _propTypes2.default.node.isRequired
+};
+
+/**
+ * Renders given component into DOM, using "react-dom/test-utils".
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} Rendered DOM.
+ */
+function renderDom(component) {
+ return _testUtils2.default.renderIntoDocument(_react2.default.createElement(
+ Wrapper,
+ null,
+ component
+ ));
+}
+
+/**
+ * Auxiliary wrapper around ReactJS Shallow Test Renderer.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON representation of the shallow component's render tree.
+ */
+function shallowRender(component) {
+ var renderer = new _shallow2.default();
+ renderer.render(component);
+ return renderer.getRenderOutput();
+}
+
+/**
+ * Renders provided ReactJS component with ReactJS Shallow Test Renderer,
+ * creates/tests its snapshot, and returns the render result.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON representation of shallow render.
+ */
+function shallowSnapshot(component) {
+ var res = shallowRender(component);
+ expect(res).toMatchSnapshot();
+ return res;
+}
+
+/**
+ * Renders provided ReactJS component with ReactJS Test Renderer,
+ * creates/tests the snapshot, and returns the render.
+ * @param {Object} component ReactJS component to render.
+ * @return {Object} JSON render of the component.
+ */
+function snapshot(component) {
+ var res = render(component);
+ expect(res).toMatchSnapshot();
+ return res;
+}
+
+var simulate = exports.simulate = _testUtils2.default.Simulate;
diff --git a/dist/prod/style.css b/dist/prod/style.css
new file mode 100644
index 00000000..79f5e18c
--- /dev/null
+++ b/dist/prod/style.css
@@ -0,0 +1 @@
+a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:after,blockquote:before,q:after,q:before{content:"";content:none}table{border-collapse:collapse;border-spacing:0}body,html{text-rendering:geometricPrecision}body.scrolling-disabled-by-modal{overflow:hidden}.X12tn9{background:#ebebeb;border:none;height:100%;left:0;opacity:.8;outline:none;position:fixed;top:0;width:100%;z-index:998}._1SoeQl{background:#fff;box-shadow:0 0 14px 1px rgba(38,38,40,.15);border-radius:4;max-height:95vh;max-width:1024px;overflow:hidden;padding:40;width:480px;position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:999}@media (max-width:1280px){._1SoeQl{max-width:95vw}}@media (max-width:768px){._1SoeQl{padding:40px 10px}}._3YhfNf{position:relative;width:100%}._3qZoWe{height:100%;position:absolute;width:100%}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 2222c72d..5c2f7879 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "topcoder-react-utils",
- "version": "0.7.8",
+ "version": "0.9.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 4c210834..434deaad 100644
--- a/package.json
+++ b/package.json
@@ -121,5 +121,5 @@
"mkDistDir:prod": "mkdir -p dist/prod/shared/utils && mkdir -p dist/prod/client",
"test": "npm run lint && npm run jest"
},
- "version": "0.7.8"
+ "version": "0.9.5"
}
diff --git a/src/server/renderer.jsx b/src/server/renderer.jsx
index 905cb8b6..8401d977 100644
--- a/src/server/renderer.jsx
+++ b/src/server/renderer.jsx
@@ -157,7 +157,8 @@ export default function factory(webpackConfig, options) {
const INJ = forge.util.encode64(`${iv}${cipher.output.data}`);
/* It is supposed to end with '/' symbol as path separator. */
- const { publicPath } = webpackConfig.output;
+ const { publicPath, crossOriginLoading } = webpackConfig.output;
+ const crossorigin = crossOriginLoading ? `crossorigin="${crossOriginLoading}"` : '';
let assetsByChunkName;
const { webpackStats } = res.locals;
@@ -177,19 +178,22 @@ export default function factory(webpackConfig, options) {
assets = assets.filter(asset => asset.endsWith('.css'));
assets.forEach((asset) => {
styles.push((
- ``
+ ``
));
});
});
res.send((
`
-
+
${helmet ? helmet.title.toString() : ''}
${helmet ? helmet.meta.toString() : ''}
+
+
@@ -209,11 +213,13 @@ export default function factory(webpackConfig, options) {
${extraScripts ? extraScripts.join('') : ''}
diff --git a/src/server/server.js b/src/server/server.js
index 446df6bc..acbac93f 100644
--- a/src/server/server.js
+++ b/src/server/server.js
@@ -44,6 +44,14 @@ export default async function factory(webpackConfig, options) {
}),
}));
+ const exludeSW = middleware => (req, res, next) => {
+ if (req.url.indexOf('/sw.js') > -1) {
+ next();
+ return;
+ }
+ middleware(req, res, next);
+ };
+
/* Setup of Hot Module Reloading for development environment.
* These dependencies are not used, nor installed for production use,
* hence we should violate some import-related lint rules. */
@@ -56,18 +64,19 @@ export default async function factory(webpackConfig, options) {
const webpackHotMiddleware = require('webpack-hot-middleware');
const compiler = webpack(webpackConfig);
compiler.apply(new webpack.ProgressPlugin());
- server.use(webpackDevMiddleware(compiler, {
+ server.use(exludeSW(webpackDevMiddleware(compiler, {
name: 'main.js',
publicPath,
serverSideRender: true,
- }));
- server.use(webpackHotMiddleware(compiler));
+ })));
+ server.use(exludeSW(webpackHotMiddleware(compiler)));
}
/* eslint-enable global-require */
/* eslint-enable import/no-extraneous-dependencies */
/* eslint-enable import/no-unresolved */
- server.use(publicPath, express.static(webpackConfig.output.path));
+ server.use(publicPath, exludeSW(express.static(webpackConfig.output.path)));
+
if (options.onExpressJsSetup) {
await options.onExpressJsSetup(server);
}
diff --git a/src/shared/components/Modal/index.jsx b/src/shared/components/Modal/index.jsx
index c0e86608..243cbcf4 100644
--- a/src/shared/components/Modal/index.jsx
+++ b/src/shared/components/Modal/index.jsx
@@ -19,7 +19,7 @@ import defaultStyle from './style.scss';
/* NOTE: Modal component is implemented as class, as it demands advanced
* interaction with DOM upon mount and unmount. */
-class Modal extends React.Component {
+class BaseModal extends React.Component {
constructor(props) {
super(props);
this.portal = document.createElement('div');
@@ -62,19 +62,19 @@ class Modal extends React.Component {
}
}
-Modal.defaultProps = {
+BaseModal.defaultProps = {
onCancel: _.noop,
children: null,
theme: {},
};
-Modal.propTypes = {
+BaseModal.propTypes = {
onCancel: PT.func,
children: PT.node,
theme: PT.shape(),
};
/* Non-themed version of the Modal. */
-export const BaseModal = Modal;
+export { BaseModal };
-export default themr('Modal', defaultStyle)(Modal);
+export default themr('Modal', defaultStyle)(BaseModal);
diff --git a/src/shared/containers/AppChunk/index.jsx b/src/shared/containers/AppChunk/index.jsx
index 7be83c56..05bfe581 100644
--- a/src/shared/containers/AppChunk/index.jsx
+++ b/src/shared/containers/AppChunk/index.jsx
@@ -61,6 +61,7 @@ export default class SplitRoute extends React.Component {
} = this.props;
const PUBLIC_PATH = global.TRU_BUILD_INFO.publicPath;
+ const CROSS_ORIGIN_LOADING = global.TRU_BUILD_INFO.crossOriginLoading;
const timestamp = moment(buildTimestamp()).valueOf();
@@ -171,6 +172,9 @@ export default class SplitRoute extends React.Component {
link = document.createElement('link');
link.setAttribute('data-chunk', chunkName);
link.setAttribute('href', `${PUBLIC_PATH}/${chunkName}-${timestamp}.css`);
+ if (CROSS_ORIGIN_LOADING) {
+ link.setAttribute('crossorigin', CROSS_ORIGIN_LOADING);
+ }
link.setAttribute('id', 'tru-style');
link.setAttribute('rel', 'stylesheet');
const head = document.getElementsByTagName('head')[0];