diff --git a/__tests__/__snapshots__/index.js.snap b/__tests__/__snapshots__/index.js.snap
index 606f576c..3c3af962 100644
--- a/__tests__/__snapshots__/index.js.snap
+++ b/__tests__/__snapshots__/index.js.snap
@@ -237,6 +237,7 @@ Object {
"services": Object {
"api": Object {
"default": [Function],
+ "getApi": [Function],
"getApiV2": [Function],
"getApiV3": [Function],
"getApiV4": [Function],
diff --git a/__tests__/services/api.js b/__tests__/services/api.js
index 402c6a33..e880e127 100644
--- a/__tests__/services/api.js
+++ b/__tests__/services/api.js
@@ -5,7 +5,7 @@ jest.mock(
);
const { config } = require('topcoder-react-utils');
-const { getApiV2, getApiV3 } = require('../../src/services/api');
+const { getApi } = require('../../src/services/api');
describe('Test api', () => {
const ENDPOINT = '/ENDPOINT';
@@ -79,43 +79,43 @@ describe('Test api', () => {
let api;
test('API v2 service works without auth token', () => {
- api = getApiV2();
+ api = getApi('V2');
return testApi(api, config.API.V2);
});
test('API v2 service works with auth token', () => {
- api = getApiV2('TOKEN');
+ api = getApi('V2', 'TOKEN');
return testApi(api, config.API.V2, 'TOKEN');
});
test(
'API v2 service from the previous call is re-used, if token is the same',
- () => expect(getApiV2('TOKEN')).toBe(api),
+ () => expect(getApi('V2', 'TOKEN')).toBe(api),
);
test('New API v2 service is created if token is new', () => {
- const api2 = getApiV2('TOKEN2');
+ const api2 = getApi('V2', 'TOKEN2');
expect(api2).not.toBe(api);
return testApi(api2, config.API.V2, 'TOKEN2');
});
test('API v3 service works without auth token', () => {
- api = getApiV3();
+ api = getApi('V3');
return testApi(api, config.API.V3);
});
test('API v3 service works with auth token', () => {
- api = getApiV3('TOKEN');
+ api = getApi('V3', 'TOKEN');
return testApi(api, config.API.V3, 'TOKEN');
});
test(
'API v3 service from the previous call is re-used, if token is the same',
- () => expect(getApiV3('TOKEN')).toBe(api),
+ () => expect(getApi('V3', 'TOKEN')).toBe(api),
);
test('New API v3 service is created if token is new', () => {
- const api2 = getApiV3('TOKEN2');
+ const api2 = getApi('V3', 'TOKEN2');
expect(api2).not.toBe(api);
return testApi(api2, config.API.V3, 'TOKEN2');
});
diff --git a/dist/dev/index.js b/dist/dev/index.js
index 5836bb40..248d961b 100644
--- a/dist/dev/index.js
+++ b/dist/dev/index.js
@@ -412,7 +412,7 @@ eval("var Keys = __webpack_require__(/*! object-keys */ \"./node_modules/object-
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\nvar _slicedToArray2 = __webpack_require__(/*! babel-runtime/helpers/slicedToArray */ \"babel-runtime/helpers/slicedToArray\");\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _tcAccounts = __webpack_require__(/*! tc-accounts */ \"tc-accounts\");\n\nvar _api = __webpack_require__(/*! ../services/api */ \"./src/services/api.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 * @module \"actions.auth\"\n * @desc Actions related to Topcoder authentication system.\n */\n\n/**\n * @static\n * @desc Creates an action that loads Topcoder user profile from v3 API.\n * @param {String} userTokenV3 v3 authentication token.\n * @return {Action}\n */\nfunction loadProfileDone(userTokenV3) {\n if (!userTokenV3) return _promise2.default.resolve(null);\n var user = (0, _tcAccounts.decodeToken)(userTokenV3);\n var api = (0, _api.getApiV3)(userTokenV3);\n return _promise2.default.all([api.get('/members/' + user.handle).then(function (res) {\n return res.json();\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : {};\n }), api.get('/groups?memberId=' + user.userId + '&membershipType=user').then(function (res) {\n return res.json();\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : [];\n })]).then(function (_ref) {\n var _ref2 = (0, _slicedToArray3.default)(_ref, 2),\n profile = _ref2[0],\n groups = _ref2[1];\n\n return (0, _extends3.default)({}, profile, { groups: groups });\n });\n}\n\n/**\n * @static\n * @desc Creates an action that sets Topcoder v2 authentication token.\n * @param {String} tokenV2 Topcoder v2 authentication token.\n * @return {Action}\n */\nfunction setTcTokenV2(tokenV2) {\n return tokenV2;\n}\n\n/**\n * @static\n * @desc Creates an action that decodes Topcoder v3 authentication token,\n * to get user object, and then writes both the token and the user object into\n * Redux store.\n * @param {String} tokenV3 Topcoder v3 authentication token.\n * @return {Action}\n */\nfunction setTcTokenV3(tokenV3) {\n return tokenV3;\n}\n\nvar _default = (0, _reduxActions.createActions)({\n AUTH: {\n LOAD_PROFILE: loadProfileDone,\n SET_TC_TOKEN_V2: setTcTokenV2,\n SET_TC_TOKEN_V3: setTcTokenV3\n }\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(loadProfileDone, 'loadProfileDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.js');\n reactHotLoader.register(setTcTokenV2, 'setTcTokenV2', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.js');\n reactHotLoader.register(setTcTokenV3, 'setTcTokenV3', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.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-lib/./src/actions/auth.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\nvar _slicedToArray2 = __webpack_require__(/*! babel-runtime/helpers/slicedToArray */ \"babel-runtime/helpers/slicedToArray\");\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _tcAccounts = __webpack_require__(/*! tc-accounts */ \"tc-accounts\");\n\nvar _api = __webpack_require__(/*! ../services/api */ \"./src/services/api.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 * @module \"actions.auth\"\n * @desc Actions related to Topcoder authentication system.\n */\n\n/**\n * @static\n * @desc Creates an action that loads Topcoder user profile from v3 API.\n * @param {String} userTokenV3 v3 authentication token.\n * @return {Action}\n */\nfunction loadProfileDone(userTokenV3) {\n if (!userTokenV3) return _promise2.default.resolve(null);\n var user = (0, _tcAccounts.decodeToken)(userTokenV3);\n var api = (0, _api.getApi)('V3', userTokenV3);\n return _promise2.default.all([api.get('/members/' + user.handle).then(function (res) {\n return res.json();\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : {};\n }), api.get('/groups?memberId=' + user.userId + '&membershipType=user').then(function (res) {\n return res.json();\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : [];\n })]).then(function (_ref) {\n var _ref2 = (0, _slicedToArray3.default)(_ref, 2),\n profile = _ref2[0],\n groups = _ref2[1];\n\n return (0, _extends3.default)({}, profile, { groups: groups });\n });\n}\n\n/**\n * @static\n * @desc Creates an action that sets Topcoder v2 authentication token.\n * @param {String} tokenV2 Topcoder v2 authentication token.\n * @return {Action}\n */\nfunction setTcTokenV2(tokenV2) {\n return tokenV2;\n}\n\n/**\n * @static\n * @desc Creates an action that decodes Topcoder v3 authentication token,\n * to get user object, and then writes both the token and the user object into\n * Redux store.\n * @param {String} tokenV3 Topcoder v3 authentication token.\n * @return {Action}\n */\nfunction setTcTokenV3(tokenV3) {\n return tokenV3;\n}\n\nvar _default = (0, _reduxActions.createActions)({\n AUTH: {\n LOAD_PROFILE: loadProfileDone,\n SET_TC_TOKEN_V2: setTcTokenV2,\n SET_TC_TOKEN_V3: setTcTokenV3\n }\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(loadProfileDone, 'loadProfileDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.js');\n reactHotLoader.register(setTcTokenV2, 'setTcTokenV2', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.js');\n reactHotLoader.register(setTcTokenV3, 'setTcTokenV3', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/auth.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-lib/./src/actions/auth.js?");
/***/ }),
@@ -424,7 +424,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _challenges = __webpack_require__(/*! ../services/challenges */ \"./src/services/challenges.js\");\n\nvar _api = __webpack_require__(/*! ../services/api */ \"./src/services/api.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 * @module \"actions.challenge\"\n * @desc Actions related to Topcoder challenges APIs.\n */\n\n/**\n * @static\n * @desc Creates an action that drops from Redux store all checkpoints loaded\n * before.\n * @return {Action}\n */\nfunction dropCheckpoints() {}\n\n/**\n * @static\n * @desc Creates an action that drops from Redux store all challenge results\n * loaded before.\n * @return {Action}\n */\nfunction dropResults() {}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge details loading.\n * @param {Number|String} challengeId Challenge ID\n * @return {Action}\n */\nfunction getDetailsInit(challengeId) {\n return _lodash2.default.toString(challengeId);\n}\n\n/**\n * @static\n * @desc Creates an action that loads challenge details.\n * @param {Number|String} challengeId Challenge ID.\n * @param {String} tokenV3 Topcoder v3 auth token.\n * @param {String} tokenV2 Topcoder v2 auth token.\n * @return {Action}\n */\nfunction getDetailsDone(challengeId, tokenV3, tokenV2) {\n var service = (0, _challenges.getService)(tokenV3, tokenV2);\n var v3Promise = service.getChallengeDetails(challengeId);\n return v3Promise;\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of user submissions loading.\n * @param {String} challengeId Challenge ID.\n * @return {Action}\n */\nfunction getSubmissionsInit(challengeId) {\n /* As a safeguard, we enforce challengeId to be string (in case somebody\n * passes in a number, by mistake). */\n return _lodash2.default.toString(challengeId);\n}\n\n/**\n * @static\n * @desc Creates an action that loads user's submissions to the specified\n * challenge.\n * @param {String} challengeId Challenge ID.\n * @param {String} tokenV2 Topcoder auth token v2.\n * @return {Action}\n */\nfunction getSubmissionsDone(challengeId, tokenV2) {\n return (0, _api.getApiV2)(tokenV2).fetch('/challenges/submissions/' + challengeId + '/mySubmissions').then(function (response) {\n return response.json();\n }).then(function (response) {\n return {\n challengeId: _lodash2.default.toString(challengeId),\n submissions: response.submissions\n };\n }).catch(function (error) {\n var err = { challengeId: _lodash2.default.toString(challengeId), error: error };\n throw err;\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of registration for a\n * challenge.\n * @return {Action}\n */\nfunction registerInit() {}\n\n/**\n * @static\n * @desc Creates an action that registers user for a challenge.\n * @param {Object} auth An object that holds auth tokens. You can directly pass\n * here the `auth` segment of Redux store.\n * @param [auth.tokenV2]{String} Topcoder auth token v2.\n * @param [auth.tokenV3]{String} Topcoder auth token v3.\n * @param {String} challengeId Challenge ID.\n * @return {Action}\n */\nfunction registerDone(auth, challengeId) {\n return (0, _challenges.getService)(auth.tokenV3).register(challengeId)\n /* As a part of registration flow we silently update challenge details,\n * reusing for this purpose the corresponding action handler. */\n // Uses a delay to allow API time to update\n .then(function () {\n return new _promise2.default(function (resolve) {\n return setTimeout(function () {\n return resolve(getDetailsDone(challengeId, auth.tokenV3, auth.tokenV2));\n }, _topcoderReactUtils.config.CHALLENGE_DETAILS_REFRESH_DELAY);\n });\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of user unregistration from a\n * challenge.\n * @return {Action}\n */\nfunction unregisterInit() {}\n\n/**\n * @static\n * @desc Creates an action that unregisters user from a challenge.\n * @param {Object} auth Object that holds Topcoder auth tokens.\n * @param {String} [auth.tokenV2] v2 token.\n * @param {String} [auth.tokenV3] v3 token.\n * @param {String} challengeId Challenge ID.\n * @return {Action}\n */\nfunction unregisterDone(auth, challengeId) {\n return (0, _challenges.getService)(auth.tokenV3).unregister(challengeId)\n /* As a part of unregistration flow we silently update challenge details,\n * reusing for this purpose the corresponding action handler. */\n // Uses a delay to allow API time to update\n .then(function () {\n return new _promise2.default(function (resolve) {\n return setTimeout(function () {\n return resolve(getDetailsDone(challengeId, auth.tokenV3, auth.tokenV2));\n }, _topcoderReactUtils.config.CHALLENGE_DETAILS_REFRESH_DELAY);\n });\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge results loading.\n * @param {Number|String} challengeId Challenge ID\n * @return {Action}\n */\nfunction loadResultsInit(challengeId) {\n return _lodash2.default.toString(challengeId);\n}\n\n/**\n * @static\n * @desc Creates an action that loads challenge results.\n * @param {Object} auth Object that holds Topcoder auth tokens.\n * @param {String} [auth.tokenV2] v2 token.\n * @param {String} [auth.tokenV3] v3 token.\n * @param {Number|String} challengeId Challenge ID. Should match the one passed\n * in the previous {@link module:actions.challenge.loadResultsInit} call.\n * @param {String} type Challenge type.\n * @return {Action}\n */\nfunction loadResultsDone(auth, challengeId, type) {\n return (0, _api.getApiV2)(auth.tokenV2).fetch('/' + type + '/challenges/result/' + challengeId).then(function (response) {\n return response.json();\n }).then(function (response) {\n return {\n challengeId: _lodash2.default.toString(challengeId),\n results: response.results\n };\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge checkpoints data\n * loading.\n * @return {Action}\n */\nfunction fetchCheckpointsInit() {}\n\n/**\n * @static\n * @desc Creates an action that loads challenge checkpoints data.\n * @param {String} tokenV2 Topcoder v2 auth token.\n * @param {String} challengeId Challenge ID.\n */\nfunction fetchCheckpointsDone(tokenV2, challengeId) {\n var endpoint = '/design/challenges/checkpoint/' + challengeId;\n return (0, _api.getApiV2)(tokenV2).fetch(endpoint).then(function (response) {\n if (response.status !== 200) {\n throw response.status;\n } else {\n return response.json();\n }\n }).then(function (response) {\n // Expanded key is used for UI expand/collapse.\n response.checkpointResults.forEach(function (checkpoint, index) {\n response.checkpointResults[index].expanded = false;\n });\n return {\n challengeId: Number(challengeId),\n checkpoints: response\n };\n }).catch(function (error) {\n return {\n error: error,\n challengeId: Number(challengeId)\n };\n });\n}\n\n/**\n * @static\n * @desc Creates an action that Toggles checkpoint details panel in the Topcoder\n * Submission Management Page.\n * @todo This is UI action relevant to a specific page in specific app. Must be\n * moved back to Community App.\n * @param {Number} id Checkpoint ID.\n * @param {Boolean} open Target state: `true` to expand, `false` to collapse the\n * details.\n * @return {Action}\n */\nfunction toggleCheckpointFeedback(id, open) {\n return { id: id, open: open };\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge details update.\n * @todo No idea, why we have this action. This functionality should be covered\n * by {@link module:actions.challenge.getDetailsInit} and\n * {@link module:actions.challenge.getDetailsDone}. We need to refactor this.\n * @param {String} uuid UUID of the operation (the same should be passed into\n * the corresponding {@link module:actions.challenge.updateChallengeDone}).\n * @return {Action}\n */\nfunction updateChallengeInit(uuid) {\n return uuid;\n}\n\n/**\n * @static\n * @desc Creates an action that updates challenge details.\n * @todo No idea, why we have this action. This functionality should be covered\n * by {@link module:actions.challenge.getDetailsInit} and\n * {@link module:actions.challenge.getDetailsDone}. We need to refactor this.\n * @param {String} uuid Operation UUID. Should match the one passed into the\n * previous {@link module:actions.challenge.updateChallengeInit} call.\n * @param {Object} challenge Challenge data.\n * @param {String} tokenV3 Topcoder v3 auth token.\n * @return {Action}\n */\nfunction updateChallengeDone(uuid, challenge, tokenV3) {\n return (0, _challenges.getService)(tokenV3).updateChallenge(challenge).then(function (res) {\n return { uuid: uuid, res: res };\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of getting count of user's active challenges.\n * @return {Action}\n */\nfunction getActiveChallengesCountInit() {}\n\n/**\n * @static\n * @desc Creates an action that gets count of user's active challenges from the backend.\n * @param {String} handle Topcoder user handle.\n * @param {String} tokenV3 Optional. Topcoder auth token v3. Without token only\n * public challenges will be counted. With the token provided, the action will\n * also count private challenges related to this user.\n * @return {Action}\n */\nfunction getActiveChallengesCountDone(handle, tokenV3) {\n return (0, _challenges.getService)(tokenV3).getActiveChallengesCount(handle);\n}\n\nvar _default = (0, _reduxActions.createActions)({\n CHALLENGE: {\n DROP_CHECKPOINTS: dropCheckpoints,\n DROP_RESULTS: dropResults,\n FETCH_CHECKPOINTS_INIT: fetchCheckpointsInit,\n FETCH_CHECKPOINTS_DONE: fetchCheckpointsDone,\n GET_DETAILS_INIT: getDetailsInit,\n GET_DETAILS_DONE: getDetailsDone,\n GET_SUBMISSIONS_INIT: getSubmissionsInit,\n GET_SUBMISSIONS_DONE: getSubmissionsDone,\n LOAD_RESULTS_INIT: loadResultsInit,\n LOAD_RESULTS_DONE: loadResultsDone,\n REGISTER_INIT: registerInit,\n REGISTER_DONE: registerDone,\n TOGGLE_CHECKPOINT_FEEDBACK: toggleCheckpointFeedback,\n UNREGISTER_INIT: unregisterInit,\n UNREGISTER_DONE: unregisterDone,\n UPDATE_CHALLENGE_INIT: updateChallengeInit,\n UPDATE_CHALLENGE_DONE: updateChallengeDone,\n GET_ACTIVE_CHALLENGES_COUNT_INIT: getActiveChallengesCountInit,\n GET_ACTIVE_CHALLENGES_COUNT_DONE: getActiveChallengesCountDone\n }\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(dropCheckpoints, 'dropCheckpoints', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(dropResults, 'dropResults', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getDetailsInit, 'getDetailsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getDetailsDone, 'getDetailsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getSubmissionsInit, 'getSubmissionsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getSubmissionsDone, 'getSubmissionsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(registerInit, 'registerInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(registerDone, 'registerDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(unregisterInit, 'unregisterInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(unregisterDone, 'unregisterDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(loadResultsInit, 'loadResultsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(loadResultsDone, 'loadResultsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(fetchCheckpointsInit, 'fetchCheckpointsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(fetchCheckpointsDone, 'fetchCheckpointsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(toggleCheckpointFeedback, 'toggleCheckpointFeedback', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(updateChallengeInit, 'updateChallengeInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(updateChallengeDone, 'updateChallengeDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getActiveChallengesCountInit, 'getActiveChallengesCountInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getActiveChallengesCountDone, 'getActiveChallengesCountDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.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-lib/./src/actions/challenge.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _challenges = __webpack_require__(/*! ../services/challenges */ \"./src/services/challenges.js\");\n\nvar _api = __webpack_require__(/*! ../services/api */ \"./src/services/api.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 * @module \"actions.challenge\"\n * @desc Actions related to Topcoder challenges APIs.\n */\n\n/**\n * @static\n * @desc Creates an action that drops from Redux store all checkpoints loaded\n * before.\n * @return {Action}\n */\nfunction dropCheckpoints() {}\n\n/**\n * @static\n * @desc Creates an action that drops from Redux store all challenge results\n * loaded before.\n * @return {Action}\n */\nfunction dropResults() {}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge details loading.\n * @param {Number|String} challengeId Challenge ID\n * @return {Action}\n */\nfunction getDetailsInit(challengeId) {\n return _lodash2.default.toString(challengeId);\n}\n\n/**\n * @static\n * @desc Creates an action that loads challenge details.\n * @param {Number|String} challengeId Challenge ID.\n * @param {String} tokenV3 Topcoder v3 auth token.\n * @param {String} tokenV2 Topcoder v2 auth token.\n * @return {Action}\n */\nfunction getDetailsDone(challengeId, tokenV3, tokenV2) {\n var service = (0, _challenges.getService)(tokenV3, tokenV2);\n var v3Promise = service.getChallengeDetails(challengeId);\n return v3Promise;\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of user submissions loading.\n * @param {String} challengeId Challenge ID.\n * @return {Action}\n */\nfunction getSubmissionsInit(challengeId) {\n /* As a safeguard, we enforce challengeId to be string (in case somebody\n * passes in a number, by mistake). */\n return _lodash2.default.toString(challengeId);\n}\n\n/**\n * @static\n * @desc Creates an action that loads user's submissions to the specified\n * challenge.\n * @param {String} challengeId Challenge ID.\n * @param {String} tokenV2 Topcoder auth token v2.\n * @return {Action}\n */\nfunction getSubmissionsDone(challengeId, tokenV2) {\n return (0, _api.getApi)('V2', tokenV2).fetch('/challenges/submissions/' + challengeId + '/mySubmissions').then(function (response) {\n return response.json();\n }).then(function (response) {\n return {\n challengeId: _lodash2.default.toString(challengeId),\n submissions: response.submissions\n };\n }).catch(function (error) {\n var err = { challengeId: _lodash2.default.toString(challengeId), error: error };\n throw err;\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of registration for a\n * challenge.\n * @return {Action}\n */\nfunction registerInit() {}\n\n/**\n * @static\n * @desc Creates an action that registers user for a challenge.\n * @param {Object} auth An object that holds auth tokens. You can directly pass\n * here the `auth` segment of Redux store.\n * @param [auth.tokenV2]{String} Topcoder auth token v2.\n * @param [auth.tokenV3]{String} Topcoder auth token v3.\n * @param {String} challengeId Challenge ID.\n * @return {Action}\n */\nfunction registerDone(auth, challengeId) {\n return (0, _challenges.getService)(auth.tokenV3).register(challengeId)\n /* As a part of registration flow we silently update challenge details,\n * reusing for this purpose the corresponding action handler. */\n // Uses a delay to allow API time to update\n .then(function () {\n return new _promise2.default(function (resolve) {\n return setTimeout(function () {\n return resolve(getDetailsDone(challengeId, auth.tokenV3, auth.tokenV2));\n }, _topcoderReactUtils.config.CHALLENGE_DETAILS_REFRESH_DELAY);\n });\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of user unregistration from a\n * challenge.\n * @return {Action}\n */\nfunction unregisterInit() {}\n\n/**\n * @static\n * @desc Creates an action that unregisters user from a challenge.\n * @param {Object} auth Object that holds Topcoder auth tokens.\n * @param {String} [auth.tokenV2] v2 token.\n * @param {String} [auth.tokenV3] v3 token.\n * @param {String} challengeId Challenge ID.\n * @return {Action}\n */\nfunction unregisterDone(auth, challengeId) {\n return (0, _challenges.getService)(auth.tokenV3).unregister(challengeId)\n /* As a part of unregistration flow we silently update challenge details,\n * reusing for this purpose the corresponding action handler. */\n // Uses a delay to allow API time to update\n .then(function () {\n return new _promise2.default(function (resolve) {\n return setTimeout(function () {\n return resolve(getDetailsDone(challengeId, auth.tokenV3, auth.tokenV2));\n }, _topcoderReactUtils.config.CHALLENGE_DETAILS_REFRESH_DELAY);\n });\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge results loading.\n * @param {Number|String} challengeId Challenge ID\n * @return {Action}\n */\nfunction loadResultsInit(challengeId) {\n return _lodash2.default.toString(challengeId);\n}\n\n/**\n * @static\n * @desc Creates an action that loads challenge results.\n * @param {Object} auth Object that holds Topcoder auth tokens.\n * @param {String} [auth.tokenV2] v2 token.\n * @param {String} [auth.tokenV3] v3 token.\n * @param {Number|String} challengeId Challenge ID. Should match the one passed\n * in the previous {@link module:actions.challenge.loadResultsInit} call.\n * @param {String} type Challenge type.\n * @return {Action}\n */\nfunction loadResultsDone(auth, challengeId, type) {\n return (0, _api.getApi)('V2', auth.tokenV2).fetch('/' + type + '/challenges/result/' + challengeId).then(function (response) {\n return response.json();\n }).then(function (response) {\n return {\n challengeId: _lodash2.default.toString(challengeId),\n results: response.results\n };\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge checkpoints data\n * loading.\n * @return {Action}\n */\nfunction fetchCheckpointsInit() {}\n\n/**\n * @static\n * @desc Creates an action that loads challenge checkpoints data.\n * @param {String} tokenV2 Topcoder v2 auth token.\n * @param {String} challengeId Challenge ID.\n */\nfunction fetchCheckpointsDone(tokenV2, challengeId) {\n var endpoint = '/design/challenges/checkpoint/' + challengeId;\n return (0, _api.getApi)('V2', tokenV2).fetch(endpoint).then(function (response) {\n if (response.status !== 200) {\n throw response.status;\n } else {\n return response.json();\n }\n }).then(function (response) {\n // Expanded key is used for UI expand/collapse.\n response.checkpointResults.forEach(function (checkpoint, index) {\n response.checkpointResults[index].expanded = false;\n });\n return {\n challengeId: Number(challengeId),\n checkpoints: response\n };\n }).catch(function (error) {\n return {\n error: error,\n challengeId: Number(challengeId)\n };\n });\n}\n\n/**\n * @static\n * @desc Creates an action that Toggles checkpoint details panel in the Topcoder\n * Submission Management Page.\n * @todo This is UI action relevant to a specific page in specific app. Must be\n * moved back to Community App.\n * @param {Number} id Checkpoint ID.\n * @param {Boolean} open Target state: `true` to expand, `false` to collapse the\n * details.\n * @return {Action}\n */\nfunction toggleCheckpointFeedback(id, open) {\n return { id: id, open: open };\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of challenge details update.\n * @todo No idea, why we have this action. This functionality should be covered\n * by {@link module:actions.challenge.getDetailsInit} and\n * {@link module:actions.challenge.getDetailsDone}. We need to refactor this.\n * @param {String} uuid UUID of the operation (the same should be passed into\n * the corresponding {@link module:actions.challenge.updateChallengeDone}).\n * @return {Action}\n */\nfunction updateChallengeInit(uuid) {\n return uuid;\n}\n\n/**\n * @static\n * @desc Creates an action that updates challenge details.\n * @todo No idea, why we have this action. This functionality should be covered\n * by {@link module:actions.challenge.getDetailsInit} and\n * {@link module:actions.challenge.getDetailsDone}. We need to refactor this.\n * @param {String} uuid Operation UUID. Should match the one passed into the\n * previous {@link module:actions.challenge.updateChallengeInit} call.\n * @param {Object} challenge Challenge data.\n * @param {String} tokenV3 Topcoder v3 auth token.\n * @return {Action}\n */\nfunction updateChallengeDone(uuid, challenge, tokenV3) {\n return (0, _challenges.getService)(tokenV3).updateChallenge(challenge).then(function (res) {\n return { uuid: uuid, res: res };\n });\n}\n\n/**\n * @static\n * @desc Creates an action that signals beginning of getting count of user's active challenges.\n * @return {Action}\n */\nfunction getActiveChallengesCountInit() {}\n\n/**\n * @static\n * @desc Creates an action that gets count of user's active challenges from the backend.\n * @param {String} handle Topcoder user handle.\n * @param {String} tokenV3 Optional. Topcoder auth token v3. Without token only\n * public challenges will be counted. With the token provided, the action will\n * also count private challenges related to this user.\n * @return {Action}\n */\nfunction getActiveChallengesCountDone(handle, tokenV3) {\n return (0, _challenges.getService)(tokenV3).getActiveChallengesCount(handle);\n}\n\nvar _default = (0, _reduxActions.createActions)({\n CHALLENGE: {\n DROP_CHECKPOINTS: dropCheckpoints,\n DROP_RESULTS: dropResults,\n FETCH_CHECKPOINTS_INIT: fetchCheckpointsInit,\n FETCH_CHECKPOINTS_DONE: fetchCheckpointsDone,\n GET_DETAILS_INIT: getDetailsInit,\n GET_DETAILS_DONE: getDetailsDone,\n GET_SUBMISSIONS_INIT: getSubmissionsInit,\n GET_SUBMISSIONS_DONE: getSubmissionsDone,\n LOAD_RESULTS_INIT: loadResultsInit,\n LOAD_RESULTS_DONE: loadResultsDone,\n REGISTER_INIT: registerInit,\n REGISTER_DONE: registerDone,\n TOGGLE_CHECKPOINT_FEEDBACK: toggleCheckpointFeedback,\n UNREGISTER_INIT: unregisterInit,\n UNREGISTER_DONE: unregisterDone,\n UPDATE_CHALLENGE_INIT: updateChallengeInit,\n UPDATE_CHALLENGE_DONE: updateChallengeDone,\n GET_ACTIVE_CHALLENGES_COUNT_INIT: getActiveChallengesCountInit,\n GET_ACTIVE_CHALLENGES_COUNT_DONE: getActiveChallengesCountDone\n }\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(dropCheckpoints, 'dropCheckpoints', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(dropResults, 'dropResults', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getDetailsInit, 'getDetailsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getDetailsDone, 'getDetailsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getSubmissionsInit, 'getSubmissionsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getSubmissionsDone, 'getSubmissionsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(registerInit, 'registerInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(registerDone, 'registerDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(unregisterInit, 'unregisterInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(unregisterDone, 'unregisterDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(loadResultsInit, 'loadResultsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(loadResultsDone, 'loadResultsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(fetchCheckpointsInit, 'fetchCheckpointsInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(fetchCheckpointsDone, 'fetchCheckpointsDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(toggleCheckpointFeedback, 'toggleCheckpointFeedback', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(updateChallengeInit, 'updateChallengeInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(updateChallengeDone, 'updateChallengeDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getActiveChallengesCountInit, 'getActiveChallengesCountInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(getActiveChallengesCountDone, 'getActiveChallengesCountDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/challenge.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-lib/./src/actions/challenge.js?");
/***/ }),
@@ -568,7 +568,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _api = __webpack_require__(/*! ../services/api */ \"./src/services/api.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 * @module \"actions.smp\"\n * @desc Actions related to *My Submissions Management* page.\n */\n\n/**\n * @static\n * @desc Creates an action that signals beginning of submission download.\n * @return {Action}\n */\nfunction deleteSubmissionInit() {}\n\n/**\n * @static\n * @desc Creates an action that deletes user's submission to a challenge.\n * @param {String} tokenV3 Topcoder v3 auth token.\n * @param {Number|String} submissionId Submission ID.\n * @return {Action}\n */\nfunction deleteSubmissionDone(tokenV3, submissionId) {\n return (0, _api.getApiV3)(tokenV3).delete('/submissions/' + submissionId).then(function () {\n return submissionId;\n });\n}\n\n/**\n * @static\n * @todo At this moment we don't need any special JS code to download\n * submissions: we get them from legacy Topcoder Studio API, which is\n * authenticated by cookies, and can be done with a simple link in\n * the component. Soon we'll migrate to use the new TC API instead, and\n * then we'll decide, whether we need operate downloads in JS, or can we\n * just remove this action.\n * @return {Action}\n */\nfunction downloadSubmission(tokens, type, submissionId) {\n _lodash2.default.noop(tokens, type, submissionId);\n}\n\nvar _default = (0, _reduxActions.createActions)({\n SMP: {\n DELETE_SUBMISSION_DONE: deleteSubmissionDone,\n DELETE_SUBMISSION_INIT: deleteSubmissionInit,\n DOWNLOAD_SUBMISSION: downloadSubmission\n }\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(deleteSubmissionInit, 'deleteSubmissionInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.js');\n reactHotLoader.register(deleteSubmissionDone, 'deleteSubmissionDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.js');\n reactHotLoader.register(downloadSubmission, 'downloadSubmission', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.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-lib/./src/actions/smp.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _reduxActions = __webpack_require__(/*! redux-actions */ \"redux-actions\");\n\nvar _api = __webpack_require__(/*! ../services/api */ \"./src/services/api.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 * @module \"actions.smp\"\n * @desc Actions related to *My Submissions Management* page.\n */\n\n/**\n * @static\n * @desc Creates an action that signals beginning of submission download.\n * @return {Action}\n */\nfunction deleteSubmissionInit() {}\n\n/**\n * @static\n * @desc Creates an action that deletes user's submission to a challenge.\n * @param {String} tokenV3 Topcoder v3 auth token.\n * @param {Number|String} submissionId Submission ID.\n * @return {Action}\n */\nfunction deleteSubmissionDone(tokenV3, submissionId) {\n return (0, _api.getApi)('V3', tokenV3).delete('/submissions/' + submissionId).then(function () {\n return submissionId;\n });\n}\n\n/**\n * @static\n * @todo At this moment we don't need any special JS code to download\n * submissions: we get them from legacy Topcoder Studio API, which is\n * authenticated by cookies, and can be done with a simple link in\n * the component. Soon we'll migrate to use the new TC API instead, and\n * then we'll decide, whether we need operate downloads in JS, or can we\n * just remove this action.\n * @return {Action}\n */\nfunction downloadSubmission(tokens, type, submissionId) {\n _lodash2.default.noop(tokens, type, submissionId);\n}\n\nvar _default = (0, _reduxActions.createActions)({\n SMP: {\n DELETE_SUBMISSION_DONE: deleteSubmissionDone,\n DELETE_SUBMISSION_INIT: deleteSubmissionInit,\n DOWNLOAD_SUBMISSION: downloadSubmission\n }\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(deleteSubmissionInit, 'deleteSubmissionInit', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.js');\n reactHotLoader.register(deleteSubmissionDone, 'deleteSubmissionDone', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.js');\n reactHotLoader.register(downloadSubmission, 'downloadSubmission', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/actions/smp.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-lib/./src/actions/smp.js?");
/***/ }),
@@ -886,7 +886,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getTcM2mToken = undefined;\n\nvar _keys = __webpack_require__(/*! babel-runtime/core-js/object/keys */ \"babel-runtime/core-js/object/keys\");\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\n\nvar _regenerator = __webpack_require__(/*! babel-runtime/regenerator */ \"babel-runtime/regenerator\");\n\nvar _regenerator2 = _interopRequireDefault(_regenerator);\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\nvar _asyncToGenerator2 = __webpack_require__(/*! babel-runtime/helpers/asyncToGenerator */ \"babel-runtime/helpers/asyncToGenerator\");\n\nvar _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);\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\n/**\n * Gets a valid TC M2M token, either requesting one from TC Auth0 API, or\n * serving one from internal cache.\n *\n * @return {Promise} Resolves to a token, valid at least next\n * getTcM2mToken.MIN_LIFETIME milliseconds.\n *\n * @throw if called outside of the server.s\n */\nvar getTcM2mToken = exports.getTcM2mToken = function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {\n var now, cached, TC_M2M, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n if (_topcoderReactUtils.isomorphy.isServerSide()) {\n _context2.next = 2;\n break;\n }\n\n throw new Error('getTcM2mToken() called outside the server');\n\n case 2:\n now = Date.now();\n cached = getTcM2mToken.cached;\n TC_M2M = _topcoderReactUtils.config.SECRET.TC_M2M;\n\n if (!(!cached || cached.expires < now + getTcM2mToken.MIN_LIFETIME)) {\n _context2.next = 13;\n break;\n }\n\n _context2.next = 8;\n return (0, _isomorphicFetch2.default)('https://' + _topcoderReactUtils.config.AUTH0.DOMAIN + '/oauth/token', {\n headers: { 'Content-Type': 'application/json' },\n body: (0, _stringify2.default)({\n client_id: TC_M2M.CLIENT_ID,\n client_secret: TC_M2M.CLIENT_SECRET,\n audience: TC_M2M.AUDIENCE,\n grant_type: TC_M2M.GRANT_TYPE\n }),\n method: 'POST'\n });\n\n case 8:\n res = _context2.sent;\n _context2.next = 11;\n return res.json();\n\n case 11:\n res = _context2.sent;\n\n getTcM2mToken.cached = {\n expires: now + 1000 * res.expires_in, // [ms]\n token: res.access_token\n };\n\n case 13:\n return _context2.abrupt('return', getTcM2mToken.cached.token);\n\n case 14:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n return function getTcM2mToken() {\n return _ref2.apply(this, arguments);\n };\n}();\n\nexports.getApiV2 = getApiV2;\nexports.getApiV3 = getApiV3;\nexports.getApiV4 = getApiV4;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _isomorphicFetch = __webpack_require__(/*! isomorphic-fetch */ \"isomorphic-fetch\");\n\nvar _isomorphicFetch2 = _interopRequireDefault(_isomorphicFetch);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _time = __webpack_require__(/*! ../utils/time */ \"./src/utils/time.js\");\n\nvar _errors = __webpack_require__(/*! ../utils/errors */ \"./src/utils/errors.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 * @module \"services.api\"\n * @desc This module provides a service for conventient access to Topcoder APIs.\n */\n\n/* The minimal delay [ms] between API calls. To avoid problems with the requests\n * rate limits configured in Topcoder APIs, we throttle requests rate at the\n * client side, and at server-side, in dev mode (which is meant to be used for\n * local development. */\nvar MIN_API_CALL_DELAY = _topcoderReactUtils.isomorphy.isDevBuild() ? 1000 : 200;\n\nvar API_THROTTLING = true;\n\nvar lastApiCallTimestamp = Date.now();\n\n/**\n * @static\n * @member default\n * @desc The default export from the module is\n * {@link module:services.api~Api} class.\n */\n\n/**\n * API service object. It is reused for both Topcoder API v2 and v3,\n * as in these cases we are fine with the same interface, and the only\n * thing we need to be different is the base URL and auth token to use.\n */\n\nvar Api = function () {\n /**\n * Creates a new Api object.\n * @param {String} base Base URL of the API.\n * @param {String} token Optional. Authorization token.\n */\n function Api(base, token) {\n (0, _classCallCheck3.default)(this, Api);\n\n this.private = {\n base: base,\n token: token\n };\n }\n\n /**\n * Sends HTTP request to the specified API endpoint. This method is just\n * a convenient wrapper around isomorphic fetch(..):\n *\n * - If API service has auth token, Authorization header is automatically\n * added to the request;\n *\n * - If no Content-Type header set in options, it is automatically set to\n * \"application/json\". In case you want to avoid it, pass null into\n * Content-Type header option.\n *\n * For additional details see https://github.github.io/fetch/\n * @param {String} enpoint Should start with slash, like /endpoint.\n * @param {Object} options Optional. Fetch options.\n * @return {Promise} It resolves to the HTTP response object. To get the\n * actual data you probably want to call .json() method of that object.\n * Mind that this promise rejects only on network errors. In case of\n * HTTP errors (404, etc.) the promise will be resolved successfully,\n * and you should check .status or .ok fields of the response object\n * to find out the response status.\n */\n\n\n (0, _createClass3.default)(Api, [{\n key: 'fetch',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(endpoint) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n var _private, base, token, headers, now;\n\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _private = this.private, base = _private.base, token = _private.token;\n headers = options.headers ? _lodash2.default.clone(options.headers) : {};\n\n if (token) headers.Authorization = 'Bearer ' + token;\n\n _context.t0 = headers['Content-Type'];\n _context.next = _context.t0 === null ? 6 : _context.t0 === undefined ? 8 : 10;\n break;\n\n case 6:\n delete headers['Content-Type'];\n return _context.abrupt('break', 10);\n\n case 8:\n headers['Content-Type'] = 'application/json';\n return _context.abrupt('break', 10);\n\n case 10:\n if (!(API_THROTTLING && (_topcoderReactUtils.isomorphy.isClientSide() || _topcoderReactUtils.isomorphy.isDevBuild()))) {\n _context.next = 19;\n break;\n }\n\n now = Date.now();\n\n lastApiCallTimestamp += MIN_API_CALL_DELAY;\n\n if (!(lastApiCallTimestamp > now)) {\n _context.next = 18;\n break;\n }\n\n _context.next = 16;\n return (0, _time.delay)(lastApiCallTimestamp - now);\n\n case 16:\n _context.next = 19;\n break;\n\n case 18:\n lastApiCallTimestamp = now;\n\n case 19:\n return _context.abrupt('return', (0, _isomorphicFetch2.default)('' + base + endpoint, (0, _extends3.default)({}, options, {\n headers: headers\n })).catch(function (e) {\n (0, _errors.setErrorIcon)(_errors.ERROR_ICON_TYPES.NETWORK, '' + base + endpoint, e.message);\n throw e;\n }));\n\n case 20:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function fetch(_x) {\n return _ref.apply(this, arguments);\n }\n\n return fetch;\n }()\n\n /**\n * Sends DELETE request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'delete',\n value: function _delete(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'DELETE'\n });\n }\n\n /**\n * Sends GET request to the specified endpoint.\n * @param {String} endpoint\n * @return {Promise}\n */\n\n }, {\n key: 'get',\n value: function get(endpoint) {\n return this.fetch(endpoint);\n }\n\n /**\n * Sends POST request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'post',\n value: function post(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'POST'\n });\n }\n\n /**\n * Sends POST request to the specified endpoint, with JSON payload.\n * @param {String} endpoint\n * @param {JSON} json\n * @return {Promise}\n */\n\n }, {\n key: 'postJson',\n value: function postJson(endpoint, json) {\n return this.post(endpoint, (0, _stringify2.default)(json));\n }\n\n /**\n * Sends PUT request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'put',\n value: function put(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'PUT'\n });\n }\n\n /**\n * Sends PUT request to the specified endpoint.\n * @param {String} endpoint\n * @param {JSON} json\n * @return {Promise}\n */\n\n }, {\n key: 'putJson',\n value: function putJson(endpoint, json) {\n return this.put(endpoint, (0, _stringify2.default)(json));\n }\n\n /**\n * Sends PATCH request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'patch',\n value: function patch(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'PATCH'\n });\n }\n\n /**\n * Sends PATCH request to the specified endpoint.\n * @param {String} endpoint\n * @param {JSON} json\n * @return {Promise}\n */\n\n }, {\n key: 'patchJson',\n value: function patchJson(endpoint, json) {\n return this.patch(endpoint, (0, _stringify2.default)(json));\n }\n\n /**\n * Upload with progress\n * @param {String} endpoint\n * @param {Object} body and headers\n * @param {Function} callback handler for update progress only works for client side for now\n * @return {Promise}\n */\n\n }, {\n key: 'upload',\n value: function upload(endpoint, options, onProgress) {\n var _private2 = this.private,\n base = _private2.base,\n token = _private2.token;\n\n var headers = options.headers ? _lodash2.default.clone(options.headers) : {};\n if (token) headers.Authorization = 'Bearer ' + token;\n if (_topcoderReactUtils.isomorphy.isClientSide()) {\n return new _promise2.default(function (res, rej) {\n var xhr = new XMLHttpRequest(); //eslint-disable-line\n xhr.open(options.method, '' + base + endpoint);\n (0, _keys2.default)(headers).forEach(function (key) {\n if (headers[key] != null) {\n xhr.setRequestHeader(key, headers[key]);\n }\n });\n xhr.onload = function (e) {\n return res(e.target.responseText);\n };\n xhr.onerror = rej;\n if (xhr.upload && onProgress) {\n xhr.upload.onprogress = function (evt) {\n if (evt.lengthComputable) onProgress(evt.loaded / evt.total);\n };\n }\n xhr.send(options.body);\n });\n }\n return this.fetch(endpoint, options);\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 Api;\n}();\n\nvar _default = Api;\nexports.default = _default;\n\n/*\n * Topcoder API v2.\n */\n\nvar lastApiV2 = null;\n/**\n * Returns a new or existing Api object for Topcoder API v2.\n * @param {String} token Optional. Auth token for Topcoder API v2.\n * @return {Api} API v2 service object.\n */\nfunction getApiV2(token) {\n if (!lastApiV2 || lastApiV2.private.token !== token) {\n lastApiV2 = new Api(_topcoderReactUtils.config.API.V2, token);\n }\n return lastApiV2;\n}\n\n/*\n * Topcoder API v3.\n */\n\nvar lastApiV3 = null;\n/**\n * Returns a new or existing Api object for Topcoder API v3\n * @param {String} token Optional. Auth token for Topcoder API v3.\n * @return {Api} API v3 service object.\n */\nfunction getApiV3(token) {\n if (!lastApiV3 || lastApiV3.private.token !== token) {\n lastApiV3 = new Api(_topcoderReactUtils.config.API.V3, token);\n }\n return lastApiV3;\n}\n\nvar lastApiV4 = null;\n/**\n * Returns a new or existing Api object for Topcoder API V4\n * @param {String} token Optional. Auth token for Topcoder API V4.\n * @return {Api} API V4 service object.\n */\nfunction getApiV4(token) {\n if (!lastApiV4 || lastApiV4.private.token !== token) {\n lastApiV4 = new Api(_topcoderReactUtils.config.API.V4, token);\n }\n return lastApiV4;\n}\n\ngetTcM2mToken.MIN_LIFETIME = 30 * 1000; // [ms]\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(MIN_API_CALL_DELAY, 'MIN_API_CALL_DELAY', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(API_THROTTLING, 'API_THROTTLING', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(lastApiCallTimestamp, 'lastApiCallTimestamp', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(Api, 'Api', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(lastApiV2, 'lastApiV2', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApiV2, 'getApiV2', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(lastApiV3, 'lastApiV3', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApiV3, 'getApiV3', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(lastApiV4, 'lastApiV4', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApiV4, 'getApiV4', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getTcM2mToken, 'getTcM2mToken', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.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-lib/./src/services/api.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.getTcM2mToken = exports.getApiV4 = exports.getApiV3 = exports.getApiV2 = undefined;\n\nvar _keys = __webpack_require__(/*! babel-runtime/core-js/object/keys */ \"babel-runtime/core-js/object/keys\");\n\nvar _keys2 = _interopRequireDefault(_keys);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\n\nvar _regenerator = __webpack_require__(/*! babel-runtime/regenerator */ \"babel-runtime/regenerator\");\n\nvar _regenerator2 = _interopRequireDefault(_regenerator);\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\nvar _asyncToGenerator2 = __webpack_require__(/*! babel-runtime/helpers/asyncToGenerator */ \"babel-runtime/helpers/asyncToGenerator\");\n\nvar _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);\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\n/**\n * Gets a valid TC M2M token, either requesting one from TC Auth0 API, or\n * serving one from internal cache.\n *\n * @return {Promise} Resolves to a token, valid at least next\n * getTcM2mToken.MIN_LIFETIME milliseconds.\n *\n * @throw if called outside of the server.s\n */\nvar getTcM2mToken = exports.getTcM2mToken = function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {\n var now, cached, TC_M2M, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n if (_topcoderReactUtils.isomorphy.isServerSide()) {\n _context2.next = 2;\n break;\n }\n\n throw new Error('getTcM2mToken() called outside the server');\n\n case 2:\n now = Date.now();\n cached = getTcM2mToken.cached;\n TC_M2M = _topcoderReactUtils.config.SECRET.TC_M2M;\n\n if (!(!cached || cached.expires < now + getTcM2mToken.MIN_LIFETIME)) {\n _context2.next = 13;\n break;\n }\n\n _context2.next = 8;\n return (0, _isomorphicFetch2.default)('https://' + _topcoderReactUtils.config.AUTH0.DOMAIN + '/oauth/token', {\n headers: { 'Content-Type': 'application/json' },\n body: (0, _stringify2.default)({\n client_id: TC_M2M.CLIENT_ID,\n client_secret: TC_M2M.CLIENT_SECRET,\n audience: TC_M2M.AUDIENCE,\n grant_type: TC_M2M.GRANT_TYPE\n }),\n method: 'POST'\n });\n\n case 8:\n res = _context2.sent;\n _context2.next = 11;\n return res.json();\n\n case 11:\n res = _context2.sent;\n\n getTcM2mToken.cached = {\n expires: now + 1000 * res.expires_in, // [ms]\n token: res.access_token\n };\n\n case 13:\n return _context2.abrupt('return', getTcM2mToken.cached.token);\n\n case 14:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n return function getTcM2mToken() {\n return _ref2.apply(this, arguments);\n };\n}();\n\nexports.getApi = getApi;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _isomorphicFetch = __webpack_require__(/*! isomorphic-fetch */ \"isomorphic-fetch\");\n\nvar _isomorphicFetch2 = _interopRequireDefault(_isomorphicFetch);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _time = __webpack_require__(/*! ../utils/time */ \"./src/utils/time.js\");\n\nvar _errors = __webpack_require__(/*! ../utils/errors */ \"./src/utils/errors.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 * @module \"services.api\"\n * @desc This module provides a service for conventient access to Topcoder APIs.\n */\n\n/* The minimal delay [ms] between API calls. To avoid problems with the requests\n * rate limits configured in Topcoder APIs, we throttle requests rate at the\n * client side, and at server-side, in dev mode (which is meant to be used for\n * local development. */\nvar MIN_API_CALL_DELAY = _topcoderReactUtils.isomorphy.isDevBuild() ? 1000 : 200;\n\nvar API_THROTTLING = true;\n\nvar lastApiCallTimestamp = Date.now();\n\n/**\n * @static\n * @member default\n * @desc The default export from the module is\n * {@link module:services.api~Api} class.\n */\n\n/**\n * API service object. It is reused for both Topcoder API v2 and v3,\n * as in these cases we are fine with the same interface, and the only\n * thing we need to be different is the base URL and auth token to use.\n */\n\nvar Api = function () {\n /**\n * Creates a new Api object.\n * @param {String} base Base URL of the API.\n * @param {String} token Optional. Authorization token.\n */\n function Api(base, token) {\n (0, _classCallCheck3.default)(this, Api);\n\n this.private = {\n base: base,\n token: token\n };\n }\n\n /**\n * Sends HTTP request to the specified API endpoint. This method is just\n * a convenient wrapper around isomorphic fetch(..):\n *\n * - If API service has auth token, Authorization header is automatically\n * added to the request;\n *\n * - If no Content-Type header set in options, it is automatically set to\n * \"application/json\". In case you want to avoid it, pass null into\n * Content-Type header option.\n *\n * For additional details see https://github.github.io/fetch/\n * @param {String} enpoint Should start with slash, like /endpoint.\n * @param {Object} options Optional. Fetch options.\n * @return {Promise} It resolves to the HTTP response object. To get the\n * actual data you probably want to call .json() method of that object.\n * Mind that this promise rejects only on network errors. In case of\n * HTTP errors (404, etc.) the promise will be resolved successfully,\n * and you should check .status or .ok fields of the response object\n * to find out the response status.\n */\n\n\n (0, _createClass3.default)(Api, [{\n key: 'fetch',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(endpoint) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n\n var _private, base, token, headers, now;\n\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _private = this.private, base = _private.base, token = _private.token;\n headers = options.headers ? _lodash2.default.clone(options.headers) : {};\n\n if (token) headers.Authorization = 'Bearer ' + token;\n\n _context.t0 = headers['Content-Type'];\n _context.next = _context.t0 === null ? 6 : _context.t0 === undefined ? 8 : 10;\n break;\n\n case 6:\n delete headers['Content-Type'];\n return _context.abrupt('break', 10);\n\n case 8:\n headers['Content-Type'] = 'application/json';\n return _context.abrupt('break', 10);\n\n case 10:\n if (!(API_THROTTLING && (_topcoderReactUtils.isomorphy.isClientSide() || _topcoderReactUtils.isomorphy.isDevBuild()))) {\n _context.next = 19;\n break;\n }\n\n now = Date.now();\n\n lastApiCallTimestamp += MIN_API_CALL_DELAY;\n\n if (!(lastApiCallTimestamp > now)) {\n _context.next = 18;\n break;\n }\n\n _context.next = 16;\n return (0, _time.delay)(lastApiCallTimestamp - now);\n\n case 16:\n _context.next = 19;\n break;\n\n case 18:\n lastApiCallTimestamp = now;\n\n case 19:\n return _context.abrupt('return', (0, _isomorphicFetch2.default)('' + base + endpoint, (0, _extends3.default)({}, options, {\n headers: headers\n })).catch(function (e) {\n (0, _errors.setErrorIcon)(_errors.ERROR_ICON_TYPES.NETWORK, '' + base + endpoint, e.message);\n throw e;\n }));\n\n case 20:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function fetch(_x) {\n return _ref.apply(this, arguments);\n }\n\n return fetch;\n }()\n\n /**\n * Sends DELETE request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'delete',\n value: function _delete(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'DELETE'\n });\n }\n\n /**\n * Sends GET request to the specified endpoint.\n * @param {String} endpoint\n * @return {Promise}\n */\n\n }, {\n key: 'get',\n value: function get(endpoint) {\n return this.fetch(endpoint);\n }\n\n /**\n * Sends POST request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'post',\n value: function post(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'POST'\n });\n }\n\n /**\n * Sends POST request to the specified endpoint, with JSON payload.\n * @param {String} endpoint\n * @param {JSON} json\n * @return {Promise}\n */\n\n }, {\n key: 'postJson',\n value: function postJson(endpoint, json) {\n return this.post(endpoint, (0, _stringify2.default)(json));\n }\n\n /**\n * Sends PUT request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'put',\n value: function put(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'PUT'\n });\n }\n\n /**\n * Sends PUT request to the specified endpoint.\n * @param {String} endpoint\n * @param {JSON} json\n * @return {Promise}\n */\n\n }, {\n key: 'putJson',\n value: function putJson(endpoint, json) {\n return this.put(endpoint, (0, _stringify2.default)(json));\n }\n\n /**\n * Sends PATCH request to the specified endpoint.\n * @param {String} endpoint\n * @param {Blob|BufferSource|FormData|String} body\n * @return {Promise}\n */\n\n }, {\n key: 'patch',\n value: function patch(endpoint, body) {\n return this.fetch(endpoint, {\n body: body,\n method: 'PATCH'\n });\n }\n\n /**\n * Sends PATCH request to the specified endpoint.\n * @param {String} endpoint\n * @param {JSON} json\n * @return {Promise}\n */\n\n }, {\n key: 'patchJson',\n value: function patchJson(endpoint, json) {\n return this.patch(endpoint, (0, _stringify2.default)(json));\n }\n\n /**\n * Upload with progress\n * @param {String} endpoint\n * @param {Object} body and headers\n * @param {Function} callback handler for update progress only works for client side for now\n * @return {Promise}\n */\n\n }, {\n key: 'upload',\n value: function upload(endpoint, options, onProgress) {\n var _private2 = this.private,\n base = _private2.base,\n token = _private2.token;\n\n var headers = options.headers ? _lodash2.default.clone(options.headers) : {};\n if (token) headers.Authorization = 'Bearer ' + token;\n if (_topcoderReactUtils.isomorphy.isClientSide()) {\n return new _promise2.default(function (res, rej) {\n var xhr = new XMLHttpRequest(); //eslint-disable-line\n xhr.open(options.method, '' + base + endpoint);\n (0, _keys2.default)(headers).forEach(function (key) {\n if (headers[key] != null) {\n xhr.setRequestHeader(key, headers[key]);\n }\n });\n xhr.onload = function (e) {\n return res(e.target.responseText);\n };\n xhr.onerror = rej;\n if (xhr.upload && onProgress) {\n xhr.upload.onprogress = function (evt) {\n if (evt.lengthComputable) onProgress(evt.loaded / evt.total);\n };\n }\n xhr.send(options.body);\n });\n }\n return this.fetch(endpoint, options);\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 Api;\n}();\n\nvar _default = Api;\nexports.default = _default;\n\n/*\n * Topcoder API\n */\n\nvar lastApiInstances = {};\n\n/**\n * Returns a new or existing Api object for Topcoder API.\n * @param {String} version The API version.\n * @param {String} token Optional. Auth token for Topcoder API.\n * @return {Api} API service object.\n */\nfunction getApi(version, token) {\n if (!version || !_topcoderReactUtils.config.API[version]) {\n throw new Error(version + ' is not a valid API version');\n }\n if (!lastApiInstances[version] || lastApiInstances[version].private.token !== token) {\n lastApiInstances[version] = new Api(_topcoderReactUtils.config.API[version], token);\n }\n return lastApiInstances[version];\n}\n\n/**\n * Keep the old API factories for backwards compatibility\n * DO NOT USE THEM FOR NEW IMPLEMENTATIONS.\n * USE THE getApi(version, token) FACTORY.\n */\nvar getApiV2 = exports.getApiV2 = function getApiV2(token) {\n return getApi('V2', token);\n};\nvar getApiV3 = exports.getApiV3 = function getApiV3(token) {\n return getApi('V3', token);\n};\nvar getApiV4 = exports.getApiV4 = function getApiV4(token) {\n return getApi('V4', token);\n};\n\ngetTcM2mToken.MIN_LIFETIME = 30 * 1000; // [ms]\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(MIN_API_CALL_DELAY, 'MIN_API_CALL_DELAY', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(API_THROTTLING, 'API_THROTTLING', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(lastApiCallTimestamp, 'lastApiCallTimestamp', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(Api, 'Api', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(lastApiInstances, 'lastApiInstances', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApi, 'getApi', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApiV2, 'getApiV2', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApiV3, 'getApiV3', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getApiV4, 'getApiV4', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(getTcM2mToken, 'getTcM2mToken', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/api.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-lib/./src/services/api.js?");
/***/ }),
@@ -898,7 +898,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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\nexports.getService = getService;\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.billing\"\n * @desc Access to Topcoder billing accounts.\n */\n\n\n/**\n * @static\n * @member default\n * @desc Default module export is\n * {@link module:services.billing~Billing} class.\n */\n\n/**\n * Billing service object.\n */\nvar Billing = function () {\n /**\n * Creates a new service.\n * @param {String} tokenV3 Topcoder auth token v3.\n */\n function Billing(tokenV3) {\n (0, _classCallCheck3.default)(this, Billing);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets billing accounts accessible to service user.\n * @return {Promise} Resolves to the list of billing account objects.\n */\n\n\n (0, _createClass3.default)(Billing, [{\n key: 'getUserBillingAccounts',\n value: function getUserBillingAccounts() {\n return this.private.api.fetch();\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 Billing;\n}();\n\nvar lastInstance = null;\n\n/**\n * Returns a new or existing Billing service for the user specified by token.\n * @param {String} tokenV3 Topcoder auth token v3.\n * @return {Billing} Billing service instance.\n */\nfunction getService(tokenV3) {\n if (!lastInstance || lastInstance.private.tokenV3 !== tokenV3) {\n lastInstance = new Billing(tokenV3);\n }\n return lastInstance;\n}\n\nvar _default = Billing;\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(Billing, 'Billing', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.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-lib/./src/services/billing.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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\nexports.getService = getService;\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.billing\"\n * @desc Access to Topcoder billing accounts.\n */\n\n\n/**\n * @static\n * @member default\n * @desc Default module export is\n * {@link module:services.billing~Billing} class.\n */\n\n/**\n * Billing service object.\n */\nvar Billing = function () {\n /**\n * Creates a new service.\n * @param {String} tokenV3 Topcoder auth token v3.\n */\n function Billing(tokenV3) {\n (0, _classCallCheck3.default)(this, Billing);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets billing accounts accessible to service user.\n * @return {Promise} Resolves to the list of billing account objects.\n */\n\n\n (0, _createClass3.default)(Billing, [{\n key: 'getUserBillingAccounts',\n value: function getUserBillingAccounts() {\n return this.private.api.fetch();\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 Billing;\n}();\n\nvar lastInstance = null;\n\n/**\n * Returns a new or existing Billing service for the user specified by token.\n * @param {String} tokenV3 Topcoder auth token v3.\n * @return {Billing} Billing service instance.\n */\nfunction getService(tokenV3) {\n if (!lastInstance || lastInstance.private.tokenV3 !== tokenV3) {\n lastInstance = new Billing(tokenV3);\n }\n return lastInstance;\n}\n\nvar _default = Billing;\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(Billing, 'Billing', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/billing.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-lib/./src/services/billing.js?");
/***/ }),
@@ -910,7 +910,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ORDER_BY = undefined;\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\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 _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 _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _set = __webpack_require__(/*! babel-runtime/core-js/set */ \"babel-runtime/core-js/set\");\n\nvar _set2 = _interopRequireDefault(_set);\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\n/**\n * Helper method that checks for HTTP error response and throws Error in this case.\n * @param {Object} res HTTP response object\n * @return {Object} API JSON response object\n * @private\n */\nvar checkError = function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(res) {\n var jsonRes;\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (res.ok) {\n _context.next = 3;\n break;\n }\n\n if (res.status >= 500) {\n (0, _errors.setErrorIcon)(_errors.ERROR_ICON_TYPES.API, '/challenges', res.statusText);\n }\n throw new Error(res.statusText);\n\n case 3:\n _context.next = 5;\n return res.json();\n\n case 5:\n jsonRes = _context.sent.result;\n\n if (!(jsonRes.status !== 200)) {\n _context.next = 8;\n break;\n }\n\n throw new Error(jsonRes.content);\n\n case 8:\n return _context.abrupt('return', jsonRes);\n\n case 9:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n return function checkError(_x) {\n return _ref3.apply(this, arguments);\n };\n}();\n\n/**\n * Challenge service.\n */\n\n\nexports.normalizeChallengeDetails = normalizeChallengeDetails;\nexports.normalizeChallenge = normalizeChallenge;\nexports.getService = getService;\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 _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _tcAccounts = __webpack_require__(/*! tc-accounts */ \"tc-accounts\");\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _errors = __webpack_require__(/*! ../utils/errors */ \"./src/utils/errors.js\");\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.challenges\"\n * @desc This module provides a service for convenient manipulation with\n * Topcoder challenges via TC API.\n */\n\nvar ORDER_BY = exports.ORDER_BY = {\n SUBMISSION_END_DATE: 'submissionEndDate'\n};\n\n/**\n * Normalizes a regular challenge details object received from the backend APIs.\n * NOTE: It is possible, that this normalization is not necessary after we\n * have moved to Topcoder API v4, but it is kept for now to minimize a risk of\n * breaking anything.\n * @todo Why this one is exported? It should be only used internally!\n * @param {Object} v4 Challenge object received from the /v4/challenges/{id}\n * endpoint.\n * @param {Object} v4Filtered Challenge object received from the\n * /v4/challenges?filter=id={id} endpoint.\n * @param {Object} v4User Challenge object received from the\n * /v4/members/{username}/challenges?filter=id={id} endpoint.\n * If action was fired for authenticated visitor, v4_user will contain\n * details fetched specifically for the user (thus may include additional\n * data comparing to the standard API v4 response for the challenge details,\n * stored in v4_filtered).\n * @param {String} username Optional.\n * @return {Object} Normalized challenge object.\n */\nfunction normalizeChallengeDetails(v4, v4Filtered, v4User, username) {\n // Normalize exising data to make it consistent with the rest of the code\n var challenge = (0, _extends3.default)({}, v4, {\n\n id: v4.challengeId,\n reliabilityBonus: _lodash2.default.get(v4Filtered, 'reliabilityBonus', 0),\n status: (v4.currentStatus || '').toUpperCase(),\n\n allPhases: [],\n currentPhases: [],\n name: v4.challengeName || v4.challengeTitle,\n projectId: Number(v4.projectId),\n forumId: Number(v4.forumId),\n introduction: v4.introduction || '',\n detailedRequirements: v4.detailedRequirements === 'null' ? '' : v4.detailedRequirements,\n finalSubmissionGuidelines: v4.finalSubmissionGuidelines === 'null' ? '' : v4.finalSubmissionGuidelines,\n screeningScorecardId: Number(v4.screeningScorecardId),\n reviewScorecardId: Number(v4.reviewScorecardId),\n numberOfCheckpointsPrizes: v4.numberOfCheckpointsPrizes,\n topCheckPointPrize: v4.topCheckPointPrize,\n submissionsViewable: v4.submissionsViewable || 'false',\n reviewType: v4.reviewType,\n allowStockArt: v4.allowStockArt === 'true',\n fileTypes: v4.filetypes || [],\n environment: v4.environment,\n codeRepo: v4.codeRepo,\n forumLink: v4.forumLink,\n submissionLimit: Number(v4.submissionLimit) || 0,\n drPoints: v4.digitalRunPoints,\n directUrl: v4.directUrl,\n technologies: v4.technologies || v4.technology || [],\n platforms: v4.platforms || [],\n prizes: v4.prize || v4.prizes || [],\n events: _lodash2.default.map(v4.event, function (e) {\n return {\n eventName: e.eventShortDesc,\n eventId: e.id,\n description: e.eventDescription\n };\n }),\n terms: v4.terms,\n submissions: v4.submissions,\n track: _lodash2.default.toUpper(v4.challengeCommunity),\n subTrack: v4.subTrack,\n checkpoints: v4.checkpoints,\n documents: v4.documents || [],\n numRegistrants: v4.numberOfRegistrants,\n numberOfCheckpointSubmissions: v4.numberOfCheckpointSubmissions,\n registrants: v4.registrants || []\n });\n\n // v4 Winners have different field names, needs to be normalized to match v4 filtered and v4\n challenge.winners = _lodash2.default.map(v4.winners, function (winner, index) {\n return (0, _extends3.default)({}, winner, {\n handle: winner.submitter,\n placement: winner.rank || index + 1 // Legacy MMs do not have a rank but are sorted by points\n });\n });\n\n if (challenge.subTrack === 'MARATHON_MATCH') {\n challenge.track = 'DATA_SCIENCE';\n }\n\n // It's not clear if this will be the main event, will need to be investigated\n challenge.mainEvent = challenge.events[0] || {};\n\n /* It's unclear if these normalization steps are still required for V4 */\n // Fill missing data from v4_filtered\n if (v4Filtered) {\n var groups = {};\n if (v4Filtered.groupIds) {\n v4Filtered.groupIds.forEach(function (id) {\n groups[id] = true;\n });\n }\n\n _lodash2.default.merge(challenge, {\n componentId: v4Filtered.componentId,\n contestId: v4Filtered.contestId,\n\n submissionEndDate: v4Filtered.submissionEndDate, // Dates are not correct in v4\n submissionEndTimestamp: v4Filtered.submissionEndDate, // Dates are not correct in v4\n\n /* Taking phases from v4_filtered, because dates are not correct in v4 */\n allPhases: v4Filtered.allPhases || [],\n\n /* Taking phases from v4_filtered, because dates are not correct in v4 */\n currentPhases: v4Filtered.currentPhases || [],\n\n /* v4 returns incorrect value for numberOfSubmissions for some reason */\n numSubmissions: v4Filtered.numSubmissions,\n groups: groups\n });\n }\n\n // Fill missing data from v4_user\n if (v4User) {\n _lodash2.default.defaults(challenge, {\n userDetails: v4User.userDetails\n });\n }\n\n // Fill some derived data\n var registrationOpen = _lodash2.default.some(challenge.allPhases, function (phase) {\n return phase.phaseType === 'Registration' && phase.phaseStatus === 'Open';\n }) ? 'Yes' : 'No';\n _lodash2.default.defaults(challenge, {\n communities: new _set2.default([_tc.COMPETITION_TRACKS[challenge.track]]),\n registrationOpen: registrationOpen,\n users: username ? (0, _defineProperty3.default)({}, username, true) : {}\n });\n\n // A hot fix to show submissions for on-going challenges\n if (!challenge.submissions || !challenge.submissions.length) {\n challenge.submissions = challenge.registrants.filter(function (r) {\n return r.submissionDate || '';\n }).sort(function (a, b) {\n return (a.submissionDate || '').localeCompare(b.submissionDate || '');\n });\n }\n\n if (!challenge.allPhases) challenge.allPhases = [];\n if (!challenge.track) challenge.track = '';\n\n return challenge;\n}\n\n/**\n * Normalizes a regular challenge object received from the backend.\n * NOTE: This function is copied from the existing code in the challenge listing\n * component. It is possible, that this normalization is not necessary after we\n * have moved to Topcoder API v4, but it is kept for now to minimize a risk of\n * breaking anything.\n * @todo Should be used only internally!\n * @param {Object} challenge Challenge object received from the backend.\n * @param {String} username Optional.\n */\nfunction normalizeChallenge(challenge, username) {\n var registrationOpen = challenge.allPhases.filter(function (d) {\n return d.phaseType === 'Registration';\n })[0].phaseStatus === 'Open' ? 'Yes' : 'No';\n var groups = {};\n if (challenge.groupIds) {\n challenge.groupIds.forEach(function (id) {\n groups[id] = true;\n });\n }\n /* eslint-disable no-param-reassign */\n if (!challenge.prizes) challenge.prizes = challenge.prize || [];\n if (!challenge.totalPrize) {\n challenge.totalPrize = challenge.prizes.reduce(function (sum, x) {\n return sum + x;\n }, 0);\n }\n if (!challenge.technologies) challenge.technologies = [];\n if (!challenge.platforms) challenge.platforms = [];\n\n if (challenge.subTrack === 'DEVELOP_MARATHON_MATCH') {\n challenge.track = 'DATA_SCIENCE';\n }\n /* eslint-enable no-param-reassign */\n\n _lodash2.default.defaults(challenge, {\n communities: new _set2.default([_tc.COMPETITION_TRACKS[challenge.track]]),\n groups: groups,\n registrationOpen: registrationOpen,\n submissionEndTimestamp: challenge.submissionEndDate,\n users: username ? (0, _defineProperty3.default)({}, username, true) : {}\n });\n}\nvar ChallengesService = function () {\n /**\n * Creates a new ChallengeService instance.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n */\n function ChallengesService(tokenV3, tokenV2) {\n var _this = this;\n\n (0, _classCallCheck3.default)(this, ChallengesService);\n\n /**\n * Private function being re-used in all methods related to getting\n * challenges. It handles query-related arguments in the uniform way:\n * @param {String} endpoint API V4 endpoint, where the request will be send.\n * @param {Object} filters Optional. A map of filters to pass as `filter`\n * query parameter (this function takes care to stringify it properly).\n * @param {Object} params Optional. A map of any other parameters beside\n * `filter`.\n */\n var getChallenges = function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(endpoint) {\n var filters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var query, url, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n query = (0, _extends3.default)({\n filter: _qs2.default.stringify(filters, { encode: false })\n }, params);\n url = endpoint + '?' + _qs2.default.stringify(query);\n _context2.next = 4;\n return _this.private.api.get(url).then(checkError);\n\n case 4:\n res = _context2.sent;\n return _context2.abrupt('return', {\n challenges: res.content || [],\n totalCount: res.metadata.totalCount,\n meta: res.metadata\n });\n\n case 6:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, _this);\n }));\n\n return function getChallenges(_x2) {\n return _ref4.apply(this, arguments);\n };\n }();\n\n this.private = {\n api: (0, _api.getApiV4)(tokenV3),\n apiV2: (0, _api.getApiV2)(tokenV2),\n getChallenges: getChallenges,\n tokenV2: tokenV2,\n tokenV3: tokenV3\n };\n }\n\n /**\n * Activates the specified challenge.\n * @param {Number} challengeId\n * @return {Promise} Resolves to null value in case of success; otherwise it\n * is rejected.\n */\n\n\n (0, _createClass3.default)(ChallengesService, [{\n key: 'activate',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(challengeId) {\n var res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _context3.next = 2;\n return this.private.api.post('/challenges/' + challengeId + '/activate');\n\n case 2:\n res = _context3.sent;\n\n if (res.ok) {\n _context3.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n _context3.next = 7;\n return res.json();\n\n case 7:\n res = _context3.sent.result;\n\n if (!(res.status !== 200)) {\n _context3.next = 10;\n break;\n }\n\n throw new Error(res.content);\n\n case 10:\n return _context3.abrupt('return', res.content);\n\n case 11:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function activate(_x5) {\n return _ref5.apply(this, arguments);\n }\n\n return activate;\n }()\n\n /**\n * Closes the specified challenge.\n * @param {Number} challengeId\n * @param {Number} winnerId Optional. ID of the assignee to declare the\n * winner.\n * @return {Promise} Resolves to null value in case of success; otherwise it\n * is rejected.\n */\n\n }, {\n key: 'close',\n value: function () {\n var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(challengeId, winnerId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n url = '/challenges/' + challengeId + '/close';\n\n if (winnerId) url = url + '?winnerId=' + winnerId;\n _context4.next = 4;\n return this.private.api.post(url);\n\n case 4:\n res = _context4.sent;\n\n if (res.ok) {\n _context4.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context4.next = 9;\n return res.json();\n\n case 9:\n res = _context4.sent.result;\n\n if (!(res.status !== 200)) {\n _context4.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context4.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function close(_x6, _x7) {\n return _ref6.apply(this, arguments);\n }\n\n return close;\n }()\n\n /**\n * Creates a new payment task.\n * @param {Number} projectId\n * @param {Number} accountId Billing account ID.\n * @param {String} title\n * @param {String} description\n * @param {String} assignee\n * @param {Number} payment\n * @param {String} submissionGuidelines\n * @param {Number} copilotId\n * @param {Number} copilotFee\n * @param {?} technologies\n * @return {Promise} Resolves to the created challenge object (payment task).\n */\n\n }, {\n key: 'createTask',\n value: function () {\n var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(projectId, accountId, title, description, assignee, payment, submissionGuidelines, copilotId, copilotFee, technologies) {\n var payload, res;\n return _regenerator2.default.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n payload = {\n param: {\n assignees: [assignee],\n billingAccountId: accountId,\n confidentialityType: 'public',\n detailedRequirements: description,\n submissionGuidelines: submissionGuidelines,\n milestoneId: 1,\n name: title,\n technologies: technologies,\n prizes: payment ? [payment] : [],\n projectId: projectId,\n registrationStartsAt: (0, _moment2.default)().toISOString(),\n reviewType: 'INTERNAL',\n subTrack: 'FIRST_2_FINISH',\n task: true\n }\n };\n\n if (copilotId) {\n _lodash2.default.assign(payload.param, {\n copilotId: copilotId,\n copilotFee: copilotFee\n });\n }\n _context5.next = 4;\n return this.private.api.postJson('/challenges', payload);\n\n case 4:\n res = _context5.sent;\n\n if (res.ok) {\n _context5.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context5.next = 9;\n return res.json();\n\n case 9:\n res = _context5.sent.result;\n\n if (!(res.status !== 200)) {\n _context5.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context5.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function createTask(_x8, _x9, _x10, _x11, _x12, _x13, _x14, _x15, _x16, _x17) {\n return _ref7.apply(this, arguments);\n }\n\n return createTask;\n }()\n\n /**\n * Gets challenge details from Topcoder API v4.\n * NOTE: This function also uses API v2 and other v4 endpoints for now, due\n * to some information is missing or\n * incorrect in the main v4 endpoint. This may change in the future.\n * @param {Number|String} challengeId\n * @return {Promise} Resolves to the challenge object.\n */\n\n }, {\n key: 'getChallengeDetails',\n value: function () {\n var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(challengeId) {\n var challengeV4, challengeV4Filtered, username, challengeV4User, challenge;\n return _regenerator2.default.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n _context6.next = 2;\n return this.private.api.get('/challenges/' + challengeId).then(checkError).then(function (res) {\n return res.content;\n });\n\n case 2:\n challengeV4 = _context6.sent;\n _context6.next = 5;\n return this.private.getChallenges('/challenges/', { id: challengeId }).then(function (res) {\n return res.challenges[0];\n });\n\n case 5:\n challengeV4Filtered = _context6.sent;\n username = this.private.tokenV3 && (0, _tcAccounts.decodeToken)(this.private.tokenV3).handle;\n _context6.t0 = username;\n\n if (!_context6.t0) {\n _context6.next = 12;\n break;\n }\n\n _context6.next = 11;\n return this.getUserChallenges(username, { id: challengeId }).then(function (res) {\n return res.challenges[0];\n }).catch(function () {\n return null;\n });\n\n case 11:\n _context6.t0 = _context6.sent;\n\n case 12:\n challengeV4User = _context6.t0;\n challenge = normalizeChallengeDetails(challengeV4, challengeV4Filtered, challengeV4User, username);\n\n\n challenge.fetchedWithAuth = Boolean(this.private.api.private.token);\n\n return _context6.abrupt('return', challenge);\n\n case 16:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getChallengeDetails(_x18) {\n return _ref8.apply(this, arguments);\n }\n\n return getChallengeDetails;\n }()\n\n /**\n * Gets possible challenge subtracks.\n * @return {Promise} Resolves to the array of subtrack names.\n */\n\n }, {\n key: 'getChallengeSubtracks',\n value: function getChallengeSubtracks() {\n return this.private.api.get('/challenge-types').then(function (res) {\n return res.ok ? res.json() : new Error(res.statusText);\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : new Error(res.result.content);\n });\n }\n\n /**\n * Gets possible challenge tags (technologies).\n * @return {Promise} Resolves to the array of tag strings.\n */\n\n }, {\n key: 'getChallengeTags',\n value: function getChallengeTags() {\n return this.private.api.get('/technologies').then(function (res) {\n return res.ok ? res.json() : new Error(res.statusText);\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : new Error(res.result.content);\n });\n }\n\n /**\n * Gets challenges.\n * @param {Object} filters Optional.\n * @param {Object} params Optional.\n * @return {Promise} Resolves to the api response.\n */\n\n }, {\n key: 'getChallenges',\n value: function getChallenges(filters, params) {\n return this.private.getChallenges('/challenges/', filters, params).then(function (res) {\n res.challenges.forEach(function (item) {\n return normalizeChallenge(item);\n });\n return res;\n });\n }\n\n /**\n * Gets SRM matches.\n * @param {Object} params\n * @return {Promise}\n */\n\n }, {\n key: 'getSrms',\n value: function () {\n var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(params) {\n var res;\n return _regenerator2.default.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n _context7.next = 2;\n return this.private.api.get('/srms/?' + _qs2.default.stringify(params));\n\n case 2:\n res = _context7.sent;\n return _context7.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function getSrms(_x19) {\n return _ref9.apply(this, arguments);\n }\n\n return getSrms;\n }()\n\n /**\n * Gets challenges of the specified user.\n * @param {String} username User whose challenges we want to fetch.\n * @param {Object} filters Optional.\n * @param {Number} params Optional.\n * @return {Promise} Resolves to the api response.\n */\n\n }, {\n key: 'getUserChallenges',\n value: function getUserChallenges(username, filters, params) {\n var endpoint = '/members/' + username.toLowerCase() + '/challenges/';\n return this.private.getChallenges(endpoint, filters, params).then(function (res) {\n res.challenges.forEach(function (item) {\n return normalizeChallenge(item, username);\n });\n return res;\n });\n }\n\n /**\n * Gets SRM matches related to the user.\n * @param {String} handle\n * @param {Object} params\n * @return {Promise}\n */\n\n }, {\n key: 'getUserSrms',\n value: function () {\n var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(handle, params) {\n var url, res;\n return _regenerator2.default.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n url = '/members/' + handle + '/srms/?' + _qs2.default.stringify(params);\n _context8.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context8.sent;\n return _context8.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function getUserSrms(_x20, _x21) {\n return _ref10.apply(this, arguments);\n }\n\n return getUserSrms;\n }()\n\n /**\n * Registers user to the specified challenge.\n * @param {String} challengeId\n * @return {Promise}\n */\n\n }, {\n key: 'register',\n value: function () {\n var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(challengeId) {\n var endpoint, res;\n return _regenerator2.default.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n endpoint = '/challenges/' + challengeId + '/register';\n _context9.next = 3;\n return this.private.api.postJson(endpoint);\n\n case 3:\n res = _context9.sent;\n\n if (res.ok) {\n _context9.next = 6;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 6:\n return _context9.abrupt('return', res.json());\n\n case 7:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function register(_x22) {\n return _ref11.apply(this, arguments);\n }\n\n return register;\n }()\n\n /**\n * Unregisters user from the specified challenge.\n * @param {String} challengeId\n * @return {Promise}\n */\n\n }, {\n key: 'unregister',\n value: function () {\n var _ref12 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(challengeId) {\n var endpoint, res;\n return _regenerator2.default.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n endpoint = '/challenges/' + challengeId + '/unregister';\n _context10.next = 3;\n return this.private.api.post(endpoint);\n\n case 3:\n res = _context10.sent;\n\n if (res.ok) {\n _context10.next = 6;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 6:\n return _context10.abrupt('return', res.json());\n\n case 7:\n case 'end':\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function unregister(_x23) {\n return _ref12.apply(this, arguments);\n }\n\n return unregister;\n }()\n\n /**\n * Gets count of user's active challenges.\n * @param {String} handle Topcoder user handle.\n * @return {Action} Resolves to the api response.\n */\n\n }, {\n key: 'getActiveChallengesCount',\n value: function getActiveChallengesCount(handle) {\n var filter = { status: 'ACTIVE' };\n var params = { limit: 1, offset: 0 };\n return this.getUserChallenges(handle, filter, params).then(function (res) {\n return res.totalCount;\n });\n }\n\n /**\n * Submits a challenge submission. Uses APIV2 for Development submission\n * and APIV3 for Design submisisons.\n * @param {Object} body\n * @param {String} challengeId\n * @param {String} track Either DESIGN or DEVELOP\n * @return {Promise}\n */\n\n }, {\n key: 'submit',\n value: function submit(body, challengeId, track, onProgress) {\n var api = void 0;\n var contentType = void 0;\n var url = void 0;\n\n if (track === 'DESIGN') {\n api = this.private.api;\n\n contentType = 'application/json';\n url = '/submissions/'; // The submission info is contained entirely in the JSON body\n } else {\n api = this.private.apiV2;\n // contentType = 'multipart/form-data';\n contentType = null;\n url = '/develop/challenges/' + challengeId + '/upload';\n }\n\n return api.upload(url, {\n body: body,\n headers: { 'Content-Type': contentType },\n method: 'POST'\n }, onProgress).then(function (res) {\n var jres = JSON.parse(res);\n // Return result for Develop submission\n if (track === 'DEVELOP') {\n return jres;\n }\n // Design Submission requires an extra \"Processing\" POST\n var procId = jres.result.content.id;\n return api.upload('/submissions/' + procId + '/process/', {\n body: (0, _stringify2.default)({ param: jres.result.content }),\n headers: { 'Content-Type': contentType },\n method: 'POST'\n }, onProgress).then(function (procres) {\n return JSON.parse(procres);\n });\n }, function (err) {\n _logger2.default.error('Failed to submit to the challenge #' + challengeId, err);\n throw err;\n });\n }\n\n /**\n * Updates the challenge (saves the give challenge to the API).\n * @param {Object} challenge\n * @param {String} tokenV3\n * @return {Promise}\n */\n\n }, {\n key: 'updateChallenge',\n value: function () {\n var _ref13 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee11(challenge) {\n var URL, body, res;\n return _regenerator2.default.wrap(function _callee11$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n URL = '/challenges/' + challenge.id;\n body = { param: challenge };\n _context11.next = 4;\n return this.private.api.putJson(URL, body);\n\n case 4:\n res = _context11.sent;\n\n if (res.ok) {\n _context11.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context11.next = 9;\n return res.json();\n\n case 9:\n res = _context11.sent.result;\n\n if (!(res.status !== 200)) {\n _context11.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context11.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context11.stop();\n }\n }\n }, _callee11, this);\n }));\n\n function updateChallenge(_x24) {\n return _ref13.apply(this, arguments);\n }\n\n return updateChallenge;\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 ChallengesService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing challenges service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n * @return {ChallengesService} Challenges service object\n */\nfunction getService(tokenV3, tokenV2) {\n if (!lastInstance || lastInstance.private.tokenV3 !== tokenV3 || lastInstance.tokenV2 !== tokenV2) {\n lastInstance = new ChallengesService(tokenV3, tokenV2);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(ORDER_BY, 'ORDER_BY', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(normalizeChallengeDetails, 'normalizeChallengeDetails', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(normalizeChallenge, 'normalizeChallenge', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(checkError, 'checkError', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(ChallengesService, 'ChallengesService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.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-lib/./src/services/challenges.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\nexports.ORDER_BY = undefined;\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\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 _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 _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _set = __webpack_require__(/*! babel-runtime/core-js/set */ \"babel-runtime/core-js/set\");\n\nvar _set2 = _interopRequireDefault(_set);\n\nvar _extends2 = __webpack_require__(/*! babel-runtime/helpers/extends */ \"babel-runtime/helpers/extends\");\n\nvar _extends3 = _interopRequireDefault(_extends2);\n\n/**\n * Helper method that checks for HTTP error response and throws Error in this case.\n * @param {Object} res HTTP response object\n * @return {Object} API JSON response object\n * @private\n */\nvar checkError = function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(res) {\n var jsonRes;\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (res.ok) {\n _context.next = 3;\n break;\n }\n\n if (res.status >= 500) {\n (0, _errors.setErrorIcon)(_errors.ERROR_ICON_TYPES.API, '/challenges', res.statusText);\n }\n throw new Error(res.statusText);\n\n case 3:\n _context.next = 5;\n return res.json();\n\n case 5:\n jsonRes = _context.sent.result;\n\n if (!(jsonRes.status !== 200)) {\n _context.next = 8;\n break;\n }\n\n throw new Error(jsonRes.content);\n\n case 8:\n return _context.abrupt('return', jsonRes);\n\n case 9:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n return function checkError(_x) {\n return _ref3.apply(this, arguments);\n };\n}();\n\n/**\n * Challenge service.\n */\n\n\nexports.normalizeChallengeDetails = normalizeChallengeDetails;\nexports.normalizeChallenge = normalizeChallenge;\nexports.getService = getService;\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 _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _tcAccounts = __webpack_require__(/*! tc-accounts */ \"tc-accounts\");\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _errors = __webpack_require__(/*! ../utils/errors */ \"./src/utils/errors.js\");\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.challenges\"\n * @desc This module provides a service for convenient manipulation with\n * Topcoder challenges via TC API.\n */\n\nvar ORDER_BY = exports.ORDER_BY = {\n SUBMISSION_END_DATE: 'submissionEndDate'\n};\n\n/**\n * Normalizes a regular challenge details object received from the backend APIs.\n * @todo Why this one is exported? It should be only used internally!\n * @param {Object} challenge Challenge object received from the /challenges/{id}\n * endpoint.\n * @param {Object} filtered Challenge object received from the\n * /challenges?filter=id={id} endpoint.\n * @param {Object} user Challenge object received from the\n * /members/{username}/challenges?filter=id={id} endpoint.\n * If action was fired for authenticated visitor, `user` will contain\n * details fetched specifically for the user (thus may include additional\n * data comparing to the standard API response for the challenge details,\n * stored in `filtered`).\n * @param {String} username Optional.\n * @return {Object} Normalized challenge object.\n */\nfunction normalizeChallengeDetails(challenge, filtered, user, username) {\n // Normalize exising data to make it consistent with the rest of the code\n var finalChallenge = (0, _extends3.default)({}, challenge, {\n\n id: challenge.challengeId,\n reliabilityBonus: _lodash2.default.get(filtered, 'reliabilityBonus', 0),\n status: (challenge.currentStatus || '').toUpperCase(),\n\n allPhases: [],\n currentPhases: [],\n name: challenge.challengeName || challenge.challengeTitle,\n projectId: Number(challenge.projectId),\n forumId: Number(challenge.forumId),\n introduction: challenge.introduction || '',\n detailedRequirements: challenge.detailedRequirements === 'null' ? '' : challenge.detailedRequirements,\n finalSubmissionGuidelines: challenge.finalSubmissionGuidelines === 'null' ? '' : challenge.finalSubmissionGuidelines,\n screeningScorecardId: Number(challenge.screeningScorecardId),\n reviewScorecardId: Number(challenge.reviewScorecardId),\n numberOfCheckpointsPrizes: challenge.numberOfCheckpointsPrizes,\n topCheckPointPrize: challenge.topCheckPointPrize,\n submissionsViewable: challenge.submissionsViewable || 'false',\n reviewType: challenge.reviewType,\n allowStockArt: challenge.allowStockArt === 'true',\n fileTypes: challenge.filetypes || [],\n environment: challenge.environment,\n codeRepo: challenge.codeRepo,\n forumLink: challenge.forumLink,\n submissionLimit: Number(challenge.submissionLimit) || 0,\n drPoints: challenge.digitalRunPoints,\n directUrl: challenge.directUrl,\n technologies: challenge.technologies || challenge.technology || [],\n platforms: challenge.platforms || [],\n prizes: challenge.prize || challenge.prizes || [],\n events: _lodash2.default.map(challenge.event, function (e) {\n return {\n eventName: e.eventShortDesc,\n eventId: e.id,\n description: e.eventDescription\n };\n }),\n terms: challenge.terms,\n submissions: challenge.submissions,\n track: _lodash2.default.toUpper(challenge.challengeCommunity),\n subTrack: challenge.subTrack,\n checkpoints: challenge.checkpoints,\n documents: challenge.documents || [],\n numRegistrants: challenge.numberOfRegistrants,\n numberOfCheckpointSubmissions: challenge.numberOfCheckpointSubmissions,\n registrants: challenge.registrants || []\n });\n\n // Winners have different field names, needs to be normalized to match `filtered` and `challenge`\n finalChallenge.winners = _lodash2.default.map(challenge.winners, function (winner, index) {\n return (0, _extends3.default)({}, winner, {\n handle: winner.submitter,\n placement: winner.rank || index + 1 // Legacy MMs do not have a rank but are sorted by points\n });\n });\n\n if (finalChallenge.subTrack === 'MARATHON_MATCH') {\n finalChallenge.track = 'DATA_SCIENCE';\n }\n\n // It's not clear if this will be the main event, will need to be investigated\n finalChallenge.mainEvent = finalChallenge.events[0] || {};\n\n /* It's unclear if these normalization steps are still required for `challenge` */\n // Fill missing data from filtered\n if (filtered) {\n var groups = {};\n if (filtered.groupIds) {\n filtered.groupIds.forEach(function (id) {\n groups[id] = true;\n });\n }\n\n _lodash2.default.merge(finalChallenge, {\n componentId: filtered.componentId,\n contestId: filtered.contestId,\n\n submissionEndDate: filtered.submissionEndDate, // Dates are not correct in `challenge`\n submissionEndTimestamp: filtered.submissionEndDate, // Dates are not correct in `challenge`\n\n /* Taking phases from filtered, because dates are not correct in `challenge` */\n allPhases: filtered.allPhases || [],\n\n /* Taking phases from filtered, because dates are not correct in `challenge` */\n currentPhases: filtered.currentPhases || [],\n\n /* `challenge` has incorrect value for numberOfSubmissions for some reason */\n numSubmissions: filtered.numSubmissions,\n groups: groups\n });\n }\n\n // Fill missing data from user\n if (user) {\n _lodash2.default.defaults(finalChallenge, {\n userDetails: user.userDetails\n });\n }\n\n // Fill some derived data\n var registrationOpen = _lodash2.default.some(finalChallenge.allPhases, function (phase) {\n return phase.phaseType === 'Registration' && phase.phaseStatus === 'Open';\n }) ? 'Yes' : 'No';\n _lodash2.default.defaults(finalChallenge, {\n communities: new _set2.default([_tc.COMPETITION_TRACKS[finalChallenge.track]]),\n registrationOpen: registrationOpen,\n users: username ? (0, _defineProperty3.default)({}, username, true) : {}\n });\n\n // A hot fix to show submissions for on-going challenges\n if (!finalChallenge.submissions || !finalChallenge.submissions.length) {\n finalChallenge.submissions = finalChallenge.registrants.filter(function (r) {\n return r.submissionDate || '';\n }).sort(function (a, b) {\n return (a.submissionDate || '').localeCompare(b.submissionDate || '');\n });\n }\n\n if (!finalChallenge.allPhases) finalChallenge.allPhases = [];\n if (!finalChallenge.track) finalChallenge.track = '';\n\n return finalChallenge;\n}\n\n/**\n * Normalizes a regular challenge object received from the backend.\n * NOTE: This function is copied from the existing code in the challenge listing\n * component. It is possible, that this normalization is not necessary after we\n * have moved to Topcoder API, but it is kept for now to minimize a risk of\n * breaking anything.\n * @todo Should be used only internally!\n * @param {Object} challenge Challenge object received from the backend.\n * @param {String} username Optional.\n */\nfunction normalizeChallenge(challenge, username) {\n var registrationOpen = challenge.allPhases.filter(function (d) {\n return d.phaseType === 'Registration';\n })[0].phaseStatus === 'Open' ? 'Yes' : 'No';\n var groups = {};\n if (challenge.groupIds) {\n challenge.groupIds.forEach(function (id) {\n groups[id] = true;\n });\n }\n /* eslint-disable no-param-reassign */\n if (!challenge.prizes) challenge.prizes = challenge.prize || [];\n if (!challenge.totalPrize) {\n challenge.totalPrize = challenge.prizes.reduce(function (sum, x) {\n return sum + x;\n }, 0);\n }\n if (!challenge.technologies) challenge.technologies = [];\n if (!challenge.platforms) challenge.platforms = [];\n\n if (challenge.subTrack === 'DEVELOP_MARATHON_MATCH') {\n challenge.track = 'DATA_SCIENCE';\n }\n /* eslint-enable no-param-reassign */\n\n _lodash2.default.defaults(challenge, {\n communities: new _set2.default([_tc.COMPETITION_TRACKS[challenge.track]]),\n groups: groups,\n registrationOpen: registrationOpen,\n submissionEndTimestamp: challenge.submissionEndDate,\n users: username ? (0, _defineProperty3.default)({}, username, true) : {}\n });\n}\nvar ChallengesService = function () {\n /**\n * Creates a new ChallengeService instance.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n */\n function ChallengesService(tokenV3, tokenV2) {\n var _this = this;\n\n (0, _classCallCheck3.default)(this, ChallengesService);\n\n /**\n * Private function being re-used in all methods related to getting\n * challenges. It handles query-related arguments in the uniform way:\n * @param {String} endpoint API endpoint, where the request will be send.\n * @param {Object} filters Optional. A map of filters to pass as `filter`\n * query parameter (this function takes care to stringify it properly).\n * @param {Object} params Optional. A map of any other parameters beside\n * `filter`.\n */\n var getChallenges = function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(endpoint) {\n var filters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var query, url, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n query = (0, _extends3.default)({\n filter: _qs2.default.stringify(filters, { encode: false })\n }, params);\n url = endpoint + '?' + _qs2.default.stringify(query);\n _context2.next = 4;\n return _this.private.api.get(url).then(checkError);\n\n case 4:\n res = _context2.sent;\n return _context2.abrupt('return', {\n challenges: res.content || [],\n totalCount: res.metadata.totalCount,\n meta: res.metadata\n });\n\n case 6:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, _this);\n }));\n\n return function getChallenges(_x2) {\n return _ref4.apply(this, arguments);\n };\n }();\n\n this.private = {\n api: (0, _api.getApi)('V4', tokenV3),\n apiV2: (0, _api.getApi)('V2', tokenV2),\n getChallenges: getChallenges,\n tokenV2: tokenV2,\n tokenV3: tokenV3\n };\n }\n\n /**\n * Activates the specified challenge.\n * @param {Number} challengeId\n * @return {Promise} Resolves to null value in case of success; otherwise it\n * is rejected.\n */\n\n\n (0, _createClass3.default)(ChallengesService, [{\n key: 'activate',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(challengeId) {\n var res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _context3.next = 2;\n return this.private.api.post('/challenges/' + challengeId + '/activate');\n\n case 2:\n res = _context3.sent;\n\n if (res.ok) {\n _context3.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n _context3.next = 7;\n return res.json();\n\n case 7:\n res = _context3.sent.result;\n\n if (!(res.status !== 200)) {\n _context3.next = 10;\n break;\n }\n\n throw new Error(res.content);\n\n case 10:\n return _context3.abrupt('return', res.content);\n\n case 11:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function activate(_x5) {\n return _ref5.apply(this, arguments);\n }\n\n return activate;\n }()\n\n /**\n * Closes the specified challenge.\n * @param {Number} challengeId\n * @param {Number} winnerId Optional. ID of the assignee to declare the\n * winner.\n * @return {Promise} Resolves to null value in case of success; otherwise it\n * is rejected.\n */\n\n }, {\n key: 'close',\n value: function () {\n var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(challengeId, winnerId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n url = '/challenges/' + challengeId + '/close';\n\n if (winnerId) url = url + '?winnerId=' + winnerId;\n _context4.next = 4;\n return this.private.api.post(url);\n\n case 4:\n res = _context4.sent;\n\n if (res.ok) {\n _context4.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context4.next = 9;\n return res.json();\n\n case 9:\n res = _context4.sent.result;\n\n if (!(res.status !== 200)) {\n _context4.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context4.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function close(_x6, _x7) {\n return _ref6.apply(this, arguments);\n }\n\n return close;\n }()\n\n /**\n * Creates a new payment task.\n * @param {Number} projectId\n * @param {Number} accountId Billing account ID.\n * @param {String} title\n * @param {String} description\n * @param {String} assignee\n * @param {Number} payment\n * @param {String} submissionGuidelines\n * @param {Number} copilotId\n * @param {Number} copilotFee\n * @param {?} technologies\n * @return {Promise} Resolves to the created challenge object (payment task).\n */\n\n }, {\n key: 'createTask',\n value: function () {\n var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(projectId, accountId, title, description, assignee, payment, submissionGuidelines, copilotId, copilotFee, technologies) {\n var payload, res;\n return _regenerator2.default.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n payload = {\n param: {\n assignees: [assignee],\n billingAccountId: accountId,\n confidentialityType: 'public',\n detailedRequirements: description,\n submissionGuidelines: submissionGuidelines,\n milestoneId: 1,\n name: title,\n technologies: technologies,\n prizes: payment ? [payment] : [],\n projectId: projectId,\n registrationStartsAt: (0, _moment2.default)().toISOString(),\n reviewType: 'INTERNAL',\n subTrack: 'FIRST_2_FINISH',\n task: true\n }\n };\n\n if (copilotId) {\n _lodash2.default.assign(payload.param, {\n copilotId: copilotId,\n copilotFee: copilotFee\n });\n }\n _context5.next = 4;\n return this.private.api.postJson('/challenges', payload);\n\n case 4:\n res = _context5.sent;\n\n if (res.ok) {\n _context5.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context5.next = 9;\n return res.json();\n\n case 9:\n res = _context5.sent.result;\n\n if (!(res.status !== 200)) {\n _context5.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context5.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function createTask(_x8, _x9, _x10, _x11, _x12, _x13, _x14, _x15, _x16, _x17) {\n return _ref7.apply(this, arguments);\n }\n\n return createTask;\n }()\n\n /**\n * Gets challenge details from Topcoder API.\n * NOTE: This function also uses API v2 and other endpoints for now, due\n * to some information is missing or\n * incorrect in the main endpoint. This may change in the future.\n * @param {Number|String} challengeId\n * @return {Promise} Resolves to the challenge object.\n */\n\n }, {\n key: 'getChallengeDetails',\n value: function () {\n var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(challengeId) {\n var challenge, challengeFiltered, username, challengeUser, finalChallenge;\n return _regenerator2.default.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n _context6.next = 2;\n return this.private.api.get('/challenges/' + challengeId).then(checkError).then(function (res) {\n return res.content;\n });\n\n case 2:\n challenge = _context6.sent;\n _context6.next = 5;\n return this.private.getChallenges('/challenges/', { id: challengeId }).then(function (res) {\n return res.challenges[0];\n });\n\n case 5:\n challengeFiltered = _context6.sent;\n username = this.private.tokenV3 && (0, _tcAccounts.decodeToken)(this.private.tokenV3).handle;\n _context6.t0 = username;\n\n if (!_context6.t0) {\n _context6.next = 12;\n break;\n }\n\n _context6.next = 11;\n return this.getUserChallenges(username, { id: challengeId }).then(function (res) {\n return res.challenges[0];\n }).catch(function () {\n return null;\n });\n\n case 11:\n _context6.t0 = _context6.sent;\n\n case 12:\n challengeUser = _context6.t0;\n finalChallenge = normalizeChallengeDetails(challenge, challengeFiltered, challengeUser, username);\n\n\n finalChallenge.fetchedWithAuth = Boolean(this.private.api.private.token);\n\n return _context6.abrupt('return', finalChallenge);\n\n case 16:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getChallengeDetails(_x18) {\n return _ref8.apply(this, arguments);\n }\n\n return getChallengeDetails;\n }()\n\n /**\n * Gets possible challenge subtracks.\n * @return {Promise} Resolves to the array of subtrack names.\n */\n\n }, {\n key: 'getChallengeSubtracks',\n value: function getChallengeSubtracks() {\n return this.private.api.get('/challenge-types').then(function (res) {\n return res.ok ? res.json() : new Error(res.statusText);\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : new Error(res.result.content);\n });\n }\n\n /**\n * Gets possible challenge tags (technologies).\n * @return {Promise} Resolves to the array of tag strings.\n */\n\n }, {\n key: 'getChallengeTags',\n value: function getChallengeTags() {\n return this.private.api.get('/technologies').then(function (res) {\n return res.ok ? res.json() : new Error(res.statusText);\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : new Error(res.result.content);\n });\n }\n\n /**\n * Gets challenges.\n * @param {Object} filters Optional.\n * @param {Object} params Optional.\n * @return {Promise} Resolves to the api response.\n */\n\n }, {\n key: 'getChallenges',\n value: function getChallenges(filters, params) {\n return this.private.getChallenges('/challenges/', filters, params).then(function (res) {\n res.challenges.forEach(function (item) {\n return normalizeChallenge(item);\n });\n return res;\n });\n }\n\n /**\n * Gets SRM matches.\n * @param {Object} params\n * @return {Promise}\n */\n\n }, {\n key: 'getSrms',\n value: function () {\n var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(params) {\n var res;\n return _regenerator2.default.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n _context7.next = 2;\n return this.private.api.get('/srms/?' + _qs2.default.stringify(params));\n\n case 2:\n res = _context7.sent;\n return _context7.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function getSrms(_x19) {\n return _ref9.apply(this, arguments);\n }\n\n return getSrms;\n }()\n\n /**\n * Gets challenges of the specified user.\n * @param {String} username User whose challenges we want to fetch.\n * @param {Object} filters Optional.\n * @param {Number} params Optional.\n * @return {Promise} Resolves to the api response.\n */\n\n }, {\n key: 'getUserChallenges',\n value: function getUserChallenges(username, filters, params) {\n var endpoint = '/members/' + username.toLowerCase() + '/challenges/';\n return this.private.getChallenges(endpoint, filters, params).then(function (res) {\n res.challenges.forEach(function (item) {\n return normalizeChallenge(item, username);\n });\n return res;\n });\n }\n\n /**\n * Gets SRM matches related to the user.\n * @param {String} handle\n * @param {Object} params\n * @return {Promise}\n */\n\n }, {\n key: 'getUserSrms',\n value: function () {\n var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(handle, params) {\n var url, res;\n return _regenerator2.default.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n url = '/members/' + handle + '/srms/?' + _qs2.default.stringify(params);\n _context8.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context8.sent;\n return _context8.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function getUserSrms(_x20, _x21) {\n return _ref10.apply(this, arguments);\n }\n\n return getUserSrms;\n }()\n\n /**\n * Registers user to the specified challenge.\n * @param {String} challengeId\n * @return {Promise}\n */\n\n }, {\n key: 'register',\n value: function () {\n var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(challengeId) {\n var endpoint, res;\n return _regenerator2.default.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n endpoint = '/challenges/' + challengeId + '/register';\n _context9.next = 3;\n return this.private.api.postJson(endpoint);\n\n case 3:\n res = _context9.sent;\n\n if (res.ok) {\n _context9.next = 6;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 6:\n return _context9.abrupt('return', res.json());\n\n case 7:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function register(_x22) {\n return _ref11.apply(this, arguments);\n }\n\n return register;\n }()\n\n /**\n * Unregisters user from the specified challenge.\n * @param {String} challengeId\n * @return {Promise}\n */\n\n }, {\n key: 'unregister',\n value: function () {\n var _ref12 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(challengeId) {\n var endpoint, res;\n return _regenerator2.default.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n endpoint = '/challenges/' + challengeId + '/unregister';\n _context10.next = 3;\n return this.private.api.post(endpoint);\n\n case 3:\n res = _context10.sent;\n\n if (res.ok) {\n _context10.next = 6;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 6:\n return _context10.abrupt('return', res.json());\n\n case 7:\n case 'end':\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function unregister(_x23) {\n return _ref12.apply(this, arguments);\n }\n\n return unregister;\n }()\n\n /**\n * Gets count of user's active challenges.\n * @param {String} handle Topcoder user handle.\n * @return {Action} Resolves to the api response.\n */\n\n }, {\n key: 'getActiveChallengesCount',\n value: function getActiveChallengesCount(handle) {\n var filter = { status: 'ACTIVE' };\n var params = { limit: 1, offset: 0 };\n return this.getUserChallenges(handle, filter, params).then(function (res) {\n return res.totalCount;\n });\n }\n\n /**\n * Submits a challenge submission. Uses APIV2 for Development submission\n * and APIV3 for Design submisisons.\n * @param {Object} body\n * @param {String} challengeId\n * @param {String} track Either DESIGN or DEVELOP\n * @return {Promise}\n */\n\n }, {\n key: 'submit',\n value: function submit(body, challengeId, track, onProgress) {\n var api = void 0;\n var contentType = void 0;\n var url = void 0;\n\n if (track === 'DESIGN') {\n api = this.private.api;\n\n contentType = 'application/json';\n url = '/submissions/'; // The submission info is contained entirely in the JSON body\n } else {\n api = this.private.apiV2;\n // contentType = 'multipart/form-data';\n contentType = null;\n url = '/develop/challenges/' + challengeId + '/upload';\n }\n\n return api.upload(url, {\n body: body,\n headers: { 'Content-Type': contentType },\n method: 'POST'\n }, onProgress).then(function (res) {\n var jres = JSON.parse(res);\n // Return result for Develop submission\n if (track === 'DEVELOP') {\n return jres;\n }\n // Design Submission requires an extra \"Processing\" POST\n var procId = jres.result.content.id;\n return api.upload('/submissions/' + procId + '/process/', {\n body: (0, _stringify2.default)({ param: jres.result.content }),\n headers: { 'Content-Type': contentType },\n method: 'POST'\n }, onProgress).then(function (procres) {\n return JSON.parse(procres);\n });\n }, function (err) {\n _logger2.default.error('Failed to submit to the challenge #' + challengeId, err);\n throw err;\n });\n }\n\n /**\n * Updates the challenge (saves the give challenge to the API).\n * @param {Object} challenge\n * @param {String} tokenV3\n * @return {Promise}\n */\n\n }, {\n key: 'updateChallenge',\n value: function () {\n var _ref13 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee11(challenge) {\n var URL, body, res;\n return _regenerator2.default.wrap(function _callee11$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n URL = '/challenges/' + challenge.id;\n body = { param: challenge };\n _context11.next = 4;\n return this.private.api.putJson(URL, body);\n\n case 4:\n res = _context11.sent;\n\n if (res.ok) {\n _context11.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context11.next = 9;\n return res.json();\n\n case 9:\n res = _context11.sent.result;\n\n if (!(res.status !== 200)) {\n _context11.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context11.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context11.stop();\n }\n }\n }, _callee11, this);\n }));\n\n function updateChallenge(_x24) {\n return _ref13.apply(this, arguments);\n }\n\n return updateChallenge;\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 ChallengesService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing challenges service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n * @return {ChallengesService} Challenges service object\n */\nfunction getService(tokenV3, tokenV2) {\n if (!lastInstance || lastInstance.private.tokenV3 !== tokenV3 || lastInstance.tokenV2 !== tokenV2) {\n lastInstance = new ChallengesService(tokenV3, tokenV2);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(ORDER_BY, 'ORDER_BY', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(normalizeChallengeDetails, 'normalizeChallengeDetails', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(normalizeChallenge, 'normalizeChallenge', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(checkError, 'checkError', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(ChallengesService, 'ChallengesService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/challenges.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-lib/./src/services/challenges.js?");
/***/ }),
@@ -934,7 +934,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.direct\"\n * @desc The Direct service takes care about communication with Direct APIs:\n * projects, billing accounts, copilots, all these stuff should be added here,\n * at least for now.\n */\n\n/**\n * Direct service class.\n */\nvar Direct = function () {\n /**\n * Creates a new {@link module:services.direct~Direct} instance.\n * @param {String} tokenV3 Optional. Topcoder auth token v3. Though optional,\n * most probably most, if not all, of the service functionality won't work\n * for non-authenticated visitors.\n */\n function Direct(tokenV3) {\n (0, _classCallCheck3.default)(this, Direct);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets details of the specified project.\n * @param {Number} projectId\n * @return {Promise} Resolves to the project details object.\n */\n\n\n (0, _createClass3.default)(Direct, [{\n key: 'getProjectDetails',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(projectId) {\n var res;\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 this.private.api.get('/direct/projects/' + projectId);\n\n case 2:\n res = _context.sent;\n\n if (res.ok) {\n _context.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n _context.next = 7;\n return res.json();\n\n case 7:\n res = _context.sent.result;\n\n if (!(res.status !== 200)) {\n _context.next = 10;\n break;\n }\n\n throw new Error(res.content);\n\n case 10:\n return _context.abrupt('return', res.content);\n\n case 11:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getProjectDetails(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getProjectDetails;\n }()\n\n /**\n * Gets user permissions on the specified project.\n * @param {Number|String} projectId\n * @param {String} tokenV3 Auth token for API v3.\n * @return {Promise} Resolves to the user permissions data.\n */\n\n }, {\n key: 'getProjectPermissions',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(projectId) {\n var URL, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n URL = '/direct/projects/' + projectId + '/permissions';\n _context2.next = 3;\n return this.private.api.get(URL);\n\n case 3:\n res = _context2.sent;\n\n if (res.ok) {\n _context2.next = 6;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 6:\n _context2.next = 8;\n return res.json();\n\n case 8:\n res = _context2.sent.result;\n\n if (!(res.status !== 200)) {\n _context2.next = 11;\n break;\n }\n\n throw new Error(res.content);\n\n case 11:\n return _context2.abrupt('return', res.content);\n\n case 12:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getProjectPermissions(_x2) {\n return _ref2.apply(this, arguments);\n }\n\n return getProjectPermissions;\n }()\n\n /**\n * Gets all projects the user can see.\n * @param {Object} query Optional. Query params for the request.\n * @return {Promise} Resolves to an array of project objects.\n */\n\n }, {\n key: 'getUserProjects',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(query) {\n var url, res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n url = '/direct/projects/user';\n\n if (query) url += '?' + _qs2.default.stringify(query);\n _context3.next = 4;\n return this.private.api.get(url);\n\n case 4:\n res = _context3.sent;\n\n if (res.ok) {\n _context3.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context3.next = 9;\n return res.json();\n\n case 9:\n res = _context3.sent.result;\n\n if (!(res.status !== 200)) {\n _context3.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context3.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function getUserProjects(_x3) {\n return _ref3.apply(this, arguments);\n }\n\n return getUserProjects;\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 Direct;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing {@link module:services.direct~Direct} service.\n * @param {String} tokenV3 Optional. Topcoder auth token v3.\n * @return {Direct} Direct service object.\n */\nfunction getService(tokenV3) {\n if (!lastInstance || lastInstance.private.tokenV3 !== tokenV3) {\n lastInstance = new Direct(tokenV3);\n }\n return lastInstance;\n}\n\nvar _default = undefined;\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(Direct, 'Direct', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.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-lib/./src/services/direct.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.direct\"\n * @desc The Direct service takes care about communication with Direct APIs:\n * projects, billing accounts, copilots, all these stuff should be added here,\n * at least for now.\n */\n\n/**\n * Direct service class.\n */\nvar Direct = function () {\n /**\n * Creates a new {@link module:services.direct~Direct} instance.\n * @param {String} tokenV3 Optional. Topcoder auth token v3. Though optional,\n * most probably most, if not all, of the service functionality won't work\n * for non-authenticated visitors.\n */\n function Direct(tokenV3) {\n (0, _classCallCheck3.default)(this, Direct);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets details of the specified project.\n * @param {Number} projectId\n * @return {Promise} Resolves to the project details object.\n */\n\n\n (0, _createClass3.default)(Direct, [{\n key: 'getProjectDetails',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(projectId) {\n var res;\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 this.private.api.get('/direct/projects/' + projectId);\n\n case 2:\n res = _context.sent;\n\n if (res.ok) {\n _context.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n _context.next = 7;\n return res.json();\n\n case 7:\n res = _context.sent.result;\n\n if (!(res.status !== 200)) {\n _context.next = 10;\n break;\n }\n\n throw new Error(res.content);\n\n case 10:\n return _context.abrupt('return', res.content);\n\n case 11:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getProjectDetails(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getProjectDetails;\n }()\n\n /**\n * Gets user permissions on the specified project.\n * @param {Number|String} projectId\n * @param {String} tokenV3 Auth token for API v3.\n * @return {Promise} Resolves to the user permissions data.\n */\n\n }, {\n key: 'getProjectPermissions',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(projectId) {\n var URL, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n URL = '/direct/projects/' + projectId + '/permissions';\n _context2.next = 3;\n return this.private.api.get(URL);\n\n case 3:\n res = _context2.sent;\n\n if (res.ok) {\n _context2.next = 6;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 6:\n _context2.next = 8;\n return res.json();\n\n case 8:\n res = _context2.sent.result;\n\n if (!(res.status !== 200)) {\n _context2.next = 11;\n break;\n }\n\n throw new Error(res.content);\n\n case 11:\n return _context2.abrupt('return', res.content);\n\n case 12:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getProjectPermissions(_x2) {\n return _ref2.apply(this, arguments);\n }\n\n return getProjectPermissions;\n }()\n\n /**\n * Gets all projects the user can see.\n * @param {Object} query Optional. Query params for the request.\n * @return {Promise} Resolves to an array of project objects.\n */\n\n }, {\n key: 'getUserProjects',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(query) {\n var url, res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n url = '/direct/projects/user';\n\n if (query) url += '?' + _qs2.default.stringify(query);\n _context3.next = 4;\n return this.private.api.get(url);\n\n case 4:\n res = _context3.sent;\n\n if (res.ok) {\n _context3.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context3.next = 9;\n return res.json();\n\n case 9:\n res = _context3.sent.result;\n\n if (!(res.status !== 200)) {\n _context3.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context3.abrupt('return', res.content);\n\n case 13:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function getUserProjects(_x3) {\n return _ref3.apply(this, arguments);\n }\n\n return getUserProjects;\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 Direct;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing {@link module:services.direct~Direct} service.\n * @param {String} tokenV3 Optional. Topcoder auth token v3.\n * @return {Direct} Direct service object.\n */\nfunction getService(tokenV3) {\n if (!lastInstance || lastInstance.private.tokenV3 !== tokenV3) {\n lastInstance = new Direct(tokenV3);\n }\n return lastInstance;\n}\n\nvar _default = undefined;\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(Direct, 'Direct', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/direct.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-lib/./src/services/direct.js?");
/***/ }),
@@ -946,7 +946,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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 _set = __webpack_require__(/*! babel-runtime/core-js/set */ \"babel-runtime/core-js/set\");\n\nvar _set2 = _interopRequireDefault(_set);\n\nexports.addDescendantGroups = addDescendantGroups;\nexports.checkGroupsStatus = checkGroupsStatus;\nexports.checkUserGroups = checkUserGroups;\nexports.reduceGroupIds = reduceGroupIds;\nexports.getService = getService;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.groups\"\n * @desc Service for communication with group-related part of Topcoder API.\n *\n * NOTE: Through this file, and in related contexts, by loading a user group,\n * or user groups data, we refer to loading the information about descendant\n * user groups; i.e. given some user group(s) we speak about loading the sub-\n * three of related child groups.\n *\n * By group maps we refer to the object having group IDs as the keys, and\n * group data objects as the values. Any group object included into a group map\n * has its \"subGroups\" array (if present) replaced by \"subGroupIds\", that lists\n * only the IDs of immediate child groups; actual child group objects from\n * \"subGroups\" are recursively added to the top level of the group map.\n * Also each group in the group map is timestamped to keep caching of\n * the loaded data.\n */\n\n/* The value of USER_GROUP_MAXAGE constant converted to [ms]. */\nvar USER_GROUP_MAXAGE = _topcoderReactUtils.config.USER_GROUP_MAXAGE * 1000;\n\n/**\n * Given an array of IDs (or a single ID) of user groups, and a map of known\n * user groups, it returns the array including all specified user groups, and\n * all their known descendant groups.\n * @param {String|String[]} groupIds\n * @param {Object} knownGroups\n * @return {String[]}\n */\nfunction addDescendantGroups(groupIds, knownGroups) {\n var res = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n var visitedGroupsIds = new _set2.default();\n var pos = 0;\n while (pos < res.length) {\n var id = res[pos];\n if (!visitedGroupsIds.has(id)) {\n visitedGroupsIds.add(id);\n var g = knownGroups[id];\n if (g && g.subGroupIds) res = res.concat(g.subGroupIds);\n }\n pos += 1;\n }\n return _lodash2.default.uniq(res);\n}\n\n/**\n * Splits the given list of group IDs into the lists of groups being loaded,\n * loaded, and others.\n * @param {String|String[]} groupIds ID, or an array of IDs, of the group(s) we\n * are interested in.\n * @param {Object} knownGroups Optional. The map of already known groups (some\n * of them may be outdated, though). This should be of the same format as the\n * object on \"groups.groups\" path of the Redux store. Defaults to empty object.\n * @param {Object} loadingGroups Optional. Set of groups beign loaded now. This\n * should be of the same format as the object on \"groups.loading\" path of the\n * Redux store. Defaults to empty object.\n * @return {Object} Resulting object may hold four arrays with group IDs from\n * \"groupIds\" (empty arrays will not be included into the result object):\n * - \"loaded\" - the groups that are present in \"knownGroups\" and are not\n * outdated;\n * - \"loading\" - the groups that are not present in \"knownGroups\" (or present,\n * but outdated); but they are already being loaded;\n * - \"missing\" - the groups that are not present in \"knownGroups\"\n * (or outdated), and are not being loaded.\n * - \"unknown\" - the groups that are absent in \"knownGroups\" map.\n */\nfunction checkGroupsStatus(groupIds) {\n var knownGroups = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var loadingGroups = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n var loaded = [];\n var loading = [];\n var missing = [];\n var unknown = [];\n var now = Date.now();\n var tested = new _set2.default();\n var ids = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n ids.forEach(function (id) {\n if (tested.has(id)) return;\n tested.add(id);\n var g = knownGroups[id];\n if (!g) unknown.push(id);\n if (g && (now - g.timestamp || 0) < USER_GROUP_MAXAGE) loaded.push(id);else if (loadingGroups[id]) loading.push(id);else missing.push(id);\n });\n return {\n loaded: loaded.length ? loaded : null,\n loading: loading.length ? loading : null,\n missing: missing.length ? missing : null,\n unknown: unknown.length ? unknown : null\n };\n}\n\n/**\n * Returns \"true\" if \"userGroups\" arrays includes any group specified by\n * \"groupIds\", or any group descendant from a group specified by \"groupIds\".\n * The is the map of known groups\n * @param {String|String[]} groupIds\n * @param {Object[]|String[]} userGroups Array of user's groups or their IDs.\n * @param {Object} knownGroups Map of known groups.\n * @return {Boolean}\n */\nfunction checkUserGroups(groupIds, userGroups, knownGroups) {\n var queue = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n if (!queue.length) return true;\n if (!userGroups.length) return false;\n\n /* Algorithmically, \"knownGroups\" stores, in compressed form, data on\n * known trees of user groups; and we want to check whether any of groups\n * from \"userGroups\" belong to sub-trees having groups from \"groupIds\" as\n * their roots. So, we do a breadth-frist search through the group trees. */\n var userGroupIds = new _set2.default();\n var visitedGroupIds = new _set2.default();\n userGroups.forEach(function (g) {\n return userGroupIds.add(_lodash2.default.isObject(g) ? g.id : g);\n });\n var pos = 0;\n while (pos < queue.length) {\n var id = queue[pos];\n if (userGroupIds.has(id)) return true;\n visitedGroupIds.add(id);\n var g = knownGroups[id];\n if (g && g.subGroupIds) {\n g.subGroupIds.forEach(function (sgId) {\n return !visitedGroupIds.has(sgId) ? queue.push(sgId) : null;\n });\n }\n pos += 1;\n }\n return false;\n}\n\n/**\n * Private. Handles given response from the groups API.\n * @param {Object} response\n * @return {Promise} On success resolves to the data fetched from the API.\n */\nfunction handleApiResponse(response) {\n if (!response.ok) throw new Error(response.statusText);\n return response.json().then(function (_ref) {\n var result = _ref.result;\n\n if (result.status !== 200) throw new Error(result.content);\n return result.content;\n });\n}\n\n/**\n * Private. Merges given user group (possibly a tree of user groups) into\n * groups map. This function intended only for internal use inside this module,\n * as it may mutate both arguments (hence, the corresponding ESLint rule is\n * disabled within this function), thus should be used only where it is safe.\n * For external use a similar function is provided by \"utils/tc\" module.\n * @param {Object} groups\n * @param {Object} group\n */\nfunction mergeGroup(groups, group) {\n /* eslint-disable no-param-reassign */\n var sg = group.subGroups;\n group.timestamp = Date.now();\n if (sg && sg.length) {\n group.subGroupIds = sg.map(function (g) {\n return g.id;\n });\n sg.forEach(function (g) {\n return mergeGroup(groups, g);\n });\n }\n delete group.subGroups;\n groups[group.id] = group;\n /* eslint-enable no-param-reassign */\n}\n\n/**\n * Given a group tree, reduces it to the array of all group IDs encountered in\n * the tree.\n * @param {Object} group\n * @return {String[]} Array of IDs.\n */\nfunction reduceGroupIds(_ref2) {\n var id = _ref2.id,\n subGroups = _ref2.subGroups;\n\n var res = [id];\n if (subGroups) {\n subGroups.forEach(function (g) {\n res = res.concat(reduceGroupIds(g));\n });\n }\n return res;\n}\n\n/**\n * Service class.\n */\n\nvar GroupService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function GroupService(tokenV3) {\n (0, _classCallCheck3.default)(this, GroupService);\n\n var now = Date.now();\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n cache: {\n groupTreeIds: {\n lastCleanUp: now,\n data: {}\n }\n },\n tokenV3: tokenV3\n };\n }\n\n /**\n * Adds new member to the group.\n * @param {String} groupId\n * @param {String} memberId\n * @param {String} membershipType\n * @return {Promise}\n */\n\n\n (0, _createClass3.default)(GroupService, [{\n key: 'addMember',\n value: function addMember(groupId, memberId, membershipType) {\n return this.private.api.postJson('/groups/' + groupId + '/members', {\n param: { memberId: memberId, membershipType: membershipType }\n }).then(handleApiResponse);\n }\n\n /**\n * Gets detailed information about the group.\n *\n * Notice, when \"withSubGroups\" argument is true (default) this method returns\n * a tree of group data objects, connected via their \"subGroups\" fields.\n * getMap(..) method below wraps this functionality in a more practical way!\n *\n * @param {String} groupId\n * @param {Boolean} withSubGroups Optional. Defaults to true. Specifies,\n * whether the response should information about sub-groups, if any.\n * @return {Promise} On success resolves to the group data object.\n */\n\n }, {\n key: 'getGroup',\n value: function getGroup(groupId) {\n var withSubGroups = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n var url = '/groups/' + groupId;\n if (withSubGroups) {\n url = url + '/getSubGroups?includeSubGroups=true&oneLevel=false';\n }\n return this.private.api.get(url).then(handleApiResponse);\n }\n\n /**\n * Gets detailed information about the specified user group(s) and their\n * descendant sub-groups.\n *\n * @param {String|String[]} groupIds Group ID, or an array of group IDs,\n * to query from Topcoder API.\n * @return {Promise} Resolves to the group map. That object will have group\n * IDs as the keys, and corresponding group data objects as the values. In\n * each group data object the \"subGroups\" field, if any, will be replaced by\n * \"subGroupIds\" (array of IDs of the immediate child groups), and the actual\n * data on the sub-groups will be moved to the root of the map object.\n * It also timestamps each fetched group.\n */\n\n }, {\n key: 'getGroupMap',\n value: function getGroupMap(groupIds) {\n var _this = this;\n\n var res = {};\n var seen = new _set2.default();\n var query = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n var promises = query.map(function (id) {\n if (seen.has(id)) return null;\n seen.add(id);\n return _this.getGroup(id).then(function (group) {\n return mergeGroup(res, group);\n }).catch(function (err) {\n /* In case we have failed to get some of the requested groups,\n * we just send error message to logs, and serve the result with\n * those groups that we managed to get. Otherwise it will be to\n * easy to break our code by minor mistakes in the group-related\n * configuration in the API and in the App. */\n _logger2.default.error('Failed to get user group #' + id, err);\n\n /* Empty group with timestamp is added to the result, as we still\n * want to cache the result, even if the result is that we cannot\n * load this group, at least for this visitor. */\n res[id] = { id: id, timestamp: Date.now() };\n });\n });\n return _promise2.default.all(promises).then(function () {\n return res;\n });\n }\n\n /**\n * Given a root group ID, returns an ID array that contains the root group ID,\n * and IDs of all descendant groups in the group (sub-)tree rooted at the\n * specified group.\n *\n * Results are cached inside the class instance to minimize the load on TC\n * Group API. To take advantage of that, be sure to keep and reuse the same\n * class instance.\n *\n * The reason to have such strange method and pay an extra attention to its\n * optimization for smaller API load is that it is essential for authorization\n * checks.\n *\n * @param {String} rootGroupId\n * @param {Number} maxage Optional. Max age [ms] of records served from the\n * cache. Defaults to 5 minutes.\n * @return {Promise} Resolves to ID array.\n */\n\n }, {\n key: 'getGroupTreeIds',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(rootGroupId) {\n var maxage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5 * 60 * 1000;\n var now, cache, CLEAN_UP_INTERVAL, cached, res;\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n now = Date.now();\n cache = this.private.cache.groupTreeIds;\n\n /* Clean-up: removes stale records from the cache. */\n\n CLEAN_UP_INTERVAL = 24 * 60 * 60 * 1000; // 1 day in ms.\n\n if (now - cache.lastCleanUp > CLEAN_UP_INTERVAL) {\n _lodash2.default.forOwn(cache, function (_ref4, key) {\n var timestamp = _ref4.timestamp;\n\n if (now - timestamp > CLEAN_UP_INTERVAL) delete cache[key];\n });\n cache.lastCleanUp = now;\n }\n\n /* If result is found in cache, and is fresh enough, return it. */\n cached = cache[rootGroupId];\n\n if (!(cached && now - cached.timestamp < maxage)) {\n _context.next = 7;\n break;\n }\n\n return _context.abrupt('return', _lodash2.default.clone(cached.data));\n\n case 7:\n _context.t0 = reduceGroupIds;\n _context.next = 10;\n return this.getGroup(rootGroupId);\n\n case 10:\n _context.t1 = _context.sent;\n res = (0, _context.t0)(_context.t1);\n\n cache[rootGroupId] = { data: res, timestamp: now };\n return _context.abrupt('return', _lodash2.default.clone(res));\n\n case 14:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getGroupTreeIds(_x4) {\n return _ref3.apply(this, arguments);\n }\n\n return getGroupTreeIds;\n }()\n\n /**\n * Gets group members.\n * @param {String} groupId\n * @return {Promise} On sucess resolves to the array of member objects,\n * which include user IDs, membership time, and some bookkeeping data.\n */\n\n }, {\n key: 'getMembers',\n value: function getMembers(groupId) {\n return this.private.api.get('/groups/' + groupId + '/members').then(handleApiResponse);\n }\n\n /**\n * Gets the number of members in the group.\n * @param {Number|String} groupId ID of the group.\n * @param {Boolean} withSubGroups Optional. When this flag is set, the count\n * will include members of sub-groups of the specified group.\n * @return {Promise} Resolves to the members count.\n */\n\n }, {\n key: 'getMembersCount',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(groupId, withSubGroups) {\n var url, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n url = '/groups/' + groupId + '/membersCount';\n\n if (withSubGroups) url += '?includeSubGroups=true';\n _context2.next = 4;\n return this.private.api.get(url);\n\n case 4:\n res = _context2.sent;\n\n if (res.ok) {\n _context2.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context2.next = 9;\n return res.json();\n\n case 9:\n res = _context2.sent.result;\n\n if (res.success) {\n _context2.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context2.abrupt('return', Number(res.content));\n\n case 13:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getMembersCount(_x6, _x7) {\n return _ref5.apply(this, arguments);\n }\n\n return getMembersCount;\n }()\n\n /**\n * Returns TC Auth Token V3 used by the service instance.\n * @return {String} Token.\n */\n\n }, {\n key: 'getTokenV3',\n value: function getTokenV3() {\n return this.private.tokenV3;\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 GroupService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing instance of challenge service, which works with\n * the specified auth token.\n * @param {String} tokenV3 Optional. Topcoder API v3 auth token.\n * @return {GroupService} Instance of the service.\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new GroupService(tokenV3);\n }\n return lastInstance;\n}\n\nvar _default = undefined;\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(USER_GROUP_MAXAGE, 'USER_GROUP_MAXAGE', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(addDescendantGroups, 'addDescendantGroups', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(checkGroupsStatus, 'checkGroupsStatus', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(checkUserGroups, 'checkUserGroups', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(handleApiResponse, 'handleApiResponse', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(mergeGroup, 'mergeGroup', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(reduceGroupIds, 'reduceGroupIds', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(GroupService, 'GroupService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.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-lib/./src/services/groups.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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 _set = __webpack_require__(/*! babel-runtime/core-js/set */ \"babel-runtime/core-js/set\");\n\nvar _set2 = _interopRequireDefault(_set);\n\nexports.addDescendantGroups = addDescendantGroups;\nexports.checkGroupsStatus = checkGroupsStatus;\nexports.checkUserGroups = checkUserGroups;\nexports.reduceGroupIds = reduceGroupIds;\nexports.getService = getService;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.groups\"\n * @desc Service for communication with group-related part of Topcoder API.\n *\n * NOTE: Through this file, and in related contexts, by loading a user group,\n * or user groups data, we refer to loading the information about descendant\n * user groups; i.e. given some user group(s) we speak about loading the sub-\n * three of related child groups.\n *\n * By group maps we refer to the object having group IDs as the keys, and\n * group data objects as the values. Any group object included into a group map\n * has its \"subGroups\" array (if present) replaced by \"subGroupIds\", that lists\n * only the IDs of immediate child groups; actual child group objects from\n * \"subGroups\" are recursively added to the top level of the group map.\n * Also each group in the group map is timestamped to keep caching of\n * the loaded data.\n */\n\n/* The value of USER_GROUP_MAXAGE constant converted to [ms]. */\nvar USER_GROUP_MAXAGE = _topcoderReactUtils.config.USER_GROUP_MAXAGE * 1000;\n\n/**\n * Given an array of IDs (or a single ID) of user groups, and a map of known\n * user groups, it returns the array including all specified user groups, and\n * all their known descendant groups.\n * @param {String|String[]} groupIds\n * @param {Object} knownGroups\n * @return {String[]}\n */\nfunction addDescendantGroups(groupIds, knownGroups) {\n var res = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n var visitedGroupsIds = new _set2.default();\n var pos = 0;\n while (pos < res.length) {\n var id = res[pos];\n if (!visitedGroupsIds.has(id)) {\n visitedGroupsIds.add(id);\n var g = knownGroups[id];\n if (g && g.subGroupIds) res = res.concat(g.subGroupIds);\n }\n pos += 1;\n }\n return _lodash2.default.uniq(res);\n}\n\n/**\n * Splits the given list of group IDs into the lists of groups being loaded,\n * loaded, and others.\n * @param {String|String[]} groupIds ID, or an array of IDs, of the group(s) we\n * are interested in.\n * @param {Object} knownGroups Optional. The map of already known groups (some\n * of them may be outdated, though). This should be of the same format as the\n * object on \"groups.groups\" path of the Redux store. Defaults to empty object.\n * @param {Object} loadingGroups Optional. Set of groups beign loaded now. This\n * should be of the same format as the object on \"groups.loading\" path of the\n * Redux store. Defaults to empty object.\n * @return {Object} Resulting object may hold four arrays with group IDs from\n * \"groupIds\" (empty arrays will not be included into the result object):\n * - \"loaded\" - the groups that are present in \"knownGroups\" and are not\n * outdated;\n * - \"loading\" - the groups that are not present in \"knownGroups\" (or present,\n * but outdated); but they are already being loaded;\n * - \"missing\" - the groups that are not present in \"knownGroups\"\n * (or outdated), and are not being loaded.\n * - \"unknown\" - the groups that are absent in \"knownGroups\" map.\n */\nfunction checkGroupsStatus(groupIds) {\n var knownGroups = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n var loadingGroups = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n\n var loaded = [];\n var loading = [];\n var missing = [];\n var unknown = [];\n var now = Date.now();\n var tested = new _set2.default();\n var ids = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n ids.forEach(function (id) {\n if (tested.has(id)) return;\n tested.add(id);\n var g = knownGroups[id];\n if (!g) unknown.push(id);\n if (g && (now - g.timestamp || 0) < USER_GROUP_MAXAGE) loaded.push(id);else if (loadingGroups[id]) loading.push(id);else missing.push(id);\n });\n return {\n loaded: loaded.length ? loaded : null,\n loading: loading.length ? loading : null,\n missing: missing.length ? missing : null,\n unknown: unknown.length ? unknown : null\n };\n}\n\n/**\n * Returns \"true\" if \"userGroups\" arrays includes any group specified by\n * \"groupIds\", or any group descendant from a group specified by \"groupIds\".\n * The is the map of known groups\n * @param {String|String[]} groupIds\n * @param {Object[]|String[]} userGroups Array of user's groups or their IDs.\n * @param {Object} knownGroups Map of known groups.\n * @return {Boolean}\n */\nfunction checkUserGroups(groupIds, userGroups, knownGroups) {\n var queue = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n if (!queue.length) return true;\n if (!userGroups.length) return false;\n\n /* Algorithmically, \"knownGroups\" stores, in compressed form, data on\n * known trees of user groups; and we want to check whether any of groups\n * from \"userGroups\" belong to sub-trees having groups from \"groupIds\" as\n * their roots. So, we do a breadth-frist search through the group trees. */\n var userGroupIds = new _set2.default();\n var visitedGroupIds = new _set2.default();\n userGroups.forEach(function (g) {\n return userGroupIds.add(_lodash2.default.isObject(g) ? g.id : g);\n });\n var pos = 0;\n while (pos < queue.length) {\n var id = queue[pos];\n if (userGroupIds.has(id)) return true;\n visitedGroupIds.add(id);\n var g = knownGroups[id];\n if (g && g.subGroupIds) {\n g.subGroupIds.forEach(function (sgId) {\n return !visitedGroupIds.has(sgId) ? queue.push(sgId) : null;\n });\n }\n pos += 1;\n }\n return false;\n}\n\n/**\n * Private. Handles given response from the groups API.\n * @param {Object} response\n * @return {Promise} On success resolves to the data fetched from the API.\n */\nfunction handleApiResponse(response) {\n if (!response.ok) throw new Error(response.statusText);\n return response.json().then(function (_ref) {\n var result = _ref.result;\n\n if (result.status !== 200) throw new Error(result.content);\n return result.content;\n });\n}\n\n/**\n * Private. Merges given user group (possibly a tree of user groups) into\n * groups map. This function intended only for internal use inside this module,\n * as it may mutate both arguments (hence, the corresponding ESLint rule is\n * disabled within this function), thus should be used only where it is safe.\n * For external use a similar function is provided by \"utils/tc\" module.\n * @param {Object} groups\n * @param {Object} group\n */\nfunction mergeGroup(groups, group) {\n /* eslint-disable no-param-reassign */\n var sg = group.subGroups;\n group.timestamp = Date.now();\n if (sg && sg.length) {\n group.subGroupIds = sg.map(function (g) {\n return g.id;\n });\n sg.forEach(function (g) {\n return mergeGroup(groups, g);\n });\n }\n delete group.subGroups;\n groups[group.id] = group;\n /* eslint-enable no-param-reassign */\n}\n\n/**\n * Given a group tree, reduces it to the array of all group IDs encountered in\n * the tree.\n * @param {Object} group\n * @return {String[]} Array of IDs.\n */\nfunction reduceGroupIds(_ref2) {\n var id = _ref2.id,\n subGroups = _ref2.subGroups;\n\n var res = [id];\n if (subGroups) {\n subGroups.forEach(function (g) {\n res = res.concat(reduceGroupIds(g));\n });\n }\n return res;\n}\n\n/**\n * Service class.\n */\n\nvar GroupService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function GroupService(tokenV3) {\n (0, _classCallCheck3.default)(this, GroupService);\n\n var now = Date.now();\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n cache: {\n groupTreeIds: {\n lastCleanUp: now,\n data: {}\n }\n },\n tokenV3: tokenV3\n };\n }\n\n /**\n * Adds new member to the group.\n * @param {String} groupId\n * @param {String} memberId\n * @param {String} membershipType\n * @return {Promise}\n */\n\n\n (0, _createClass3.default)(GroupService, [{\n key: 'addMember',\n value: function addMember(groupId, memberId, membershipType) {\n return this.private.api.postJson('/groups/' + groupId + '/members', {\n param: { memberId: memberId, membershipType: membershipType }\n }).then(handleApiResponse);\n }\n\n /**\n * Gets detailed information about the group.\n *\n * Notice, when \"withSubGroups\" argument is true (default) this method returns\n * a tree of group data objects, connected via their \"subGroups\" fields.\n * getMap(..) method below wraps this functionality in a more practical way!\n *\n * @param {String} groupId\n * @param {Boolean} withSubGroups Optional. Defaults to true. Specifies,\n * whether the response should information about sub-groups, if any.\n * @return {Promise} On success resolves to the group data object.\n */\n\n }, {\n key: 'getGroup',\n value: function getGroup(groupId) {\n var withSubGroups = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n var url = '/groups/' + groupId;\n if (withSubGroups) {\n url = url + '/getSubGroups?includeSubGroups=true&oneLevel=false';\n }\n return this.private.api.get(url).then(handleApiResponse);\n }\n\n /**\n * Gets detailed information about the specified user group(s) and their\n * descendant sub-groups.\n *\n * @param {String|String[]} groupIds Group ID, or an array of group IDs,\n * to query from Topcoder API.\n * @return {Promise} Resolves to the group map. That object will have group\n * IDs as the keys, and corresponding group data objects as the values. In\n * each group data object the \"subGroups\" field, if any, will be replaced by\n * \"subGroupIds\" (array of IDs of the immediate child groups), and the actual\n * data on the sub-groups will be moved to the root of the map object.\n * It also timestamps each fetched group.\n */\n\n }, {\n key: 'getGroupMap',\n value: function getGroupMap(groupIds) {\n var _this = this;\n\n var res = {};\n var seen = new _set2.default();\n var query = _lodash2.default.isArray(groupIds) ? groupIds : [groupIds];\n var promises = query.map(function (id) {\n if (seen.has(id)) return null;\n seen.add(id);\n return _this.getGroup(id).then(function (group) {\n return mergeGroup(res, group);\n }).catch(function (err) {\n /* In case we have failed to get some of the requested groups,\n * we just send error message to logs, and serve the result with\n * those groups that we managed to get. Otherwise it will be to\n * easy to break our code by minor mistakes in the group-related\n * configuration in the API and in the App. */\n _logger2.default.error('Failed to get user group #' + id, err);\n\n /* Empty group with timestamp is added to the result, as we still\n * want to cache the result, even if the result is that we cannot\n * load this group, at least for this visitor. */\n res[id] = { id: id, timestamp: Date.now() };\n });\n });\n return _promise2.default.all(promises).then(function () {\n return res;\n });\n }\n\n /**\n * Given a root group ID, returns an ID array that contains the root group ID,\n * and IDs of all descendant groups in the group (sub-)tree rooted at the\n * specified group.\n *\n * Results are cached inside the class instance to minimize the load on TC\n * Group API. To take advantage of that, be sure to keep and reuse the same\n * class instance.\n *\n * The reason to have such strange method and pay an extra attention to its\n * optimization for smaller API load is that it is essential for authorization\n * checks.\n *\n * @param {String} rootGroupId\n * @param {Number} maxage Optional. Max age [ms] of records served from the\n * cache. Defaults to 5 minutes.\n * @return {Promise} Resolves to ID array.\n */\n\n }, {\n key: 'getGroupTreeIds',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(rootGroupId) {\n var maxage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5 * 60 * 1000;\n var now, cache, CLEAN_UP_INTERVAL, cached, res;\n return _regenerator2.default.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n now = Date.now();\n cache = this.private.cache.groupTreeIds;\n\n /* Clean-up: removes stale records from the cache. */\n\n CLEAN_UP_INTERVAL = 24 * 60 * 60 * 1000; // 1 day in ms.\n\n if (now - cache.lastCleanUp > CLEAN_UP_INTERVAL) {\n _lodash2.default.forOwn(cache, function (_ref4, key) {\n var timestamp = _ref4.timestamp;\n\n if (now - timestamp > CLEAN_UP_INTERVAL) delete cache[key];\n });\n cache.lastCleanUp = now;\n }\n\n /* If result is found in cache, and is fresh enough, return it. */\n cached = cache[rootGroupId];\n\n if (!(cached && now - cached.timestamp < maxage)) {\n _context.next = 7;\n break;\n }\n\n return _context.abrupt('return', _lodash2.default.clone(cached.data));\n\n case 7:\n _context.t0 = reduceGroupIds;\n _context.next = 10;\n return this.getGroup(rootGroupId);\n\n case 10:\n _context.t1 = _context.sent;\n res = (0, _context.t0)(_context.t1);\n\n cache[rootGroupId] = { data: res, timestamp: now };\n return _context.abrupt('return', _lodash2.default.clone(res));\n\n case 14:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getGroupTreeIds(_x4) {\n return _ref3.apply(this, arguments);\n }\n\n return getGroupTreeIds;\n }()\n\n /**\n * Gets group members.\n * @param {String} groupId\n * @return {Promise} On sucess resolves to the array of member objects,\n * which include user IDs, membership time, and some bookkeeping data.\n */\n\n }, {\n key: 'getMembers',\n value: function getMembers(groupId) {\n return this.private.api.get('/groups/' + groupId + '/members').then(handleApiResponse);\n }\n\n /**\n * Gets the number of members in the group.\n * @param {Number|String} groupId ID of the group.\n * @param {Boolean} withSubGroups Optional. When this flag is set, the count\n * will include members of sub-groups of the specified group.\n * @return {Promise} Resolves to the members count.\n */\n\n }, {\n key: 'getMembersCount',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(groupId, withSubGroups) {\n var url, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n url = '/groups/' + groupId + '/membersCount';\n\n if (withSubGroups) url += '?includeSubGroups=true';\n _context2.next = 4;\n return this.private.api.get(url);\n\n case 4:\n res = _context2.sent;\n\n if (res.ok) {\n _context2.next = 7;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 7:\n _context2.next = 9;\n return res.json();\n\n case 9:\n res = _context2.sent.result;\n\n if (res.success) {\n _context2.next = 12;\n break;\n }\n\n throw new Error(res.content);\n\n case 12:\n return _context2.abrupt('return', Number(res.content));\n\n case 13:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getMembersCount(_x6, _x7) {\n return _ref5.apply(this, arguments);\n }\n\n return getMembersCount;\n }()\n\n /**\n * Returns TC Auth Token V3 used by the service instance.\n * @return {String} Token.\n */\n\n }, {\n key: 'getTokenV3',\n value: function getTokenV3() {\n return this.private.tokenV3;\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 GroupService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing instance of challenge service, which works with\n * the specified auth token.\n * @param {String} tokenV3 Optional. Topcoder API v3 auth token.\n * @return {GroupService} Instance of the service.\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new GroupService(tokenV3);\n }\n return lastInstance;\n}\n\nvar _default = undefined;\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(USER_GROUP_MAXAGE, 'USER_GROUP_MAXAGE', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(addDescendantGroups, 'addDescendantGroups', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(checkGroupsStatus, 'checkGroupsStatus', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(checkUserGroups, 'checkUserGroups', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(handleApiResponse, 'handleApiResponse', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(mergeGroup, 'mergeGroup', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(reduceGroupIds, 'reduceGroupIds', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(GroupService, 'GroupService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/groups.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-lib/./src/services/groups.js?");
/***/ }),
@@ -970,7 +970,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.looker\"\n * @desc This module provides a service to get look data json\n * via API V4.\n */\n\n\n/**\n * Service class.\n */\nvar LookerService = function () {\n /**\n * @param {String} tokenV4 Optional. Auth token for Topcoder API v4.\n */\n function LookerService(tokenV4) {\n (0, _classCallCheck3.default)(this, LookerService);\n\n this.private = {\n api: (0, _api.getApiV4)(tokenV4),\n tokenV4: tokenV4\n };\n }\n\n /**\n * Get json look data by id.\n * @param {String} lookerId Look id.\n * @return {Promise} Resolves to the json data.\n */\n\n\n (0, _createClass3.default)(LookerService, [{\n key: 'getLooker',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(lookerId) {\n var res;\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 this.private.api.get('/looks/' + lookerId + '/run/json');\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getLookerApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getLooker(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getLooker;\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 LookerService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing looker service.\n * @param {String} tokenV4 Optional. Auth token for Topcoder API v4.\n * @return {LookerService} looker service object\n */\nfunction getService(tokenV4) {\n if (!lastInstance || tokenV4 !== lastInstance.private.tokenV4) {\n lastInstance = new LookerService(tokenV4);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(LookerService, 'LookerService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.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-lib/./src/services/looker.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.looker\"\n * @desc This module provides a service to get look data json via Topcoder API.\n */\n\n\n/**\n * Service class.\n */\nvar LookerService = function () {\n /**\n * @param {String} token Optional. Auth token for Topcoder API.\n */\n function LookerService(token) {\n (0, _classCallCheck3.default)(this, LookerService);\n\n this.private = {\n api: (0, _api.getApi)('V4', token),\n token: token\n };\n }\n\n /**\n * Get json look data by id.\n * @param {String} lookerId Look id.\n * @return {Promise} Resolves to the json data.\n */\n\n\n (0, _createClass3.default)(LookerService, [{\n key: 'getLooker',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(lookerId) {\n var res;\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 this.private.api.get('/looks/' + lookerId + '/run/json');\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getLookerApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getLooker(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getLooker;\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 LookerService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing looker service.\n * @param {String} token Optional. Auth token for Topcoder API.\n * @return {LookerService} looker service object\n */\nfunction getService(token) {\n if (!lastInstance || token !== lastInstance.private.token) {\n lastInstance = new LookerService(token);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(LookerService, 'LookerService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/looker.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-lib/./src/services/looker.js?");
/***/ }),
@@ -982,7 +982,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.lookup\"\n * @desc This module provides a service to get lookup data from Topcoder\n * via API V3.\n */\n\n\nvar LookupService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function LookupService(tokenV3) {\n (0, _classCallCheck3.default)(this, LookupService);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets tags.\n * @param {Object} params Parameters\n * @return {Promise} Resolves to the tags.\n */\n\n\n (0, _createClass3.default)(LookupService, [{\n key: 'getTags',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(params) {\n var res;\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 this.private.api.get('/tags/?' + _qs2.default.stringify(params));\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getTags(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getTags;\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 LookupService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing lookup service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {LookupService} Lookup service object\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new LookupService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(LookupService, 'LookupService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.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-lib/./src/services/lookup.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.lookup\"\n * @desc This module provides a service to get lookup data from Topcoder\n * via API V3.\n */\n\n\nvar LookupService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function LookupService(tokenV3) {\n (0, _classCallCheck3.default)(this, LookupService);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets tags.\n * @param {Object} params Parameters\n * @return {Promise} Resolves to the tags.\n */\n\n\n (0, _createClass3.default)(LookupService, [{\n key: 'getTags',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(params) {\n var res;\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 this.private.api.get('/tags/?' + _qs2.default.stringify(params));\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getTags(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getTags;\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 LookupService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing lookup service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {LookupService} Lookup service object\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new LookupService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(LookupService, 'LookupService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/lookup.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-lib/./src/services/lookup.js?");
/***/ }),
@@ -994,7 +994,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\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 _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\nexports.getService = getService;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.members\"\n * @desc This module provides a service for searching for Topcoder\n * members via API V3.\n */\n\n/* global XMLHttpRequest */\n\n\n/**\n * Service class.\n */\nvar MembersService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function MembersService(tokenV3) {\n (0, _classCallCheck3.default)(this, MembersService);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets member's financial information.\n * @param {String} handle User handle.\n * @return {Promise} Resolves to the financial information object.\n */\n\n\n (0, _createClass3.default)(MembersService, [{\n key: 'getMemberFinances',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(handle) {\n var res;\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 this.private.api.get('/members/' + handle + '/financial');\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getMemberFinances(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getMemberFinances;\n }()\n\n /**\n * Gets public information on a member.\n *\n * This method does not require any authorization.\n *\n * @param {String} handle Member handle.\n * @return {Promise} Resolves to the data object.\n */\n\n }, {\n key: 'getMemberInfo',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(handle) {\n var res;\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 this.private.api.get('/members/' + handle);\n\n case 2:\n res = _context2.sent;\n return _context2.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getMemberInfo(_x2) {\n return _ref2.apply(this, arguments);\n }\n\n return getMemberInfo;\n }()\n\n /**\n * Gets member external account info.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getExternalAccounts',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _context3.next = 2;\n return this.private.api.get('/members/' + handle + '/externalAccounts');\n\n case 2:\n res = _context3.sent;\n return _context3.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function getExternalAccounts(_x3) {\n return _ref3.apply(this, arguments);\n }\n\n return getExternalAccounts;\n }()\n\n /**\n * Gets member external links.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getExternalLinks',\n value: function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return this.private.api.get('/members/' + handle + '/externalLinks');\n\n case 2:\n res = _context4.sent;\n return _context4.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function getExternalLinks(_x4) {\n return _ref4.apply(this, arguments);\n }\n\n return getExternalLinks;\n }()\n\n /**\n * Gets member skills.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getSkills',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n _context5.next = 2;\n return this.private.api.get('/members/' + handle + '/skills');\n\n case 2:\n res = _context5.sent;\n return _context5.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function getSkills(_x5) {\n return _ref5.apply(this, arguments);\n }\n\n return getSkills;\n }()\n\n /**\n * Gets member statistics.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getStats',\n value: function () {\n var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n _context6.next = 2;\n return this.private.api.get('/members/' + handle + '/stats');\n\n case 2:\n res = _context6.sent;\n return _context6.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getStats(_x6) {\n return _ref6.apply(this, arguments);\n }\n\n return getStats;\n }()\n\n /**\n * Gets member statistics history\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getStatsHistory',\n value: function () {\n var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n _context7.next = 2;\n return this.private.api.get('/members/' + handle + '/stats/history');\n\n case 2:\n res = _context7.sent;\n return _context7.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function getStatsHistory(_x7) {\n return _ref7.apply(this, arguments);\n }\n\n return getStatsHistory;\n }()\n\n /**\n * Gets member statistics distribution\n * @param {String} handle\n * @param {String} track\n * @param {String} subTrack\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getStatsDistribution',\n value: function () {\n var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(handle, track, subTrack) {\n var res;\n return _regenerator2.default.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n _context8.next = 2;\n return this.private.api.get('/members/stats/distribution?filter=' + encodeURIComponent(_qs2.default.stringify({\n track: track,\n subTrack: subTrack\n })));\n\n case 2:\n res = _context8.sent;\n return _context8.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function getStatsDistribution(_x8, _x9, _x10) {\n return _ref8.apply(this, arguments);\n }\n\n return getStatsDistribution;\n }()\n\n /**\n * Gets a list of suggested member names for the supplied partial.\n *\n * WARNING: This method requires v3 authorization.\n *\n * @param {String} keyword Partial string to find suggestions for\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'getMemberSuggestions',\n value: function () {\n var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(keyword) {\n var res;\n return _regenerator2.default.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n _context9.next = 2;\n return this.private.api.get('/members/_suggest/' + keyword);\n\n case 2:\n res = _context9.sent;\n return _context9.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function getMemberSuggestions(_x11) {\n return _ref9.apply(this, arguments);\n }\n\n return getMemberSuggestions;\n }()\n\n /**\n * Adds external web link for member.\n * @param {String} userHandle The user handle\n * @param {String} webLink The external web link\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'addWebLink',\n value: function () {\n var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(userHandle, webLink) {\n var res;\n return _regenerator2.default.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n _context10.next = 2;\n return this.private.api.postJson('/members/' + userHandle + '/externalLinks', { param: { url: webLink } });\n\n case 2:\n res = _context10.sent;\n return _context10.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function addWebLink(_x12, _x13) {\n return _ref10.apply(this, arguments);\n }\n\n return addWebLink;\n }()\n\n /**\n * Deletes external web link for member.\n * @param {String} userHandle The user handle\n * @param {String} webLinkHandle The external web link handle\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'deleteWebLink',\n value: function () {\n var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee11(userHandle, webLinkHandle) {\n var body, res;\n return _regenerator2.default.wrap(function _callee11$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n body = {\n param: {\n handle: webLinkHandle\n }\n };\n _context11.next = 3;\n return this.private.api.delete('/members/' + userHandle + '/externalLinks/' + webLinkHandle, (0, _stringify2.default)(body));\n\n case 3:\n res = _context11.sent;\n return _context11.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context11.stop();\n }\n }\n }, _callee11, this);\n }));\n\n function deleteWebLink(_x14, _x15) {\n return _ref11.apply(this, arguments);\n }\n\n return deleteWebLink;\n }()\n\n /**\n * Adds user skill.\n * @param {String} handle Topcoder user handle\n * @param {Number} skillTagId Skill tag id\n * @return {Promise} Resolves to operation result\n */\n\n }, {\n key: 'addSkill',\n value: function () {\n var _ref12 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee12(handle, skillTagId) {\n var body, res;\n return _regenerator2.default.wrap(function _callee12$(_context12) {\n while (1) {\n switch (_context12.prev = _context12.next) {\n case 0:\n body = {\n param: {\n skills: (0, _defineProperty3.default)({}, skillTagId, {\n hidden: false\n })\n }\n };\n _context12.next = 3;\n return this.private.api.patchJson('/members/' + handle + '/skills', body);\n\n case 3:\n res = _context12.sent;\n return _context12.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context12.stop();\n }\n }\n }, _callee12, this);\n }));\n\n function addSkill(_x16, _x17) {\n return _ref12.apply(this, arguments);\n }\n\n return addSkill;\n }()\n\n /**\n * Hides user skill.\n * @param {String} handle Topcoder user handle\n * @param {Number} skillTagId Skill tag id\n * @return {Promise} Resolves to operation result\n */\n\n }, {\n key: 'hideSkill',\n value: function () {\n var _ref13 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee13(handle, skillTagId) {\n var body, res;\n return _regenerator2.default.wrap(function _callee13$(_context13) {\n while (1) {\n switch (_context13.prev = _context13.next) {\n case 0:\n body = {\n param: {\n skills: (0, _defineProperty3.default)({}, skillTagId, {\n hidden: true\n })\n }\n };\n _context13.next = 3;\n return this.private.api.fetch('/members/' + handle + '/skills', {\n body: (0, _stringify2.default)(body),\n method: 'PATCH'\n });\n\n case 3:\n res = _context13.sent;\n return _context13.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context13.stop();\n }\n }\n }, _callee13, this);\n }));\n\n function hideSkill(_x18, _x19) {\n return _ref13.apply(this, arguments);\n }\n\n return hideSkill;\n }()\n\n /**\n * Updates member profile.\n * @param {Object} profile The profile to update.\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'updateMemberProfile',\n value: function () {\n var _ref14 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee14(profile) {\n var changeEmail, url, res;\n return _regenerator2.default.wrap(function _callee14$(_context14) {\n while (1) {\n switch (_context14.prev = _context14.next) {\n case 0:\n changeEmail = !!(_lodash2.default.get(profile, 'successUrl') || _lodash2.default.get(profile, 'failUrl'));\n url = '/members/' + profile.handle;\n\n if (changeEmail) {\n url = url + '?successUrl=' + _lodash2.default.get(profile, 'successUrl') + '&failUrl=' + _lodash2.default.get(profile, 'failUrl');\n }\n _context14.next = 5;\n return this.private.api.putJson(url, { param: _lodash2.default.omit(profile, ['successUrl', 'failUrl']) });\n\n case 5:\n res = _context14.sent;\n return _context14.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 7:\n case 'end':\n return _context14.stop();\n }\n }\n }, _callee14, this);\n }));\n\n function updateMemberProfile(_x20) {\n return _ref14.apply(this, arguments);\n }\n\n return updateMemberProfile;\n }()\n\n /**\n * Gets presigned url for member photo file.\n * @param {String} userHandle The user handle\n * @param {File} file The file to get its presigned url\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'getPresignedUrl',\n value: function () {\n var _ref15 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee15(userHandle, file) {\n var res, payload;\n return _regenerator2.default.wrap(function _callee15$(_context15) {\n while (1) {\n switch (_context15.prev = _context15.next) {\n case 0:\n _context15.next = 2;\n return this.private.api.postJson('/members/' + userHandle + '/photoUploadUrl', { param: { contentType: file.type } });\n\n case 2:\n res = _context15.sent;\n _context15.next = 5;\n return (0, _tc.getApiResponsePayload)(res);\n\n case 5:\n payload = _context15.sent;\n return _context15.abrupt('return', {\n preSignedURL: payload.preSignedURL,\n token: payload.token,\n file: file,\n userHandle: userHandle\n });\n\n case 7:\n case 'end':\n return _context15.stop();\n }\n }\n }, _callee15, this);\n }));\n\n function getPresignedUrl(_x21, _x22) {\n return _ref15.apply(this, arguments);\n }\n\n return getPresignedUrl;\n }()\n\n /**\n * Updates member photo.\n * @param {Object} S3Response The response from uploadFileToS3() function.\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'updateMemberPhoto',\n value: function () {\n var _ref16 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee16(S3Response) {\n var res;\n return _regenerator2.default.wrap(function _callee16$(_context16) {\n while (1) {\n switch (_context16.prev = _context16.next) {\n case 0:\n _context16.next = 2;\n return this.private.api.putJson('/members/' + S3Response.userHandle + '/photo', { param: S3Response.body });\n\n case 2:\n res = _context16.sent;\n return _context16.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context16.stop();\n }\n }\n }, _callee16, this);\n }));\n\n function updateMemberPhoto(_x23) {\n return _ref16.apply(this, arguments);\n }\n\n return updateMemberPhoto;\n }()\n\n /**\n * Uploads file to S3.\n * @param {Object} presignedUrlResponse The presigned url response from\n * getPresignedUrl() function.\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'uploadFileToS3',\n value: function uploadFileToS3(presignedUrlResponse) {\n _lodash2.default.noop(this);\n return new _promise2.default(function (resolve, reject) {\n var xhr = new XMLHttpRequest();\n\n xhr.open('PUT', presignedUrlResponse.preSignedURL, true);\n xhr.setRequestHeader('Content-Type', presignedUrlResponse.file.type);\n\n xhr.onreadystatechange = function () {\n var status = xhr.status;\n\n if ((status >= 200 && status < 300 || status === 304) && xhr.readyState === 4) {\n resolve({\n userHandle: presignedUrlResponse.userHandle,\n body: {\n token: presignedUrlResponse.token,\n contentType: presignedUrlResponse.file.type\n }\n });\n } else if (status >= 400) {\n var err = new Error('Could not upload image to S3');\n err.status = status;\n reject(err);\n }\n };\n\n xhr.onerror = function (err) {\n _logger2.default.error('Could not upload image to S3', err);\n\n reject(err);\n };\n\n xhr.send(presignedUrlResponse.file);\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 MembersService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing members service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {MembersService} Members service object\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new MembersService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(MembersService, 'MembersService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.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-lib/./src/services/members.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\n\nvar _defineProperty2 = __webpack_require__(/*! babel-runtime/helpers/defineProperty */ \"babel-runtime/helpers/defineProperty\");\n\nvar _defineProperty3 = _interopRequireDefault(_defineProperty2);\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\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 _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\nexports.getService = getService;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _qs = __webpack_require__(/*! qs */ \"qs\");\n\nvar _qs2 = _interopRequireDefault(_qs);\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.members\"\n * @desc This module provides a service for searching for Topcoder\n * members via API V3.\n */\n\n/* global XMLHttpRequest */\n\n\n/**\n * Service class.\n */\nvar MembersService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function MembersService(tokenV3) {\n (0, _classCallCheck3.default)(this, MembersService);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets member's financial information.\n * @param {String} handle User handle.\n * @return {Promise} Resolves to the financial information object.\n */\n\n\n (0, _createClass3.default)(MembersService, [{\n key: 'getMemberFinances',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(handle) {\n var res;\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 this.private.api.get('/members/' + handle + '/financial');\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getMemberFinances(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getMemberFinances;\n }()\n\n /**\n * Gets public information on a member.\n *\n * This method does not require any authorization.\n *\n * @param {String} handle Member handle.\n * @return {Promise} Resolves to the data object.\n */\n\n }, {\n key: 'getMemberInfo',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(handle) {\n var res;\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 this.private.api.get('/members/' + handle);\n\n case 2:\n res = _context2.sent;\n return _context2.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getMemberInfo(_x2) {\n return _ref2.apply(this, arguments);\n }\n\n return getMemberInfo;\n }()\n\n /**\n * Gets member external account info.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getExternalAccounts',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n _context3.next = 2;\n return this.private.api.get('/members/' + handle + '/externalAccounts');\n\n case 2:\n res = _context3.sent;\n return _context3.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function getExternalAccounts(_x3) {\n return _ref3.apply(this, arguments);\n }\n\n return getExternalAccounts;\n }()\n\n /**\n * Gets member external links.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getExternalLinks',\n value: function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return this.private.api.get('/members/' + handle + '/externalLinks');\n\n case 2:\n res = _context4.sent;\n return _context4.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function getExternalLinks(_x4) {\n return _ref4.apply(this, arguments);\n }\n\n return getExternalLinks;\n }()\n\n /**\n * Gets member skills.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getSkills',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n _context5.next = 2;\n return this.private.api.get('/members/' + handle + '/skills');\n\n case 2:\n res = _context5.sent;\n return _context5.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function getSkills(_x5) {\n return _ref5.apply(this, arguments);\n }\n\n return getSkills;\n }()\n\n /**\n * Gets member statistics.\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getStats',\n value: function () {\n var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n _context6.next = 2;\n return this.private.api.get('/members/' + handle + '/stats');\n\n case 2:\n res = _context6.sent;\n return _context6.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getStats(_x6) {\n return _ref6.apply(this, arguments);\n }\n\n return getStats;\n }()\n\n /**\n * Gets member statistics history\n * @param {String} handle\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getStatsHistory',\n value: function () {\n var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(handle) {\n var res;\n return _regenerator2.default.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n _context7.next = 2;\n return this.private.api.get('/members/' + handle + '/stats/history');\n\n case 2:\n res = _context7.sent;\n return _context7.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function getStatsHistory(_x7) {\n return _ref7.apply(this, arguments);\n }\n\n return getStatsHistory;\n }()\n\n /**\n * Gets member statistics distribution\n * @param {String} handle\n * @param {String} track\n * @param {String} subTrack\n * @return {Promise} Resolves to the stats object.\n */\n\n }, {\n key: 'getStatsDistribution',\n value: function () {\n var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(handle, track, subTrack) {\n var res;\n return _regenerator2.default.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n _context8.next = 2;\n return this.private.api.get('/members/stats/distribution?filter=' + encodeURIComponent(_qs2.default.stringify({\n track: track,\n subTrack: subTrack\n })));\n\n case 2:\n res = _context8.sent;\n return _context8.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function getStatsDistribution(_x8, _x9, _x10) {\n return _ref8.apply(this, arguments);\n }\n\n return getStatsDistribution;\n }()\n\n /**\n * Gets a list of suggested member names for the supplied partial.\n *\n * WARNING: This method requires v3 authorization.\n *\n * @param {String} keyword Partial string to find suggestions for\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'getMemberSuggestions',\n value: function () {\n var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(keyword) {\n var res;\n return _regenerator2.default.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n _context9.next = 2;\n return this.private.api.get('/members/_suggest/' + keyword);\n\n case 2:\n res = _context9.sent;\n return _context9.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function getMemberSuggestions(_x11) {\n return _ref9.apply(this, arguments);\n }\n\n return getMemberSuggestions;\n }()\n\n /**\n * Adds external web link for member.\n * @param {String} userHandle The user handle\n * @param {String} webLink The external web link\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'addWebLink',\n value: function () {\n var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(userHandle, webLink) {\n var res;\n return _regenerator2.default.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n _context10.next = 2;\n return this.private.api.postJson('/members/' + userHandle + '/externalLinks', { param: { url: webLink } });\n\n case 2:\n res = _context10.sent;\n return _context10.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function addWebLink(_x12, _x13) {\n return _ref10.apply(this, arguments);\n }\n\n return addWebLink;\n }()\n\n /**\n * Deletes external web link for member.\n * @param {String} userHandle The user handle\n * @param {String} webLinkHandle The external web link handle\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'deleteWebLink',\n value: function () {\n var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee11(userHandle, webLinkHandle) {\n var body, res;\n return _regenerator2.default.wrap(function _callee11$(_context11) {\n while (1) {\n switch (_context11.prev = _context11.next) {\n case 0:\n body = {\n param: {\n handle: webLinkHandle\n }\n };\n _context11.next = 3;\n return this.private.api.delete('/members/' + userHandle + '/externalLinks/' + webLinkHandle, (0, _stringify2.default)(body));\n\n case 3:\n res = _context11.sent;\n return _context11.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context11.stop();\n }\n }\n }, _callee11, this);\n }));\n\n function deleteWebLink(_x14, _x15) {\n return _ref11.apply(this, arguments);\n }\n\n return deleteWebLink;\n }()\n\n /**\n * Adds user skill.\n * @param {String} handle Topcoder user handle\n * @param {Number} skillTagId Skill tag id\n * @return {Promise} Resolves to operation result\n */\n\n }, {\n key: 'addSkill',\n value: function () {\n var _ref12 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee12(handle, skillTagId) {\n var body, res;\n return _regenerator2.default.wrap(function _callee12$(_context12) {\n while (1) {\n switch (_context12.prev = _context12.next) {\n case 0:\n body = {\n param: {\n skills: (0, _defineProperty3.default)({}, skillTagId, {\n hidden: false\n })\n }\n };\n _context12.next = 3;\n return this.private.api.patchJson('/members/' + handle + '/skills', body);\n\n case 3:\n res = _context12.sent;\n return _context12.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context12.stop();\n }\n }\n }, _callee12, this);\n }));\n\n function addSkill(_x16, _x17) {\n return _ref12.apply(this, arguments);\n }\n\n return addSkill;\n }()\n\n /**\n * Hides user skill.\n * @param {String} handle Topcoder user handle\n * @param {Number} skillTagId Skill tag id\n * @return {Promise} Resolves to operation result\n */\n\n }, {\n key: 'hideSkill',\n value: function () {\n var _ref13 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee13(handle, skillTagId) {\n var body, res;\n return _regenerator2.default.wrap(function _callee13$(_context13) {\n while (1) {\n switch (_context13.prev = _context13.next) {\n case 0:\n body = {\n param: {\n skills: (0, _defineProperty3.default)({}, skillTagId, {\n hidden: true\n })\n }\n };\n _context13.next = 3;\n return this.private.api.fetch('/members/' + handle + '/skills', {\n body: (0, _stringify2.default)(body),\n method: 'PATCH'\n });\n\n case 3:\n res = _context13.sent;\n return _context13.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context13.stop();\n }\n }\n }, _callee13, this);\n }));\n\n function hideSkill(_x18, _x19) {\n return _ref13.apply(this, arguments);\n }\n\n return hideSkill;\n }()\n\n /**\n * Updates member profile.\n * @param {Object} profile The profile to update.\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'updateMemberProfile',\n value: function () {\n var _ref14 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee14(profile) {\n var changeEmail, url, res;\n return _regenerator2.default.wrap(function _callee14$(_context14) {\n while (1) {\n switch (_context14.prev = _context14.next) {\n case 0:\n changeEmail = !!(_lodash2.default.get(profile, 'successUrl') || _lodash2.default.get(profile, 'failUrl'));\n url = '/members/' + profile.handle;\n\n if (changeEmail) {\n url = url + '?successUrl=' + _lodash2.default.get(profile, 'successUrl') + '&failUrl=' + _lodash2.default.get(profile, 'failUrl');\n }\n _context14.next = 5;\n return this.private.api.putJson(url, { param: _lodash2.default.omit(profile, ['successUrl', 'failUrl']) });\n\n case 5:\n res = _context14.sent;\n return _context14.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 7:\n case 'end':\n return _context14.stop();\n }\n }\n }, _callee14, this);\n }));\n\n function updateMemberProfile(_x20) {\n return _ref14.apply(this, arguments);\n }\n\n return updateMemberProfile;\n }()\n\n /**\n * Gets presigned url for member photo file.\n * @param {String} userHandle The user handle\n * @param {File} file The file to get its presigned url\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'getPresignedUrl',\n value: function () {\n var _ref15 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee15(userHandle, file) {\n var res, payload;\n return _regenerator2.default.wrap(function _callee15$(_context15) {\n while (1) {\n switch (_context15.prev = _context15.next) {\n case 0:\n _context15.next = 2;\n return this.private.api.postJson('/members/' + userHandle + '/photoUploadUrl', { param: { contentType: file.type } });\n\n case 2:\n res = _context15.sent;\n _context15.next = 5;\n return (0, _tc.getApiResponsePayload)(res);\n\n case 5:\n payload = _context15.sent;\n return _context15.abrupt('return', {\n preSignedURL: payload.preSignedURL,\n token: payload.token,\n file: file,\n userHandle: userHandle\n });\n\n case 7:\n case 'end':\n return _context15.stop();\n }\n }\n }, _callee15, this);\n }));\n\n function getPresignedUrl(_x21, _x22) {\n return _ref15.apply(this, arguments);\n }\n\n return getPresignedUrl;\n }()\n\n /**\n * Updates member photo.\n * @param {Object} S3Response The response from uploadFileToS3() function.\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'updateMemberPhoto',\n value: function () {\n var _ref16 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee16(S3Response) {\n var res;\n return _regenerator2.default.wrap(function _callee16$(_context16) {\n while (1) {\n switch (_context16.prev = _context16.next) {\n case 0:\n _context16.next = 2;\n return this.private.api.putJson('/members/' + S3Response.userHandle + '/photo', { param: S3Response.body });\n\n case 2:\n res = _context16.sent;\n return _context16.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context16.stop();\n }\n }\n }, _callee16, this);\n }));\n\n function updateMemberPhoto(_x23) {\n return _ref16.apply(this, arguments);\n }\n\n return updateMemberPhoto;\n }()\n\n /**\n * Uploads file to S3.\n * @param {Object} presignedUrlResponse The presigned url response from\n * getPresignedUrl() function.\n * @return {Promise} Resolves to the api response content\n */\n\n }, {\n key: 'uploadFileToS3',\n value: function uploadFileToS3(presignedUrlResponse) {\n _lodash2.default.noop(this);\n return new _promise2.default(function (resolve, reject) {\n var xhr = new XMLHttpRequest();\n\n xhr.open('PUT', presignedUrlResponse.preSignedURL, true);\n xhr.setRequestHeader('Content-Type', presignedUrlResponse.file.type);\n\n xhr.onreadystatechange = function () {\n var status = xhr.status;\n\n if ((status >= 200 && status < 300 || status === 304) && xhr.readyState === 4) {\n resolve({\n userHandle: presignedUrlResponse.userHandle,\n body: {\n token: presignedUrlResponse.token,\n contentType: presignedUrlResponse.file.type\n }\n });\n } else if (status >= 400) {\n var err = new Error('Could not upload image to S3');\n err.status = status;\n reject(err);\n }\n };\n\n xhr.onerror = function (err) {\n _logger2.default.error('Could not upload image to S3', err);\n\n reject(err);\n };\n\n xhr.send(presignedUrlResponse.file);\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 MembersService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing members service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {MembersService} Members service object\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new MembersService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(MembersService, 'MembersService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/members.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-lib/./src/services/members.js?");
/***/ }),
@@ -1006,7 +1006,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\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\nexports.getReviewOpportunitiesService = getReviewOpportunitiesService;\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.reviewOpportunities\"\n * @desc This module provides a service for retrieving Review Opportunities and\n * submitting applications.\n */\n\n\n/**\n * Service class.\n */\nvar ReviewOpportunitiesService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function ReviewOpportunitiesService(tokenV3) {\n (0, _classCallCheck3.default)(this, ReviewOpportunitiesService);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets a list of currently open Review Opportunities.\n * @param {Number} limit The max number to return in one call.\n * @param {Number} offset Offset, used with limit to lazy load.\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n\n (0, _createClass3.default)(ReviewOpportunitiesService, [{\n key: 'getReviewOpportunities',\n value: function getReviewOpportunities(limit, offset) {\n var endpoint = '/reviewOpportunities?limit=' + limit + '&offset=' + offset;\n return this.private.api.get(endpoint).then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(new Error('Error Code: ' + res.status));\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : _promise2.default.reject(res.result.content);\n });\n }\n\n /**\n * Gets the details of the review opportunity for the corresponding challenge\n * @param {Number} challengeId The ID of the challenge (not the opportunity id)\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n }, {\n key: 'getDetails',\n value: function getDetails(challengeId) {\n var endpoint = '/reviewOpportunities/' + challengeId;\n return this.private.api.get(endpoint).then(function (res) {\n return res.json();\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : _promise2.default.reject(res.result);\n });\n }\n\n /**\n * Submits review opportunity application for the specified challenge\n * @param {Number} challengeId The ID of the challenge (not the opportunity id)\n * @param {Array} roleIds List of review role IDs to apply for\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n }, {\n key: 'submitApplications',\n value: function submitApplications(challengeId, roleIds) {\n var endpoint = '/reviewOpportunities/' + challengeId + '/applications?reviewApplicationRoleIds=' + roleIds.join(',');\n return this.private.api.post(endpoint, {}).then(function (res) {\n return JSON.parse(res);\n });\n }\n\n /**\n * Cancels review opportunity application for the specified challenge\n * @param {Number} challengeId The ID of the challenge (not the opportunity id)\n * @param {Array} roleIds List of review role IDs to cancel applications for\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n }, {\n key: 'cancelApplications',\n value: function cancelApplications(challengeId, roleIds) {\n var endpoint = '/reviewOpportunities/' + challengeId + '/applications?reviewApplicationRoleIds=' + roleIds.join(',');\n return this.private.api.delete(endpoint, {}).then(function (res) {\n return JSON.parse(res);\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 ReviewOpportunitiesService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing review opportunities service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {MembersService} Members service object\n */\nfunction getReviewOpportunitiesService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new ReviewOpportunitiesService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(ReviewOpportunitiesService, 'ReviewOpportunitiesService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.js');\n reactHotLoader.register(getReviewOpportunitiesService, 'getReviewOpportunitiesService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.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-lib/./src/services/reviewOpportunities.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\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\nexports.getReviewOpportunitiesService = getReviewOpportunitiesService;\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.reviewOpportunities\"\n * @desc This module provides a service for retrieving Review Opportunities and\n * submitting applications.\n */\n\n\n/**\n * Service class.\n */\nvar ReviewOpportunitiesService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function ReviewOpportunitiesService(tokenV3) {\n (0, _classCallCheck3.default)(this, ReviewOpportunitiesService);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets a list of currently open Review Opportunities.\n * @param {Number} limit The max number to return in one call.\n * @param {Number} offset Offset, used with limit to lazy load.\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n\n (0, _createClass3.default)(ReviewOpportunitiesService, [{\n key: 'getReviewOpportunities',\n value: function getReviewOpportunities(limit, offset) {\n var endpoint = '/reviewOpportunities?limit=' + limit + '&offset=' + offset;\n return this.private.api.get(endpoint).then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(new Error('Error Code: ' + res.status));\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : _promise2.default.reject(res.result.content);\n });\n }\n\n /**\n * Gets the details of the review opportunity for the corresponding challenge\n * @param {Number} challengeId The ID of the challenge (not the opportunity id)\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n }, {\n key: 'getDetails',\n value: function getDetails(challengeId) {\n var endpoint = '/reviewOpportunities/' + challengeId;\n return this.private.api.get(endpoint).then(function (res) {\n return res.json();\n }).then(function (res) {\n return res.result.status === 200 ? res.result.content : _promise2.default.reject(res.result);\n });\n }\n\n /**\n * Submits review opportunity application for the specified challenge\n * @param {Number} challengeId The ID of the challenge (not the opportunity id)\n * @param {Array} roleIds List of review role IDs to apply for\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n }, {\n key: 'submitApplications',\n value: function submitApplications(challengeId, roleIds) {\n var endpoint = '/reviewOpportunities/' + challengeId + '/applications?reviewApplicationRoleIds=' + roleIds.join(',');\n return this.private.api.post(endpoint, {}).then(function (res) {\n return JSON.parse(res);\n });\n }\n\n /**\n * Cancels review opportunity application for the specified challenge\n * @param {Number} challengeId The ID of the challenge (not the opportunity id)\n * @param {Array} roleIds List of review role IDs to cancel applications for\n * @return {Promise} Resolves to the api response in JSON.\n */\n\n }, {\n key: 'cancelApplications',\n value: function cancelApplications(challengeId, roleIds) {\n var endpoint = '/reviewOpportunities/' + challengeId + '/applications?reviewApplicationRoleIds=' + roleIds.join(',');\n return this.private.api.delete(endpoint, {}).then(function (res) {\n return JSON.parse(res);\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 ReviewOpportunitiesService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing review opportunities service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {MembersService} Members service object\n */\nfunction getReviewOpportunitiesService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new ReviewOpportunitiesService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(ReviewOpportunitiesService, 'ReviewOpportunitiesService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.js');\n reactHotLoader.register(getReviewOpportunitiesService, 'getReviewOpportunitiesService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/reviewOpportunities.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-lib/./src/services/reviewOpportunities.js?");
/***/ }),
@@ -1018,7 +1018,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\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\nexports.getService = getService;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _communities = __webpack_require__(/*! ./communities */ \"./src/services/communities.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.terms\"\n * @desc This module provides a service for convenient manipulation with\n * Topcoder challenges' terms via TC API.\n */\n\n/**\n * Service class.\n */\nvar TermsService = function () {\n /**\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n */\n function TermsService(tokenV2) {\n (0, _classCallCheck3.default)(this, TermsService);\n\n this.private = {\n api: (0, _api.getApiV2)(tokenV2),\n tokenV2: tokenV2\n };\n }\n\n /**\n * get all terms of specified challenge\n * @param {Number|String} challengeId id of the challenge\n * @return {Promise} promise of the request result\n */\n\n\n (0, _createClass3.default)(TermsService, [{\n key: 'getChallengeTerms',\n value: function getChallengeTerms(challengeId) {\n var _this = this;\n\n if (this.private.tokenV2) {\n var registered = false;\n return this.private.api.get('/terms/' + challengeId + '?role=Submitter').then(function (res) {\n return res.json();\n }).then(function (res) {\n if (res.error) {\n if (res.error.details === 'You are already registered for this challenge.') {\n registered = true;\n }\n return _this.private.api.get('/terms/' + challengeId + '?role=Submitter&noauth=true').then(function (resp) {\n if (resp.ok) {\n return resp.json().then(function (result) {\n if (registered) {\n // eslint-disable-next-line no-param-reassign\n _lodash2.default.forEach(result.terms, function (t) {\n t.agreed = true;\n });\n }\n return result;\n });\n }\n return new Error(resp.statusText);\n });\n }\n return res;\n });\n }\n return this.private.api.get('/terms/' + challengeId + '?role=Submitter&noauth=true').then(function (resp) {\n if (resp.ok) {\n return resp.json();\n }\n throw new Error(resp.statusText);\n });\n }\n\n /**\n * get all terms for community\n *\n * NOTE: As there is no specific endpoint to get community terms by one call\n * currently we get community term ids from community service and after\n * we get community terms using term ids list one by one\n *\n * @param {String} communityId community id\n * @param {String} tokenV3 auth token V3 - we need to get community meta data\n *\n * @return {Promise} resolves to the list of community terms\n */\n\n }, {\n key: 'getCommunityTerms',\n value: function getCommunityTerms(communityId, tokenV3) {\n var _this2 = this;\n\n var communityService = (0, _communities.getService)(tokenV3);\n\n return communityService.getMetadata(communityId).then(function (meta) {\n if (meta.terms && meta.terms.length) {\n return _promise2.default.all(meta.terms.map(function (termId) {\n return _this2.getTermDetails(termId);\n })).then(function (terms) {\n return terms.map(function (term) {\n return _lodash2.default.omit(term, 'text');\n }) // don't include text as it's big and we need it for list\n ;\n });\n }\n\n return [];\n }).then(function (terms) {\n return {\n terms: terms\n };\n });\n }\n\n /**\n * Get the terms for Review Opportunities. This will ensure that the\n * provided terms have all the necessary fields by getting anything missing\n * from the terms details endpoint\n *\n * @param {Object} requiredTerms Required terms for review opportunity\n *\n * @return {Promise} resolves to the list of validated terms\n */\n\n }, {\n key: 'getReviewOpportunityTerms',\n value: function getReviewOpportunityTerms(requiredTerms) {\n var _this3 = this;\n\n var promises = requiredTerms.map(function (term) {\n // Agreed field is present, all the necessary information is present for this term, but will\n // need to verify if agreed is false as user may have agreed to terms after data was loaded\n if (term.agreed) {\n return _promise2.default.resolve(term);\n }\n // Otherwise grab new details from terms api\n return _this3.getTermDetails(term.termsOfUseId).then(function (res) {\n return _lodash2.default.pick(res, ['termsOfUseId', 'agreed', 'title']);\n });\n });\n\n return _promise2.default.all(promises).then(function (terms) {\n return { terms: terms };\n });\n }\n\n /**\n * get details of specified term\n * @param {Number|String} termId id of the term\n * @return {Promise} promise of the request result\n */\n\n }, {\n key: 'getTermDetails',\n value: function getTermDetails(termId) {\n // looks like server cache responses, to prevent it we add nocache param with always new value\n var nocache = new Date().getTime();\n return this.private.api.get('/terms/detail/' + termId + '?nocache=' + nocache).then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(res.json());\n });\n }\n\n /**\n * generate the url of DocuSign term\n * @param {Number|String} templateId id of the term's template\n * @param {String} returnUrl callback url after finishing signing\n * @return {Promise} promise of the request result\n */\n\n }, {\n key: 'getDocuSignUrl',\n value: function getDocuSignUrl(templateId, returnUrl) {\n return this.private.api.post('/terms/docusign/viewURL?templateId=' + templateId + '&returnUrl=' + returnUrl).then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(res.json());\n });\n }\n\n /**\n * Agree a term\n * @param {Number|String} termId id of the term\n * @return {Promise} promise of the request result\n */\n\n }, {\n key: 'agreeTerm',\n value: function agreeTerm(termId) {\n return this.private.api.post('/terms/' + termId + '/agree').then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(res.json());\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 TermsService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing terms service.\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n * @return {TermsService} Terms service object\n */\nfunction getService(tokenV2) {\n /* Because of Topcoder backend restrictions, it is not straightforward to test\n * terms-related functionality in any other way than just providing an option\n * to run the app against mock terms service. */\n if (_topcoderReactUtils.config.MOCK_TERMS_SERVICE) {\n /* eslint-disable global-require */\n return __webpack_require__(/*! ./__mocks__/terms */ \"./src/services/__mocks__/terms.js\").getService(tokenV2);\n /* eslint-enable global-require */\n }\n if (!lastInstance || tokenV2 && lastInstance.private.tokenV2 !== tokenV2) {\n lastInstance = new TermsService(tokenV2);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(TermsService, 'TermsService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.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-lib/./src/services/terms.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\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\nexports.getService = getService;\n\nvar _lodash = __webpack_require__(/*! lodash */ \"lodash\");\n\nvar _lodash2 = _interopRequireDefault(_lodash);\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _communities = __webpack_require__(/*! ./communities */ \"./src/services/communities.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.terms\"\n * @desc This module provides a service for convenient manipulation with\n * Topcoder challenges' terms via TC API.\n */\n\n/**\n * Service class.\n */\nvar TermsService = function () {\n /**\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n */\n function TermsService(tokenV2) {\n (0, _classCallCheck3.default)(this, TermsService);\n\n this.private = {\n api: (0, _api.getApi)('V2', tokenV2),\n tokenV2: tokenV2\n };\n }\n\n /**\n * get all terms of specified challenge\n * @param {Number|String} challengeId id of the challenge\n * @return {Promise} promise of the request result\n */\n\n\n (0, _createClass3.default)(TermsService, [{\n key: 'getChallengeTerms',\n value: function getChallengeTerms(challengeId) {\n var _this = this;\n\n if (this.private.tokenV2) {\n var registered = false;\n return this.private.api.get('/terms/' + challengeId + '?role=Submitter').then(function (res) {\n return res.json();\n }).then(function (res) {\n if (res.error) {\n if (res.error.details === 'You are already registered for this challenge.') {\n registered = true;\n }\n return _this.private.api.get('/terms/' + challengeId + '?role=Submitter&noauth=true').then(function (resp) {\n if (resp.ok) {\n return resp.json().then(function (result) {\n if (registered) {\n // eslint-disable-next-line no-param-reassign\n _lodash2.default.forEach(result.terms, function (t) {\n t.agreed = true;\n });\n }\n return result;\n });\n }\n return new Error(resp.statusText);\n });\n }\n return res;\n });\n }\n return this.private.api.get('/terms/' + challengeId + '?role=Submitter&noauth=true').then(function (resp) {\n if (resp.ok) {\n return resp.json();\n }\n throw new Error(resp.statusText);\n });\n }\n\n /**\n * get all terms for community\n *\n * NOTE: As there is no specific endpoint to get community terms by one call\n * currently we get community term ids from community service and after\n * we get community terms using term ids list one by one\n *\n * @param {String} communityId community id\n * @param {String} tokenV3 auth token V3 - we need to get community meta data\n *\n * @return {Promise} resolves to the list of community terms\n */\n\n }, {\n key: 'getCommunityTerms',\n value: function getCommunityTerms(communityId, tokenV3) {\n var _this2 = this;\n\n var communityService = (0, _communities.getService)(tokenV3);\n\n return communityService.getMetadata(communityId).then(function (meta) {\n if (meta.terms && meta.terms.length) {\n return _promise2.default.all(meta.terms.map(function (termId) {\n return _this2.getTermDetails(termId);\n })).then(function (terms) {\n return terms.map(function (term) {\n return _lodash2.default.omit(term, 'text');\n }) // don't include text as it's big and we need it for list\n ;\n });\n }\n\n return [];\n }).then(function (terms) {\n return {\n terms: terms\n };\n });\n }\n\n /**\n * Get the terms for Review Opportunities. This will ensure that the\n * provided terms have all the necessary fields by getting anything missing\n * from the terms details endpoint\n *\n * @param {Object} requiredTerms Required terms for review opportunity\n *\n * @return {Promise} resolves to the list of validated terms\n */\n\n }, {\n key: 'getReviewOpportunityTerms',\n value: function getReviewOpportunityTerms(requiredTerms) {\n var _this3 = this;\n\n var promises = requiredTerms.map(function (term) {\n // Agreed field is present, all the necessary information is present for this term, but will\n // need to verify if agreed is false as user may have agreed to terms after data was loaded\n if (term.agreed) {\n return _promise2.default.resolve(term);\n }\n // Otherwise grab new details from terms api\n return _this3.getTermDetails(term.termsOfUseId).then(function (res) {\n return _lodash2.default.pick(res, ['termsOfUseId', 'agreed', 'title']);\n });\n });\n\n return _promise2.default.all(promises).then(function (terms) {\n return { terms: terms };\n });\n }\n\n /**\n * get details of specified term\n * @param {Number|String} termId id of the term\n * @return {Promise} promise of the request result\n */\n\n }, {\n key: 'getTermDetails',\n value: function getTermDetails(termId) {\n // looks like server cache responses, to prevent it we add nocache param with always new value\n var nocache = new Date().getTime();\n return this.private.api.get('/terms/detail/' + termId + '?nocache=' + nocache).then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(res.json());\n });\n }\n\n /**\n * generate the url of DocuSign term\n * @param {Number|String} templateId id of the term's template\n * @param {String} returnUrl callback url after finishing signing\n * @return {Promise} promise of the request result\n */\n\n }, {\n key: 'getDocuSignUrl',\n value: function getDocuSignUrl(templateId, returnUrl) {\n return this.private.api.post('/terms/docusign/viewURL?templateId=' + templateId + '&returnUrl=' + returnUrl).then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(res.json());\n });\n }\n\n /**\n * Agree a term\n * @param {Number|String} termId id of the term\n * @return {Promise} promise of the request result\n */\n\n }, {\n key: 'agreeTerm',\n value: function agreeTerm(termId) {\n return this.private.api.post('/terms/' + termId + '/agree').then(function (res) {\n return res.ok ? res.json() : _promise2.default.reject(res.json());\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 TermsService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing terms service.\n * @param {String} tokenV2 Optional. Auth token for Topcoder API v2.\n * @return {TermsService} Terms service object\n */\nfunction getService(tokenV2) {\n /* Because of Topcoder backend restrictions, it is not straightforward to test\n * terms-related functionality in any other way than just providing an option\n * to run the app against mock terms service. */\n if (_topcoderReactUtils.config.MOCK_TERMS_SERVICE) {\n /* eslint-disable global-require */\n return __webpack_require__(/*! ./__mocks__/terms */ \"./src/services/__mocks__/terms.js\").getService(tokenV2);\n /* eslint-enable global-require */\n }\n if (!lastInstance || tokenV2 && lastInstance.private.tokenV2 !== tokenV2) {\n lastInstance = new TermsService(tokenV2);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(TermsService, 'TermsService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/terms.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-lib/./src/services/terms.js?");
/***/ }),
@@ -1042,7 +1042,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _toCapitalCase = __webpack_require__(/*! to-capital-case */ \"to-capital-case\");\n\nvar _toCapitalCase2 = _interopRequireDefault(_toCapitalCase);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.userTraits\"\n * @desc This module provides a service for user traits crud\n * via API V3.\n */\n\n\n/**\n * Service class.\n */\nvar UserTraitsService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function UserTraitsService(tokenV3) {\n (0, _classCallCheck3.default)(this, UserTraitsService);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Get member's all traits.\n * @param {String} handle User handle.\n * @return {Promise} Resolves to the member traits.\n */\n\n\n (0, _createClass3.default)(UserTraitsService, [{\n key: 'getAllUserTraits',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(handle) {\n var res;\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 this.private.api.get('/members/' + handle.toLowerCase() + '/traits');\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getAllUserTraits(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getAllUserTraits;\n }()\n\n /**\n * Add member's trait.\n * @param {String} handle User handle.\n * @param {String} traitId Trait Id.\n * @param {Array} data Trait data.\n * @return {Promise} Resolves to the member traits.\n */\n\n }, {\n key: 'addUserTrait',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(handle, traitId, data) {\n var body, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n body = {\n param: [{\n traitId: traitId,\n categoryName: (0, _toCapitalCase2.default)(traitId),\n traits: {\n data: data\n }\n }]\n };\n _context2.next = 3;\n return this.private.api.postJson('/members/' + handle + '/traits', body);\n\n case 3:\n res = _context2.sent;\n return _context2.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function addUserTrait(_x2, _x3, _x4) {\n return _ref2.apply(this, arguments);\n }\n\n return addUserTrait;\n }()\n\n /**\n * Update member's trait.\n * @param {String} handle User handle.\n * @param {String} traitId Trait Id.\n * @param {Array} data Trait data.\n * @return {Promise} Resolves to the member traits.\n */\n\n }, {\n key: 'updateUserTrait',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(handle, traitId, data) {\n var body, res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n body = {\n param: [{\n traitId: traitId,\n categoryName: (0, _toCapitalCase2.default)(traitId),\n traits: {\n data: data\n }\n }]\n };\n _context3.next = 3;\n return this.private.api.putJson('/members/' + handle + '/traits', body);\n\n case 3:\n res = _context3.sent;\n return _context3.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function updateUserTrait(_x5, _x6, _x7) {\n return _ref3.apply(this, arguments);\n }\n\n return updateUserTrait;\n }()\n\n /**\n * Delete member's trait.\n * @param {String} handle User handle.\n * @param {String} traitId Trait Id.\n * @return {Promise} Resolves to the member traits.\n */\n\n }, {\n key: 'deleteUserTrait',\n value: function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(handle, traitId) {\n var res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return this.private.api.delete('/members/' + handle + '/traits?traitIds=' + traitId);\n\n case 2:\n res = _context4.sent;\n return _context4.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function deleteUserTrait(_x8, _x9) {\n return _ref4.apply(this, arguments);\n }\n\n return deleteUserTrait;\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 UserTraitsService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing user trait service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {UserTraitsService} userTraits service object\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new UserTraitsService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(UserTraitsService, 'UserTraitsService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.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-lib/./src/services/user-traits.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\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 _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\nexports.getService = getService;\n\nvar _toCapitalCase = __webpack_require__(/*! to-capital-case */ \"to-capital-case\");\n\nvar _toCapitalCase2 = _interopRequireDefault(_toCapitalCase);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.userTraits\"\n * @desc This module provides a service for user traits crud\n * via API V3.\n */\n\n\n/**\n * Service class.\n */\nvar UserTraitsService = function () {\n /**\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n */\n function UserTraitsService(tokenV3) {\n (0, _classCallCheck3.default)(this, UserTraitsService);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n tokenV3: tokenV3\n };\n }\n\n /**\n * Get member's all traits.\n * @param {String} handle User handle.\n * @return {Promise} Resolves to the member traits.\n */\n\n\n (0, _createClass3.default)(UserTraitsService, [{\n key: 'getAllUserTraits',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(handle) {\n var res;\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 this.private.api.get('/members/' + handle.toLowerCase() + '/traits');\n\n case 2:\n res = _context.sent;\n return _context.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getAllUserTraits(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getAllUserTraits;\n }()\n\n /**\n * Add member's trait.\n * @param {String} handle User handle.\n * @param {String} traitId Trait Id.\n * @param {Array} data Trait data.\n * @return {Promise} Resolves to the member traits.\n */\n\n }, {\n key: 'addUserTrait',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(handle, traitId, data) {\n var body, res;\n return _regenerator2.default.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n body = {\n param: [{\n traitId: traitId,\n categoryName: (0, _toCapitalCase2.default)(traitId),\n traits: {\n data: data\n }\n }]\n };\n _context2.next = 3;\n return this.private.api.postJson('/members/' + handle + '/traits', body);\n\n case 3:\n res = _context2.sent;\n return _context2.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function addUserTrait(_x2, _x3, _x4) {\n return _ref2.apply(this, arguments);\n }\n\n return addUserTrait;\n }()\n\n /**\n * Update member's trait.\n * @param {String} handle User handle.\n * @param {String} traitId Trait Id.\n * @param {Array} data Trait data.\n * @return {Promise} Resolves to the member traits.\n */\n\n }, {\n key: 'updateUserTrait',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(handle, traitId, data) {\n var body, res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n body = {\n param: [{\n traitId: traitId,\n categoryName: (0, _toCapitalCase2.default)(traitId),\n traits: {\n data: data\n }\n }]\n };\n _context3.next = 3;\n return this.private.api.putJson('/members/' + handle + '/traits', body);\n\n case 3:\n res = _context3.sent;\n return _context3.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function updateUserTrait(_x5, _x6, _x7) {\n return _ref3.apply(this, arguments);\n }\n\n return updateUserTrait;\n }()\n\n /**\n * Delete member's trait.\n * @param {String} handle User handle.\n * @param {String} traitId Trait Id.\n * @return {Promise} Resolves to the member traits.\n */\n\n }, {\n key: 'deleteUserTrait',\n value: function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(handle, traitId) {\n var res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n _context4.next = 2;\n return this.private.api.delete('/members/' + handle + '/traits?traitIds=' + traitId);\n\n case 2:\n res = _context4.sent;\n return _context4.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 4:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function deleteUserTrait(_x8, _x9) {\n return _ref4.apply(this, arguments);\n }\n\n return deleteUserTrait;\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 UserTraitsService;\n}();\n\nvar lastInstance = null;\n/**\n * Returns a new or existing user trait service.\n * @param {String} tokenV3 Optional. Auth token for Topcoder API v3.\n * @return {UserTraitsService} userTraits service object\n */\nfunction getService(tokenV3) {\n if (!lastInstance || tokenV3 !== lastInstance.private.tokenV3) {\n lastInstance = new UserTraitsService(tokenV3);\n }\n return lastInstance;\n}\n\n/* Using default export would be confusing in this case. */\nvar _default = undefined;\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(UserTraitsService, 'UserTraitsService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user-traits.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-lib/./src/services/user-traits.js?");
/***/ }),
@@ -1054,7 +1054,7 @@ eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(ex
/***/ (function(module, exports, __webpack_require__) {
"use strict";
-eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\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 _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 _slicedToArray2 = __webpack_require__(/*! babel-runtime/helpers/slicedToArray */ \"babel-runtime/helpers/slicedToArray\");\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nexports.getService = getService;\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.user\"\n * @desc The User service provides functionality related to Topcoder user\n * accounts.\n */\n\n\nvar auth0 = void 0;\n\n/**\n * Returns a new, or cached auth0 instance.\n * @return {Object} Auth0 object.\n */\nfunction getAuth0() {\n if (!auth0 && _topcoderReactUtils.isomorphy.isClientSide()) {\n var Auth0 = __webpack_require__(/*! auth0-js */ \"./node_modules/auth0-js/index.js\"); /* eslint-disable-line global-require */\n auth0 = new Auth0({\n domain: _topcoderReactUtils.config.AUTH0.DOMAIN,\n clientID: _topcoderReactUtils.config.AUTH0.CLIENT_ID,\n callbackOnLocationHash: true,\n sso: false\n });\n }\n return auth0;\n}\n\n/**\n * Gets social user data.\n * @param {Object} profile The user social profile\n * @param {*} accessToken The access token\n * @returns {Object} Social user data\n */\nfunction getSocialUserData(profile, accessToken) {\n var socialProvider = profile.identities[0].connection;\n var firstName = '';\n var lastName = '';\n var handle = '';\n var email = profile.email || '';\n\n var socialUserId = profile.user_id.substring(profile.user_id.lastIndexOf('|') + 1);\n var splitName = void 0;\n\n if (socialProvider === 'google-oauth2') {\n firstName = profile.given_name;\n lastName = profile.family_name;\n handle = profile.nickname;\n } else if (socialProvider === 'facebook') {\n firstName = profile.given_name;\n lastName = profile.family_name;\n handle = firstName + '.' + lastName;\n } else if (socialProvider === 'twitter') {\n splitName = profile.name.split(' ');\n var _splitName = splitName;\n\n var _splitName2 = (0, _slicedToArray3.default)(_splitName, 1);\n\n firstName = _splitName2[0];\n\n if (splitName.length > 1) {\n var _splitName3 = splitName;\n\n var _splitName4 = (0, _slicedToArray3.default)(_splitName3, 2);\n\n lastName = _splitName4[1];\n }\n handle = profile.screen_name;\n } else if (socialProvider === 'github') {\n splitName = profile.name.split(' ');\n var _splitName5 = splitName;\n\n var _splitName6 = (0, _slicedToArray3.default)(_splitName5, 1);\n\n firstName = _splitName6[0];\n\n if (splitName.length > 1) {\n var _splitName7 = splitName;\n\n var _splitName8 = (0, _slicedToArray3.default)(_splitName7, 2);\n\n lastName = _splitName8[1];\n }\n handle = profile.nickname;\n } else if (socialProvider === 'bitbucket') {\n firstName = profile.first_name;\n lastName = profile.last_name;\n handle = profile.username;\n } else if (socialProvider === 'stackoverflow') {\n firstName = profile.first_name;\n lastName = profile.last_name;\n handle = socialUserId;\n } else if (socialProvider === 'dribbble') {\n firstName = profile.first_name;\n lastName = profile.last_name;\n handle = socialUserId;\n }\n\n var token = accessToken;\n var tokenSecret = null;\n if (profile.identities[0].access_token) {\n token = profile.identities[0].access_token;\n }\n if (profile.identities[0].access_token_secret) {\n tokenSecret = profile.identities[0].access_token_secret;\n }\n return {\n socialUserId: socialUserId,\n username: handle,\n firstname: firstName,\n lastname: lastName,\n email: email,\n socialProfile: profile,\n socialProvider: socialProvider,\n accessToken: token,\n accessTokenSecret: tokenSecret\n };\n}\n\n/**\n * Service class.\n */\n\nvar User = function () {\n /**\n * Creates a new User service.\n * @param {String} tokenV3 Topcoder auth tokenV3.\n * @param {String} tokenV2 TC auth token v2.\n */\n function User(tokenV3, tokenV2) {\n (0, _classCallCheck3.default)(this, User);\n\n this.private = {\n api: (0, _api.getApiV3)(tokenV3),\n apiV2: (0, _api.getApiV2)(tokenV2),\n tokenV2: tokenV2,\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets user achievements. Does not need auth.\n * @param {String} username\n * @return {Object}\n */\n\n\n (0, _createClass3.default)(User, [{\n key: 'getAchievements',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(username) {\n var res;\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 this.private.apiV2.get('/users/' + username);\n\n case 2:\n res = _context.sent;\n\n if (res.ok) {\n _context.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n _context.next = 7;\n return res.json();\n\n case 7:\n _context.t0 = _context.sent.Achievements;\n\n if (_context.t0) {\n _context.next = 10;\n break;\n }\n\n _context.t0 = [];\n\n case 10:\n return _context.abrupt('return', _context.t0);\n\n case 11:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getAchievements(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getAchievements;\n }()\n\n /**\n * Gets public user info. Does not need auth.\n * @param {String} username\n * @return {Object}\n */\n\n }, {\n key: 'getUserPublic',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(username) {\n var res;\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 this.private.apiV2.get('/users/' + username);\n\n case 2:\n res = _context2.sent;\n\n if (res.ok) {\n _context2.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n return _context2.abrupt('return', res.json() || null);\n\n case 6:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getUserPublic(_x2) {\n return _ref2.apply(this, arguments);\n }\n\n return getUserPublic;\n }()\n\n /**\n * Gets user data object for the specified username.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {String} username\n * @return {Promise} Resolves to the user data object.\n */\n\n }, {\n key: 'getUser',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(username) {\n var url, res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n url = '/users?filter=handle%3D' + username;\n _context3.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context3.sent;\n _context3.next = 6;\n return (0, _tc.getApiResponsePayload)(res);\n\n case 6:\n return _context3.abrupt('return', _context3.sent[0]);\n\n case 7:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function getUser(_x3) {\n return _ref3.apply(this, arguments);\n }\n\n return getUser;\n }()\n\n /**\n * Gets email preferences.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The TopCoder user id\n * @returns {Promise} Resolves to the email preferences result\n */\n\n }, {\n key: 'getEmailPreferences',\n value: function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(userId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n url = '/users/' + userId + '/preferences/email';\n _context4.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context4.sent;\n return _context4.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function getEmailPreferences(_x4) {\n return _ref4.apply(this, arguments);\n }\n\n return getEmailPreferences;\n }()\n\n /**\n * Saves email preferences.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Object} user The TopCoder user\n * @param {Object} preferences The email preferences\n * @returns {Promise} Resolves to the email preferences result\n */\n\n }, {\n key: 'saveEmailPreferences',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(_ref6, preferences) {\n var firstName = _ref6.firstName,\n lastName = _ref6.lastName,\n userId = _ref6.userId;\n var settings, url, res;\n return _regenerator2.default.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n settings = {\n firstName: firstName,\n lastName: lastName,\n subscriptions: {}\n };\n\n\n if (!preferences) {\n settings.subscriptions.TOPCODER_NL_GEN = true;\n } else {\n settings.subscriptions = preferences;\n }\n url = '/users/' + userId + '/preferences/email';\n _context5.next = 5;\n return this.private.api.putJson(url, { param: settings });\n\n case 5:\n res = _context5.sent;\n return _context5.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 7:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function saveEmailPreferences(_x5, _x6) {\n return _ref5.apply(this, arguments);\n }\n\n return saveEmailPreferences;\n }()\n\n /**\n * Gets credential for the specified user id.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The user id\n * @return {Promise} Resolves to the linked accounts array.\n */\n\n }, {\n key: 'getCredential',\n value: function () {\n var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(userId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n url = '/users/' + userId + '?fields=credential';\n _context6.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context6.sent;\n return _context6.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getCredential(_x7) {\n return _ref7.apply(this, arguments);\n }\n\n return getCredential;\n }()\n\n /**\n * Updates user password.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The user id\n * @param {String} newPassword The new password\n * @param {String} oldPassword The old password\n * @return {Promise} Resolves to the update result.\n */\n\n }, {\n key: 'updatePassword',\n value: function () {\n var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(userId, newPassword, oldPassword) {\n var credential, url, res;\n return _regenerator2.default.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n credential = {\n password: newPassword,\n currentPassword: oldPassword\n };\n url = '/users/' + userId;\n _context7.next = 4;\n return this.private.api.patchJson(url, { param: { credential: credential } });\n\n case 4:\n res = _context7.sent;\n return _context7.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 6:\n case 'end':\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function updatePassword(_x8, _x9, _x10) {\n return _ref8.apply(this, arguments);\n }\n\n return updatePassword;\n }()\n\n /**\n * Gets linked accounts for the specified user id.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The user id\n * @return {Promise} Resolves to the linked accounts array.\n */\n\n }, {\n key: 'getLinkedAccounts',\n value: function () {\n var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(userId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n url = '/users/' + userId + '?fields=profiles';\n _context8.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context8.sent;\n return _context8.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function getLinkedAccounts(_x11) {\n return _ref9.apply(this, arguments);\n }\n\n return getLinkedAccounts;\n }()\n\n /**\n * Unlinks external account.\n * @param {Number} userId The TopCoder user id\n * @param {String} provider The external account service provider\n * @returns {Promise} Resolves to the unlink result\n */\n\n }, {\n key: 'unlinkExternalAccount',\n value: function () {\n var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(userId, provider) {\n var url, res;\n return _regenerator2.default.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n url = '/users/' + userId + '/profiles/' + provider;\n _context9.next = 3;\n return this.private.api.delete(url);\n\n case 3:\n res = _context9.sent;\n return _context9.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function unlinkExternalAccount(_x12, _x13) {\n return _ref10.apply(this, arguments);\n }\n\n return unlinkExternalAccount;\n }()\n\n /**\n * Links external account.\n * @param {Number} userId The TopCoder user id\n * @param {String} provider The external account service provider\n * @param {String} callbackUrl Optional. The callback url\n * @returns {Promise} Resolves to the linked account result\n */\n\n }, {\n key: 'linkExternalAccount',\n value: function () {\n var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(userId, provider, callbackUrl) {\n var _this = this;\n\n return _regenerator2.default.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n return _context10.abrupt('return', new _promise2.default(function (resolve, reject) {\n getAuth0().signin({\n popup: true,\n connection: provider,\n scope: 'openid profile offline_access',\n state: callbackUrl\n }, function (authError, profile, idToken, accessToken) {\n if (authError) {\n _logger2.default.error('Error signing in - onSocialLoginFailure', authError);\n reject(authError);\n return;\n }\n\n var socialData = getSocialUserData(profile, accessToken);\n\n var postData = {\n userId: socialData.socialUserId,\n name: socialData.username,\n email: socialData.email,\n emailVerified: false,\n providerType: socialData.socialProvider,\n context: {\n handle: socialData.username,\n accessToken: socialData.accessToken,\n auth0UserId: profile.user_id\n }\n };\n if (socialData.accessTokenSecret) {\n postData.context.accessTokenSecret = socialData.accessTokenSecret;\n }\n _logger2.default.debug('link API postdata: ' + (0, _stringify2.default)(postData));\n _this.private.api.postJson('/users/' + userId + '/profiles', { param: postData }).then(function (resp) {\n return (0, _tc.getApiResponsePayload)(resp).then(function (result) {\n _logger2.default.debug('Succesfully linked account: ' + (0, _stringify2.default)(result));\n resolve(postData);\n });\n }).catch(function (err) {\n _logger2.default.error('Error linking account', err);\n reject(err);\n });\n });\n }));\n\n case 1:\n case 'end':\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function linkExternalAccount(_x14, _x15, _x16) {\n return _ref11.apply(this, arguments);\n }\n\n return linkExternalAccount;\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 User;\n}();\n\nvar lastInstance = null;\n\n/**\n * Returns a new or existing User service for the specified tokenV3.\n * @param {String} tokenV3 Optional. Topcoder auth token v3.\n * @param {String} tokenV2 Optional. TC auth token v2.\n * @return {Api} API v3 service object.\n */\nfunction getService(tokenV3, tokenV2) {\n if (!lastInstance || lastInstance.private.tokenV2 !== tokenV2 || lastInstance.private.tokenV3 !== tokenV3) {\n lastInstance = new User(tokenV3, tokenV2);\n }\n return lastInstance;\n}\n\n/**\n * @static\n * @member default\n * @desc Default export is {@link module:services.user~User} class.\n */\nvar _default = User;\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(auth0, 'auth0', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(getAuth0, 'getAuth0', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(getSocialUserData, 'getSocialUserData', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(User, 'User', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.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-lib/./src/services/user.js?");
+eval("/* WEBPACK VAR INJECTION */(function(module) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _stringify = __webpack_require__(/*! babel-runtime/core-js/json/stringify */ \"babel-runtime/core-js/json/stringify\");\n\nvar _stringify2 = _interopRequireDefault(_stringify);\n\nvar _promise = __webpack_require__(/*! babel-runtime/core-js/promise */ \"babel-runtime/core-js/promise\");\n\nvar _promise2 = _interopRequireDefault(_promise);\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 _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 _slicedToArray2 = __webpack_require__(/*! babel-runtime/helpers/slicedToArray */ \"babel-runtime/helpers/slicedToArray\");\n\nvar _slicedToArray3 = _interopRequireDefault(_slicedToArray2);\n\nexports.getService = getService;\n\nvar _topcoderReactUtils = __webpack_require__(/*! topcoder-react-utils */ \"topcoder-react-utils\");\n\nvar _logger = __webpack_require__(/*! ../utils/logger */ \"./src/utils/logger.js\");\n\nvar _logger2 = _interopRequireDefault(_logger);\n\nvar _tc = __webpack_require__(/*! ../utils/tc */ \"./src/utils/tc.js\");\n\nvar _api = __webpack_require__(/*! ./api */ \"./src/services/api.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 * @module \"services.user\"\n * @desc The User service provides functionality related to Topcoder user\n * accounts.\n */\n\n\nvar auth0 = void 0;\n\n/**\n * Returns a new, or cached auth0 instance.\n * @return {Object} Auth0 object.\n */\nfunction getAuth0() {\n if (!auth0 && _topcoderReactUtils.isomorphy.isClientSide()) {\n var Auth0 = __webpack_require__(/*! auth0-js */ \"./node_modules/auth0-js/index.js\"); /* eslint-disable-line global-require */\n auth0 = new Auth0({\n domain: _topcoderReactUtils.config.AUTH0.DOMAIN,\n clientID: _topcoderReactUtils.config.AUTH0.CLIENT_ID,\n callbackOnLocationHash: true,\n sso: false\n });\n }\n return auth0;\n}\n\n/**\n * Gets social user data.\n * @param {Object} profile The user social profile\n * @param {*} accessToken The access token\n * @returns {Object} Social user data\n */\nfunction getSocialUserData(profile, accessToken) {\n var socialProvider = profile.identities[0].connection;\n var firstName = '';\n var lastName = '';\n var handle = '';\n var email = profile.email || '';\n\n var socialUserId = profile.user_id.substring(profile.user_id.lastIndexOf('|') + 1);\n var splitName = void 0;\n\n if (socialProvider === 'google-oauth2') {\n firstName = profile.given_name;\n lastName = profile.family_name;\n handle = profile.nickname;\n } else if (socialProvider === 'facebook') {\n firstName = profile.given_name;\n lastName = profile.family_name;\n handle = firstName + '.' + lastName;\n } else if (socialProvider === 'twitter') {\n splitName = profile.name.split(' ');\n var _splitName = splitName;\n\n var _splitName2 = (0, _slicedToArray3.default)(_splitName, 1);\n\n firstName = _splitName2[0];\n\n if (splitName.length > 1) {\n var _splitName3 = splitName;\n\n var _splitName4 = (0, _slicedToArray3.default)(_splitName3, 2);\n\n lastName = _splitName4[1];\n }\n handle = profile.screen_name;\n } else if (socialProvider === 'github') {\n splitName = profile.name.split(' ');\n var _splitName5 = splitName;\n\n var _splitName6 = (0, _slicedToArray3.default)(_splitName5, 1);\n\n firstName = _splitName6[0];\n\n if (splitName.length > 1) {\n var _splitName7 = splitName;\n\n var _splitName8 = (0, _slicedToArray3.default)(_splitName7, 2);\n\n lastName = _splitName8[1];\n }\n handle = profile.nickname;\n } else if (socialProvider === 'bitbucket') {\n firstName = profile.first_name;\n lastName = profile.last_name;\n handle = profile.username;\n } else if (socialProvider === 'stackoverflow') {\n firstName = profile.first_name;\n lastName = profile.last_name;\n handle = socialUserId;\n } else if (socialProvider === 'dribbble') {\n firstName = profile.first_name;\n lastName = profile.last_name;\n handle = socialUserId;\n }\n\n var token = accessToken;\n var tokenSecret = null;\n if (profile.identities[0].access_token) {\n token = profile.identities[0].access_token;\n }\n if (profile.identities[0].access_token_secret) {\n tokenSecret = profile.identities[0].access_token_secret;\n }\n return {\n socialUserId: socialUserId,\n username: handle,\n firstname: firstName,\n lastname: lastName,\n email: email,\n socialProfile: profile,\n socialProvider: socialProvider,\n accessToken: token,\n accessTokenSecret: tokenSecret\n };\n}\n\n/**\n * Service class.\n */\n\nvar User = function () {\n /**\n * Creates a new User service.\n * @param {String} tokenV3 Topcoder auth tokenV3.\n * @param {String} tokenV2 TC auth token v2.\n */\n function User(tokenV3, tokenV2) {\n (0, _classCallCheck3.default)(this, User);\n\n this.private = {\n api: (0, _api.getApi)('V3', tokenV3),\n apiV2: (0, _api.getApi)('V2', tokenV2),\n tokenV2: tokenV2,\n tokenV3: tokenV3\n };\n }\n\n /**\n * Gets user achievements. Does not need auth.\n * @param {String} username\n * @return {Object}\n */\n\n\n (0, _createClass3.default)(User, [{\n key: 'getAchievements',\n value: function () {\n var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(username) {\n var res;\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 this.private.apiV2.get('/users/' + username);\n\n case 2:\n res = _context.sent;\n\n if (res.ok) {\n _context.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n _context.next = 7;\n return res.json();\n\n case 7:\n _context.t0 = _context.sent.Achievements;\n\n if (_context.t0) {\n _context.next = 10;\n break;\n }\n\n _context.t0 = [];\n\n case 10:\n return _context.abrupt('return', _context.t0);\n\n case 11:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function getAchievements(_x) {\n return _ref.apply(this, arguments);\n }\n\n return getAchievements;\n }()\n\n /**\n * Gets public user info. Does not need auth.\n * @param {String} username\n * @return {Object}\n */\n\n }, {\n key: 'getUserPublic',\n value: function () {\n var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(username) {\n var res;\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 this.private.apiV2.get('/users/' + username);\n\n case 2:\n res = _context2.sent;\n\n if (res.ok) {\n _context2.next = 5;\n break;\n }\n\n throw new Error(res.statusText);\n\n case 5:\n return _context2.abrupt('return', res.json() || null);\n\n case 6:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, this);\n }));\n\n function getUserPublic(_x2) {\n return _ref2.apply(this, arguments);\n }\n\n return getUserPublic;\n }()\n\n /**\n * Gets user data object for the specified username.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {String} username\n * @return {Promise} Resolves to the user data object.\n */\n\n }, {\n key: 'getUser',\n value: function () {\n var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(username) {\n var url, res;\n return _regenerator2.default.wrap(function _callee3$(_context3) {\n while (1) {\n switch (_context3.prev = _context3.next) {\n case 0:\n url = '/users?filter=handle%3D' + username;\n _context3.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context3.sent;\n _context3.next = 6;\n return (0, _tc.getApiResponsePayload)(res);\n\n case 6:\n return _context3.abrupt('return', _context3.sent[0]);\n\n case 7:\n case 'end':\n return _context3.stop();\n }\n }\n }, _callee3, this);\n }));\n\n function getUser(_x3) {\n return _ref3.apply(this, arguments);\n }\n\n return getUser;\n }()\n\n /**\n * Gets email preferences.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The TopCoder user id\n * @returns {Promise} Resolves to the email preferences result\n */\n\n }, {\n key: 'getEmailPreferences',\n value: function () {\n var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(userId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee4$(_context4) {\n while (1) {\n switch (_context4.prev = _context4.next) {\n case 0:\n url = '/users/' + userId + '/preferences/email';\n _context4.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context4.sent;\n return _context4.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context4.stop();\n }\n }\n }, _callee4, this);\n }));\n\n function getEmailPreferences(_x4) {\n return _ref4.apply(this, arguments);\n }\n\n return getEmailPreferences;\n }()\n\n /**\n * Saves email preferences.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Object} user The TopCoder user\n * @param {Object} preferences The email preferences\n * @returns {Promise} Resolves to the email preferences result\n */\n\n }, {\n key: 'saveEmailPreferences',\n value: function () {\n var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(_ref6, preferences) {\n var firstName = _ref6.firstName,\n lastName = _ref6.lastName,\n userId = _ref6.userId;\n var settings, url, res;\n return _regenerator2.default.wrap(function _callee5$(_context5) {\n while (1) {\n switch (_context5.prev = _context5.next) {\n case 0:\n settings = {\n firstName: firstName,\n lastName: lastName,\n subscriptions: {}\n };\n\n\n if (!preferences) {\n settings.subscriptions.TOPCODER_NL_GEN = true;\n } else {\n settings.subscriptions = preferences;\n }\n url = '/users/' + userId + '/preferences/email';\n _context5.next = 5;\n return this.private.api.putJson(url, { param: settings });\n\n case 5:\n res = _context5.sent;\n return _context5.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 7:\n case 'end':\n return _context5.stop();\n }\n }\n }, _callee5, this);\n }));\n\n function saveEmailPreferences(_x5, _x6) {\n return _ref5.apply(this, arguments);\n }\n\n return saveEmailPreferences;\n }()\n\n /**\n * Gets credential for the specified user id.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The user id\n * @return {Promise} Resolves to the linked accounts array.\n */\n\n }, {\n key: 'getCredential',\n value: function () {\n var _ref7 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee6(userId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee6$(_context6) {\n while (1) {\n switch (_context6.prev = _context6.next) {\n case 0:\n url = '/users/' + userId + '?fields=credential';\n _context6.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context6.sent;\n return _context6.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context6.stop();\n }\n }\n }, _callee6, this);\n }));\n\n function getCredential(_x7) {\n return _ref7.apply(this, arguments);\n }\n\n return getCredential;\n }()\n\n /**\n * Updates user password.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The user id\n * @param {String} newPassword The new password\n * @param {String} oldPassword The old password\n * @return {Promise} Resolves to the update result.\n */\n\n }, {\n key: 'updatePassword',\n value: function () {\n var _ref8 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee7(userId, newPassword, oldPassword) {\n var credential, url, res;\n return _regenerator2.default.wrap(function _callee7$(_context7) {\n while (1) {\n switch (_context7.prev = _context7.next) {\n case 0:\n credential = {\n password: newPassword,\n currentPassword: oldPassword\n };\n url = '/users/' + userId;\n _context7.next = 4;\n return this.private.api.patchJson(url, { param: { credential: credential } });\n\n case 4:\n res = _context7.sent;\n return _context7.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 6:\n case 'end':\n return _context7.stop();\n }\n }\n }, _callee7, this);\n }));\n\n function updatePassword(_x8, _x9, _x10) {\n return _ref8.apply(this, arguments);\n }\n\n return updatePassword;\n }()\n\n /**\n * Gets linked accounts for the specified user id.\n *\n * NOTE: Only admins are authorized to use the underlying endpoint.\n *\n * @param {Number} userId The user id\n * @return {Promise} Resolves to the linked accounts array.\n */\n\n }, {\n key: 'getLinkedAccounts',\n value: function () {\n var _ref9 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee8(userId) {\n var url, res;\n return _regenerator2.default.wrap(function _callee8$(_context8) {\n while (1) {\n switch (_context8.prev = _context8.next) {\n case 0:\n url = '/users/' + userId + '?fields=profiles';\n _context8.next = 3;\n return this.private.api.get(url);\n\n case 3:\n res = _context8.sent;\n return _context8.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context8.stop();\n }\n }\n }, _callee8, this);\n }));\n\n function getLinkedAccounts(_x11) {\n return _ref9.apply(this, arguments);\n }\n\n return getLinkedAccounts;\n }()\n\n /**\n * Unlinks external account.\n * @param {Number} userId The TopCoder user id\n * @param {String} provider The external account service provider\n * @returns {Promise} Resolves to the unlink result\n */\n\n }, {\n key: 'unlinkExternalAccount',\n value: function () {\n var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee9(userId, provider) {\n var url, res;\n return _regenerator2.default.wrap(function _callee9$(_context9) {\n while (1) {\n switch (_context9.prev = _context9.next) {\n case 0:\n url = '/users/' + userId + '/profiles/' + provider;\n _context9.next = 3;\n return this.private.api.delete(url);\n\n case 3:\n res = _context9.sent;\n return _context9.abrupt('return', (0, _tc.getApiResponsePayload)(res));\n\n case 5:\n case 'end':\n return _context9.stop();\n }\n }\n }, _callee9, this);\n }));\n\n function unlinkExternalAccount(_x12, _x13) {\n return _ref10.apply(this, arguments);\n }\n\n return unlinkExternalAccount;\n }()\n\n /**\n * Links external account.\n * @param {Number} userId The TopCoder user id\n * @param {String} provider The external account service provider\n * @param {String} callbackUrl Optional. The callback url\n * @returns {Promise} Resolves to the linked account result\n */\n\n }, {\n key: 'linkExternalAccount',\n value: function () {\n var _ref11 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee10(userId, provider, callbackUrl) {\n var _this = this;\n\n return _regenerator2.default.wrap(function _callee10$(_context10) {\n while (1) {\n switch (_context10.prev = _context10.next) {\n case 0:\n return _context10.abrupt('return', new _promise2.default(function (resolve, reject) {\n getAuth0().signin({\n popup: true,\n connection: provider,\n scope: 'openid profile offline_access',\n state: callbackUrl\n }, function (authError, profile, idToken, accessToken) {\n if (authError) {\n _logger2.default.error('Error signing in - onSocialLoginFailure', authError);\n reject(authError);\n return;\n }\n\n var socialData = getSocialUserData(profile, accessToken);\n\n var postData = {\n userId: socialData.socialUserId,\n name: socialData.username,\n email: socialData.email,\n emailVerified: false,\n providerType: socialData.socialProvider,\n context: {\n handle: socialData.username,\n accessToken: socialData.accessToken,\n auth0UserId: profile.user_id\n }\n };\n if (socialData.accessTokenSecret) {\n postData.context.accessTokenSecret = socialData.accessTokenSecret;\n }\n _logger2.default.debug('link API postdata: ' + (0, _stringify2.default)(postData));\n _this.private.api.postJson('/users/' + userId + '/profiles', { param: postData }).then(function (resp) {\n return (0, _tc.getApiResponsePayload)(resp).then(function (result) {\n _logger2.default.debug('Succesfully linked account: ' + (0, _stringify2.default)(result));\n resolve(postData);\n });\n }).catch(function (err) {\n _logger2.default.error('Error linking account', err);\n reject(err);\n });\n });\n }));\n\n case 1:\n case 'end':\n return _context10.stop();\n }\n }\n }, _callee10, this);\n }));\n\n function linkExternalAccount(_x14, _x15, _x16) {\n return _ref11.apply(this, arguments);\n }\n\n return linkExternalAccount;\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 User;\n}();\n\nvar lastInstance = null;\n\n/**\n * Returns a new or existing User service for the specified tokenV3.\n * @param {String} tokenV3 Optional. Topcoder auth token v3.\n * @param {String} tokenV2 Optional. TC auth token v2.\n * @return {Api} API v3 service object.\n */\nfunction getService(tokenV3, tokenV2) {\n if (!lastInstance || lastInstance.private.tokenV2 !== tokenV2 || lastInstance.private.tokenV3 !== tokenV3) {\n lastInstance = new User(tokenV3, tokenV2);\n }\n return lastInstance;\n}\n\n/**\n * @static\n * @member default\n * @desc Default export is {@link module:services.user~User} class.\n */\nvar _default = User;\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(auth0, 'auth0', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(getAuth0, 'getAuth0', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(getSocialUserData, 'getSocialUserData', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(User, 'User', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(lastInstance, 'lastInstance', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(getService, 'getService', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.js');\n reactHotLoader.register(_default, 'default', '/Users/thomaskranitsas/Desktop/topcoder-react-lib/src/services/user.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-lib/./src/services/user.js?");
/***/ }),
diff --git a/dist/prod/index.js b/dist/prod/index.js
index 37e90bfb..720910a8 100644
--- a/dist/prod/index.js
+++ b/dist/prod/index.js
@@ -1,6 +1,6 @@
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("lodash"),require("babel-runtime/core-js/promise"),require("redux-actions"),require("babel-runtime/helpers/extends"),require("babel-runtime/regenerator"),require("babel-runtime/helpers/asyncToGenerator"),require("babel-runtime/helpers/defineProperty"),require("topcoder-react-utils"),require("babel-runtime/helpers/classCallCheck"),require("babel-runtime/helpers/createClass"),require("qs"),require("babel-runtime/core-js/json/stringify"),require("babel-runtime/helpers/slicedToArray"),require("tc-accounts"),require("babel-runtime/helpers/toConsumableArray"),require("moment"),require("babel-runtime/core-js/set"),require("isomorphic-fetch"),require("babel-runtime/core-js/object/keys"),require("moment-duration-format"),require("babel-runtime/core-js/set-immediate"),require("le_node"),require("to-capital-case"),require("babel-runtime/core-js/object/values")):"function"==typeof define&&define.amd?define(["lodash","babel-runtime/core-js/promise","redux-actions","babel-runtime/helpers/extends","babel-runtime/regenerator","babel-runtime/helpers/asyncToGenerator","babel-runtime/helpers/defineProperty","topcoder-react-utils","babel-runtime/helpers/classCallCheck","babel-runtime/helpers/createClass","qs","babel-runtime/core-js/json/stringify","babel-runtime/helpers/slicedToArray","tc-accounts","babel-runtime/helpers/toConsumableArray","moment","babel-runtime/core-js/set","isomorphic-fetch","babel-runtime/core-js/object/keys","moment-duration-format","babel-runtime/core-js/set-immediate","le_node","to-capital-case","babel-runtime/core-js/object/values"],t):"object"==typeof exports?exports["topcoder-react-lib"]=t(require("lodash"),require("babel-runtime/core-js/promise"),require("redux-actions"),require("babel-runtime/helpers/extends"),require("babel-runtime/regenerator"),require("babel-runtime/helpers/asyncToGenerator"),require("babel-runtime/helpers/defineProperty"),require("topcoder-react-utils"),require("babel-runtime/helpers/classCallCheck"),require("babel-runtime/helpers/createClass"),require("qs"),require("babel-runtime/core-js/json/stringify"),require("babel-runtime/helpers/slicedToArray"),require("tc-accounts"),require("babel-runtime/helpers/toConsumableArray"),require("moment"),require("babel-runtime/core-js/set"),require("isomorphic-fetch"),require("babel-runtime/core-js/object/keys"),require("moment-duration-format"),require("babel-runtime/core-js/set-immediate"),require("le_node"),require("to-capital-case"),require("babel-runtime/core-js/object/values")):e["topcoder-react-lib"]=t(e.lodash,e["babel-runtime/core-js/promise"],e["redux-actions"],e["babel-runtime/helpers/extends"],e["babel-runtime/regenerator"],e["babel-runtime/helpers/asyncToGenerator"],e["babel-runtime/helpers/defineProperty"],e["topcoder-react-utils"],e["babel-runtime/helpers/classCallCheck"],e["babel-runtime/helpers/createClass"],e.qs,e["babel-runtime/core-js/json/stringify"],e["babel-runtime/helpers/slicedToArray"],e["tc-accounts"],e["babel-runtime/helpers/toConsumableArray"],e.moment,e["babel-runtime/core-js/set"],e["isomorphic-fetch"],e["babel-runtime/core-js/object/keys"],e["moment-duration-format"],e["babel-runtime/core-js/set-immediate"],e.le_node,e["to-capital-case"],e["babel-runtime/core-js/object/values"])}("undefined"!=typeof self?self:this,function(__WEBPACK_EXTERNAL_MODULE__0__,__WEBPACK_EXTERNAL_MODULE__1__,__WEBPACK_EXTERNAL_MODULE__2__,__WEBPACK_EXTERNAL_MODULE__3__,__WEBPACK_EXTERNAL_MODULE__4__,__WEBPACK_EXTERNAL_MODULE__5__,__WEBPACK_EXTERNAL_MODULE__6__,__WEBPACK_EXTERNAL_MODULE__8__,__WEBPACK_EXTERNAL_MODULE__9__,__WEBPACK_EXTERNAL_MODULE__10__,__WEBPACK_EXTERNAL_MODULE__14__,__WEBPACK_EXTERNAL_MODULE__15__,__WEBPACK_EXTERNAL_MODULE__16__,__WEBPACK_EXTERNAL_MODULE__17__,__WEBPACK_EXTERNAL_MODULE__19__,__WEBPACK_EXTERNAL_MODULE__20__,__WEBPACK_EXTERNAL_MODULE__23__,__WEBPACK_EXTERNAL_MODULE__29__,__WEBPACK_EXTERNAL_MODULE__53__,__WEBPACK_EXTERNAL_MODULE__54__,__WEBPACK_EXTERNAL_MODULE__55__,__WEBPACK_EXTERNAL_MODULE__56__,__WEBPACK_EXTERNAL_MODULE__90__,__WEBPACK_EXTERNAL_MODULE__103__){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=51)}([function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__0__},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__1__},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__2__},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__3__},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__4__},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__5__},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE__6__},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getTcM2mToken=void 0;var r=y(n(53)),o=y(n(1)),a=y(n(15)),i=y(n(4)),s=y(n(3)),u=y(n(5)),l=y(n(9)),c=y(n(10)),d=t.getTcM2mToken=function(){var e=(0,u.default)(i.default.mark(function e(){var t,n,r,o;return i.default.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(h.isomorphy.isServerSide()){e.next=2;break}throw new Error("getTcM2mToken() called outside the server");case 2:if(t=Date.now(),n=d.cached,r=h.config.SECRET.TC_M2M,n&&!(n.expires
\r\nOnce signed, you will be automatically added to the NDA terms of use and notified by email. \r\n
',agreed:!1,docusignTemplateId:"fake-template-id",serverInformation:{serverName:"TopCoder API",apiVersion:"0.0.1",requestDuration:4,currentTime:1504891122158},requesterInformation:{id:"d9994de712597c11d1caad64996d9fa0d9b4aa2c-w2VCwwGwnN6EeyhK",remoteIP:"12.34.56.789",receivedParams:{apiVersion:"v2",termsOfUseId:"21153",action:"getTermsOfUse"}}}},function(e){e.exports={terms:[{termsOfUseId:21193,title:"Standard Terms for Topcoder Competitions v2.1",url:"",agreeabilityType:"Electronically-agreeable",templateId:null},{termsOfUseId:21153,title:"Appirio NDA v2.0",url:"http://community.topcoder.com/tc?module=Terms&tuid=21153",agreeabilityType:"DocuSignable",templateId:"fake-template-id"}],serverInformation:{serverName:"Topcoder API",apiVersion:"0.0.1",requestDuration:11471,currentTime:1504879510947},requesterInformation:{id:"456f987dee6e9823179c8184fd3509ffdf9c613a-FyefLdEpb8UHgFQF",remoteIP:"12.34.567.890",receivedParams:{role:"Submitter",noauth:"true",apiVersion:"v2",challengeId:"30059255",action:"getChallengeTerms"}}}},function(e){e.exports={terms:[{termsOfUseId:21153,title:"Appirio NDA v2.0",url:"http://community.topcoder.com/tc?module=Terms&tuid=21153",agreeabilityType:"DocuSignable",agreed:!1,templateId:"fake-template-id"},{termsOfUseId:20704,title:"Standard Reviewer Terms v1.0",url:"",agreeabilityType:"Electronically-agreeable",agreed:!1,templateId:null}],serverInformation:{serverName:"Topcoder API",apiVersion:"0.0.1",requestDuration:29,currentTime:1504878884618},requesterInformation:{id:"1b37607c519c318194ce6da08c519c0a3f7c9855-7FSFCyd6oSX2mV6Z",remoteIP:"12.34.567.890",receivedParams:{role:"Submitter",apiVersion:"v2",challengeId:"30059255",action:"getChallengeTerms"}}}},function(e){e.exports={termsOfUseId:20704,title:"Standard Reviewer Terms v1.0",url:"",text:'THESE ARE THE TERMS AND CONDITIONS ("TERMS") UNDER WHICH YOU AGREE TO WORK UNDER AS A TOPCODER REVIEW BOARD MEMBER. THESE TERMS AND CONDITIONS AFFECT YOUR RIGHTS AND YOU SHOULD READ THEM CAREFULLY BEFORE AGREEING TO THEM. IN THESE TERMS AND CONDITIONS, "WE," "US," "ITS" AND "OUR" REFER TO TOPCODER, INC. AND "YOU" AND "YOUR" REFER TO YOU.
\r\n\r\nIt is understood that We need, and You have, expertise in evaluating and critiquing software designs and/or software development solutions. Furthermore, You agree that You are ready, willing, and able to undertake the performance of evaluating and critiquing such software designs and/or software development solutions submitted to Us, and You agree to assign and transfer your rights as a result of performing such services.
\r\n\r\nIn consideration of the premises and the mutual promises and covenants set forth herein, and for other good and valuable consideration, the receipt and sufficiency of which are hereby acknowledged, the parties agree as follows:
\r\n\r\nAs used in these Terms, the following capitalized terms shall have the following meanings unless otherwise indicated:
\r\n\r\n1.1.\t"Development(s)" shall mean any idea, design, concept, development, component, algorithm, process, method, formula, code, software, technique, technology, discovery or improvement, whether or not patentable, made, conceived, created, discovered, invented or reduced to practice by You in connection with the performance of services hereunder.
\r\n\r\n1.2.\t"Intellectual Property Rights" shall mean all intellectual property rights worldwide arising under statutory or common law or by contract and whether or not perfected, now existing or hereafter filed, issued or acquired, including all patent rights; all rights associated with works of authorship including copyrights and moral rights; rights relating to the protection of trade secrets and confidential information; and any right analogous to those set forth herein and any other proprietary rights relating to intangible property, other than Trademarks.
\r\n\r\n1.3.\t"TopCoder Information" shall mean TopCoder\'s and TopCoder Software\'s specifications, descriptions, architecture, plans, interfaces, and code for TopCoder\'s and TopCoder Software\'s hardware, software, and web site; TopCoder\'s competitions and competition operation procedures; TopCoder\'s and TopCoder Software\'s business and operational plans; and derivatives of the foregoing. The TopCoder Information shall be Confidential Information hereunder.
\r\n\r\n1.4.\t"Software Component" shall mean all software and related materials, technology and documentation (including without limitation design documents, source code and object code) to be evaluated and assessed by You for Us hereunder in accordance with our requirements, as set forth herein and in other documents provided by Us. The Software Component shall be Confidential Information hereunder.
\r\n\r\n2.1\tYou hereby agree to provide services relating to the evaluation and assessment of the Software Component. You agree to perform such services according to and in conformity with the following specifications, in addition to any specifications and/or scheduled provided by Us in our sole discretion (the "Services"):
\r\n\r\n2.2\tYou agree to commit sufficient time and resources to perform the Services according to the schedule set forth by Us. You shall promptly notify Us of any circumstances, as such circumstances arise, that may reasonably be anticipated to lead to a material deviation from the schedule.
\r\n\r\n2.3\tYou agree to keep Us updated, promptly upon our request, of any progress, problems, and/or developments of which You are aware regarding the Services. We shall have the right to require such updates in writing from You in a format specified by Us or acceptable to Us in our sole discretion. You shall conduct and conclude the Services in a professional manner.
\r\n\r\n3.1\tFee. In consideration for performance of the Services required by You, We shall pay You the fee set forth on TopCoder\'s website and/or in other correspondence from Us to You (the "Fee"). The Fee shall be in U.S. Dollars and may be paid in installments, as set forth on our website or in other correspondence from Us. The Fee shall be paid upon the conclusion of the review period, and once completed scorecards have been received, provided the completed scorecards are submitted to Us by the deadline as set forth on the website and/or in the correspondence from Us.
\r\n\r\n3.2\tRoyalty Payments.
\r\n \r\n(a)\tDefinitions. As used in this Section 3, the following capitalized terms shall have the following meanings unless otherwise indicated:
\r\n(b)\tIn consideration of Your evaluation of the Software Components and performance of Your obligations hereunder, We may pay to You a royalty (the "Royalty Payment"). The Royalty Payment to be paid shall be a portion of the Royalty Pool. The Royalty Pool shall be distributed as follows:
\r\n\r\n3.3\tTotal Payment. The sum of the Fee and the Royalty Payments shall be the total payment due to You. Any and all out-of-pocket expenses incurred by You in connection with performing the obligations hereunder are your sole responsibility. We will not reimburse You for any expenses incurred.
\r\n\r\n3.4\tYou shall not be entitled to receive any other compensation or any benefits from Us in connection with the Services. Except as otherwise required by law, We shall not withhold any sums or payments made to You for social security or other federal, state or local tax liabilities or contributions, and all withholdings, liabilities, and contributions shall be solely your responsibility. Further, You understand and agree that the Services are not covered under the unemployment compensation laws and are not intended to be covered by workers\' compensation laws.
\r\n\r\n4.1\tYou hereby acknowledge and agree that We own, solely and exclusively, all right, title and interest, including all Intellectual Property Rights, in and to the TopCoder Information. In addition, You hereby irrevocably and unconditionally transfer and assign to Us all right, title and interest You had, have, may have or acquire in or to all Developments and Software Components, and You agree to execute and deliver such documents, certificates, assignments and other writings, and take such other actions as may be necessary or desirable to vest in Us the ownership rights granted to Us hereunder.
\r\n\r\n4.2\tYou further agree that any and all works of authorship created, authored or developed by You hereunder shall be deemed to be "works made for hire" within the meaning of the United States Copyright Law and, as such, all rights therein including copyright shall belong solely and exclusively to Us from the time of their creation. To the extent any such work of authorship may not be deemed to be a work made for hire, You agree to, and do hereby, irrevocably and unconditionally transfer and assign to Us all right, title and interest including copyright in and to such work.
\r\n\r\n4.3\tYou agree that if We are unable, because of your unavailability, or for any other reason, to secure your signature to apply for or to pursue any application for any United States or foreign patents, mask work, copyright or trademark registrations covering the assignments to Us above, then You hereby irrevocably designates and appoints Us and your duly authorized officers and agents as your agent and attorney in fact, to act for and in your behalf and stead to execute and file any such applications and to do all other lawfully permitted acts to further the prosecution and issuance of patents, copyright, mask work and trademark registrations thereon with the same legal force and effect as if executed by your authorized agent.
\r\n\r\n4.4\tAll Intellectual Property Rights owned by a party as of the date You agree to these Terms shall remain the property of such party and no licenses or other rights with respect to such intellectual property are granted to the other party except as expressly set forth herein.
\r\n\r\n4.5\tNothing in these terms shall be construed as granting You any right or license under any of our Intellectual Property Right (including any rights We may have in any patents, copyrights, trademarks, service marks or any trade secrets), by implication, estoppel or otherwise, except as expressly set forth herein.
\r\n\r\n5.1\t"Confidential Information" shall mean any information, in whatever form, provided by Us to You with obligation of confidentiality, or designated by Us in writing as confidential, proprietary or marked with words of like import when provided to You, and information orally conveyed if We state at the time of oral conveyance or promptly thereafter that such information is confidential. Notwithstanding anything to the contrary contained herein, information about or relating to our software, our system interfaces, our hardware and software architecture, our business, operational and marketing plans, our member lists and database, all information and technology provided by Us to You to enable You to perform your obligations hereunder, TopCoder Information, and any and all Developments shall be considered Confidential Information.
\r\n\r\n5.2\tConfidential Information shall not include information which (a) was in your possession without confidentiality restriction prior to disclosure by Us hereunder; (b) at or after the time of disclosure by Us becomes generally available to the public through no act or omission on our part; (c) is developed by You independently of and without reference to any Confidential Information You receive from Us; or (d) has come into your possession without confidentiality restriction from a third party and such third party is under no obligation to Us to maintain the confidentiality of such information.
\r\n\r\n5.3\tYou acknowledge the confidential and proprietary nature of Confidential Information and agree (i) to hold Confidential Information in confidence and to take all reasonable precautions to protect such Confidential Information (including, without limitation, all precautions You employ with respect to your own confidential materials), (ii) not to divulge any such Confidential Information to any third person; and (iii) not to make any use whatsoever of such Confidential Information except as expressly authorized herein.
\r\n\r\n5.4\tIn the event You are ordered to disclose Confidential Information pursuant to a judicial or government request, requirement or order, You shall promptly notify Us and upon our request, You shall, at our expense, take reasonable steps to assist Us in contesting such request, requirement or order or in otherwise protecting our rights prior to disclosure.
\r\n\r\n5.5\tYou agree not to reproduce or copy by any means Confidential Information, except as reasonably required to perform the Services. Upon termination of your performance of the Services as a review board member, your right to use Confidential Information shall immediately terminate. In addition, upon such termination, or upon demand by Us at any time, You shall return promptly to Us or destroy, at our option, all tangible materials and computer data that disclose or embody Confidential Information.
\r\n\r\n5.6\tYou agree that any breach of these terms by You could cause irreparable damage to Us. In view of the difficulties of placing a monetary value on the Confidential Information, We shall have, in addition to any and all remedies of law, the right to an injunction or other equitable relief, and may be entitled to a preliminary and final injunction without the necessity of posting any bond or undertaking in connection therewith to prevent any further breach or further unauthorized use of Confidential Information. This remedy is separate from any other remedy We may have.
\r\n\r\n6.1\tYou represent and warrant that:\r\n
7.1\tYou shall indemnify, hold harmless and defend Us and our customers from and against any and all suits, actions, damages, costs, losses, expenses (including settlement awards and reasonable attorneys\' fees) and other liabilities arising from or in connection with any claim alleging that, to your knowledge, any Development and/or Software Component violates any trade secret right, or infringes any copyright, patent, trademark, or other intellectual property interest, in any country, and shall pay all costs and damages awarded. We shall promptly notify You of any such claim of which We are aware.
\r\n\r\n7.2\tYour obligations shall not extend to any claim for violation or infringement resulting solely from your compliance with any specific or direct written instructions from Us if such infringement would have been avoided but for such compliance.
\r\n\r\n8.1\tBoth parties expressly agree and understand that You are an independent contractor and nothing herein nor the services rendered hereunder is meant, or shall be construed in any way or manner, to create a relationship of employer and employee, principal and agent, partners or any other relationship other than that of independent parties contracting with each other solely for the purpose of carrying out the provisions of these Terms. Accordingly, You acknowledge and agree that You shall not be entitled to any benefits provided by Us to our employees. You shall be responsible for any and all out-of-pocket expenses incurred in connection with performing the Services. In addition, You shall have sole and exclusive responsibility for the payment of all federal, state and local income taxes, for all employment and disability insurance and for Social Security and other similar taxes with respect to any compensation provided by Us hereunder. You further agree that if We pay or become liable for such taxes or related civil penalties or interest as a result of your failure to pay taxes or report same, or due to our failure to withhold taxes, You shall indemnify and hold us harmless for any such liability. You shall assume and accept all responsibilities which are imposed on independent contractors by any statute, regulation, rule of law, or otherwise. You are not our agent and are not authorized and shall not have the power or authority to bind Us or incur any liability or obligation, or act on behalf of Us. At no time shall You represent that You are our agent, or that any of the views, advice, statements and/or information that may be provided while performing the Services are ours.
\r\n\r\n8.2\tWe are entitled to provide You with general guidance to assist You in completing the scope of work to our satisfaction, You are ultimately responsible for directing and controlling the performance of the task and the scope of work, in accordance with these Terms. You shall use your best efforts, energy and skill in your own name and in such manner as You see fit.
',agreeabilityType:"Electronically-agreeable",serverInformation:{serverName:"Topcoder API",apiVersion:"0.0.1",requestDuration:52,currentTime:1504892902498},requesterInformation:{id:"d8c441f8332161f71533f368c09aeead856e4366-K1RdFai7LCAgXVu5",remoteIP:"12.34.56.78",receivedParams:{apiVersion:"v2",termsOfUseId:"21193",action:"getTermsOfUse"}}}},function(e){e.exports={termsOfUseId:21193,title:"Standard Terms for Topcoder Competitions v2.1",url:"",agreeabilityType:"Electronically-agreeable",text:'\r\n\r\n\r\n\r\n\r\n\r\nBY E-MAIL: | \r\nGC@appirio.com | \r\n
BY MAIL: | \r\nDan Lascell\r\n\r\nTopcoder, Inc.\r\n\r\n760 Market Street\r\n\r\nSan Francisco, CA 94102 | \r\n
BY PHONE: | \r\n(650) 268-9911 | \r\n
\r\nOnce signed, you will be automatically added to the NDA terms of use and notified by email. \r\n
',agreed:!1,docusignTemplateId:"fake-template-id",serverInformation:{serverName:"TopCoder API",apiVersion:"0.0.1",requestDuration:4,currentTime:1504891122158},requesterInformation:{id:"d9994de712597c11d1caad64996d9fa0d9b4aa2c-w2VCwwGwnN6EeyhK",remoteIP:"12.34.56.789",receivedParams:{apiVersion:"v2",termsOfUseId:"21153",action:"getTermsOfUse"}}}},function(e){e.exports={terms:[{termsOfUseId:21193,title:"Standard Terms for Topcoder Competitions v2.1",url:"",agreeabilityType:"Electronically-agreeable",templateId:null},{termsOfUseId:21153,title:"Appirio NDA v2.0",url:"http://community.topcoder.com/tc?module=Terms&tuid=21153",agreeabilityType:"DocuSignable",templateId:"fake-template-id"}],serverInformation:{serverName:"Topcoder API",apiVersion:"0.0.1",requestDuration:11471,currentTime:1504879510947},requesterInformation:{id:"456f987dee6e9823179c8184fd3509ffdf9c613a-FyefLdEpb8UHgFQF",remoteIP:"12.34.567.890",receivedParams:{role:"Submitter",noauth:"true",apiVersion:"v2",challengeId:"30059255",action:"getChallengeTerms"}}}},function(e){e.exports={terms:[{termsOfUseId:21153,title:"Appirio NDA v2.0",url:"http://community.topcoder.com/tc?module=Terms&tuid=21153",agreeabilityType:"DocuSignable",agreed:!1,templateId:"fake-template-id"},{termsOfUseId:20704,title:"Standard Reviewer Terms v1.0",url:"",agreeabilityType:"Electronically-agreeable",agreed:!1,templateId:null}],serverInformation:{serverName:"Topcoder API",apiVersion:"0.0.1",requestDuration:29,currentTime:1504878884618},requesterInformation:{id:"1b37607c519c318194ce6da08c519c0a3f7c9855-7FSFCyd6oSX2mV6Z",remoteIP:"12.34.567.890",receivedParams:{role:"Submitter",apiVersion:"v2",challengeId:"30059255",action:"getChallengeTerms"}}}},function(e){e.exports={termsOfUseId:20704,title:"Standard Reviewer Terms v1.0",url:"",text:'THESE ARE THE TERMS AND CONDITIONS ("TERMS") UNDER WHICH YOU AGREE TO WORK UNDER AS A TOPCODER REVIEW BOARD MEMBER. THESE TERMS AND CONDITIONS AFFECT YOUR RIGHTS AND YOU SHOULD READ THEM CAREFULLY BEFORE AGREEING TO THEM. IN THESE TERMS AND CONDITIONS, "WE," "US," "ITS" AND "OUR" REFER TO TOPCODER, INC. AND "YOU" AND "YOUR" REFER TO YOU.
\r\n\r\nIt is understood that We need, and You have, expertise in evaluating and critiquing software designs and/or software development solutions. Furthermore, You agree that You are ready, willing, and able to undertake the performance of evaluating and critiquing such software designs and/or software development solutions submitted to Us, and You agree to assign and transfer your rights as a result of performing such services.
\r\n\r\nIn consideration of the premises and the mutual promises and covenants set forth herein, and for other good and valuable consideration, the receipt and sufficiency of which are hereby acknowledged, the parties agree as follows:
\r\n\r\nAs used in these Terms, the following capitalized terms shall have the following meanings unless otherwise indicated:
\r\n\r\n1.1.\t"Development(s)" shall mean any idea, design, concept, development, component, algorithm, process, method, formula, code, software, technique, technology, discovery or improvement, whether or not patentable, made, conceived, created, discovered, invented or reduced to practice by You in connection with the performance of services hereunder.
\r\n\r\n1.2.\t"Intellectual Property Rights" shall mean all intellectual property rights worldwide arising under statutory or common law or by contract and whether or not perfected, now existing or hereafter filed, issued or acquired, including all patent rights; all rights associated with works of authorship including copyrights and moral rights; rights relating to the protection of trade secrets and confidential information; and any right analogous to those set forth herein and any other proprietary rights relating to intangible property, other than Trademarks.
\r\n\r\n1.3.\t"TopCoder Information" shall mean TopCoder\'s and TopCoder Software\'s specifications, descriptions, architecture, plans, interfaces, and code for TopCoder\'s and TopCoder Software\'s hardware, software, and web site; TopCoder\'s competitions and competition operation procedures; TopCoder\'s and TopCoder Software\'s business and operational plans; and derivatives of the foregoing. The TopCoder Information shall be Confidential Information hereunder.
\r\n\r\n1.4.\t"Software Component" shall mean all software and related materials, technology and documentation (including without limitation design documents, source code and object code) to be evaluated and assessed by You for Us hereunder in accordance with our requirements, as set forth herein and in other documents provided by Us. The Software Component shall be Confidential Information hereunder.
\r\n\r\n2.1\tYou hereby agree to provide services relating to the evaluation and assessment of the Software Component. You agree to perform such services according to and in conformity with the following specifications, in addition to any specifications and/or scheduled provided by Us in our sole discretion (the "Services"):
\r\n\r\n2.2\tYou agree to commit sufficient time and resources to perform the Services according to the schedule set forth by Us. You shall promptly notify Us of any circumstances, as such circumstances arise, that may reasonably be anticipated to lead to a material deviation from the schedule.
\r\n\r\n2.3\tYou agree to keep Us updated, promptly upon our request, of any progress, problems, and/or developments of which You are aware regarding the Services. We shall have the right to require such updates in writing from You in a format specified by Us or acceptable to Us in our sole discretion. You shall conduct and conclude the Services in a professional manner.
\r\n\r\n3.1\tFee. In consideration for performance of the Services required by You, We shall pay You the fee set forth on TopCoder\'s website and/or in other correspondence from Us to You (the "Fee"). The Fee shall be in U.S. Dollars and may be paid in installments, as set forth on our website or in other correspondence from Us. The Fee shall be paid upon the conclusion of the review period, and once completed scorecards have been received, provided the completed scorecards are submitted to Us by the deadline as set forth on the website and/or in the correspondence from Us.
\r\n\r\n3.2\tRoyalty Payments.
\r\n \r\n(a)\tDefinitions. As used in this Section 3, the following capitalized terms shall have the following meanings unless otherwise indicated:
\r\n(b)\tIn consideration of Your evaluation of the Software Components and performance of Your obligations hereunder, We may pay to You a royalty (the "Royalty Payment"). The Royalty Payment to be paid shall be a portion of the Royalty Pool. The Royalty Pool shall be distributed as follows:
\r\n\r\n3.3\tTotal Payment. The sum of the Fee and the Royalty Payments shall be the total payment due to You. Any and all out-of-pocket expenses incurred by You in connection with performing the obligations hereunder are your sole responsibility. We will not reimburse You for any expenses incurred.
\r\n\r\n3.4\tYou shall not be entitled to receive any other compensation or any benefits from Us in connection with the Services. Except as otherwise required by law, We shall not withhold any sums or payments made to You for social security or other federal, state or local tax liabilities or contributions, and all withholdings, liabilities, and contributions shall be solely your responsibility. Further, You understand and agree that the Services are not covered under the unemployment compensation laws and are not intended to be covered by workers\' compensation laws.
\r\n\r\n4.1\tYou hereby acknowledge and agree that We own, solely and exclusively, all right, title and interest, including all Intellectual Property Rights, in and to the TopCoder Information. In addition, You hereby irrevocably and unconditionally transfer and assign to Us all right, title and interest You had, have, may have or acquire in or to all Developments and Software Components, and You agree to execute and deliver such documents, certificates, assignments and other writings, and take such other actions as may be necessary or desirable to vest in Us the ownership rights granted to Us hereunder.
\r\n\r\n4.2\tYou further agree that any and all works of authorship created, authored or developed by You hereunder shall be deemed to be "works made for hire" within the meaning of the United States Copyright Law and, as such, all rights therein including copyright shall belong solely and exclusively to Us from the time of their creation. To the extent any such work of authorship may not be deemed to be a work made for hire, You agree to, and do hereby, irrevocably and unconditionally transfer and assign to Us all right, title and interest including copyright in and to such work.
\r\n\r\n4.3\tYou agree that if We are unable, because of your unavailability, or for any other reason, to secure your signature to apply for or to pursue any application for any United States or foreign patents, mask work, copyright or trademark registrations covering the assignments to Us above, then You hereby irrevocably designates and appoints Us and your duly authorized officers and agents as your agent and attorney in fact, to act for and in your behalf and stead to execute and file any such applications and to do all other lawfully permitted acts to further the prosecution and issuance of patents, copyright, mask work and trademark registrations thereon with the same legal force and effect as if executed by your authorized agent.
\r\n\r\n4.4\tAll Intellectual Property Rights owned by a party as of the date You agree to these Terms shall remain the property of such party and no licenses or other rights with respect to such intellectual property are granted to the other party except as expressly set forth herein.
\r\n\r\n4.5\tNothing in these terms shall be construed as granting You any right or license under any of our Intellectual Property Right (including any rights We may have in any patents, copyrights, trademarks, service marks or any trade secrets), by implication, estoppel or otherwise, except as expressly set forth herein.
\r\n\r\n5.1\t"Confidential Information" shall mean any information, in whatever form, provided by Us to You with obligation of confidentiality, or designated by Us in writing as confidential, proprietary or marked with words of like import when provided to You, and information orally conveyed if We state at the time of oral conveyance or promptly thereafter that such information is confidential. Notwithstanding anything to the contrary contained herein, information about or relating to our software, our system interfaces, our hardware and software architecture, our business, operational and marketing plans, our member lists and database, all information and technology provided by Us to You to enable You to perform your obligations hereunder, TopCoder Information, and any and all Developments shall be considered Confidential Information.
\r\n\r\n5.2\tConfidential Information shall not include information which (a) was in your possession without confidentiality restriction prior to disclosure by Us hereunder; (b) at or after the time of disclosure by Us becomes generally available to the public through no act or omission on our part; (c) is developed by You independently of and without reference to any Confidential Information You receive from Us; or (d) has come into your possession without confidentiality restriction from a third party and such third party is under no obligation to Us to maintain the confidentiality of such information.
\r\n\r\n5.3\tYou acknowledge the confidential and proprietary nature of Confidential Information and agree (i) to hold Confidential Information in confidence and to take all reasonable precautions to protect such Confidential Information (including, without limitation, all precautions You employ with respect to your own confidential materials), (ii) not to divulge any such Confidential Information to any third person; and (iii) not to make any use whatsoever of such Confidential Information except as expressly authorized herein.
\r\n\r\n5.4\tIn the event You are ordered to disclose Confidential Information pursuant to a judicial or government request, requirement or order, You shall promptly notify Us and upon our request, You shall, at our expense, take reasonable steps to assist Us in contesting such request, requirement or order or in otherwise protecting our rights prior to disclosure.
\r\n\r\n5.5\tYou agree not to reproduce or copy by any means Confidential Information, except as reasonably required to perform the Services. Upon termination of your performance of the Services as a review board member, your right to use Confidential Information shall immediately terminate. In addition, upon such termination, or upon demand by Us at any time, You shall return promptly to Us or destroy, at our option, all tangible materials and computer data that disclose or embody Confidential Information.
\r\n\r\n5.6\tYou agree that any breach of these terms by You could cause irreparable damage to Us. In view of the difficulties of placing a monetary value on the Confidential Information, We shall have, in addition to any and all remedies of law, the right to an injunction or other equitable relief, and may be entitled to a preliminary and final injunction without the necessity of posting any bond or undertaking in connection therewith to prevent any further breach or further unauthorized use of Confidential Information. This remedy is separate from any other remedy We may have.
\r\n\r\n6.1\tYou represent and warrant that:\r\n
7.1\tYou shall indemnify, hold harmless and defend Us and our customers from and against any and all suits, actions, damages, costs, losses, expenses (including settlement awards and reasonable attorneys\' fees) and other liabilities arising from or in connection with any claim alleging that, to your knowledge, any Development and/or Software Component violates any trade secret right, or infringes any copyright, patent, trademark, or other intellectual property interest, in any country, and shall pay all costs and damages awarded. We shall promptly notify You of any such claim of which We are aware.
\r\n\r\n7.2\tYour obligations shall not extend to any claim for violation or infringement resulting solely from your compliance with any specific or direct written instructions from Us if such infringement would have been avoided but for such compliance.
\r\n\r\n8.1\tBoth parties expressly agree and understand that You are an independent contractor and nothing herein nor the services rendered hereunder is meant, or shall be construed in any way or manner, to create a relationship of employer and employee, principal and agent, partners or any other relationship other than that of independent parties contracting with each other solely for the purpose of carrying out the provisions of these Terms. Accordingly, You acknowledge and agree that You shall not be entitled to any benefits provided by Us to our employees. You shall be responsible for any and all out-of-pocket expenses incurred in connection with performing the Services. In addition, You shall have sole and exclusive responsibility for the payment of all federal, state and local income taxes, for all employment and disability insurance and for Social Security and other similar taxes with respect to any compensation provided by Us hereunder. You further agree that if We pay or become liable for such taxes or related civil penalties or interest as a result of your failure to pay taxes or report same, or due to our failure to withhold taxes, You shall indemnify and hold us harmless for any such liability. You shall assume and accept all responsibilities which are imposed on independent contractors by any statute, regulation, rule of law, or otherwise. You are not our agent and are not authorized and shall not have the power or authority to bind Us or incur any liability or obligation, or act on behalf of Us. At no time shall You represent that You are our agent, or that any of the views, advice, statements and/or information that may be provided while performing the Services are ours.
\r\n\r\n8.2\tWe are entitled to provide You with general guidance to assist You in completing the scope of work to our satisfaction, You are ultimately responsible for directing and controlling the performance of the task and the scope of work, in accordance with these Terms. You shall use your best efforts, energy and skill in your own name and in such manner as You see fit.
',agreeabilityType:"Electronically-agreeable",serverInformation:{serverName:"Topcoder API",apiVersion:"0.0.1",requestDuration:52,currentTime:1504892902498},requesterInformation:{id:"d8c441f8332161f71533f368c09aeead856e4366-K1RdFai7LCAgXVu5",remoteIP:"12.34.56.78",receivedParams:{apiVersion:"v2",termsOfUseId:"21193",action:"getTermsOfUse"}}}},function(e){e.exports={termsOfUseId:21193,title:"Standard Terms for Topcoder Competitions v2.1",url:"",agreeabilityType:"Electronically-agreeable",text:'\r\n\r\n\r\n\r\n\r\n\r\nBY E-MAIL: | \r\nGC@appirio.com | \r\n
BY MAIL: | \r\nDan Lascell\r\n\r\nTopcoder, Inc.\r\n\r\n760 Market Street\r\n\r\nSan Francisco, CA 94102 | \r\n
BY PHONE: | \r\n(650) 268-9911 | \r\n
Api
- * [.getApiV3(token)](#module_services.api.getApiV3) ⇒ Api
+ * [.getApi(version, token)](#module_services.api.getApi) ⇒ Api
* _inner_
* [~Api](#module_services.api..Api)
* [new Api(base, token)](#new_module_services.api..Api_new)
@@ -30,30 +29,19 @@ The default export from the module is
[Api](#module_services.api..Api) class.
**Kind**: static property of [services.api
](#module_services.api)
-
+
-### services.api.getApiV2(token) ⇒ Api
-Returns a new or existing Api object for Topcoder API v2.
+### services.api.getApi(version, token) ⇒ Api
+Returns a new or existing Api object for Topcoder API.
**Kind**: static method of [services.api
](#module_services.api)
-**Returns**: Api
- API v2 service object.
+**Returns**: Api
- API service object.
| Param | Type | Description |
| --- | --- | --- |
+| version | String
| The version of the API. |
| token | String
| Optional. Auth token for Topcoder API v2. |
-
-
-### services.api.getApiV3(token) ⇒ Api
-Returns a new or existing Api object for Topcoder API v3
-
-**Kind**: static method of [services.api
](#module_services.api)
-**Returns**: Api
- API v3 service object.
-
-| Param | Type | Description |
-| --- | --- | --- |
-| token | String
| Optional. Auth token for Topcoder API v3. |
-
### services.api~Api
diff --git a/src/actions/auth.js b/src/actions/auth.js
index 4a6752bb..c585ec71 100644
--- a/src/actions/auth.js
+++ b/src/actions/auth.js
@@ -5,7 +5,7 @@
import { createActions } from 'redux-actions';
import { decodeToken } from 'tc-accounts';
-import { getApiV3 } from '../services/api';
+import { getApi } from '../services/api';
/**
* @static
@@ -16,7 +16,7 @@ import { getApiV3 } from '../services/api';
function loadProfileDone(userTokenV3) {
if (!userTokenV3) return Promise.resolve(null);
const user = decodeToken(userTokenV3);
- const api = getApiV3(userTokenV3);
+ const api = getApi('V3', userTokenV3);
return Promise.all([
api.get(`/members/${user.handle}`)
.then(res => res.json()).then(res => (res.result.status === 200 ? res.result.content : {})),
diff --git a/src/actions/challenge.js b/src/actions/challenge.js
index a01d9e9b..f5dfb09b 100644
--- a/src/actions/challenge.js
+++ b/src/actions/challenge.js
@@ -7,7 +7,7 @@ import _ from 'lodash';
import { config } from 'topcoder-react-utils';
import { createActions } from 'redux-actions';
import { getService as getChallengesService } from '../services/challenges';
-import { getApiV2 } from '../services/api';
+import { getApi } from '../services/api';
/**
* @static
@@ -70,7 +70,7 @@ function getSubmissionsInit(challengeId) {
* @return {Action}
*/
function getSubmissionsDone(challengeId, tokenV2) {
- return getApiV2(tokenV2)
+ return getApi('V2', tokenV2)
.fetch(`/challenges/submissions/${challengeId}/mySubmissions`)
.then(response => response.json())
.then(response => ({
@@ -169,7 +169,7 @@ function loadResultsInit(challengeId) {
* @return {Action}
*/
function loadResultsDone(auth, challengeId, type) {
- return getApiV2(auth.tokenV2)
+ return getApi('V2', auth.tokenV2)
.fetch(`/${type}/challenges/result/${challengeId}`)
.then(response => response.json())
.then(response => ({
@@ -194,7 +194,7 @@ function fetchCheckpointsInit() {}
*/
function fetchCheckpointsDone(tokenV2, challengeId) {
const endpoint = `/design/challenges/checkpoint/${challengeId}`;
- return getApiV2(tokenV2).fetch(endpoint)
+ return getApi('V2', tokenV2).fetch(endpoint)
.then((response) => {
if (response.status !== 200) {
throw response.status;
diff --git a/src/actions/smp.js b/src/actions/smp.js
index 07370f5d..9c46f513 100644
--- a/src/actions/smp.js
+++ b/src/actions/smp.js
@@ -5,7 +5,7 @@
import _ from 'lodash';
import { createActions } from 'redux-actions';
-import { getApiV3 } from '../services/api';
+import { getApi } from '../services/api';
/**
* @static
@@ -22,7 +22,7 @@ function deleteSubmissionInit() {}
* @return {Action}
*/
function deleteSubmissionDone(tokenV3, submissionId) {
- return getApiV3(tokenV3).delete(`/submissions/${submissionId}`)
+ return getApi('V3', tokenV3).delete(`/submissions/${submissionId}`)
.then(() => submissionId);
}
diff --git a/src/services/__mocks__/api.js b/src/services/__mocks__/api.js
index 084c3a61..8b7b2a31 100644
--- a/src/services/__mocks__/api.js
+++ b/src/services/__mocks__/api.js
@@ -103,36 +103,32 @@ export default class Api {
}
}
-/**
- * Topcoder API v2.
+/*
+ * Topcoder API
*/
+const lastApiInstances = {};
/**
- * Returns a new or existing Api object for Topcoder API v2.
- * @param {String} token Optional. Auth token for Topcoder API v2.
- * @return {Api} API v2 service object.
+ * Returns a new or existing Api object for Topcoder API.
+ * @param {String} version The API version.
+ * @param {String} token Optional. Auth token for Topcoder API.
+ * @return {Api} API service object.
*/
-let lastApiV2 = null;
-export function getApiV2(token) {
- if (!lastApiV2 || lastApiV2.private.token !== token) {
- lastApiV2 = new Api(config.API.V2, token);
+export function getApi(version, token) {
+ if (!version || !config.API[version]) {
+ throw new Error(`${version} is not a valid API version`);
+ }
+ if (!lastApiInstances[version] || lastApiInstances[version].private.token !== token) {
+ lastApiInstances[version] = new Api(config.API[version], token);
}
- return lastApiV2;
+ return lastApiInstances[version];
}
/**
- * Topcoder API v3.
+ * Keep the old API factories for backwards compatibility
+ * DO NOT USE THEM FOR NEW IMPLEMENTATIONS.
+ * USE THE getApi(version, token) FACTORY.
*/
-
-/**
- * Returns a new or existing Api object for Topcoder API v3
- * @param {String} token Optional. Auth token for Topcoder API v3.
- * @return {Api} API v3 service object.
- */
-let lastApiV3 = null;
-export function getApiV3(token) {
- if (!lastApiV3 || lastApiV3.private.token !== token) {
- lastApiV3 = new Api(config.API.V3, token);
- }
- return lastApiV3;
-}
+export const getApiV2 = token => getApi('V2', token);
+export const getApiV3 = token => getApi('V3', token);
+export const getApiV4 = token => getApi('V4', token);
diff --git a/src/services/__mocks__/challenges.js b/src/services/__mocks__/challenges.js
index 4c18b67a..f881884e 100644
--- a/src/services/__mocks__/challenges.js
+++ b/src/services/__mocks__/challenges.js
@@ -5,7 +5,7 @@
import _ from 'lodash';
import { COMPETITION_TRACKS } from '../../utils/tc';
-import { getApiV2, getApiV3 } from './api';
+import { getApi } from './api';
import sampleApiV3Response from './data/challenges-v3.json';
import sampleApiV3ResponseSingle from './data/challenge-v3.json';
@@ -215,8 +215,8 @@ class ChallengesService {
};
this.private = {
- api: getApiV3(tokenV3),
- apiV2: getApiV2(tokenV2),
+ api: getApi('V3', tokenV3),
+ apiV2: getApi('V2', tokenV2),
getChallenges,
tokenV2,
tokenV3,
diff --git a/src/services/__mocks__/groups.js b/src/services/__mocks__/groups.js
index dedf041d..fdf474aa 100644
--- a/src/services/__mocks__/groups.js
+++ b/src/services/__mocks__/groups.js
@@ -17,7 +17,7 @@
import _ from 'lodash';
import { config } from 'topcoder-react-utils';
-import { getApiV3 } from './api';
+import { getApi } from './api';
import logger from '../../utils/logger';
/* The value of USER_GROUP_MAXAGE constant converted to [ms]. */
@@ -172,7 +172,7 @@ class GroupService {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/api.js b/src/services/api.js
index 7f9fb8ea..7c1e3355 100644
--- a/src/services/api.js
+++ b/src/services/api.js
@@ -236,51 +236,34 @@ class Api {
export default Api;
/*
- * Topcoder API v2.
+ * Topcoder API
*/
+const lastApiInstances = {};
-let lastApiV2 = null;
/**
- * Returns a new or existing Api object for Topcoder API v2.
- * @param {String} token Optional. Auth token for Topcoder API v2.
- * @return {Api} API v2 service object.
+ * Returns a new or existing Api object for Topcoder API.
+ * @param {String} version The API version.
+ * @param {String} token Optional. Auth token for Topcoder API.
+ * @return {Api} API service object.
*/
-export function getApiV2(token) {
- if (!lastApiV2 || lastApiV2.private.token !== token) {
- lastApiV2 = new Api(config.API.V2, token);
+export function getApi(version, token) {
+ if (!version || !config.API[version]) {
+ throw new Error(`${version} is not a valid API version`);
}
- return lastApiV2;
-}
-
-/*
- * Topcoder API v3.
- */
-
-let lastApiV3 = null;
-/**
- * Returns a new or existing Api object for Topcoder API v3
- * @param {String} token Optional. Auth token for Topcoder API v3.
- * @return {Api} API v3 service object.
- */
-export function getApiV3(token) {
- if (!lastApiV3 || lastApiV3.private.token !== token) {
- lastApiV3 = new Api(config.API.V3, token);
+ if (!lastApiInstances[version] || lastApiInstances[version].private.token !== token) {
+ lastApiInstances[version] = new Api(config.API[version], token);
}
- return lastApiV3;
+ return lastApiInstances[version];
}
-let lastApiV4 = null;
/**
- * Returns a new or existing Api object for Topcoder API V4
- * @param {String} token Optional. Auth token for Topcoder API V4.
- * @return {Api} API V4 service object.
+ * Keep the old API factories for backwards compatibility
+ * DO NOT USE THEM FOR NEW IMPLEMENTATIONS.
+ * USE THE getApi(version, token) FACTORY.
*/
-export function getApiV4(token) {
- if (!lastApiV4 || lastApiV4.private.token !== token) {
- lastApiV4 = new Api(config.API.V4, token);
- }
- return lastApiV4;
-}
+export const getApiV2 = token => getApi('V2', token);
+export const getApiV3 = token => getApi('V3', token);
+export const getApiV4 = token => getApi('V4', token);
/**
* Gets a valid TC M2M token, either requesting one from TC Auth0 API, or
diff --git a/src/services/billing.js b/src/services/billing.js
index efd22020..55d974e0 100644
--- a/src/services/billing.js
+++ b/src/services/billing.js
@@ -2,7 +2,7 @@
* @module "services.billing"
* @desc Access to Topcoder billing accounts.
*/
-import { getApiV3 } from './api';
+import { getApi } from './api';
/**
* @static
@@ -21,7 +21,7 @@ class Billing {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/challenges.js b/src/services/challenges.js
index 318478ad..cdf70c47 100644
--- a/src/services/challenges.js
+++ b/src/services/challenges.js
@@ -11,7 +11,7 @@ import { decodeToken } from 'tc-accounts';
import logger from '../utils/logger';
import { setErrorIcon, ERROR_ICON_TYPES } from '../utils/errors';
import { COMPETITION_TRACKS, getApiResponsePayload } from '../utils/tc';
-import { getApiV2, getApiV4 } from './api';
+import { getApi } from './api';
export const ORDER_BY = {
SUBMISSION_END_DATE: 'submissionEndDate',
@@ -19,76 +19,73 @@ export const ORDER_BY = {
/**
* Normalizes a regular challenge details object received from the backend APIs.
- * NOTE: It is possible, that this normalization is not necessary after we
- * have moved to Topcoder API v4, but it is kept for now to minimize a risk of
- * breaking anything.
* @todo Why this one is exported? It should be only used internally!
- * @param {Object} v4 Challenge object received from the /v4/challenges/{id}
+ * @param {Object} challenge Challenge object received from the /challenges/{id}
* endpoint.
- * @param {Object} v4Filtered Challenge object received from the
- * /v4/challenges?filter=id={id} endpoint.
- * @param {Object} v4User Challenge object received from the
- * /v4/members/{username}/challenges?filter=id={id} endpoint.
- * If action was fired for authenticated visitor, v4_user will contain
+ * @param {Object} filtered Challenge object received from the
+ * /challenges?filter=id={id} endpoint.
+ * @param {Object} user Challenge object received from the
+ * /members/{username}/challenges?filter=id={id} endpoint.
+ * If action was fired for authenticated visitor, `user` will contain
* details fetched specifically for the user (thus may include additional
- * data comparing to the standard API v4 response for the challenge details,
- * stored in v4_filtered).
+ * data comparing to the standard API response for the challenge details,
+ * stored in `filtered`).
* @param {String} username Optional.
* @return {Object} Normalized challenge object.
*/
-export function normalizeChallengeDetails(v4, v4Filtered, v4User, username) {
+export function normalizeChallengeDetails(challenge, filtered, user, username) {
// Normalize exising data to make it consistent with the rest of the code
- const challenge = {
- ...v4,
+ const finalChallenge = {
+ ...challenge,
- id: v4.challengeId,
- reliabilityBonus: _.get(v4Filtered, 'reliabilityBonus', 0),
- status: (v4.currentStatus || '').toUpperCase(),
+ id: challenge.challengeId,
+ reliabilityBonus: _.get(filtered, 'reliabilityBonus', 0),
+ status: (challenge.currentStatus || '').toUpperCase(),
allPhases: [],
currentPhases: [],
- name: v4.challengeName || v4.challengeTitle,
- projectId: Number(v4.projectId),
- forumId: Number(v4.forumId),
- introduction: v4.introduction || '',
- detailedRequirements: v4.detailedRequirements === 'null' ? '' : v4.detailedRequirements,
- finalSubmissionGuidelines: v4.finalSubmissionGuidelines === 'null' ? '' : v4.finalSubmissionGuidelines,
- screeningScorecardId: Number(v4.screeningScorecardId),
- reviewScorecardId: Number(v4.reviewScorecardId),
- numberOfCheckpointsPrizes: v4.numberOfCheckpointsPrizes,
- topCheckPointPrize: v4.topCheckPointPrize,
- submissionsViewable: v4.submissionsViewable || 'false',
- reviewType: v4.reviewType,
- allowStockArt: v4.allowStockArt === 'true',
- fileTypes: v4.filetypes || [],
- environment: v4.environment,
- codeRepo: v4.codeRepo,
- forumLink: v4.forumLink,
- submissionLimit: Number(v4.submissionLimit) || 0,
- drPoints: v4.digitalRunPoints,
- directUrl: v4.directUrl,
- technologies: v4.technologies || v4.technology || [],
- platforms: v4.platforms || [],
- prizes: v4.prize || v4.prizes || [],
- events: _.map(v4.event, e => ({
+ name: challenge.challengeName || challenge.challengeTitle,
+ projectId: Number(challenge.projectId),
+ forumId: Number(challenge.forumId),
+ introduction: challenge.introduction || '',
+ detailedRequirements: challenge.detailedRequirements === 'null' ? '' : challenge.detailedRequirements,
+ finalSubmissionGuidelines: challenge.finalSubmissionGuidelines === 'null' ? '' : challenge.finalSubmissionGuidelines,
+ screeningScorecardId: Number(challenge.screeningScorecardId),
+ reviewScorecardId: Number(challenge.reviewScorecardId),
+ numberOfCheckpointsPrizes: challenge.numberOfCheckpointsPrizes,
+ topCheckPointPrize: challenge.topCheckPointPrize,
+ submissionsViewable: challenge.submissionsViewable || 'false',
+ reviewType: challenge.reviewType,
+ allowStockArt: challenge.allowStockArt === 'true',
+ fileTypes: challenge.filetypes || [],
+ environment: challenge.environment,
+ codeRepo: challenge.codeRepo,
+ forumLink: challenge.forumLink,
+ submissionLimit: Number(challenge.submissionLimit) || 0,
+ drPoints: challenge.digitalRunPoints,
+ directUrl: challenge.directUrl,
+ technologies: challenge.technologies || challenge.technology || [],
+ platforms: challenge.platforms || [],
+ prizes: challenge.prize || challenge.prizes || [],
+ events: _.map(challenge.event, e => ({
eventName: e.eventShortDesc,
eventId: e.id,
description: e.eventDescription,
})),
- terms: v4.terms,
- submissions: v4.submissions,
- track: _.toUpper(v4.challengeCommunity),
- subTrack: v4.subTrack,
- checkpoints: v4.checkpoints,
- documents: v4.documents || [],
- numRegistrants: v4.numberOfRegistrants,
- numberOfCheckpointSubmissions: v4.numberOfCheckpointSubmissions,
- registrants: v4.registrants || [],
+ terms: challenge.terms,
+ submissions: challenge.submissions,
+ track: _.toUpper(challenge.challengeCommunity),
+ subTrack: challenge.subTrack,
+ checkpoints: challenge.checkpoints,
+ documents: challenge.documents || [],
+ numRegistrants: challenge.numberOfRegistrants,
+ numberOfCheckpointSubmissions: challenge.numberOfCheckpointSubmissions,
+ registrants: challenge.registrants || [],
};
- // v4 Winners have different field names, needs to be normalized to match v4 filtered and v4
- challenge.winners = _.map(
- v4.winners,
+ // Winners have different field names, needs to be normalized to match `filtered` and `challenge`
+ finalChallenge.winners = _.map(
+ challenge.winners,
(winner, index) => ({
...winner,
handle: winner.submitter,
@@ -96,79 +93,79 @@ export function normalizeChallengeDetails(v4, v4Filtered, v4User, username) {
}),
);
- if (challenge.subTrack === 'MARATHON_MATCH') {
- challenge.track = 'DATA_SCIENCE';
+ if (finalChallenge.subTrack === 'MARATHON_MATCH') {
+ finalChallenge.track = 'DATA_SCIENCE';
}
// It's not clear if this will be the main event, will need to be investigated
- challenge.mainEvent = challenge.events[0] || {};
+ finalChallenge.mainEvent = finalChallenge.events[0] || {};
- /* It's unclear if these normalization steps are still required for V4 */
- // Fill missing data from v4_filtered
- if (v4Filtered) {
+ /* It's unclear if these normalization steps are still required for `challenge` */
+ // Fill missing data from filtered
+ if (filtered) {
const groups = {};
- if (v4Filtered.groupIds) {
- v4Filtered.groupIds.forEach((id) => {
+ if (filtered.groupIds) {
+ filtered.groupIds.forEach((id) => {
groups[id] = true;
});
}
- _.merge(challenge, {
- componentId: v4Filtered.componentId,
- contestId: v4Filtered.contestId,
+ _.merge(finalChallenge, {
+ componentId: filtered.componentId,
+ contestId: filtered.contestId,
- submissionEndDate: v4Filtered.submissionEndDate, // Dates are not correct in v4
- submissionEndTimestamp: v4Filtered.submissionEndDate, // Dates are not correct in v4
+ submissionEndDate: filtered.submissionEndDate, // Dates are not correct in `challenge`
+ submissionEndTimestamp: filtered.submissionEndDate, // Dates are not correct in `challenge`
- /* Taking phases from v4_filtered, because dates are not correct in v4 */
- allPhases: v4Filtered.allPhases || [],
+ /* Taking phases from filtered, because dates are not correct in `challenge` */
+ allPhases: filtered.allPhases || [],
- /* Taking phases from v4_filtered, because dates are not correct in v4 */
- currentPhases: v4Filtered.currentPhases || [],
+ /* Taking phases from filtered, because dates are not correct in `challenge` */
+ currentPhases: filtered.currentPhases || [],
- /* v4 returns incorrect value for numberOfSubmissions for some reason */
- numSubmissions: v4Filtered.numSubmissions,
+ /* `challenge` has incorrect value for numberOfSubmissions for some reason */
+ numSubmissions: filtered.numSubmissions,
groups,
});
}
- // Fill missing data from v4_user
- if (v4User) {
- _.defaults(challenge, {
- userDetails: v4User.userDetails,
+ // Fill missing data from user
+ if (user) {
+ _.defaults(finalChallenge, {
+ userDetails: user.userDetails,
});
}
// Fill some derived data
const registrationOpen = _.some(
- challenge.allPhases,
+ finalChallenge.allPhases,
phase => phase.phaseType === 'Registration' && phase.phaseStatus === 'Open',
) ? 'Yes' : 'No';
- _.defaults(challenge, {
- communities: new Set([COMPETITION_TRACKS[challenge.track]]),
+ _.defaults(finalChallenge, {
+ communities: new Set([COMPETITION_TRACKS[finalChallenge.track]]),
registrationOpen,
users: username ? { [username]: true } : {},
});
// A hot fix to show submissions for on-going challenges
- if (!challenge.submissions || !challenge.submissions.length) {
- challenge.submissions = challenge.registrants
+ if (!finalChallenge.submissions || !finalChallenge.submissions.length) {
+ finalChallenge.submissions = finalChallenge.registrants
.filter(r => r.submissionDate || '')
.sort((a, b) => (a.submissionDate || '')
.localeCompare(b.submissionDate || ''));
}
- if (!challenge.allPhases) challenge.allPhases = [];
- if (!challenge.track) challenge.track = '';
+ if (!finalChallenge.allPhases) finalChallenge.allPhases = [];
+ if (!finalChallenge.track) finalChallenge.track = '';
- return challenge;
+ return finalChallenge;
}
/**
* Normalizes a regular challenge object received from the backend.
* NOTE: This function is copied from the existing code in the challenge listing
* component. It is possible, that this normalization is not necessary after we
- * have moved to Topcoder API v4, but it is kept for now to minimize a risk of
+ * have moved to Topcoder API, but it is kept for now to minimize a risk of
* breaking anything.
* @todo Should be used only internally!
* @param {Object} challenge Challenge object received from the backend.
@@ -235,7 +232,7 @@ class ChallengesService {
/**
* Private function being re-used in all methods related to getting
* challenges. It handles query-related arguments in the uniform way:
- * @param {String} endpoint API V4 endpoint, where the request will be send.
+ * @param {String} endpoint API endpoint, where the request will be send.
* @param {Object} filters Optional. A map of filters to pass as `filter`
* query parameter (this function takes care to stringify it properly).
* @param {Object} params Optional. A map of any other parameters beside
@@ -260,8 +257,8 @@ class ChallengesService {
};
this.private = {
- api: getApiV4(tokenV3),
- apiV2: getApiV2(tokenV2),
+ api: getApi('V4', tokenV3),
+ apiV2: getApi('V2', tokenV2),
getChallenges,
tokenV2,
tokenV3,
@@ -358,34 +355,34 @@ class ChallengesService {
}
/**
- * Gets challenge details from Topcoder API v4.
- * NOTE: This function also uses API v2 and other v4 endpoints for now, due
+ * Gets challenge details from Topcoder API.
+ * NOTE: This function also uses API v2 and other endpoints for now, due
* to some information is missing or
- * incorrect in the main v4 endpoint. This may change in the future.
+ * incorrect in the main endpoint. This may change in the future.
* @param {Number|String} challengeId
* @return {Promise} Resolves to the challenge object.
*/
async getChallengeDetails(challengeId) {
- const challengeV4 = await this.private.api.get(`/challenges/${challengeId}`)
+ const challenge = await this.private.api.get(`/challenges/${challengeId}`)
.then(checkError).then(res => res.content);
- const challengeV4Filtered = await this.private.getChallenges('/challenges/', { id: challengeId })
+ const challengeFiltered = await this.private.getChallenges('/challenges/', { id: challengeId })
.then(res => res.challenges[0]);
const username = this.private.tokenV3 && decodeToken(this.private.tokenV3).handle;
- const challengeV4User = username && await this.getUserChallenges(username, { id: challengeId })
+ const challengeUser = username && await this.getUserChallenges(username, { id: challengeId })
.then(res => res.challenges[0]).catch(() => null);
- const challenge = normalizeChallengeDetails(
- challengeV4,
- challengeV4Filtered,
- challengeV4User,
+ const finalChallenge = normalizeChallengeDetails(
+ challenge,
+ challengeFiltered,
+ challengeUser,
username,
);
- challenge.fetchedWithAuth = Boolean(this.private.api.private.token);
+ finalChallenge.fetchedWithAuth = Boolean(this.private.api.private.token);
- return challenge;
+ return finalChallenge;
}
/**
diff --git a/src/services/direct.js b/src/services/direct.js
index ac3c60fc..82cda59c 100644
--- a/src/services/direct.js
+++ b/src/services/direct.js
@@ -7,7 +7,7 @@
import qs from 'qs';
-import { getApiV3 } from './api';
+import { getApi } from './api';
/**
* Direct service class.
@@ -21,7 +21,7 @@ class Direct {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/groups.js b/src/services/groups.js
index 65112fa9..a5ddc2a7 100644
--- a/src/services/groups.js
+++ b/src/services/groups.js
@@ -19,7 +19,7 @@
import _ from 'lodash';
import { config } from 'topcoder-react-utils';
import logger from '../utils/logger';
-import { getApiV3 } from './api';
+import { getApi } from './api';
/* The value of USER_GROUP_MAXAGE constant converted to [ms]. */
const USER_GROUP_MAXAGE = config.USER_GROUP_MAXAGE * 1000;
@@ -193,7 +193,7 @@ class GroupService {
constructor(tokenV3) {
const now = Date.now();
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
cache: {
groupTreeIds: {
lastCleanUp: now,
diff --git a/src/services/looker.js b/src/services/looker.js
index d0904439..dc0b7960 100644
--- a/src/services/looker.js
+++ b/src/services/looker.js
@@ -1,22 +1,21 @@
/**
* @module "services.looker"
- * @desc This module provides a service to get look data json
- * via API V4.
+ * @desc This module provides a service to get look data json via Topcoder API.
*/
import { getLookerApiResponsePayload } from '../utils/tc';
-import { getApiV4 } from './api';
+import { getApi } from './api';
/**
* Service class.
*/
class LookerService {
/**
- * @param {String} tokenV4 Optional. Auth token for Topcoder API v4.
+ * @param {String} token Optional. Auth token for Topcoder API.
*/
- constructor(tokenV4) {
+ constructor(token) {
this.private = {
- api: getApiV4(tokenV4),
- tokenV4,
+ api: getApi('V4', token),
+ token,
};
}
@@ -34,12 +33,12 @@ class LookerService {
let lastInstance = null;
/**
* Returns a new or existing looker service.
- * @param {String} tokenV4 Optional. Auth token for Topcoder API v4.
+ * @param {String} token Optional. Auth token for Topcoder API.
* @return {LookerService} looker service object
*/
-export function getService(tokenV4) {
- if (!lastInstance || tokenV4 !== lastInstance.private.tokenV4) {
- lastInstance = new LookerService(tokenV4);
+export function getService(token) {
+ if (!lastInstance || token !== lastInstance.private.token) {
+ lastInstance = new LookerService(token);
}
return lastInstance;
}
diff --git a/src/services/lookup.js b/src/services/lookup.js
index 3236f1f8..2b98bf8b 100644
--- a/src/services/lookup.js
+++ b/src/services/lookup.js
@@ -5,7 +5,7 @@
*/
import qs from 'qs';
import { getApiResponsePayload } from '../utils/tc';
-import { getApiV3 } from './api';
+import { getApi } from './api';
class LookupService {
/**
@@ -13,7 +13,7 @@ class LookupService {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/members.js b/src/services/members.js
index a9f04091..0e573dc9 100644
--- a/src/services/members.js
+++ b/src/services/members.js
@@ -9,7 +9,7 @@ import _ from 'lodash';
import qs from 'qs';
import logger from '../utils/logger';
import { getApiResponsePayload } from '../utils/tc';
-import { getApiV3 } from './api';
+import { getApi } from './api';
/**
* Service class.
@@ -20,7 +20,7 @@ class MembersService {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/reviewOpportunities.js b/src/services/reviewOpportunities.js
index e4aa4260..6c37bf12 100644
--- a/src/services/reviewOpportunities.js
+++ b/src/services/reviewOpportunities.js
@@ -3,7 +3,7 @@
* @desc This module provides a service for retrieving Review Opportunities and
* submitting applications.
*/
-import { getApiV3 } from './api';
+import { getApi } from './api';
/**
* Service class.
@@ -14,7 +14,7 @@ class ReviewOpportunitiesService {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/terms.js b/src/services/terms.js
index 84945a6f..b34e62e1 100644
--- a/src/services/terms.js
+++ b/src/services/terms.js
@@ -8,7 +8,7 @@ import _ from 'lodash';
import { config } from 'topcoder-react-utils';
import { getService as getCommunityService } from './communities';
-import { getApiV2 } from './api';
+import { getApi } from './api';
/**
* Service class.
@@ -19,7 +19,7 @@ class TermsService {
*/
constructor(tokenV2) {
this.private = {
- api: getApiV2(tokenV2),
+ api: getApi('V2', tokenV2),
tokenV2,
};
}
diff --git a/src/services/user-traits.js b/src/services/user-traits.js
index 693b590b..c1d71b71 100644
--- a/src/services/user-traits.js
+++ b/src/services/user-traits.js
@@ -5,7 +5,7 @@
*/
import toCapitalCase from 'to-capital-case';
import { getApiResponsePayload } from '../utils/tc';
-import { getApiV3 } from './api';
+import { getApi } from './api';
/**
* Service class.
@@ -16,7 +16,7 @@ class UserTraitsService {
*/
constructor(tokenV3) {
this.private = {
- api: getApiV3(tokenV3),
+ api: getApi('V3', tokenV3),
tokenV3,
};
}
diff --git a/src/services/user.js b/src/services/user.js
index 89a97427..13ec5948 100644
--- a/src/services/user.js
+++ b/src/services/user.js
@@ -7,7 +7,7 @@ import { config, isomorphy } from 'topcoder-react-utils';
import logger from '../utils/logger';
import { getApiResponsePayload } from '../utils/tc';
-import { getApiV2, getApiV3 } from './api';
+import { getApi } from './api';
let auth0;
@@ -112,8 +112,8 @@ class User {
*/
constructor(tokenV3, tokenV2) {
this.private = {
- api: getApiV3(tokenV3),
- apiV2: getApiV2(tokenV2),
+ api: getApi('V3', tokenV3),
+ apiV2: getApi('V2', tokenV2),
tokenV2,
tokenV3,
};