Work on challenge flow from block to block, start refactoring the name courseware to challenges in main.js
This commit is contained in:
		
							
								
								
									
										46
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								app.js
									
									
									
									
									
								
							| @@ -36,25 +36,26 @@ var express = require('express'), | |||||||
|     /** |     /** | ||||||
|      * Controllers (route handlers). |      * Controllers (route handlers). | ||||||
|      */ |      */ | ||||||
|     homeController = require('./controllers/home'), |   homeController = require('./controllers/home'), | ||||||
|     resourcesController = require('./controllers/resources'), |   resourcesController = require('./controllers/resources'), | ||||||
|     userController = require('./controllers/user'), |   userController = require('./controllers/user'), | ||||||
|     nonprofitController = require('./controllers/nonprofits'), |   nonprofitController = require('./controllers/nonprofits'), | ||||||
|     bonfireController = require('./controllers/bonfire'), |   bonfireController = require('./controllers/bonfire'), | ||||||
|     coursewareController = require('./controllers/courseware'), |   coursewareController = require('./controllers/courseware'), | ||||||
|     fieldGuideController = require('./controllers/fieldGuide'), |   fieldGuideController = require('./controllers/fieldGuide'), | ||||||
|     challengeMapController = require('./controllers/challengeMap'), |   challengeMapController = require('./controllers/challengeMap'), | ||||||
|  |   challengeController = require('./controllers/challenge'), | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      *  Stories |      *  Stories | ||||||
|      */ |      */ | ||||||
|     storyController = require('./controllers/story'), |   storyController = require('./controllers/story'), | ||||||
|  |  | ||||||
|     /** |   /** | ||||||
|      * API keys and Passport configuration. |    * API keys and Passport configuration. | ||||||
|      */ |    */ | ||||||
|     secrets = require('./config/secrets'), |   secrets = require('./config/secrets'), | ||||||
|     passportConf = require('./config/passport'); |   passportConf = require('./config/passport'); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Create Express server. |  * Create Express server. | ||||||
| @@ -537,17 +538,24 @@ app.post('/completed-field-guide/', fieldGuideController.completedFieldGuide); | |||||||
|  * Courseware related routes |  * Courseware related routes | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| app.get('/challenges/', coursewareController.returnNextCourseware); | app.get('/getstuff', challengeController.getStuff); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | app.get('/challenges/next-challenge', challengeController.returnNextChallenge); | ||||||
|  |  | ||||||
| app.get( | app.get( | ||||||
|     '/challenges/:coursewareName', |     '/challenges/:challengeName', | ||||||
|     coursewareController.returnIndividualCourseware |     challengeController.returnIndividualChallenge | ||||||
| ); | ); | ||||||
|  |  | ||||||
| app.post('/completed-courseware/', coursewareController.completedCourseware); | app.get('/challenges/', challengeController.returnCurrentChallenge); | ||||||
|  | // todo refactor these routes | ||||||
|  | app.post('/completed-challenge/', challengeController.completedChallenge); | ||||||
|  |  | ||||||
| app.post('/completed-zipline-or-basejump', | app.post('/completed-zipline-or-basejump', | ||||||
|   coursewareController.completedZiplineOrBasejump); |   challengeController.completedZiplineOrBasejump); | ||||||
|  |  | ||||||
|  | app.post('/completed-bonfire', challengeController.completedBonfire); | ||||||
|  |  | ||||||
| // Unique Check API route | // Unique Check API route | ||||||
| app.get('/api/checkUniqueUsername/:username', | app.get('/api/checkUniqueUsername/:username', | ||||||
|   | |||||||
| @@ -40,42 +40,107 @@ exports.showAllChallenges = function(req, res) { | |||||||
|   res.send(data); |   res.send(data); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | exports.getStuff = function(req, res, next) { | ||||||
|  |   res.send({withNames: challengeMapWithNames, withIds: challengeMapWithIds}); | ||||||
|  | }; | ||||||
|  |  | ||||||
| exports.returnNextChallenge = function(req, res, next) { | exports.returnNextChallenge = function(req, res, next) { | ||||||
|   if (!req.user) { |   if (!req.user) { | ||||||
|    return res.redirect('../challenges/learn-how-free-code-camp-works'); |    return res.redirect('../challenges/learn-how-free-code-camp-works'); | ||||||
|   } |   } | ||||||
|  |   var completed = req.user.completedChallenges.map(function (elem) { | ||||||
|  |     return elem._id; | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   req.user.uncompletedChallenges = resources.allChallengeIds() | ||||||
|  |     .filter(function (elem) { | ||||||
|  |       if (completed.indexOf(elem) === -1) { | ||||||
|  |         return elem; | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   req.user.save(); | ||||||
|   // find the user's current challenge and block |   // find the user's current challenge and block | ||||||
|   // look in that block and find the index of their current challenge |   // look in that block and find the index of their current challenge | ||||||
|   // if index + 1 <= block.challenges.length - 1 |   // if index + 1 <= block.challenges.length - 1 | ||||||
|   // serve index + 1 challenge |   // serve index + 1 challenge | ||||||
|   // otherwise increment block key and serve the first challenge in that block |   // otherwise increment block key and serve the first challenge in that block | ||||||
|   var nextChallengeName; |   var nextChallengeName; | ||||||
|  |   var nextChallengeId; | ||||||
|  |   var nextChallengeBlock; | ||||||
|  |  | ||||||
|   var challengeId = req.user.currentChallenge.challengeId; |   var challengeId = req.user.currentChallenge.challengeId; | ||||||
|   var challengeBlock = req.user.currentChallenge.challengeBlock; |   var challengeBlock = req.user.currentChallenge.challengeBlock; | ||||||
|  |   debug('this is the user challenge block', challengeBlock); | ||||||
|   var indexOfChallenge = challengeMapWithIds[challengeBlock] |   var indexOfChallenge = challengeMapWithIds[challengeBlock] | ||||||
|     .indexOf(challengeId); |     .indexOf(challengeId); | ||||||
|  |  | ||||||
|   if (indexOfChallenge |   debug('Logging first two challenge blocks for sanity', challengeMapWithIds[0], challengeMapWithIds[1]); | ||||||
|     <= challengeMapWithIds[challengeBlock].length - 1) { |  | ||||||
|  |  | ||||||
|  |   debug('these are the damn keys on challengeMapWithIds...', Object.keys(challengeMapWithIds)); | ||||||
|  |   if (indexOfChallenge + 1 | ||||||
|  |     < challengeMapWithIds[challengeBlock].length) { | ||||||
|  |     debug('advancing to next challange in current block'); | ||||||
|     nextChallengeName = |     nextChallengeName = | ||||||
|       challengeMapWithNames[challengeBlock][indexOfChallenge + 1]; |       challengeMapWithNames[challengeBlock][indexOfChallenge + 1]; | ||||||
|   } else if (typeof challengeMapWithIds[challengeBlock + 1] !== 'undefined') { |     nextChallengeId = challengeMapWithIds[challengeBlock][indexOfChallenge + 1]; | ||||||
|     nextChallengeName = R.head(challengeMapWithNames[challengeBlock + 1]); |     nextChallengeBlock = challengeBlock; | ||||||
|  |   } else if (typeof challengeMapWithIds[++challengeBlock] !== 'undefined') { | ||||||
|  |     debug('Advancing to next block'); | ||||||
|  |     nextChallengeName = R.head(challengeMapWithNames[challengeBlock]); | ||||||
|  |     nextChallengeId = R.head(challengeMapWithNames[challengeBlock]); | ||||||
|  |     nextChallengeBlock = challengeBlock; | ||||||
|   } else { |   } else { | ||||||
|  |     debug('completed all challenges'); | ||||||
|     req.flash('errors', { |     req.flash('errors', { | ||||||
|       msg: 'It looks like you have finished all of our challenges.' + |       msg: 'It looks like you have finished all of our challenges.' + | ||||||
|       ' Great job! Now on to helping nonprofits!' |       ' Great job! Now on to helping nonprofits!' | ||||||
|     }); |     }); | ||||||
|     nextChallengeName = R.head(challengeMapWithNames['0'].challenges); |     nextChallengeName = R.head(challengeMapWithNames[0].challenges); | ||||||
|  |     nextChallengeId = R.head(challengeMapWithNames[0].challenges); | ||||||
|  |     nextChallengeBlock = 0; | ||||||
|   } |   } | ||||||
|   var nameString = nextChallengeName.toLowerCase().replace(/\s/g, '-'); |   req.user.currentChallenge = { | ||||||
|   return res.redirect('../challenges' + nameString); |     challengeId: nextChallengeId, | ||||||
|  |     challengeName: nextChallengeName, | ||||||
|  |     challengeBlock: nextChallengeBlock | ||||||
|  |   }; | ||||||
|  |   req.user.save(); | ||||||
|  |   var nameString = nextChallengeName.trim() | ||||||
|  |     .toLowerCase() | ||||||
|  |     .replace(/[^\w\s]/g, '') | ||||||
|  |     .replace(/\s/g, '-') | ||||||
|  |   debug('this is the namestring we\'re going to look up', nameString); | ||||||
|  |   return res.redirect('../challenges/' + nameString); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | exports.returnCurrentChallenge = function(req, res, next) { | ||||||
|  |   debug('these are the damn keys on challengeMapWithIds...', Object.keys(challengeMapWithIds)); | ||||||
|  |   debug('sanity check', challengeMapWithIds[0], challengeMapWithIds[1]); | ||||||
|  |   if (!req.user) { | ||||||
|  |    return res.redirect('../challenges/learn-how-free-code-camp-works'); | ||||||
|  |   } | ||||||
|  |   if (!req.user.currentChallenge) { | ||||||
|  |     req.user.currentChallenge = {}; | ||||||
|  |     req.user.currentChallenge.challengeId = challengeMapWithIds['0'][0]; | ||||||
|  |     req.user.currentChallenge.challengeName = challengeMapWithNames['0'][0]; | ||||||
|  |     req.user.currentChallenge.challengeBlock = '0'; | ||||||
|  |     req.user.save(); | ||||||
|  |     return res.redirect('../challenges/learn-how-free-code-camp-works'); | ||||||
|  |   } | ||||||
|  |   var nameString = req.user.currentChallenge.challengeName.trim() | ||||||
|  |     .toLowerCase() | ||||||
|  |     .replace(/[^\w\s]/g, '') | ||||||
|  |     .replace(/\s/g, '-'); | ||||||
|  |   debug('this is the namestring we\'re going to look up', nameString); | ||||||
|  |   return res.redirect('../challenges/' + nameString); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| exports.returnIndividualChallenge = function(req, res, next) { | exports.returnIndividualChallenge = function(req, res, next) { | ||||||
|   var dashedName = req.params.challengeName; |   var dashedName = req.params.challengeName; | ||||||
|  |  | ||||||
|   var challengeName = dashedName.replace(/\-/g, ' '); |   var challengeName = dashedName.replace(/\-/g, ' '); | ||||||
|  |   debug('looking for %s', challengeName); | ||||||
|  |  | ||||||
|   Challenge.find({'name': new RegExp(challengeName, 'i')}, |   Challenge.find({'name': new RegExp(challengeName, 'i')}, | ||||||
|     function(err, challengeFromMongo) { |     function(err, challengeFromMongo) { | ||||||
| @@ -84,6 +149,7 @@ exports.returnIndividualChallenge = function(req, res, next) { | |||||||
|       } |       } | ||||||
|       // Handle not found |       // Handle not found | ||||||
|       if (challengeFromMongo.length < 1) { |       if (challengeFromMongo.length < 1) { | ||||||
|  |         debug(challengeFromMongo); | ||||||
|         req.flash('errors', { |         req.flash('errors', { | ||||||
|           msg: '404: We couldn\'t find a challenge with that name. ' + |           msg: '404: We couldn\'t find a challenge with that name. ' + | ||||||
|           'Please double check the name.' |           'Please double check the name.' | ||||||
| @@ -91,6 +157,7 @@ exports.returnIndividualChallenge = function(req, res, next) { | |||||||
|         return res.redirect('/challenges'); |         return res.redirect('/challenges'); | ||||||
|       } |       } | ||||||
|       var challenge = challengeFromMongo.pop(); |       var challenge = challengeFromMongo.pop(); | ||||||
|  |       debug(challenge); | ||||||
|  |  | ||||||
|       // Redirect to full name if the user only entered a partial |       // Redirect to full name if the user only entered a partial | ||||||
|       var dashedNameFull = challenge.name.toLowerCase().replace(/\s/g, '-'); |       var dashedNameFull = challenge.name.toLowerCase().replace(/\s/g, '-'); | ||||||
| @@ -186,6 +253,148 @@ exports.returnIndividualChallenge = function(req, res, next) { | |||||||
|     }); |     }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | exports.completedBonfire = function(req, res, next) { | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | exports.completedChallenge = function (req, res, next) { | ||||||
|  |  | ||||||
|  |   var isCompletedDate = Math.round(+new Date()); | ||||||
|  |   var challengeId = req.body.challengeInfo.challengeId; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   req.user.completedChallenges.push({ | ||||||
|  |     _id: challengeId, | ||||||
|  |     completedDate: isCompletedDate, | ||||||
|  |     name: req.body.challengeInfo.challengeName, | ||||||
|  |     solution: null, | ||||||
|  |     githubLink: null, | ||||||
|  |     verified: true | ||||||
|  |   }); | ||||||
|  |   var index = req.user.uncompletedChallenges.indexOf(challengeId); | ||||||
|  |  | ||||||
|  |   if (index > -1) { | ||||||
|  |     req.user.progressTimestamps.push(Date.now() || 0); | ||||||
|  |     req.user.uncompletedChallenges.splice(index, 1); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   req.user.save(function (err, user) { | ||||||
|  |     if (err) { | ||||||
|  |       return next(err); | ||||||
|  |     } | ||||||
|  |     if (user) { | ||||||
|  |       res.sendStatus(200); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | exports.completedZiplineOrBasejump = function (req, res, next) { | ||||||
|  |   debug('Inside controller for completed zipline or basejump with data %s', | ||||||
|  |     req.body.coursewareInfo); | ||||||
|  |   var isCompletedWith = req.body.coursewareInfo.completedWith || false; | ||||||
|  |   var isCompletedDate = Math.round(+new Date()); | ||||||
|  |   var coursewareHash = req.body.coursewareInfo.coursewareHash; | ||||||
|  |   var solutionLink = req.body.coursewareInfo.publicURL; | ||||||
|  |   var githubLink = req.body.coursewareInfo.challengeType === '4' | ||||||
|  |     ? req.body.coursewareInfo.githubURL : true; | ||||||
|  |   if (!solutionLink || !githubLink) { | ||||||
|  |     req.flash('errors', { | ||||||
|  |       msg: 'You haven\'t supplied the necessary URLs for us to inspect ' + | ||||||
|  |       'your work.' | ||||||
|  |     }); | ||||||
|  |     return res.sendStatus(403); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (isCompletedWith) { | ||||||
|  |     var paired = User.find({'profile.username': isCompletedWith.toLowerCase()}).limit(1); | ||||||
|  |     paired.exec(function (err, pairedWithFromMongo) { | ||||||
|  |       if (err) { | ||||||
|  |         return next(err); | ||||||
|  |       } else { | ||||||
|  |         var index = req.user.uncompletedCoursewares.indexOf(coursewareHash); | ||||||
|  |         if (index > -1) { | ||||||
|  |           req.user.progressTimestamps.push(Date.now() || 0); | ||||||
|  |           req.user.uncompletedCoursewares.splice(index, 1); | ||||||
|  |         } | ||||||
|  |         var pairedWith = pairedWithFromMongo.pop(); | ||||||
|  |  | ||||||
|  |         req.user.completedCoursewares.push({ | ||||||
|  |           _id: coursewareHash, | ||||||
|  |           name: req.body.coursewareInfo.coursewareName, | ||||||
|  |           completedWith: pairedWith._id, | ||||||
|  |           completedDate: isCompletedDate, | ||||||
|  |           solution: solutionLink, | ||||||
|  |           githubLink: githubLink, | ||||||
|  |           verified: false | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         req.user.save(function (err, user) { | ||||||
|  |           if (err) { | ||||||
|  |             return next(err); | ||||||
|  |           } | ||||||
|  |           debug('this is the user object returned %s,' + | ||||||
|  |             ' this is the req.user._id %s, ' + | ||||||
|  |             'this is the pairedWith._id %s', user, req.user._id, pairedWith._id); | ||||||
|  |           debug(req.user._id.toString() === pairedWith._id.toString()); | ||||||
|  |           if (req.user._id.toString() === pairedWith._id.toString()) { | ||||||
|  |             return res.sendStatus(200); | ||||||
|  |           } | ||||||
|  |           index = pairedWith.uncompletedCoursewares.indexOf(coursewareHash); | ||||||
|  |           if (index > -1) { | ||||||
|  |             pairedWith.progressTimestamps.push(Date.now() || 0); | ||||||
|  |             pairedWith.uncompletedCoursewares.splice(index, 1); | ||||||
|  |  | ||||||
|  |           } | ||||||
|  |  | ||||||
|  |           pairedWith.completedCoursewares.push({ | ||||||
|  |             _id: coursewareHash, | ||||||
|  |             name: req.body.coursewareInfo.coursewareName, | ||||||
|  |             completedWith: req.user._id, | ||||||
|  |             completedDate: isCompletedDate, | ||||||
|  |             solution: solutionLink, | ||||||
|  |             githubLink: githubLink, | ||||||
|  |             verified: false | ||||||
|  |           }); | ||||||
|  |           pairedWith.save(function (err, paired) { | ||||||
|  |             if (err) { | ||||||
|  |               return next(err); | ||||||
|  |             } | ||||||
|  |             if (user && paired) { | ||||||
|  |               return res.sendStatus(200); | ||||||
|  |             } | ||||||
|  |           }); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } else { | ||||||
|  |  | ||||||
|  |     req.user.completedCoursewares.push({ | ||||||
|  |       _id: coursewareHash, | ||||||
|  |       name: req.body.coursewareInfo.coursewareName, | ||||||
|  |       completedWith: null, | ||||||
|  |       completedDate: isCompletedDate, | ||||||
|  |       solution: solutionLink, | ||||||
|  |       githubLink: githubLink, | ||||||
|  |       verified: false | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     var index = req.user.uncompletedCoursewares.indexOf(coursewareHash); | ||||||
|  |     if (index > -1) { | ||||||
|  |       req.user.progressTimestamps.push(Date.now() || 0); | ||||||
|  |       req.user.uncompletedCoursewares.splice(index, 1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     req.user.save(function (err, user) { | ||||||
|  |       if (err) { | ||||||
|  |         return next(err); | ||||||
|  |       } | ||||||
|  |       if (user) { | ||||||
|  |         return res.sendStatus(200); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| challengeBlock { | challengeBlock { | ||||||
|   0: { |   0: { | ||||||
|   | |||||||
| @@ -28,7 +28,8 @@ var async = require('async'), | |||||||
|  */ |  */ | ||||||
| var allBonfireIds, allBonfireNames, allCoursewareIds, allCoursewareNames, | var allBonfireIds, allBonfireNames, allCoursewareIds, allCoursewareNames, | ||||||
|   allFieldGuideIds, allFieldGuideNames, allNonprofitNames, |   allFieldGuideIds, allFieldGuideNames, allNonprofitNames, | ||||||
|   allBonfireIndexesAndNames, challengeMap; |   allBonfireIndexesAndNames, challengeMap, challengeMapWithIds, | ||||||
|  |   challengeMapWithNames, allChallengeIds; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * GET / |  * GET / | ||||||
| @@ -46,55 +47,73 @@ Array.zip = function(left, right, combinerFunction) { | |||||||
|   return results; |   return results; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| buildChallengeMap = function() { | (function() { | ||||||
|   challengeMap = {}; |   if (!challengeMap) { | ||||||
|   fs.readdir(__dirname + '../seed_data/challenges', function(err, files) { |     var localChallengeMap = {}; | ||||||
|     if (err) { |     var files = fs.readdirSync(__dirname + '/../seed_data/challenges'); | ||||||
|       debug(err); |     var keyCounter = 0; | ||||||
|     } else { |     files = files.map(function (file) { | ||||||
|       var keyCounter = 0; |       return require(__dirname + | ||||||
|       files = files.sort(function(a, b) { |         '/../seed_data/challenges/' + file); | ||||||
|         return a.order < b.order ? a : b; |     }); | ||||||
|       }); |     files = files.sort(function (a, b) { | ||||||
|       files.forEach(function(file) { |       return a.order - b.order; | ||||||
|         challengeMap[keyCounter++] = file; |     }); | ||||||
|       }); |     files.forEach(function (file) { | ||||||
|     } |       localChallengeMap[keyCounter++] = file; | ||||||
|   }); |     }); | ||||||
| }; |     challengeMap = _.cloneDeep(localChallengeMap); | ||||||
|  |   } | ||||||
|  | })(); | ||||||
|  |  | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|  |  | ||||||
|   getChallengeMapWithIds: function() { |   getChallengeMapWithIds: function() { | ||||||
|     // TODO finish this |     if (challengeMapWithIds) { | ||||||
|     if (challengeMap === null) { |       return challengeMapWithIds; | ||||||
|       buildChallengeMap(); |     } else { | ||||||
|     } |       challengeMapWithIds = {}; | ||||||
|     var challengeMapWithIds = {}; |       Object.keys(challengeMap).forEach(function (key) { | ||||||
|     Object.keys(challengeMap). |         var onlyIds = challengeMap[key].challenges.map(function (elem) { | ||||||
|       forEach(function(key) { |           return elem._id; | ||||||
|         var onlyIds = challengeMap[key].challenges.map(function(elem) { |  | ||||||
|           return elem.challengeId; |  | ||||||
|         }); |         }); | ||||||
|         challengeMapWithIds[key] = onlyIds; |         challengeMapWithIds[key] = onlyIds; | ||||||
|       }); |       }); | ||||||
|     return challengeMapWithIds; |       return challengeMapWithIds; | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   allChallengeIds: function() { | ||||||
|  |  | ||||||
|  |     if (allChallengeIds) { | ||||||
|  |       return allChallengeIds; | ||||||
|  |     } else { | ||||||
|  |       allChallengeIds = []; | ||||||
|  |       Object.keys(challengeMapWithIds).forEach(function(key) { | ||||||
|  |         allChallengeIds.push(challengeMapWithIds[key].challenges); | ||||||
|  |       }); | ||||||
|  |       allChallengeIds = R.flatten(allChallengeIds); | ||||||
|  |     } | ||||||
|  |     return allChallengeIds; | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   getChallengeMapWithNames: function() { |   getChallengeMapWithNames: function() { | ||||||
|     var challengeMapWithNames = {}; |     if (challengeMapWithNames) { | ||||||
|     Object.keys(challengeMap). |       return challengeMapWithNames; | ||||||
|       forEach(function(key) { |     } else { | ||||||
|         var onlyNames = challengeMap[key].challenges.map(function(elem) { |       challengeMapWithNames = {}; | ||||||
|           return elem.challengeName; |       Object.keys(challengeMap). | ||||||
|  |         forEach(function (key) { | ||||||
|  |           var onlyNames = challengeMap[key].challenges.map(function (elem) { | ||||||
|  |             return elem.name; | ||||||
|  |           }); | ||||||
|  |           challengeMapWithNames[key] = onlyNames; | ||||||
|         }); |         }); | ||||||
|         challengeMapWithNames[key] = onlyNames; |       return challengeMapWithNames; | ||||||
|       }); |     } | ||||||
|     return challengeMapWithNames; |  | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   sitemap: function sitemap(req, res, next) { |   sitemap: function sitemap(req, res, next) { | ||||||
|     var appUrl = 'http://www.freecodecamp.com'; |     var appUrl = 'http://www.freecodecamp.com'; | ||||||
|     var now = moment(new Date()).format('YYYY-MM-DD'); |     var now = moment(new Date()).format('YYYY-MM-DD'); | ||||||
|   | |||||||
| @@ -150,7 +150,19 @@ var userSchema = new mongoose.Schema({ | |||||||
|   finishedWaypoints: { type: Boolean, default: false }, |   finishedWaypoints: { type: Boolean, default: false }, | ||||||
|   sendMonthlyEmail: { type: Boolean, default: true }, |   sendMonthlyEmail: { type: Boolean, default: true }, | ||||||
|   challengesHash: {}, |   challengesHash: {}, | ||||||
|   currentChallenge: {} |   currentChallenge: {}, | ||||||
|  |   completedChallenges: [ | ||||||
|  |       { | ||||||
|  |         completedDate: Long, | ||||||
|  |         _id: String, | ||||||
|  |         name: String, | ||||||
|  |         completedWith: String, | ||||||
|  |         solution: String, | ||||||
|  |         githubLink: String, | ||||||
|  |         verified: Boolean | ||||||
|  |       } | ||||||
|  |   ], | ||||||
|  |   uncompletedChallenges: Array | ||||||
| }); | }); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|   | |||||||
| @@ -1,69 +1,69 @@ | |||||||
| var widgets = []; | var widgets = []; | ||||||
| var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), { | var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), { | ||||||
|     lineNumbers: true, |   lineNumbers: true, | ||||||
|     mode: "javascript", |   mode: "javascript", | ||||||
|     theme: 'monokai', |   theme: 'monokai', | ||||||
|     runnable: true, |   runnable: true, | ||||||
|     lint: true, |   lint: true, | ||||||
|     matchBrackets: true, |   matchBrackets: true, | ||||||
|     autoCloseBrackets: true, |   autoCloseBrackets: true, | ||||||
|     scrollbarStyle: 'null', |   scrollbarStyle: 'null', | ||||||
|     lineWrapping: true, |   lineWrapping: true, | ||||||
|     gutters: ["CodeMirror-lint-markers"], |   gutters: ["CodeMirror-lint-markers"], | ||||||
|     onKeyEvent: doLinting |   onKeyEvent: doLinting | ||||||
| }); | }); | ||||||
| var editor = myCodeMirror; | var editor = myCodeMirror; | ||||||
| editor.setSize("100%", "auto"); | editor.setSize("100%", "auto"); | ||||||
|  |  | ||||||
| // Hijack tab key to enter two spaces intead | // Hijack tab key to enter two spaces intead | ||||||
| editor.setOption("extraKeys", { | editor.setOption("extraKeys", { | ||||||
|     Tab: function(cm) { |   Tab: function(cm) { | ||||||
|         if (cm.somethingSelected()){ |     if (cm.somethingSelected()){ | ||||||
|             cm.indentSelection("add"); |       cm.indentSelection("add"); | ||||||
|         } else { |     } else { | ||||||
|             var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); |       var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); | ||||||
|             cm.replaceSelection(spaces); |       cm.replaceSelection(spaces); | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     "Shift-Tab": function(cm) { |  | ||||||
|         if (cm.somethingSelected()){ |  | ||||||
|             cm.indentSelection("subtract"); |  | ||||||
|         } else { |  | ||||||
|             var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); |  | ||||||
|             cm.replaceSelection(spaces); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     "Ctrl-Enter": function() { |  | ||||||
|         bonfireExecute(); |  | ||||||
|         return false; |  | ||||||
|     } |     } | ||||||
|  |   }, | ||||||
|  |   "Shift-Tab": function(cm) { | ||||||
|  |     if (cm.somethingSelected()){ | ||||||
|  |       cm.indentSelection("subtract"); | ||||||
|  |     } else { | ||||||
|  |       var spaces = Array(cm.getOption("indentUnit") + 1).join(" "); | ||||||
|  |       cm.replaceSelection(spaces); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "Ctrl-Enter": function() { | ||||||
|  |     bonfireExecute(); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| var attempts = 0; | var attempts = 0; | ||||||
| if (attempts) { | if (attempts) { | ||||||
|     attempts = 0; |   attempts = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), { | var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), { | ||||||
|     lineNumbers: false, |   lineNumbers: false, | ||||||
|     mode: "text", |   mode: "text", | ||||||
|     theme: 'monokai', |   theme: 'monokai', | ||||||
|     readOnly: 'nocursor', |   readOnly: 'nocursor', | ||||||
|     lineWrapping: true |   lineWrapping: true | ||||||
| }); | }); | ||||||
|  |  | ||||||
| codeOutput.setValue('/**\n' + | codeOutput.setValue('/**\n' + | ||||||
| ' * Your output will go here.\n' + ' * Console.log() -type statements\n' + |   ' * Your output will go here.\n' + ' * Console.log() -type statements\n' + | ||||||
| ' * will appear in your browser\'s\n' + ' * DevTools JavaScript console.\n' + |   ' * will appear in your browser\'s\n' + ' * DevTools JavaScript console.\n' + | ||||||
| ' */'); |   ' */'); | ||||||
| codeOutput.setSize("100%", "100%"); | codeOutput.setSize("100%", "100%"); | ||||||
| var info = editor.getScrollInfo(); | var info = editor.getScrollInfo(); | ||||||
| var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top; | var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top; | ||||||
| if (info.top + info.clientHeight < after) | if (info.top + info.clientHeight < after) | ||||||
|     editor.scrollTo(null, after - info.clientHeight + 3); |   editor.scrollTo(null, after - info.clientHeight + 3); | ||||||
|  |  | ||||||
| var editorValue; | var editorValue; | ||||||
|  |  | ||||||
| @@ -73,9 +73,9 @@ var tests = tests || []; | |||||||
|  |  | ||||||
| var allSeeds = ''; | var allSeeds = ''; | ||||||
| (function() { | (function() { | ||||||
|     challengeSeed.forEach(function(elem) { |   challengeSeed.forEach(function(elem) { | ||||||
|         allSeeds += elem + '\n'; |     allSeeds += elem + '\n'; | ||||||
|     }); |   }); | ||||||
| })(); | })(); | ||||||
|  |  | ||||||
| editorValue = allSeeds; | editorValue = allSeeds; | ||||||
| @@ -84,52 +84,52 @@ editorValue = allSeeds; | |||||||
| myCodeMirror.setValue(editorValue); | myCodeMirror.setValue(editorValue); | ||||||
|  |  | ||||||
| function doLinting () { | function doLinting () { | ||||||
|     editor.operation(function () { |   editor.operation(function () { | ||||||
|         for (var i = 0; i < widgets.length; ++i) |     for (var i = 0; i < widgets.length; ++i) | ||||||
|             editor.removeLineWidget(widgets[i]); |       editor.removeLineWidget(widgets[i]); | ||||||
|         widgets.length = 0; |     widgets.length = 0; | ||||||
|         JSHINT(editor.getValue()); |     JSHINT(editor.getValue()); | ||||||
|         for (var i = 0; i < JSHINT.errors.length; ++i) { |     for (var i = 0; i < JSHINT.errors.length; ++i) { | ||||||
|             var err = JSHINT.errors[i]; |       var err = JSHINT.errors[i]; | ||||||
|             if (!err) continue; |       if (!err) continue; | ||||||
|             var msg = document.createElement("div"); |       var msg = document.createElement("div"); | ||||||
|             var icon = msg.appendChild(document.createElement("span")); |       var icon = msg.appendChild(document.createElement("span")); | ||||||
|             icon.innerHTML = "!!"; |       icon.innerHTML = "!!"; | ||||||
|             icon.className = "lint-error-icon"; |       icon.className = "lint-error-icon"; | ||||||
|             msg.appendChild(document.createTextNode(err.reason)); |       msg.appendChild(document.createTextNode(err.reason)); | ||||||
|             msg.className = "lint-error"; |       msg.className = "lint-error"; | ||||||
|             widgets.push(editor.addLineWidget(err.line - 1, msg, { |       widgets.push(editor.addLineWidget(err.line - 1, msg, { | ||||||
|                 coverGutter: false, |         coverGutter: false, | ||||||
|                 noHScroll: true |         noHScroll: true | ||||||
|             })); |       })); | ||||||
|         } |     } | ||||||
|     }); |   }); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| $('#submitButton').on('click', function () { | $('#submitButton').on('click', function () { | ||||||
|     bonfireExecute(); |   bonfireExecute(); | ||||||
| }); | }); | ||||||
|  |  | ||||||
| function bonfireExecute() { | function bonfireExecute() { | ||||||
|     attempts++; |   attempts++; | ||||||
|     ga('send', 'event',  'Challenge', 'ran-code', challengeName); |   ga('send', 'event',  'Challenge', 'ran-code', challengeName); | ||||||
|     userTests= null; |   userTests= null; | ||||||
|     $('#codeOutput').empty(); |   $('#codeOutput').empty(); | ||||||
|     var userJavaScript = myCodeMirror.getValue(); |   var userJavaScript = myCodeMirror.getValue(); | ||||||
|     userJavaScript = removeComments(userJavaScript); |   userJavaScript = removeComments(userJavaScript); | ||||||
|     userJavaScript = scrapeTests(userJavaScript); |   userJavaScript = scrapeTests(userJavaScript); | ||||||
|     // simple fix in case the user forgets to invoke their function |   // simple fix in case the user forgets to invoke their function | ||||||
|  |  | ||||||
|     submit(userJavaScript, function(cls, message) { |   submit(userJavaScript, function(cls, message) { | ||||||
|         if (cls) { |     if (cls) { | ||||||
|             codeOutput.setValue(message.error); |       codeOutput.setValue(message.error); | ||||||
|             runTests('Error', null); |       runTests('Error', null); | ||||||
|         } else { |     } else { | ||||||
|             codeOutput.setValue(message.output); |       codeOutput.setValue(message.output); | ||||||
|             message.input = removeLogs(message.input); |       message.input = removeLogs(message.input); | ||||||
|             runTests(null, message); |       runTests(null, message); | ||||||
|         } |     } | ||||||
|     }); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -139,108 +139,108 @@ var testSalt = Math.random(); | |||||||
|  |  | ||||||
| var scrapeTests = function(userJavaScript) { | var scrapeTests = function(userJavaScript) { | ||||||
|  |  | ||||||
|     // insert tests from mongo |   // insert tests from mongo | ||||||
|     for (var i = 0; i < tests.length; i++) { |   for (var i = 0; i < tests.length; i++) { | ||||||
|         userJavaScript += '\n' + tests[i]; |     userJavaScript += '\n' + tests[i]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   var counter = 0; | ||||||
|  |   var regex = new RegExp(/(expect(\s+)?\(.*\;)|(assert(\s+)?\(.*\;)|(assert\.\w.*\;)|(.*\.should\..*\;)/); | ||||||
|  |   var match = regex.exec(userJavaScript); | ||||||
|  |   while (match != null) { | ||||||
|  |     var replacement = '//' + counter + testSalt; | ||||||
|  |     userJavaScript = userJavaScript.substring(0, match.index) + replacement + userJavaScript.substring(match.index + match[0].length); | ||||||
|  |  | ||||||
|  |     if (!userTests) { | ||||||
|  |       userTests= []; | ||||||
|     } |     } | ||||||
|  |     userTests.push({"text": match[0], "line": counter, "err": null}); | ||||||
|  |     counter++; | ||||||
|  |     match = regex.exec(userJavaScript); | ||||||
|  |   } | ||||||
|  |  | ||||||
|     var counter = 0; |   return userJavaScript; | ||||||
|     var regex = new RegExp(/(expect(\s+)?\(.*\;)|(assert(\s+)?\(.*\;)|(assert\.\w.*\;)|(.*\.should\..*\;)/); |  | ||||||
|     var match = regex.exec(userJavaScript); |  | ||||||
|     while (match != null) { |  | ||||||
|         var replacement = '//' + counter + testSalt; |  | ||||||
|         userJavaScript = userJavaScript.substring(0, match.index) + replacement + userJavaScript.substring(match.index + match[0].length); |  | ||||||
|  |  | ||||||
|         if (!userTests) { |  | ||||||
|             userTests= []; |  | ||||||
|         } |  | ||||||
|         userTests.push({"text": match[0], "line": counter, "err": null}); |  | ||||||
|         counter++; |  | ||||||
|         match = regex.exec(userJavaScript); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     return userJavaScript; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function removeComments(userJavaScript) { | function removeComments(userJavaScript) { | ||||||
|     var regex = new RegExp(/(\/\*[^(\*\/)]*\*\/)|\/\/[^\n]*/g); |   var regex = new RegExp(/(\/\*[^(\*\/)]*\*\/)|\/\/[^\n]*/g); | ||||||
|     return userJavaScript.replace(regex, ''); |   return userJavaScript.replace(regex, ''); | ||||||
| } | } | ||||||
|  |  | ||||||
| function removeLogs(userJavaScript) { | function removeLogs(userJavaScript) { | ||||||
|     return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, ''); |   return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, ''); | ||||||
| } | } | ||||||
|  |  | ||||||
| var pushed = false; | var pushed = false; | ||||||
| var createTestDisplay = function() { | var createTestDisplay = function() { | ||||||
|     if (pushed) { |   if (pushed) { | ||||||
|         userTests.pop(); |     userTests.pop(); | ||||||
|  |   } | ||||||
|  |   for (var i = 0; i < userTests.length;i++) { | ||||||
|  |     var test = userTests[i]; | ||||||
|  |     var testDoc = document.createElement("div"); | ||||||
|  |     if (test.err != null) { | ||||||
|  |       console.log('Should be displaying bad tests'); | ||||||
|  |       $(testDoc) | ||||||
|  |         .html("<div class='row'><div class='col-xs-2 text-center'><i class='ion-close-circled big-error-icon'></i></div><div class='col-xs-10 test-output wrappable test-vertical-center grayed-out-test-output'>" + test.text + "</div><div class='col-xs-10 test-output wrappable'>" + test.err + "</div></div><div class='ten-pixel-break'/>") | ||||||
|  |         .prependTo($('#testSuite')) | ||||||
|  |     } else { | ||||||
|  |       $(testDoc) | ||||||
|  |         .html("<div class='row'><div class='col-xs-2 text-center'><i class='ion-checkmark-circled big-success-icon'></i></div><div class='col-xs-10 test-output test-vertical-center wrappable grayed-out-test-output'>" + test.text + "</div></div><div class='ten-pixel-break'/>") | ||||||
|  |         .appendTo($('#testSuite')); | ||||||
|     } |     } | ||||||
|     for (var i = 0; i < userTests.length;i++) { |   }; | ||||||
|         var test = userTests[i]; |  | ||||||
|         var testDoc = document.createElement("div"); |  | ||||||
|         if (test.err != null) { |  | ||||||
|             console.log('Should be displaying bad tests'); |  | ||||||
|             $(testDoc) |  | ||||||
|                 .html("<div class='row'><div class='col-xs-2 text-center'><i class='ion-close-circled big-error-icon'></i></div><div class='col-xs-10 test-output wrappable test-vertical-center grayed-out-test-output'>" + test.text + "</div><div class='col-xs-10 test-output wrappable'>" + test.err + "</div></div><div class='ten-pixel-break'/>") |  | ||||||
|                 .prependTo($('#testSuite')) |  | ||||||
|         } else { |  | ||||||
|             $(testDoc) |  | ||||||
|                 .html("<div class='row'><div class='col-xs-2 text-center'><i class='ion-checkmark-circled big-success-icon'></i></div><div class='col-xs-10 test-output test-vertical-center wrappable grayed-out-test-output'>" + test.text + "</div></div><div class='ten-pixel-break'/>") |  | ||||||
|                 .appendTo($('#testSuite')); |  | ||||||
|         } |  | ||||||
|     }; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| var expect = chai.expect; | var expect = chai.expect; | ||||||
|  |  | ||||||
|  |  | ||||||
| var reassembleTest = function(test, data) { | var reassembleTest = function(test, data) { | ||||||
|     var lineNum = test.line; |   var lineNum = test.line; | ||||||
|     var regexp = new RegExp("\/\/" + lineNum + testSalt); |   var regexp = new RegExp("\/\/" + lineNum + testSalt); | ||||||
|     return data.input.replace(regexp, test.text); |   return data.input.replace(regexp, test.text); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| var runTests = function(err, data) { | var runTests = function(err, data) { | ||||||
|     var allTestsPassed = true; |   var allTestsPassed = true; | ||||||
|     pushed = false; |   pushed = false; | ||||||
|     $('#testSuite').children().remove(); |   $('#testSuite').children().remove(); | ||||||
|     if (err && userTests.length > 0) { |   if (err && userTests.length > 0) { | ||||||
|         userTests= [{text:"Program Execution Failure", err: "No user tests were run."}]; |     userTests= [{text:"Program Execution Failure", err: "No user tests were run."}]; | ||||||
|         createTestDisplay(); |     createTestDisplay(); | ||||||
|     } else if (userTests) { |   } else if (userTests) { | ||||||
|         userTests.push(false); |     userTests.push(false); | ||||||
|         pushed = true; |     pushed = true; | ||||||
|         userTests.forEach(function(test, ix, arr){ |     userTests.forEach(function(test, ix, arr){ | ||||||
|             try { |       try { | ||||||
|                 if (test) { |         if (test) { | ||||||
|                     var output = eval(reassembleTest(test, data)); |           var output = eval(reassembleTest(test, data)); | ||||||
|                 } |  | ||||||
|             } catch(error) { |  | ||||||
|                 allTestsPassed = false; |  | ||||||
|                 arr[ix].err = error.message; |  | ||||||
|             } finally { |  | ||||||
|                 if (!test) { |  | ||||||
|                     createTestDisplay(); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         if (allTestsPassed) { |  | ||||||
|             allTestsPassed = false; |  | ||||||
|             showCompletion(); |  | ||||||
|         } |         } | ||||||
|  |       } catch(error) { | ||||||
|  |         allTestsPassed = false; | ||||||
|  |         arr[ix].err = error.message; | ||||||
|  |       } finally { | ||||||
|  |         if (!test) { | ||||||
|  |           createTestDisplay(); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     if (allTestsPassed) { | ||||||
|  |       allTestsPassed = false; | ||||||
|  |       showCompletion(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| function showCompletion() { | function showCompletion() { | ||||||
|     var time = Math.floor(Date.now()) - started; |   var time = Math.floor(Date.now()) - started; | ||||||
|     ga('send', 'event',  'Challenge', 'solved', challengeName + ', Time: ' + time +', Attempts: ' + attempts); |   ga('send', 'event',  'Challenge', 'solved', challengeName + ', Time: ' + time +', Attempts: ' + attempts); | ||||||
|     $('#complete-courseware-dialog').modal('show'); |   $('#complete-courseware-dialog').modal('show'); | ||||||
|     $('#complete-courseware-dialog').keydown(function(e) { |   $('#complete-courseware-dialog').keydown(function(e) { | ||||||
|         if (e.ctrlKey && e.keyCode == 13) { |     if (e.ctrlKey && e.keyCode == 13) { | ||||||
|             $('#next-courseware-button').click(); |       $('#next-courseware-button').click(); | ||||||
|         } |     } | ||||||
|     }); |   }); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -127,16 +127,16 @@ $(document).ready(function() { | |||||||
|         case 1: |         case 1: | ||||||
|         case 2: |         case 2: | ||||||
|           $.post( |           $.post( | ||||||
|             '/completed-courseware/', |             '/completed-challenge/', | ||||||
|             { |             { | ||||||
|               coursewareInfo: { |               challengeInfo: { | ||||||
|                 coursewareHash: passedCoursewareHash, |                 challengeId: challengeId, | ||||||
|                 coursewareName: passedCoursewareName |                 challengeName: challengeName | ||||||
|               } |               } | ||||||
|             }).success( |             }).success( | ||||||
|             function(res) { |             function(res) { | ||||||
|               if (res) { |               if (res) { | ||||||
|                 window.location.href = '/challenges'; |                 window.location.href = '/challenges/next-challenge'; | ||||||
|               } |               } | ||||||
|             } |             } | ||||||
|           ); |           ); | ||||||
| @@ -147,16 +147,16 @@ $(document).ready(function() { | |||||||
|           $.post( |           $.post( | ||||||
|             '/completed-zipline-or-basejump/', |             '/completed-zipline-or-basejump/', | ||||||
|             { |             { | ||||||
|               coursewareInfo: { |               challengeInfo: { | ||||||
|                 coursewareHash: passedCoursewareHash, |                 challengeId: challengeId, | ||||||
|                 coursewareName: passedCoursewareName, |                 challengeName: challengeName, | ||||||
|                 completedWith: didCompleteWith, |                 completedWith: didCompleteWith, | ||||||
|                 publicURL: publicURL, |                 publicURL: publicURL, | ||||||
|                 challengeType: challengeType |                 challengeType: challengeType | ||||||
|               } |               } | ||||||
|             }).success( |             }).success( | ||||||
|             function() { |             function() { | ||||||
|               window.location.href = '/challenges'; |               window.location.href = '/challenges/next-challenge'; | ||||||
|             }).fail( |             }).fail( | ||||||
|             function() { |             function() { | ||||||
|               window.location.href = '/challenges'; |               window.location.href = '/challenges'; | ||||||
| @@ -169,9 +169,9 @@ $(document).ready(function() { | |||||||
|           $.post( |           $.post( | ||||||
|             '/completed-zipline-or-basejump/', |             '/completed-zipline-or-basejump/', | ||||||
|             { |             { | ||||||
|               coursewareInfo: { |               challengeInfo: { | ||||||
|                 coursewareHash: passedCoursewareHash, |                 challengeId: challengeId, | ||||||
|                 coursewareName: passedCoursewareName, |                 challengeName: challengeName, | ||||||
|                 completedWith: didCompleteWith, |                 completedWith: didCompleteWith, | ||||||
|                 publicURL: publicURL, |                 publicURL: publicURL, | ||||||
|                 githubURL: githubURL, |                 githubURL: githubURL, | ||||||
| @@ -179,7 +179,7 @@ $(document).ready(function() { | |||||||
|                 verified: false |                 verified: false | ||||||
|               } |               } | ||||||
|             }).success(function() { |             }).success(function() { | ||||||
|               window.location.href = '/challenges'; |               window.location.href = '/challenges/next-challenge'; | ||||||
|             }).fail(function() { |             }).fail(function() { | ||||||
|               window.location.replace(window.location.href); |               window.location.replace(window.location.href); | ||||||
|             }); |             }); | ||||||
|   | |||||||
| @@ -20,7 +20,8 @@ | |||||||
|       ], |       ], | ||||||
|       "challengeSeed": [ |       "challengeSeed": [ | ||||||
|         "<h1>Hello</h1>" |         "<h1>Hello</h1>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf0887a", |       "_id": "bad87fee1348bd9aedf0887a", | ||||||
| @@ -38,7 +39,8 @@ | |||||||
|       ], |       ], | ||||||
|       "challengeSeed": [ |       "challengeSeed": [ | ||||||
|         "<h1>Hello World</h1>" |         "<h1>Hello World</h1>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08801", |       "_id": "bad87fee1348bd9aedf08801", | ||||||
| @@ -55,7 +57,8 @@ | |||||||
|       "challengeSeed": [ |       "challengeSeed": [ | ||||||
|         "<h1>Hello World</h1>", |         "<h1>Hello World</h1>", | ||||||
|         "<h2>CatPhotoApp</h2>" |         "<h2>CatPhotoApp</h2>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aeaf08801", |       "_id": "bad87fee1348bd9aeaf08801", | ||||||
| @@ -74,7 +77,8 @@ | |||||||
|         "<h1>Hello World</h1>", |         "<h1>Hello World</h1>", | ||||||
|         "<h2>CatPhotoApp</h2>", |         "<h2>CatPhotoApp</h2>", | ||||||
|         "<p>Hello Paragraph</p>" |         "<p>Hello Paragraph</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08802", |       "_id": "bad87fee1348bd9aedf08802", | ||||||
| @@ -101,7 +105,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p>Hello Paragraph</p>", |         "<p>Hello Paragraph</p>", | ||||||
|         "-->" |         "-->" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08804", |       "_id": "bad87fee1348bd9aedf08804", | ||||||
| @@ -127,7 +132,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p>Hello Paragraph</p>", |         "<p>Hello Paragraph</p>", | ||||||
|         "-->" |         "-->" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08833", |       "_id": "bad87fee1348bd9aedf08833", | ||||||
| @@ -151,7 +157,8 @@ | |||||||
|         "<br/>", |         "<br/>", | ||||||
|         "", |         "", | ||||||
|         "<p>Hello Paragraph</p>" |         "<p>Hello Paragraph</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fed1348bd9aedf08833", |       "_id": "bad87fed1348bd9aedf08833", | ||||||
| @@ -176,7 +183,8 @@ | |||||||
|         "<br/>", |         "<br/>", | ||||||
|         "", |         "", | ||||||
|         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" |         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08803", |       "_id": "bad87fee1348bd9aedf08803", | ||||||
| @@ -195,7 +203,8 @@ | |||||||
|         "<h2>CatPhotoApp</h2>", |         "<h2>CatPhotoApp</h2>", | ||||||
|         "", |         "", | ||||||
|         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" |         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08805", |       "_id": "bad87fee1348bd9aedf08805", | ||||||
| @@ -218,7 +227,8 @@ | |||||||
|         "<h2 style='color: red'>CatPhotoApp</h2>", |         "<h2 style='color: red'>CatPhotoApp</h2>", | ||||||
|         "", |         "", | ||||||
|         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" |         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aecf08806", |       "_id": "bad87fee1348bd9aecf08806", | ||||||
| @@ -248,7 +258,8 @@ | |||||||
|         "<h2>CatPhotoApp</h2>", |         "<h2>CatPhotoApp</h2>", | ||||||
|         "", |         "", | ||||||
|         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" |         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aefe08806", |       "_id": "bad87fee1348bd9aefe08806", | ||||||
| @@ -274,7 +285,8 @@ | |||||||
|         "<h2 class='red-text'>CatPhotoApp</h2>", |         "<h2 class='red-text'>CatPhotoApp</h2>", | ||||||
|         "", |         "", | ||||||
|         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" |         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08806", |       "_id": "bad87fee1348bd9aedf08806", | ||||||
| @@ -300,7 +312,8 @@ | |||||||
|         "<h2 class='red-text'>CatPhotoApp</h2>", |         "<h2 class='red-text'>CatPhotoApp</h2>", | ||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aede08807", |       "_id": "bad87fee1348bd9aede08807", | ||||||
| @@ -329,7 +342,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08807", |       "_id": "bad87fee1348bd9aedf08807", | ||||||
| @@ -361,7 +375,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08808", |       "_id": "bad87fee1348bd9aedf08808", | ||||||
| @@ -399,7 +414,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08809", |       "_id": "bad87fee1348bd9aedf08809", | ||||||
| @@ -440,7 +456,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -478,7 +495,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9acdf08812", |       "_id": "bad87fee1348bd9acdf08812", | ||||||
| @@ -516,7 +534,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9bedf08813", |       "_id": "bad87fee1348bd9bedf08813", | ||||||
| @@ -559,7 +578,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08814", |       "_id": "bad87fee1348bd9aedf08814", | ||||||
| @@ -607,7 +627,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08815", |       "_id": "bad87fee1348bd9aedf08815", | ||||||
| @@ -654,7 +675,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08816", |       "_id": "bad87fee1348bd9aedf08816", | ||||||
| @@ -704,7 +726,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aede08817", |       "_id": "bad87fee1348bd9aede08817", | ||||||
| @@ -757,7 +780,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -809,7 +833,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08820", |       "_id": "bad87fee1348bd9aedf08820", | ||||||
| @@ -861,7 +886,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       "_id": "bad87fee1348bd9aedf08818", |       "_id": "bad87fee1348bd9aedf08818", | ||||||
| @@ -913,7 +939,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -966,7 +993,8 @@ | |||||||
|         "", |         "", | ||||||
|         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", |         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", | ||||||
|         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" |         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1025,7 +1053,8 @@ | |||||||
|         "  <li>laser pointers</li>", |         "  <li>laser pointers</li>", | ||||||
|         "  <li>lasagna</li>", |         "  <li>lasagna</li>", | ||||||
|         "</ul>" |         "</ul>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1086,7 +1115,8 @@ | |||||||
|         "  <li>thunder</li>", |         "  <li>thunder</li>", | ||||||
|         "  <li>other cats</li>", |         "  <li>other cats</li>", | ||||||
|         "</ol>" |         "</ol>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1148,7 +1178,8 @@ | |||||||
|         "  <li>other cats</li>", |         "  <li>other cats</li>", | ||||||
|         "</ol>", |         "</ol>", | ||||||
|         "<input type='text'>" |         "<input type='text'>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1211,7 +1242,8 @@ | |||||||
|         "  <li>other cats</li>", |         "  <li>other cats</li>", | ||||||
|         "</ol>", |         "</ol>", | ||||||
|         "<input type='text' placeholder='cat photo URL'>" |         "<input type='text' placeholder='cat photo URL'>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1275,7 +1307,8 @@ | |||||||
|         "<form action=\"/submit-cat-photo\">", |         "<form action=\"/submit-cat-photo\">", | ||||||
|         "  <input type='text' placeholder='cat photo URL'>", |         "  <input type='text' placeholder='cat photo URL'>", | ||||||
|         "</form>" |         "</form>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1411,7 +1444,8 @@ | |||||||
|         "  <input type='text' placeholder='cat photo URL' required>", |         "  <input type='text' placeholder='cat photo URL' required>", | ||||||
|         "  <button type='submit'>Submit</button>", |         "  <button type='submit'>Submit</button>", | ||||||
|         "</form>" |         "</form>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType": 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1479,7 +1513,8 @@ | |||||||
|         "  <input type='text' placeholder='cat photo URL' required>", |         "  <input type='text' placeholder='cat photo URL' required>", | ||||||
|         "  <button type='submit'>Submit</button>", |         "  <button type='submit'>Submit</button>", | ||||||
|         "</form>" |         "</form>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType" : 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1548,7 +1583,8 @@ | |||||||
|         "  <input type='text' placeholder='cat photo URL' required>", |         "  <input type='text' placeholder='cat photo URL' required>", | ||||||
|         "  <button type='submit'>Submit</button>", |         "  <button type='submit'>Submit</button>", | ||||||
|         "</form>" |         "</form>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType" : 0 | ||||||
|     }, |     }, | ||||||
|  |  | ||||||
|     { |     { | ||||||
| @@ -1620,7 +1656,8 @@ | |||||||
|         "  <input type='text' placeholder='cat photo URL' required>", |         "  <input type='text' placeholder='cat photo URL' required>", | ||||||
|         "  <button type='submit'>Submit</button>", |         "  <button type='submit'>Submit</button>", | ||||||
|         "</form>" |         "</form>" | ||||||
|       ] |       ], | ||||||
|  |       "challengeType" : 0 | ||||||
|     } |     } | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,11 +32,12 @@ Challenge.remove({}, function(err, data) { | |||||||
|     console.log('Deleted ', data); |     console.log('Deleted ', data); | ||||||
|   } |   } | ||||||
|   challenges.forEach(function (file) { |   challenges.forEach(function (file) { | ||||||
|     Challenge.create(require('./challenges/' + file), function (err, data) { |     Challenge.create(require('./challenges/' + file).challenges, function (err, data) { | ||||||
|       if (err) { |       if (err) { | ||||||
|         console.log(err); |         console.log(err); | ||||||
|       } else { |       } else { | ||||||
|         console.log('Successfully parsed %s', file); |         console.log('Successfully parsed %s', file); | ||||||
|  |         console.log(data); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|   | |||||||
| @@ -29,9 +29,8 @@ block content | |||||||
|             .button-spacer |             .button-spacer | ||||||
|         script(type="text/javascript"). |         script(type="text/javascript"). | ||||||
|                 var tests = !{JSON.stringify(tests)}; |                 var tests = !{JSON.stringify(tests)}; | ||||||
|                 var passedCoursewareHash = !{JSON.stringify(coursewareHash)}; |                 var challengeId = !{JSON.stringify(coursewareHash)}; | ||||||
|                 var challengeName = !{JSON.stringify(name)}; |                 var challengeName = !{JSON.stringify(name)}; | ||||||
|                 var passedCoursewareName = challengeName; |  | ||||||
|                 var started = Math.floor(Date.now()); |                 var started = Math.floor(Date.now()); | ||||||
|                 var challengeType = !{JSON.stringify(challengeType)}; |                 var challengeType = !{JSON.stringify(challengeType)}; | ||||||
|                 var controlEnterHandler = function(e) { |                 var controlEnterHandler = function(e) { | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height | |||||||
|  |  | ||||||
|             if user |             if user | ||||||
|                 li |                 li | ||||||
|                     a(href='/challenges') Next Challenge |                     a(href='/challenges') Current Challenge | ||||||
|             li |             li | ||||||
|                 a(href='/map') Map |                 a(href='/map') Map | ||||||
|             if (user && user.sentSlackInvite) |             if (user && user.sentSlackInvite) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user