Merge branch 'master' into ramda-fire

This commit is contained in:
Nathan Leniz
2015-02-16 00:51:11 -05:00
32 changed files with 5485 additions and 1073 deletions

View File

@ -130,7 +130,7 @@ List of Packages
| passport-linkedin-oauth2 | Sign-in with LinkedIn plugin. |
| passport-oauth | Allows you to set up your own OAuth 1.0a and OAuth 2.0 strategies. |
| request | Simplified HTTP request library. |
| lodash | Handy JavaScript utlities library. |
| lodash | Handy JavaScript utilities library. |
| uglify-js | Dependency for connect-assets library to minify JS. |
| mocha | Test framework. |
| chai | BDD/TDD assertion library. |

4
app.js
View File

@ -211,10 +211,6 @@ app.get('/control-shortcuts', resourcesController.deployAWebsite);
app.get('/stats', function(req, res) {
res.redirect(301, '/learn-to-code');
});
app.get(
'/pair-program-with-team-viewer',
resourcesController.pairProgramWithTeamViewer
);
app.get('/learn-to-code', resourcesController.about);
app.get('/about', function(req, res) {
res.redirect(301, '/learn-to-code');

View File

@ -24,7 +24,6 @@ exports.index = function(req, res) {
details: '',
tests: [],
challengeSeed: '',
challengeEntryPoint: '',
cc: req.user ? req.user.bonfiresHash : undefined,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
@ -89,7 +88,7 @@ exports.returnIndividualBonfire = function(req, res, next) {
return res.redirect('/bonfires');
}
bonfire = bonfire.pop()
bonfire = bonfire.pop();
var dashedNameFull = bonfire.name.toLowerCase().replace(/\s/g, '-');
if (dashedNameFull != dashedName) {
return res.redirect('../bonfires/' + dashedNameFull);
@ -105,7 +104,6 @@ exports.returnIndividualBonfire = function(req, res, next) {
details: bonfire.description.slice(1),
tests: bonfire.tests,
challengeSeed: bonfire.challengeSeed,
challengeEntryPoint: bonfire.challengeEntryPoint,
cc: !!req.user,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
@ -115,7 +113,6 @@ exports.returnIndividualBonfire = function(req, res, next) {
bonfireHash: bonfire._id
});
});
};
@ -131,7 +128,6 @@ exports.returnGenerator = function(req, res) {
details: null,
tests: null,
challengeSeed: null,
challengeEntryPoint: null,
bonfireHash: randomString()
});
};
@ -160,7 +156,6 @@ exports.testBonfire = function(req, res) {
bonfireTests = req.body.tests,
bonfireDifficulty = req.body.difficulty,
bonfireDescription = req.body.description,
bonfireEntryPoint = req.body.challengeEntryPoint,
bonfireChallengeSeed = req.body.challengeSeed;
bonfireTests = bonfireTests.split('\r\n');
bonfireDescription = bonfireDescription.split('\r\n');
@ -176,7 +171,6 @@ exports.testBonfire = function(req, res) {
details: bonfireDescription.slice(1),
tests: bonfireTests,
challengeSeed: bonfireChallengeSeed,
challengeEntryPoint: bonfireEntryPoint,
cc: req.user ? req.user.bonfiresHash : undefined,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
@ -202,7 +196,6 @@ exports.generateChallenge = function(req, res) {
bonfireTests = req.body.tests,
bonfireDifficulty = req.body.difficulty,
bonfireDescription = req.body.description,
bonfireEntryPoint = req.body.challengeEntryPoint,
bonfireChallengeSeed = req.body.challengeSeed;
bonfireTests = bonfireTests.split('\r\n');
bonfireDescription = bonfireDescription.split('\r\n');
@ -216,7 +209,6 @@ exports.generateChallenge = function(req, res) {
name: bonfireName,
difficulty: bonfireDifficulty,
description: bonfireDescription,
challengeEntryPoint: bonfireEntryPoint,
challengeSeed: bonfireChallengeSeed,
tests: bonfireTests
};

View File

@ -16,7 +16,7 @@ exports.coursewareNames = function(req, res) {
exports.returnNextCourseware = function(req, res) {
if (!req.user) {
return res.redirect('coursewares/start-our-challenges');
return res.redirect('../coursewares/start-our-challenges');
}
var completed = req.user.completedCoursewares.map(function (elem) {
return elem._id;
@ -72,8 +72,9 @@ exports.returnIndividualCourseware = function(req, res, next) {
return res.redirect('../coursewares/' + dashedNameFull);
}
// Render the view for the user
res.render('coursewares/show', {
var challengeType = {
0 : function() {
res.render('coursewares/showHTML', {
title: courseware.name,
dashedName: dashedName,
name: courseware.name,
@ -89,6 +90,48 @@ exports.returnIndividualCourseware = function(req, res, next) {
coursewareHash: courseware._id,
environment: resources.whichEnvironment()
});
},
1 : function() {
res.render('coursewares/showJS', {
title: courseware.name,
dashedName: dashedName,
name: courseware.name,
brief: courseware.description[0],
details: courseware.description.slice(1),
tests: courseware.tests,
challengeSeed: courseware.challengeSeed,
cc: !!req.user,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
coursewareHash: courseware._id,
environment: resources.whichEnvironment()
});
},
2: function() {
res.render('coursewares/showVideo', {
title: courseware.name,
dashedName: dashedName,
name: courseware.name,
details: courseware.description,
tests: courseware.tests,
video: courseware.challengeSeed[0],
cc: !!req.user,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
coursewareHash: courseware._id,
environment: resources.whichEnvironment()
});
}
};
return challengeType[courseware.challengeType]();
});
};

View File

@ -97,25 +97,6 @@ module.exports = {
});
},
pairProgramWithTeamViewer: function(req, res) {
Challenge.find({}, null, { sort: { challengeNumber: 1 } }, function(err, c) {
if (err) {
debug('Challenge err: ', err);
next(err);
}
res.render('resources/pair-program-with-team-viewer', {
title: 'Challenge: Pair Program with Team Viewer',
name: 'Pair Program with Team Viewer',
video: '',
time: 30,
steps: steps,
cc: req.user ? req.user.challengesHash : undefined,
points: req.user ? req.user.points : undefined,
challenges: c
});
});
},
about: function(req, res) {
var date1 = new Date("10/15/2014");
var date2 = new Date();
@ -123,7 +104,7 @@ module.exports = {
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
client.get('https://trello.com/1/boards/BA3xVpz9/cards?key=' + secrets.trello.key, function(trello, res2) {
client.get('https://www.googleapis.com/blogger/v3/blogs/2421288658305323950/posts?key=' + secrets.blogger.key, function(blogger, res3) {
var nonprofitProjects = trello.length || 15;
var nonprofitProjects = (JSON.parse(trello)).length || 27;
var blog = JSON.parse(blogger);
User.count({'points': {'$gt': 2}}, function (err, c3) {
if (err) {

View File

@ -117,34 +117,6 @@
"question": "Latency of Sending a packet from California to the Netherlands and back",
"answer": "150,000,000 nanoseconds"
}],
"steps": [
"In the spirit of keeping Free Code Camp 100% free, we've created directions for using a totally free pair programming tool called Team Viewer. It's not as user-friendly as Screen Hero, but it gets the job done (and works on Linux!).",
"Go to <a href='http://www.teamviewer.com/en/index.aspx' target='_blank'>http://www.teamviewer.com/en/index.aspx</a> and download Team Viewer. Be sure not to download the beta version, which isn't compatible with the current stable version everyone else will be using.",
"Install it and launch it",
"We have a special chat room for people ready to pair program. Go to <a href='https://gitter.im/FreeCodeCamp/LetsPair' target='_blank'>https://gitter.im/FreeCodeCamp/LetsPair</a> and type \"Hello Pair Programmers!\". you on a CoderByte challenge.",
"If someone is available, they will be your \"pair\" - the person you pair programming with.",
"<strong>First, you will pair program on your pair's computer.</strong> Ask your pair for his or her Team Viewer ID and password.",
"Enter this id, and then password, to start the session.",
"Once the Team Viewer session starts, look at the the top of the screen. You will see 6 buttons. If you hover your cursor over the buttons, they will slide down so that you can read them. Click the audio/video button. This will allow you to turn on Voice Over IP and unmute your microphone, opening up your voice channel.",
"Note that you can now control your pair's keyboard and mouse, enabling you to step in and code yourself on your pair's computer when desired",
"Now you can click the X to end the pair programming session.",
"<strong>Next, you will pair program on your computer.</strong> Copy your Team Viewer ID and paste it into the private chat, so that your pair can use it to connect with you.",
"You will need to share your randomly generated password with your pair as well.",
"Once your pair connects, you will see a Team Viewer side menu. ",
"Click the audio button that drops down.",
"Click the headset icon and choose Voice over IP",
"Click the microphone button to unmute your microphone. Once your pair does the same, you two will have an open voice channel.",
"Now you can click the X to end the pair programming session.",
"Now it's time to tackle CoderByte.",
"Create a CoderByte account at <a href='http://coderbyte.com/sl/' target='_blank'>http://coderbyte.com/sl/</a>",
"Now go to <a href='http://coderbyte.com/CodingArea/Challenges/#easyChals' target='_blank'>http://coderbyte.com/CodingArea/Challenges/#easyChals</a> and start working through Coderbyte's easy algorithm scripting challenges using JavaScript.",
"When you are finished pair programming, click the X to end the session.",
"Congratulations! You have completed your first pair programming session.",
"You should pair program with different campers until you've completed all the Easy, Medium and Hard CoderByte challenges. This is a big time investment, but the JavaScript practice you'll get, along with the scripting and algorithm experience, are well worth it!",
"You can complete CoderByte problems while you continue to work through Free Code Camp's challenges.",
"Be sure to pair program on these challenges, and remember to apply the RSAP methodology.",
"Click the button below to return to the Pair Programming challenge, then mark it complete."
],
"verbs": [
"aced",
"nailed",
@ -162,12 +134,6 @@
"compliments": [
"Over the top!",
"Down the rabbit hole we go!",
"Well, isn't that special!",
"Somewhere over the rainbow!",
"Follow the white rabbit!",
"Eye of the tiger!",
"Run, Forest, run!",
"Welcome to the Rock!",
"Bring that rain!",
"Target acquired!",
"Feel that need for speed!",
@ -186,7 +152,6 @@
"The town is now red!",
"To the nines!",
"Nothing but net!",
"Grumpy cat approves!",
"The world rejoices!",
"That's the way it's done!",
"You rock!",
@ -216,38 +181,27 @@
"Sonic Boom!",
"Here's looking at you, Code!",
"Ride like the wind!",
"The more you code!",
"Legen - wait for it - dary!",
"Ludicrous Speed! Go!",
"Yes you can!",
"Most triumphant!",
"One loop to rule them all!",
"Ain't got time to bleed!",
"By the power of Grayskull!",
"You did it!",
"Storm that castle!",
"Face-melting guitar Solo!",
"Checkmate!",
"Remember the Alamo!",
"Bodacious!",
"You're the man now, dog!",
"Tubular!",
"You're outta sight!",
"Keep calm and code on!",
"Even sad panda smiles!",
"Even grumpy cat approves!",
"Koolaid Man says oh yeah!",
"Kool Aid Man says oh yeah!",
"Bullseye!",
"You stay classy, San Diego!",
"Loud noises!",
"Me want cookie!",
"Far out!",
"You're heating up!",
"Crash override!",
"This is Sparta!",
"You ARE the law!",
"Hasta la vista, challenge!",
"Huh? It's just a box..."
"Hasta la vista, challenge!"
],
"phrases": [
"Shout it from on top of a mountain",

View File

@ -192,11 +192,9 @@ exports.checkUniqueUsername = function(req, res) {
*/
exports.checkExistingUsername = function(req, res) {
User.count({'profile.username': req.params.username.toLowerCase()}, function (err, data) {
if (data == 1) {
debug('sending false back')
if (data === 1) {
return res.send(true);
} else {
debug('sending true back')
return res.send(false);
}
});
@ -233,7 +231,6 @@ exports.returnUser = function(req, res, next) {
username: user.profile.username,
name: user.profile.name,
location: user.profile.location,
coderbyteProfile: user.profile.coderbyteProfile,
githubProfile: user.profile.githubProfile,
linkedinProfile: user.profile.linkedinProfile,
codepenProfile: user.profile.codepenProfile,
@ -329,7 +326,6 @@ exports.postUpdateProfile = function(req, res, next) {
user.profile.username = req.body.username.trim() || '';
user.profile.location = req.body.location.trim() || '';
user.profile.githubProfile = req.body.githubProfile.trim() || '';
user.profile.coderbyteProfile = req.body.coderbyteProfile.trim() || '';
user.profile.linkedinProfile = req.body.linkedinProfile.trim() || '';
user.profile.codepenProfile = req.body.codepenProfile.trim() || '';
user.profile.twitterHandle = req.body.twitterHandle.trim() || '';

View File

@ -15,8 +15,7 @@ var bonfireSchema = new mongoose.Schema({
difficulty: String,
description: Array,
tests: Array,
challengeSeed: String,
challengeEntryPoint: String,
challengeSeed: String
});
module.exports = mongoose.model('Bonfire', bonfireSchema);

View File

@ -15,6 +15,7 @@ var coursewareSchema = new mongoose.Schema({
description: Array,
tests: Array,
challengeSeed: Array,
completionMessage: String, // Congratulations! You've finished our HTML and CSS track!
challengeType: Number // 0 = html, 1 = javascript only, 2 = video
});

View File

@ -508,6 +508,7 @@ thead {
border-radius: 5px;
height: 200px;
width: 200px;
color: #009900
}
.testimonial-copy {
@ -684,6 +685,11 @@ iframe.iphone {
min-height: 650px;
}
// This is used to give icons text for screen readers to read out, without needing the text to actually appear.
.icon-lock{
font-size: 0px;
}
//uncomment this to see the dimensions of all elements outlined in red
//* {

View File

@ -73,11 +73,10 @@ var editorValue;
var challengeSeed = challengeSeed || null;
var tests = tests || [];
var challengeEntryPoint = challengeEntryPoint || null;
if (challengeSeed !== null) {
editorValue = challengeSeed + '\n\n' + challengeEntryPoint;
editorValue = challengeSeed;
} else {
editorValue = nonChallengeValue;
}
@ -121,9 +120,7 @@ function bonfireExecute() {
userJavaScript = removeComments(userJavaScript);
userJavaScript = scrapeTests(userJavaScript);
// simple fix in case the user forgets to invoke their function
if (challengeEntryPoint && challengeSeed) {
userJavaScript = challengeEntryPoint + ' ' + userJavaScript;
}
submit(userJavaScript, function(cls, message) {
if (cls) {
codeOutput.setValue(message.error);

View File

@ -26,7 +26,6 @@ editor.setOption("extraKeys", {
cm.replaceSelection(spaces);
},
"Ctrl-Enter": function() {
bonfireExecute();
return false;
}
});
@ -40,7 +39,8 @@ var libraryIncludes = "<script src='//ajax.googleapis.com/ajax/libs/jquery/2.1.3
"<link rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.0/animate.min.css'/>" +
"<link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css'/>" +
"<link rel='stylesheet' href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css'/>" +
"<style>body { padding: 0px 3px 0px 3px; }</style>";
"<style>body { padding: 0px 3px 0px 3px; }</style>" +
"<script>var expect = chai.expect; var should = chai.should(); var assert = chai.assert;</script>";
var allTests = '';
(function() {
@ -59,28 +59,42 @@ editor.on("change", function () {
});
var nodeEnv = prodOrDev === 'production' ? 'http://www.freecodecamp.com' : 'http://localhost:3001';
function updatePreview() {
goodTests = 0;
var previewFrame = document.getElementById('preview');
var preview = previewFrame.contentDocument || previewFrame.contentWindow.document;
preview.open();
$('#testSuite').empty();
preview.write(libraryIncludes + editor.getValue() + otherTestsForNow);
preview.close();
}
setTimeout(updatePreview, 300);
/**
* Window postMessage receiving funtionality
* "post" methods
*/
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
// Listen to message from child window
eventer(messageEvent,function(e) {
if (e.data === 'CompleteAwesomeSauce') {
var postSuccess = function(data) {
var testDoc = document.createElement("div");
$(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'>" + JSON.parse(data) + "</div></div><div class='ten-pixel-break'/>")
.appendTo($('#testSuite'));
testSuccess();
};
var postError = function(data) {
var testDoc = document.createElement("div");
$(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'>" + JSON.parse(data) + "</div></div><div class='ten-pixel-break'/>")
.prependTo($('#testSuite'))
};
var goodTests = 0;
var testSuccess = function() {
goodTests++;
if (goodTests === tests.length) {
showCompletion();
}
},false);
};
var challengeSeed = challengeSeed || null;
var tests = tests || [];
var allSeeds = '';
@ -115,14 +129,18 @@ function doLinting () {
});
};
//$('#testSuite').empty();
function showCompletion() {
var time = Math.floor(Date.now() / 1000) - started;
ga('send', 'event', 'Challenge', 'solved', challengeName + ', Time: ' + time);
$('#next-courseware-button').removeAttr('disabled');
$('#next-courseware-button').addClass('animated tada');
if (!userLoggedIn) {
$('#complete-courseware-dialog').modal('show');
$('#complete-courseware-dialog').keydown(function(e) {
}
$('body').keydown(function(e) {
if (e.ctrlKey && e.keyCode == 13) {
$('.next-courseware-button').click();
$('#next-courseware-button').click();
}
});
}

View File

@ -0,0 +1,234 @@
var widgets = [];
var myCodeMirror = CodeMirror.fromTextArea(document.getElementById("codeEditor"), {
lineNumbers: true,
mode: "javascript",
theme: 'monokai',
runnable: true,
lint: true,
matchBrackets: true,
autoCloseBrackets: true,
scrollbarStyle: 'null',
lineWrapping: true,
gutters: ["CodeMirror-lint-markers"],
onKeyEvent: doLinting
});
var editor = myCodeMirror;
editor.setSize("100%", "auto");
// Hijack tab key to enter two spaces intead
editor.setOption("extraKeys", {
Tab: function(cm) {
var spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
cm.replaceSelection(spaces);
},
"Ctrl-Enter": function() {
bonfireExecute();
return false;
}
});
var attempts = 0;
if (attempts) {
attempts = 0;
}
var codeOutput = CodeMirror.fromTextArea(document.getElementById("codeOutput"), {
lineNumbers: false,
mode: "text",
theme: 'monokai',
readOnly: 'nocursor',
lineWrapping: true
});
codeOutput.setValue('/**\n' +
' * Your output will go here.\n' + ' * Console.log() -type statements\n' +
' * will appear in your browser\'s\n' + ' * DevTools JavaScript console.\n' +
' */');
codeOutput.setSize("100%", "100%");
var info = editor.getScrollInfo();
var after = editor.charCoords({line: editor.getCursor().line + 1, ch: 0}, "local").top;
if (info.top + info.clientHeight < after)
editor.scrollTo(null, after - info.clientHeight + 3);
var editorValue;
var challengeSeed = challengeSeed || null;
var tests = tests || [];
var allSeeds = '';
(function() {
challengeSeed.forEach(function(elem) {
allSeeds += elem + '\n';
});
})();
editorValue = allSeeds;
myCodeMirror.setValue(editorValue);
function doLinting () {
editor.operation(function () {
for (var i = 0; i < widgets.length; ++i)
editor.removeLineWidget(widgets[i]);
widgets.length = 0;
JSHINT(editor.getValue());
for (var i = 0; i < JSHINT.errors.length; ++i) {
var err = JSHINT.errors[i];
if (!err) continue;
var msg = document.createElement("div");
var icon = msg.appendChild(document.createElement("span"));
icon.innerHTML = "!!";
icon.className = "lint-error-icon";
msg.appendChild(document.createTextNode(err.reason));
msg.className = "lint-error";
widgets.push(editor.addLineWidget(err.line - 1, msg, {
coverGutter: false,
noHScroll: true
}));
}
});
};
$('#submitButton').on('click', function () {
bonfireExecute();
});
function bonfireExecute() {
attempts++;
ga('send', 'event', 'Challenge', 'ran-code', challengeName);
userTests= null;
$('#codeOutput').empty();
var userJavaScript = myCodeMirror.getValue();
userJavaScript = removeComments(userJavaScript);
userJavaScript = scrapeTests(userJavaScript);
// simple fix in case the user forgets to invoke their function
submit(userJavaScript, function(cls, message) {
if (cls) {
codeOutput.setValue(message.error);
runTests('Error', null);
} else {
codeOutput.setValue(message.output);
message.input = removeLogs(message.input);
runTests(null, message);
}
});
}
var userTests;
var testSalt = Math.random();
var scrapeTests = function(userJavaScript) {
// insert tests from mongo
for (var i = 0; i < tests.length; 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);
}
return userJavaScript;
};
function removeComments(userJavaScript) {
var regex = new RegExp(/(\/\*[^(\*\/)]*\*\/)|\/\/[^\n]*/g);
return userJavaScript.replace(regex, '');
}
function removeLogs(userJavaScript) {
return userJavaScript.replace(/(console\.[\w]+\s*\(.*\;)/g, '');
}
var pushed = false;
var createTestDisplay = function() {
if (pushed) {
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.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'>" + test.text + "</div></div><div class='ten-pixel-break'/>")
.appendTo($('#testSuite'));
}
};
};
var expect = chai.expect;
var reassembleTest = function(test, data) {
var lineNum = test.line;
var regexp = new RegExp("\/\/" + lineNum + testSalt);
return data.input.replace(regexp, test.text);
};
var runTests = function(err, data) {
var allTestsPassed = true;
pushed = false;
$('#testSuite').children().remove();
if (err && userTests.length > 0) {
userTests= [{text:"Program Execution Failure", err: "No user tests were run."}];
createTestDisplay();
} else if (userTests) {
userTests.push(false);
pushed = true;
userTests.forEach(function(test, ix, arr){
try {
if (test) {
var output = eval(reassembleTest(test, data));
}
} catch(error) {
allTestsPassed = false;
arr[ix].err = error.name + ":" + error.message;
} finally {
if (!test) {
createTestDisplay();
}
}
});
if (allTestsPassed) {
allTestsPassed = false;
showCompletion();
}
}
};
function showCompletion() {
var time = Math.floor(Date.now() / 1000) - started;
ga('send', 'event', 'Challenge', 'solved', challengeName + ', Time: ' + time +', Attempts: ' + attempts);
$('#complete-courseware-dialog').modal('show');
$('#complete-courseware-dialog').keydown(function(e) {
if (e.ctrlKey && e.keyCode == 13) {
$('.next-bonfire-button').click();
}
});
}

View File

@ -1,14 +1,19 @@
(function() {
var allTestsGood = true;
var expect = chai.expect;
var tests = parent.tests;
for (var i = 0; i < tests.length; i++) {
var thisTest = true;
try {
eval(parent.allTests);
eval(parent.tests[i]);
} catch (err) {
allTestsGood = false;
thisTest = false;
parent.postError(JSON.stringify(tests[i]));
} finally {
if (allTestsGood) {
parent.postMessage('CompleteAwesomeSauce', parent.nodeEnv);
if (thisTest) {
parent.postSuccess(JSON.stringify(tests[i]));
}
}
}
})();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,16 @@
/**
* Created by jason on 2/11/15.
*/
function nextSession () {
var next = 'Our next session will be ';
var today = moment().day(moment().day());
if (today > moment().day(2)) {
next += moment().day(9).format('dddd, MMMM Do YYYY') + ' at 9PM EST!';
} else {
next += moment().day('Tuesday').format('dddd, MMMM Do YYYY') + ' at 9PM EST!';
}
return next;
}

View File

@ -66,6 +66,9 @@ $(document).ready(function() {
completedBonfire(didCompleteWith, bonfireSolution, thisBonfireHash);
});
$('#completed-courseware').on('click', function() {
$('#complete-courseware-dialog').modal('show');
});
$('#complete-bonfire-dialog').on('hidden.bs.modal', function() {
editor.focus();
@ -74,7 +77,7 @@ $(document).ready(function() {
$('#complete-courseware-dialog').on('hidden.bs.modal', function() {
editor.focus();
});
$('.next-courseware-button').on('click', function() {
$('#next-courseware-button').on('click', function() {
if ($('.signup-btn-nav').length < 1) {
$.post(
'/completed-courseware',
@ -164,7 +167,7 @@ profileValidation.controller('doneWithFirst100HoursFormController', ['$scope',
}
]);
profileValidation.directive('uniqueUsername', function($http) {
profileValidation.directive('uniqueUsername',['$http',function($http) {
return {
restrict: 'A',
require: 'ngModel',
@ -183,9 +186,9 @@ profileValidation.directive('uniqueUsername', function($http) {
});
}
}
});
}]);
profileValidation.directive('existingUsername', function($http) {
profileValidation.directive('existingUsername', ['$http', function($http) {
return {
restrict: 'A',
require: 'ngModel',
@ -194,27 +197,26 @@ profileValidation.directive('existingUsername', function($http) {
if (element.val().length > 0) {
ngModel.$setValidity('exists', false);
} else {
element.removeClass('ng-dirty');
ngModel.$setPristine();
}
if (element.val()) {
$http.get("/api/checkExistingUsername/" + element.val()).success(function (data) {
if (element.val() == scope.existingUsername) {
ngModel.$setValidity('exists', false);
} else if (data) {
ngModel.$setValidity('exists', true);
}
$http
.get("/api/checkExistingUsername/" + element.val())
.success(function (data) {
ngModel.$setValidity('exists', data);
});
}
});
}
}
});
}]);
profileValidation.directive('uniqueEmail', function($http) {
profileValidation.directive('uniqueEmail', ['$http', function($http) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModel) {
link: function getUnique (scope, element, attrs, ngModel) {
element.bind("keyup", function (event) {
ngModel.$setValidity('unique', true);
if (element.val()) {
@ -229,4 +231,4 @@ profileValidation.directive('uniqueEmail', function($http) {
});
}
}
});
}]);

View File

@ -7,14 +7,14 @@
"Click the button below for further instructions.",
"Your goal is to fix the failing test.",
"First, run all the tests by clicking \"Run code\" or by pressing Control + Enter",
"The failing test is in red. Fix the code so that all tests pass. Then you can move on to the next Bonfire."
"The failing test is in red. Fix the code so that all tests pass. Then you can move on to the next Bonfire.",
"Make this function return true no matter what."
],
"tests": [
"expect(meetBonfire(\"test\")).to.be.a(\"boolean\");",
"expect(meetBonfire(\"test\")).to.be.true;"
"expect(meetBonfire()).to.be.a(\"boolean\");",
"expect(meetBonfire()).to.be.true;"
],
"challengeSeed": "function meetBonfire(argument) {\n // Good luck!\n console.log(\"you can read this function's argument in the developer tools\", argument);\n\nreturn false;\n}\n\n",
"challengeEntryPoint": "meetBonfire(\"You can do this!\");"
"challengeSeed": "function meetBonfire(argument) {\n // Good luck!\n console.log(\"you can read this function's argument in the developer tools\", argument);\n\n return false;\n}\n\n\n\nmeetBonfire(\"You can do this!\");"
},
{
"_id": "a202eed8fc186c8434cb6d61",
@ -31,8 +31,7 @@
"You may need to turn the string into an array before you can reverse it.",
"Your result must be a string."
],
"challengeEntryPoint": "reverseString('hello');",
"challengeSeed": "function reverseString(str) {\n return str;\r\n}"
"challengeSeed": "function reverseString(str) {\n return str;\r\n}\n\nreverseString('hello');"
},
{
"_id": "a302f7aae1aa3152a5b413bc",
@ -50,19 +49,17 @@
"Factorials are often represented with the shorthand notation n!",
"For example: 5! = 1 * 2 * 3 * 4 * 5 = 120f"
],
"challengeSeed": "function factorialize(num) {\n return num;\r\n}",
"challengeEntryPoint": "factorialize(5);"
"challengeSeed": "function factorialize(num) {\n return num;\r\n}\n\nfactorialize(5);"
},
{
"_id": "aaa48de84e1ecc7c742e1124",
"name": "Check for Palindromes",
"difficulty": "1.03",
"description": [
"Return 'true' if a given string is a palindrome.",
"Return true if the given string is a palindrome. Otherwise, return false.",
"A palindrome is a word or sentence that's spelled the same way both forward and backward, ignoring punctuation, case, and spacing.",
"You'll need to remove punctuation and turn everything lower case in order to check for palindromes.",
"We'll pass strings with varying formats, such as \"racecar\", \"RaceCar\", and \"race CAR\" among others.",
"Return true if the string is a palindrome. Otherwise, return false."
"We'll pass strings with varying formats, such as \"racecar\", \"RaceCar\", and \"race CAR\" among others."
],
"tests": [
"expect(palindrome(\"eye\")).to.be.a(\"boolean\");",
@ -73,8 +70,7 @@
"assert.deepEqual(palindrome(\"never odd or even\"), true);",
"assert.deepEqual(palindrome(\"nope\"), false);"
],
"challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n",
"challengeEntryPoint": "palindrome(\"eye\");"
"challengeSeed": "function palindrome(str) {\n // Good luck!\n return true;\n}\n\n\n\npalindrome(\"eye\");"
},
{
"_id": "a26cbbe9ad8655a977e1ceb5",
@ -84,8 +80,7 @@
"Return the length of the longest word in the provided sentence.",
"Your response should be a number."
],
"challengeEntryPoint": "findLongestWord('The quick brown fox jumped over the lazy dog');",
"challengeSeed": "function findLongestWord(str) {\n return str.length;\r\n}",
"challengeSeed": "function findLongestWord(str) {\n return str.length;\r\n}\n\nfindLongestWord('The quick brown fox jumped over the lazy dog');",
"tests": [
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.be.a('Number');",
"expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.equal(6);",
@ -102,8 +97,7 @@
"Return the provided string with the first letter of each word capitalized.",
"For the purpose of this exercise, you should also capitalize connecting words like 'the' and 'of'."
],
"challengeEntryPoint": "titleCase(\"I'm a little tea pot\");",
"challengeSeed": "function titleCase(str) {\n return str;\r\n}",
"challengeSeed": "function titleCase(str) {\n return str;\r\n}\n\ntitleCase(\"I'm a little tea pot\");",
"tests": [
"expect(titleCase(\"I'm a little tea pot\")).to.be.a('String');",
"expect(titleCase(\"I'm a little tea pot\")).to.equal(\"I'm A Little Tea Pot\");",
@ -117,20 +111,145 @@
"difficulty": "1.06",
"description": [
"Return an array consisting of the largest numbers in the provided array. The array will contain 4 sub-arrays.",
"Remember, you an iterate through an array with a simple for loop, and access each member with array syntax arr[i] .",
"Remember, you can iterate through an array with a simple for loop, and access each member with array syntax arr[i] .",
"If you are writing your own Chai.js tests, be sure to use a deep equal statement instead of an equal statement when comparing arrays."
],
"challengeEntryPoint": "largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);",
"challengeSeed": "function largestOfFour(arr) {\n // You can do this!\r\n return arr;\r\n}",
"challengeSeed": "function largestOfFour(arr) {\n // You can do this!\r\n return arr;\r\n}\n\nlargestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);",
"tests": [
"expect(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])).to.be.a('array');",
"(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]])).should.eql([5,27,39,1001]);",
"assert(largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]).should.eql([9,35,97,1000000]));"
]
},
{
"_id": "acda2fb1324d9b0fa741e6b5",
"name": "Confirm the Ending",
"difficulty": "1.07",
"description": [
"Check if a string (first argument) ends with the given target string (second argument)."
],
"challengeSeed": "function end(str, target) {\n // \"Never give up and good luck will find you.\"\r\n // -- Falcor\r\n return str;\r\n}\n\nend('Bastian', 'n');",
"tests": [
"assert.strictEqual(end('Bastian', 'n'), true, 'should equal true if target equals end of string');",
"assert.strictEqual(end('He has to give me a new name', 'name'), true, 'should equal true if target equals end of string');",
"assert.strictEqual(end('If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing', 'mountain'), false, 'should equal false if target does not equal end of string');"
]
},
{
"_id": "afcc8d540bea9ea2669306b6",
"name": "Repeat a string repeat a string",
"difficulty": "1.08",
"description": [
"Repeat a given string (first argument) n times (second argument). Return an empty string if n is a negative number."
],
"challengeSeed": "function repeat(str, num) {\n // repeat after me\r\n return str;\r\n}\n\nrepeat('abc', 3);",
"tests": [
"assert.strictEqual(repeat('*', 3), '***', 'should repeat a string n times');",
"assert.strictEqual(repeat('abc', 3), 'abcabcabc', 'should repeat a string n times');",
"assert.strictEqual(repeat('abc', -2), '', 'should return an empty string for negative numbers');"
]
},
{
"_id": "ac6993d51946422351508a41",
"name": "Truncate a string",
"difficulty": "1.09",
"description": [
"Truncate a string (first argument) if it is longer than the given maximum string length (second argument). Return the truncated string with a '...' ending.",
"Note that the three dots at the end add to the string length."
],
"challengeSeed":"function truncate(str, num) {\n // Clear out that junk in your trunk\r\n return str;\r\n}\n\ntruncate('A-tisket a-tasket A green and yellow basket', 11);",
"tests": [
"expect(truncate('A-tisket a-tasket A green and yellow basket', 11)).to.eqls('A-tisket...');",
"assert(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length) === 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is = length');",
"assert.strictEqual(truncate('A-tisket a-tasket A green and yellow basket', 'A-tisket a-tasket A green and yellow basket'.length + 2), 'A-tisket a-tasket A green and yellow basket', 'should not truncate if string is < length');"
]
},
{
"_id": "a9bd25c716030ec90084d8a1",
"name": "Chunky Monkey",
"difficulty": "1.10",
"description": [
"Write a function that splits an array (first argument) into groups the length of size (second argument) and returns them as a multidimensional array."
],
"challengeSeed": "function chunk(arr, size) {\n // Break it up.\r\n return arr;\r\n}\n\nchunk(['a', 'b', 'c', 'd'], 2);",
"tests": [
"assert.deepEqual(chunk(['a', 'b', 'c', 'd'], 2), [['a', 'b'], ['c', 'd']], 'should return chunked arrays');",
"assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 3), [[0, 1, 2], [3, 4, 5]], 'should return chunked arrays');",
"assert.deepEqual(chunk([0, 1, 2, 3, 4, 5], 4), [[0, 1, 2, 3], [4, 5]], 'should return cthe last chunk as remaining elements');"
]
},
{
"_id": "ab31c21b530c0dafa9e241ee",
"name": "Slasher Flick",
"difficulty": "1.11",
"description": [
"Return the remaining elements of an array after chopping off n elements from the head."
],
"challengeSeed": "function slasher(arr, howMany) {\n // it doesn't allways pay to be first\r\n return arr;\r\n}\n\nslasher([1, 2, 3], 2);",
"tests": [
"assert.deepEqual(slasher([1, 2, 3], 2), [3], 'should drop the first two elements');",
"assert.deepEqual(slasher([1, 2, 3], 0), [1, 2, 3], 'should return all elements when n < 1');",
"assert.deepEqual(slasher([1, 2, 3], 9), [], 'should return an empty array when n >= array.length');"
]
},
{
"_id": "adf08ec01beb4f99fc7a68f2",
"name": "Falsey Bouncer",
"difficulty": "1.50",
"description": [
"Remove all falsey values from an array.",
"Falsey values in javascript are false, null, 0, \"\", undefined, and NaN."
],
"challengeSeed": "function bouncer(arr) {\n // Don't show a false ID to this bouncer.\r\n return arr;\r\n}\n\nbouncer([7, 'ate', '', false, 9]);",
"tests": [
"assert.deepEqual(bouncer([7, 'ate', '', false, 9]), [7, 'ate', 9], 'should remove falsey values');",
"assert.deepEqual(bouncer(['a', 'b', 'c']), ['a', 'b', 'c'], 'should return full array if no falsey elements');",
"assert.deepEqual(bouncer([false, null, 0]), [], 'should return empty array if all elements are falsey');"
]
},
{
"_id":"a8e512fbe388ac2f9198f0fa",
"name":"Where art thou",
"difficulty":"1.55",
"description":[
"Make a function that looks through a list (first argument) and returns an array of all objects that have equivalent property values (second argument)."
],
"challengeSeed":"function where(collection, source) {\n var arr = [];\r\n // What's in a name?\r\n return arr;\r\n}\n\nwhere([{ first: 'Romeo', last: 'Montague' }, { first: 'Mercutio', last: null }, { first: 'Tybalt', last: 'Capulet' }], { last: 'Capulet' });",
"tests":[
"assert.deepEqual(where([{ first: 'Romeo', last: 'Montague' }, { first: 'Mercutio', last: null }, { first: 'Tybalt', last: 'Capulet' }], { last: 'Capulet' }), [{ first: 'Tybalt', last: 'Capulet' }], 'should return an array of objects');",
"assert.deepEqual(where([{ 'a': 1 }, { 'a': 1 }, { 'a': 1, 'b': 2 }], { 'a': 1 }), [{ 'a': 1 }, { 'a': 1 }, { 'a': 1, 'b': 2 }], 'should return with multiples');"
]
},
{
"_id":"a39963a4c10bc8b4d4f06d7e",
"name":"Seek and Destroy",
"difficulty":"1.60",
"description":[
"Remove all values (last argument(s)) from an array (first argument) and return as a new array."
],
"challengeSeed": "function destroyer(arr) {\n // Remove all the values\r\n return arr;\r\n}\n\ndestroyer([1, 2, 3, 1, 2, 3], 2, 3);",
"tests": [
"assert.deepEqual(destroyer([1, 2, 3, 1, 2, 3], 2, 3), [1, 1], 'should remove correct values from an array');",
"assert.deepEqual(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3), [1, 5, 1], 'should remove correct values from an array');"
]
},
{
"_id": "a24c1a4622e3c05097f71d67",
"name": "Where do I belong",
"difficulty": "1.61",
"description": [
"Return the lowest index at which a value (second argument) should be inserted into a sorted array (first argument)."
],
"challengeSeed": "function where(arr, num) {\n // Find my place in this sorted array.\r\n return num;\r\n}\n\nwhere([40, 60], 50);",
"tests": [
"var numbers = [10, 20, 30, 40, 50], num = 35;",
"var indexForNum = where(numbers, num);",
"assert.equal(indexForNum, 3, '35 should be inserted at index 3');",
"var indexFor30 = where(numbers, 30);",
"assert.equal(indexFor30, 2, '30 should be inserted at index 2');"
]
},
{
"_id": "a3566b1109230028080c9345",
"name": "Sum All Numbers in a Range",
@ -139,8 +258,7 @@
"We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.",
"The lowest number will not always come first."
],
"challengeEntryPoint": "sumAll([1, 4]);",
"challengeSeed": "function sumAll(arr) {\n return(1);\r\n}",
"challengeSeed": "function sumAll(arr) {\n return(1);\r\n}\n\nsumAll([1, 4]);",
"tests": [
"expect(sumAll([1, 4])).to.be.a('Number');",
"expect(sumAll([1, 4])).to.equal(10);",
@ -150,14 +268,13 @@
]
},
{
"_id": "d5de63ebea8dbee56860f4f2",
"_id": "a5de63ebea8dbee56860f4f2",
"name": "Diff Two Arrays",
"difficulty": "2.01",
"description": [
"Compare two arrays and return a new array with any items not found in both of the original arrays."
],
"challengeEntryPoint": "diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);",
"challengeSeed": "function diff(arr1, arr2) {\n var newArr = [];\r\n // Same, same; but different.\r\n return newArr;\r\n}",
"challengeSeed": "function diff(arr1, arr2) {\n var newArr = [];\r\n // Same, same; but different.\r\n return newArr;\r\n}\n\ndiff([1, 2, 3, 5], [1, 2, 3, 4, 5]);",
"tests": [
"expect(diff([1, 2, 3, 5], [1, 2, 3, 4, 5])).to.be.a('array');",
"assert.deepEqual(diff(['diorite', 'andesite', 'grass', 'dirt', 'pink wool', 'dead shrub'], ['diorite', 'andesite', 'grass', 'dirt', 'dead shrub']), ['pink wool'], 'arrays with only one difference');",
@ -168,17 +285,79 @@
"assert.deepEqual(diff([], ['snuffleupagus', 'cookie monster', 'elmo']), ['snuffleupagus', 'cookie monster', 'elmo'], 'empty array');"
]
},
{
"_id": "a77dbc43c33f39daa4429b4f",
"name": "Boo who",
"difficulty": "2.06",
"description": [
"Check if a value is classified as a boolean primitive. Return true or false.",
"Boolean primitives are true and false."
],
"challengeSeed": "function boo(bool) {\n // What is the new fad diet for ghost developers? The Boolean.\r\n return bool;\r\n}\n\nboo(null);",
"tests": [
"assert.strictEqual(boo(true), true);",
"assert.strictEqual(boo(false), true);",
"assert.strictEqual(boo([1, 2, 3]), false);",
"assert.strictEqual(boo([].slice), false);",
"assert.strictEqual(boo({ 'a': 1 }), false);",
"assert.strictEqual(boo(1), false);",
"assert.strictEqual(boo(NaN), false);",
"assert.strictEqual(boo('a'), false);"
]
},
{
"_id": "a105e963526e7de52b219be9",
"name": "Sorted Union",
"difficulty": "2.07",
"description": [
"Write a function that takes two or more arrays and returns a new array of unique values in the order of the original provided arrays.",
"The unique numbers should be sorted by their original order, but the final array should not be sorted in numerical order.",
"Check the assertion tests for examples."
],
"challengeSeed": "function unite(arr1, arr2, arr3) {\n return arr1;\r\n}\n\nunite([1, 2, 3], [5, 2, 1, 4], [2, 1]);",
"tests": [
"assert.deepEqual(unite([1, 3, 2], [5, 2, 1, 4], [2, 1]), [1, 3, 2, 5, 4], 'should return the union of the given arrays');",
"assert.deepEqual(unite([1, 3, 2], [1, [5]], [2, [4]]), [1, 3, 2, [5], [4]], 'should not flatten nested arrays');"
]
},
{
"_id": "a6b0bb188d873cb2c8729495",
"name": "Convert HTML Entities",
"difficulty": "2.07",
"description": [
"Convert the characters \"&\", \"<\", \">\", '\"', and \"'\", in a string to their corresponding HTML entities."
],
"challengeSeed": "function convert(str) {\n // &colon;&rpar;\r\n return str;\r\n}\n\nconvert('Dolce & Gabbana');",
"tests": [
"assert.strictEqual(convert('Dolce & Gabbana'), 'Dolce &amp; Gabbana', 'should escape characters');",
"assert.strictEqual(convert('abc'), 'abc', 'should handle strings with nothing to escape');"
]
},
{
"_id": "a103376db3ba46b2d50db289",
"name": "Spinal Tap Case",
"difficulty": "2.08",
"description": [
"Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes."
],
"challengeSeed": "function spinalCase(str) {\n // \"It's such a fine line between stupid, and clever.\"\r\n // --David St. Hubbins\r\n return str;\r\n}\n\nspinalCase('This Is Spinal Tap');",
"tests": [
"assert.strictEqual(spinalCase('This Is Spinal Tap'), 'this-is-spinal-tap', 'should return spinal case from string with spaces');",
"assert.strictEqual(spinalCase('thisIsSpinalTap'), 'this-is-spinal-tap', 'should return spinal case from string with camel case');",
"assert.strictEqual(spinalCase('The_Andy_Griffith_Show'), 'the-andy-griffith-show', 'should return spinal case from string with snake case');",
"assert.strictEqual(spinalCase('Teletubbies say Eh-oh'), 'teletubbies-say-eh-oh', 'should return spinal case from string with spaces and hyphens');"
]
},
{
"_id": "a5229172f011153519423690",
"name": "Sum All Odd Fibonacci Numbers",
"difficulty": "2.09",
"description": [
"Return the sum of all odd fibonacci numbers up to and including the passed number if it is a fibonacci number.",
"Return the sum of all odd Fibonacci numbers up to and including the passed number if it is a Fibonacci number.",
"The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8, and each subsequent number is the sum of the previous two numbers.",
"As an example, passing 4 to the function should return 5 because all the odd fibonacci numbers under 4 are 1, 1, and 3."
"As an example, passing 4 to the function should return 5 because all the odd Fibonacci numbers under 4 are 1, 1, and 3."
],
"challengeEntryPoint": "sumFibs(4);",
"challengeSeed": "function sumFibs(num) {\n return num;\r\n}",
"challengeSeed": "function sumFibs(num) {\n return num;\r\n}\n\nsumFibs(4);",
"tests": [
"expect(sumFibs(1)).to.be.a('number');",
"expect(sumFibs(1000)).to.equal(1785);",
@ -197,11 +376,10 @@
"A prime number is defined as having only two divisors, 1 and itself. For example, 2 is a prime number because it's only divisible by 1 and 2. 1 isn't a prime number, because it's only divisible by itself.",
"The provided number may not be a prime."
],
"challengeEntryPoint": "sumPrimes(10);",
"challengeSeed": "function sumPrimes(num) {\n return num;\r\n}",
"challengeSeed": "function sumPrimes(num) {\n return num;\r\n}\n\nsumPrimes(10);",
"tests": [
"expect(sumPrimes(10)).to.be.a('number');",
"expect(sumPrimes(10)).to.equal(27);",
"expect(sumPrimes(10)).to.equal(17);",
"expect(sumPrimes(977)).to.equal(73156);"
]
},
@ -213,8 +391,7 @@
"Find the smallest number that evenly divides all numbers in the provided range.",
"The range will be an array of two numbers that will not necessarily be in numerical order."
],
"challengeEntryPoint": "smallestCommons([1,5]);",
"challengeSeed": "function smallestCommons(arr) {\n return arr;\r\n}\r\n",
"challengeSeed": "function smallestCommons(arr) {\n return arr;\r\n}\r\n\n\nsmallestCommons([1,5]);",
"tests": [
"expect(smallestCommons([1,5])).to.be.a('number');",
"expect(smallestCommons([1,5])).to.equal(60);",
@ -222,6 +399,77 @@
"(smallestCommons([1,13])).should.equal(360360);"
]
},
{
"_id": "a6e40f1041b06c996f7b2406",
"name": "Finders Keepers",
"difficulty": "2.12",
"description": [
"Create a function that looks through an array (first argument) and returns the first element in the array that passes a truth test (second argument)."
],
"challengeSeed": "function find(arr, func) {\n var num = 0;\r\n return num;\r\n}\n\nfind([1, 2, 3, 4], function(num){ return num % 2 === 0; });",
"tests": [
"assert.strictEqual(find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; }), 8, 'should return first found value');",
"assert.strictEqual(find([1, 3, 5, 9], function(num) { return num % 2 === 0; }), undefined, 'should return undefined if not found');"
]
},
{
"_id": "a5deed1811a43193f9f1c841",
"name": "Drop it like it's hot",
"difficulty": "2.13",
"description": [
"Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true."
],
"challengeSeed": "function drop(arr, func) {\n // Drop them elements.\r\n return arr;\r\n}\n\ndrop([1, 2, 3], function(n) {return n < 3; });",
"tests": [
"assert.deepEqual(drop([1, 2, 3, 4], function(n) {return n < 3; }), [3, 4], 'should return remaining array');",
"assert.deepEqual(drop([1, 2, 3], function(n) {return n < 0; }), [1, 2, 3], 'should return complete array if predicate met in first element.');",
"assert.deepEqual(drop([1, 2, 3, 4], function(n) {return n < 5; }), [], 'should return an empty array if predicate does not return true');"
]
},
{
"_id": "ab306dbdcc907c7ddfc30830",
"name": "Steamroller",
"difficulty": "2.14",
"description": [
"Flatten a nested array. You must account for varying levels of nesting."
],
"challengeSeed": "function steamroller(arr) {\n // I'm a steamroller, baby\r\n return arr;\r\n}\n\nsteamroller([1, [2], [3, [[4]]]]);",
"tests": [
"assert.deepEqual(steamroller([[['a']], [['b']]]), ['a', 'b'], 'should flatten nested arrays');",
"assert.deepEqual(steamroller([1, [2], [3, [[4]]]]), [1, 2, 3, 4], 'should flatten nested arrays');",
"assert.deepEqual(steamroller([1, [], [3, [[4]]]]), [1, 3, 4], 'should work with empty arrays');"
]
},
{
"_id": "a3f503de51cf954ede28891d",
"name": "Symmetric Difference",
"difficulty": "2.20",
"description": [
"Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.",
"The mathematical term symmetric difference refers to the elements in two sets that are in either the first or second set, but not in both."
],
"challengeSeed": "function sym(arr) {\n return arr;\r\n}\n\nsym([1, 2, 3], [5, 2, 1, 4]);",
"tests": [
"assert.deepEqual(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]), [1, 4, 5], 'should return the symmetric difference of the given arrays');",
"assert.deepEqual(sym([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]), [1, 4, 5], 'should return an array of unique values');",
"assert.deepEqual(sym([1, 1]), [1], 'should return an array of unique values');"
]
},
{
"_id": "a10d2431ad0c6a099a4b8b52",
"name": "Everything Be True",
"difficulty": "2.21",
"description": [
"Check if the predicate (second argument) returns truthy (defined) for all elements of a collection (first argument).",
"For this, check to see if the property defined in the second argument is present on every element of the collection.",
"Remember, you can access object properties through either dot notation or [] notation."
],
"challengeSeed": "function every(collection, pre) {\n // Does everyone have one of these?\r\n return pre;\r\n}\n\nevery([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex');",
"tests": [
"assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], 'sex'), true, 'should return true if predicate returns truthy for all elements in the collection');",
"assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'male'}, {'user': 'Dipsy', 'sex': 'male'}, {'user': 'Laa-Laa', 'sex': 'female'}, {'user': 'Po', 'sex': 'female'}], {'sex': 'female'}), false, 'should return false if predicate returns falsey for any element in the collection');"
]
},
{
"_id": "a2f1d72d9b908d0bd72bb9f6",
"name": "Make a Person",
@ -229,11 +477,9 @@
"description": [
"Fill in the object constructor with the methods specified in the tests.",
"Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(), setLastName(), and setFullName().",
"These methods must be the only available means for interacting with the object.",
"There will be some linting errors on the tests, you may safely ignore them. You should see undefined in the console output."
"These methods must be the only available means for interacting with the object."
],
"challengeEntryPoint": "var bob = new Person('Bob Ross');",
"challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};",
"challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};\n\nvar bob = new Person('Bob Ross');\nbob.getFullName();",
"tests": [
"expect(Object.keys(bob).length).to.eql(6);",
"expect(bob instanceof Person).to.be.true;",
@ -247,7 +493,8 @@
"bob.setLastName('Trees');",
"expect(bob.getLastName()).to.eql('Trees');",
"bob.setFullName('George Carlin');",
"expect(bob.getFullName()).to.eql('George Carlin');"
"expect(bob.getFullName()).to.eql('George Carlin');",
"bob.setFullName('Bob Ross');"
]
},
{
@ -258,7 +505,7 @@
"Return true if the passed string is a valid US phone number",
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:",
"555-555-5555, (555)555-5555, (555) 555-5555, 555 555 5555, 5555555555, 1 555 555 5555",
"For this challenge you will be presented with a string such as \"800-692-7753\" or \"8oo-six427676;laskdjf\". Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code code is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false."
"For this challenge you will be presented with a string such as \"800-692-7753\" or \"8oo-six427676;laskdjf\". Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false."
],
"tests": [
"expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
@ -284,18 +531,16 @@
"assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
"assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
],
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n",
"challengeEntryPoint": "telephoneCheck(\"555-555-5555\");"
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n\n\ntelephoneCheck(\"555-555-5555\");"
},
{
"_id": "ca2e6f85cab2ab736c9a9b24",
"_id": "aa2e6f85cab2ab736c9a9b24",
"name": "Cash Register",
"difficulty": "4.02",
"description": [
"Design a cash register drawer function that accepts purchase price as the first argument, payment as the second argument, and cash-in-drawer (cid) as the third argument. cid is a 2d array listing available currency. Return the string \"Insufficient Funds\" if change due is less than the cash-in-drawer. Return the string \"Closed\" if cash-in-drawer is equal to the change due. Otherwise, return change in coin and bills, sorted in highest to lowest order."
],
"challengeEntryPoint": "drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]);",
"challengeSeed": "function drawer(price, cash, cid) {\n var change;\r\n // Here is your change, ma'am.\r\n return change;\r\n}\r\n\r\n// Example cash-in-drawer array:\r\n// [['PENNY', 1.01],\r\n// ['NICKEL', 2.05],\r\n// ['DIME', 3.10],\r\n// ['QUARTER', 4.25],\r\n// ['ONE', 90.00],\r\n// ['FIVE', 55.00],\r\n// ['TEN', 20.00],\r\n// ['TWENTY', 60.00],\r\n// ['ONE HUNDRED', 100.00]]",
"challengeSeed": "function drawer(price, cash, cid) {\n var change;\r\n // Here is your change, ma'am.\r\n return change;\r\n}\r\n\r\n// Example cash-in-drawer array:\r\n// [['PENNY', 1.01],\r\n// ['NICKEL', 2.05],\r\n// ['DIME', 3.10],\r\n// ['QUARTER', 4.25],\r\n// ['ONE', 90.00],\r\n// ['FIVE', 55.00],\r\n// ['TEN', 20.00],\r\n// ['TWENTY', 60.00],\r\n// ['ONE HUNDRED', 100.00]]\n\ndrawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]);",
"tests": [
"expect(drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]])).to.be.a('array');",
"expect(drawer(19.50, 20.00, [['PENNY', 0.01], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
@ -307,14 +552,13 @@
]
},
{
"_id": "556138aff60341a09ed6c480",
"_id": "a56138aff60341a09ed6c480",
"name": "Inventory Update",
"difficulty": "4.03",
"description": [
"Compare and update inventory stored in a 2d array against a second 2d array of a fresh delivery. Update current inventory item quantity, and if an item cannot be found, add the new item and quantity into the inventory array in alphabetical order."
],
"challengeEntryPoint": "// Example inventory lists\r\nvar curInv = [\r\n [21, 'Bowling Ball'],\r\n [2, 'Dirty Sock'],\r\n [1, 'Hair pin'],\r\n [5, 'Microphone']\r\n];\r\n\r\nvar newInv = [\r\n [2, 'Hair Pin'],\r\n [3, 'Half-Eaten Apple'],\r\n [67, 'Bowling Ball'],\r\n [7, 'Toothpaste']\r\n];\r\n\r\ninventory(curInv, newInv);",
"challengeSeed": "function inventory(arr1, arr2) {\n // All inventory must be accounted for or you're fired!\r\n return arr1;\r\n}",
"challengeSeed": "function inventory(arr1, arr2) {\n // All inventory must be accounted for or you're fired!\r\n return arr1;\r\n}\n\n// Example inventory lists\r\nvar curInv = [\r\n [21, 'Bowling Ball'],\r\n [2, 'Dirty Sock'],\r\n [1, 'Hair pin'],\r\n [5, 'Microphone']\r\n];\r\n\r\nvar newInv = [\r\n [2, 'Hair Pin'],\r\n [3, 'Half-Eaten Apple'],\r\n [67, 'Bowling Ball'],\r\n [7, 'Toothpaste']\r\n];\r\n\r\ninventory(curInv, newInv);",
"tests": [
"expect(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']])).to.be.a('array');",
"assert.equal(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]).length, 6);",
@ -325,4 +569,3 @@
]
}
]

View File

@ -30,7 +30,7 @@
"Now enter the chat room by going to <a href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank'>https://gitter.im/FreeCodeCamp/FreeCodeCamp</a> and clicking the \"sign in with GitHub\" button.",
"Introduce yourself to our chat room by typing: \"hello world!\".",
"Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
"Keep the chat room open while you work through the other challenges. That way you ask for help If you get stuck on a challenge. You can also socialize when you feel like taking a break.",
"Keep the chat room open while you work through the other challenges. That way you ask for help if you get stuck on a challenge. You can also socialize when you feel like taking a break.",
"Now that you've completed this challenge, you can go directly your most-recently visited chat room by clicking the \"Chat\" button in the navigation bar above."
]
},
@ -67,7 +67,7 @@
"video": "114578441",
"challengeNumber": 4,
"steps": [
"Next, let's learn about Responsive web design and continue learning about HTML and CSS.",
"Next, let's learn about responsive web design and continue learning about HTML and CSS.",
"A responsive website will automatically adapt to changes in your browser's width. This means that you can make one version of a website that will look good on desktop, tablet and phone.",
"Later, we'll use Twitter's Bootstrap CSS framework to build responsive websites.",
"You can check it out here: <a href='http://getbootstrap.com/' target='_blank'>http://getbootstrap.com/</a>.",
@ -79,7 +79,8 @@
"time": 60,
"video": "114578438",
"challengeNumber": 5,
"steps": ["Ready for some more HTML and CSS fundamentals?",
"steps": [
"Ready for some more HTML and CSS fundamentals?",
"Go to <a href='https://dash.generalassemb.ly/projects/eshas-restaurant-1' target='_blank'>https://dash.generalassemb.ly/projects/eshas-restaurant-1</a> and complete the third project."]
},
{
@ -94,7 +95,7 @@
"Right-click an area of the page that doesn't have any HTML elements on it, then choose 'view page source'.",
"Select all the text, then copy it.",
"Go to <a href='http://codepen.io/pen/' target='_blank'>http://codepen.io/pen/</a>",
"Paste the HTML you copied from Newsweek.com into the HTML field of Codepen.",
"Paste the HTML you copied from Newsweek.com into the HTML field of CodePen.",
"You now have your own customizable version of the Newsweek.com website. See if you can change some of the text and images."
]
},
@ -103,7 +104,8 @@
"time": 60,
"video": "114578436",
"challengeNumber": 7,
"steps": ["Now let's learn some more CSS, and a small amount of a JavaScript-based tool called jQuery.",
"steps": [
"Now let's learn some more CSS, and a small amount of a JavaScript-based tool called jQuery.",
"Go to <a href='https://dash.generalassemb.ly/projects/cotbots-1' target='_blank'>https://dash.generalassemb.ly/projects/cotbots-1</a> and complete the fourth project."]
},
{
@ -155,7 +157,7 @@
"video": "114591801",
"challengeNumber": 12,
"steps": [
"Finally, let's use jQuery to manipulate the way websites look, by changing the CSS of elements.",
"Finally, let's use jQuery to manipulate the way websites look by changing the CSS of elements.",
"Go to <a href='http://try.jquery.com/levels/5/challenges/1' target='_blank'>http://try.jquery.com/levels/5/challenges/1</a> and complete the fifth section."
]
},
@ -204,12 +206,12 @@
"Right-click an area of the page that doesn't have any HTML elements on it, then choose 'view page source'.",
"Select all the text, then copy it.",
"Go to <a href='http://codepen.io/pen/' target='_blank'>http://codepen.io/pen/</a>",
"Paste the HTML you copied from GetBootStrap.com into the HTML field of Codepen.",
"Paste the HTML you copied from GetBootStrap.com into the HTML field of CodePen.",
"Go to <a href='http://bootswatch.com/' target='_blank'>http://bootswatch.com/</a>",
"Decide which theme you want to use.",
"Click the down arrow next to the download button and choose 'bootstrap.css'",
"Click the down arrow next to the download button and choose 'bootstrap.css'.",
"Select all the text, then copy it.",
"Go back to CodePen and paste the CSS you copied from Bootswatch.com into the CSS field of Codepen.",
"Go back to CodePen and paste the CSS you copied from Bootswatch.com into the CSS field of CodePen.",
"Your Bootswatch CSS should now be applied to the HTML from the GetBootStrap page.",
"This page is currently using a two-column layout, with the main content on the left and additional navigation on the right. See if you can make it a one-column layout."
]
@ -249,7 +251,8 @@
"steps": [
"Now let's tackle week 2 of Stanford's Intro to Computer Science course.",
"This will introduce us to loops, a fundamental feature of every programming language.",
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z100/a7a70ce6e4724c58862ee6007284face/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z100/a7a70ce6e4724c58862ee6007284face/</a> and complete Week 2."]
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z100/a7a70ce6e4724c58862ee6007284face/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z100/a7a70ce6e4724c58862ee6007284face/</a> and complete Week 2."
]
},
{
"name": "Learn Computer Hardware",
@ -270,7 +273,8 @@
"steps": [
"Now that you've learned about computer hardware, it's time to learn about the software that runs on top of it.",
"Particularly important, you will learn about networks and TCP/IP - the protocol that powers the internet.",
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z187/z144/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z187/z144/</a> and complete Week 4."]
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z187/z144/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z187/z144/</a> and complete Week 4."
]
},
{
"name": "Learn Boolean Logic",
@ -280,7 +284,8 @@
"steps": [
"Now we'll do some more table exercises and learn boolean logic.",
"We'll also learn the difference between digital data and analog data.",
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z208/z188/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z208/z188/</a> and complete Week 5."]
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z208/z188/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z208/z188/</a> and complete Week 5."
]
},
{
"name": "Learn Computer Security",
@ -291,7 +296,8 @@
"We're almost done with Stanford's Introduction to Computer Science course!",
"We'll learn about one of the most important inventions of the 20th century - spreadsheets.",
"We'll also learn about Computer Security and some of the more common vulnerabilities software systems have.",
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z229/z213/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z229/z213/</a> and complete Week 6, the final week of the course."]
"Go to <a href='https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z229/z213/' target='_blank'>https://class.stanford.edu/courses/Engineering/CS101/Summer2014/courseware/z229/z213/</a> and complete Week 6, the final week of the course."
]
},
{
"name": "Build an Adventure Game",
@ -379,19 +385,19 @@
"video": "114612882",
"challengeNumber": 31,
"steps": [
"In this final CodeCademy section, we'll learn even more about JavaScript objects.",
"In this final Codecademy section, we'll learn even more about JavaScript objects.",
"Go to <a href='http://www.codecademy.com/courses/objects-ii/0/1' target='_blank'>http://www.codecademy.com/courses/objects-ii/0/1</a> and complete this section.",
"Be sure to also complete the final section: <a href='http://www.codecademy.com/courses/close-the-super-makert/0/1' target='_blank'>http://www.codecademy.com/courses/close-the-super-makert/0/1</a>."
]
},
{
"name": "Get Help The Hacker Way",
"name": "Get Help the Hacker Way",
"time": 30,
"video": "111500801",
"challengeNumber": 32,
"steps": [
"Watch the video to learn the RSAP (Read, Search, Ask, Post) methodology for getting help.",
"Try an intelligent Google query that involves JavaScript and filters for this year (since JavaScript changes)",
"Try an intelligent Google query that involves JavaScript and filters for this year (since JavaScript changes).",
"Go to <a href='http://stackoverflow.com/' target='_blank'>http://stackoverflow.com/</a> and view the recent questions.",
"Go to <a href='http://webchat.freenode.net/' target='_blank'>http://webchat.freenode.net/</a> and create an IRC account.",
"Join the #JavaScript chat room and introduce yourself as a Free Code Camp student.",
@ -412,30 +418,28 @@
]
},
{
"name": "Pair Program on CoderByte",
"name": "Pair Program on Bonfires",
"time": 60,
"video": "114635308",
"video": "119657641",
"challengeNumber": 34,
"steps": [
"OK, we're finally ready to start pair programming!",
"Pair Programming is where two people code together on the same computer. It is an efficient way to collaborate, and widely practiced at software companies. Pair Programming is one of the core concepts of \"Agile\" Software Development, which you will hear more about later.",
"Many people use Skype or Google Hangouts to pair program, but if you talk with professional software engineers, they will tell you that it's not really pair programming unless both people have the ability to use the keyboard and mouse.",
"The most popular tool for pair programming is Screen Hero. You can download Screen Hero for <a href='http://links.screenhero.com/e/c/eyJlbWFpbF9pZCI6Ik1qQTNNem9XQkNJQ1pBQUNjd0FYQVZrVEdnRkxNamtfX0JWZEdGVEpSZkVCWlRwbFpXRTBNamM0WVMxaE56SmlMVEV4WlRRdE9HUXpZUzFpWXpVNE1HRTJNalkxTldNNk1UUTJNVEEyQUE9PSIsInBvc2l0aW9uIjowLCJocmVmIjoiaHR0cDovL2RsLnNjcmVlbmhlcm8uY29tL3NtYXJ0ZG93bmxvYWQvZklYQU1UUUJBTEtQQkhQTC9TY3JlZW5oZXJvLnppcD9zb3VyY2U9d2ViIn0=' target='_blank'>Mac</a> or <a href='http://links.screenhero.com/e/c/eyJlbWFpbF9pZCI6Ik1qQTNNem9XQkNJQ1pBQUNjd0FYQVZrVEdnRkxNamtfX0JWZEdGVEpSZkVCWlRwbFpXRTBNamM0WVMxaE56SmlMVEV4WlRRdE9HUXpZUzFpWXpVNE1HRTJNalkxTldNNk1UUTJNVEEyQUE9PSIsInBvc2l0aW9uIjoxLCJocmVmIjoiaHR0cDovL2RsLnNjcmVlbmhlcm8uY29tL3NtYXJ0ZG93bmxvYWQvZklYQU1UUUJBTEtQQkhQTC9TY3JlZW5oZXJvLXNldHVwLmV4ZSJ9' target='_blank'>Windows</a>. Create your new user account from within the app.",
"If you are using Linux, go to <a href='http://www.freecodecamp.com/pair-program-with-team-viewer' target='_blank'>http://www.freecodecamp.com/pair-program-with-team-viewer</a> to learn how to use an alternative (but inferior) tool called Team Viewer.",
"We have a special chat room for people ready to pair program. Go to <a href='https://gitter.im/FreeCodeCamp/LetsPair' target='_blank'>https://gitter.im/FreeCodeCamp/LetsPair</a> and type \"Hello Pair Programmers!\"",
"If someone is available, they will be your \"pair\" - the person you pair programming with.",
"Private message your pair and ask for the email address he or she used to register Screen Hero.",
"If no one gets back to you in the first few minutes, don't worry. There will be lots of opportunities to pair program in the future.",
"If someone does get back to you, private message them and ask for the email address they used to register Screen Hero.",
"Add them as a new contact in Screen Hero, then click the monitor-looking button to attempt to share your screen with them.",
"Once the Screen Hero session starts, your screen's margins will glow orange. You are now sharing your screen.",
"Your pair will have his or her own cursor, and will be able to type text on his or her and keyboard.",
"Now it's time to tackle CoderByte.",
"Create a CoderByte account at <a href='http://coderbyte.com/sl/' target='_blank'>http://coderbyte.com/sl/</a>",
"Now go to <a href='http://coderbyte.com/CodingArea/Challenges/#easyChals' target='_blank'>http://coderbyte.com/CodingArea/Challenges/#easyChals</a> and start working through Coderbyte's easy algorithm scripting challenges using JavaScript.",
"When you are finished pair programming, end the session in Screen Hero session.",
"Your pair will have their own cursor, and will be able to type text on his or her and keyboard.",
"Now it's time to tackle our Bonfires.",
"Go to <a href='http://freecodecamp.com/bonfires' target='_blank'>http://freecodecamp.com/bonfires</a> and start working through our Bonfire challenges.",
"Once you you finish pair programming, end the session in Screen Hero session.",
"Congratulations! You have completed your first pair programming session.",
"You should pair program with different campers until you've completed all the Easy, Medium and Hard CoderByte challenges. This is a big time investment, but the JavaScript practice you'll get, along with the scripting and algorithm experience, are well worth it!",
"You can complete CoderByte problems while you continue to work through Free Code Camp's challenges.",
"Be sure to pair program on these challenges, and remember to apply the RSAP methodology.",
"Try to pair program with different campers until you've completed all the Bonfire challenges. This is a big time investment, but the JavaScript practice you'll get, along with the scripting and algorithm experience, are well worth it!",
"You can complete Bonfire challenges while you continue to work through Free Code Camp's challenges. Take your time.",
"Mark this challenge as complete and move on."
]
},
@ -468,7 +472,7 @@
"video": "114684206",
"challengeNumber": 37,
"steps": [
"One of the reasons Node.js is so fast is that it is \"evented\" - it processes events in an asynchronous manner.",
"One of the reasons Node.js is so fast is that it is \"evented.\" It processes events in an asynchronous manner.",
"As a result, Node.js relies on asynchronous callbacks.",
"We'll learn more about how events and callbacks work in this exciting Code School lesson.",
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/2/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/2/video/1</a> and complete the section."
@ -494,7 +498,8 @@
"One of the most exciting features of Node.js is NPM - Node Package Manager",
"With NPM, you quickly install any of thousands of Node.js modules into your app, and it will automatically handle the other modules that each module dependends upon downstream.",
"In this lesson, we'll learn how to include these modules in our Node.js app by requiring them as variables.",
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/4/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/4/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/4/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/4/video/1</a> and complete the section."
]
},
{
"name": "Start an Express.js Server",
@ -503,14 +508,17 @@
"challengeNumber": 40,
"steps": [
"We'll complete Code School's Express.js course shortly after completing this course, but this challenge will give you a quick tour of the Express.js framework.",
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/5/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/5/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/5/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/5/video/1</a> and complete the section."
]
},
{
"name": "Use Socket.IO",
"name": "Use Socket.io",
"time": 45,
"video": "114684530",
"challengeNumber": 41,
"steps": ["Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/6/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/6/video/1</a> and complete the section."]
"steps": [
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/6/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/6/video/1</a> and complete the section."
]
},
{
"name": "Use Redis to Persist Data",
@ -520,7 +528,8 @@
"steps": [
"Redis is a key-value store, which is a type of non-relational database. It's one of the fastest and easiest ways to persist data.",
"Even though we'll ultimately use MongoDB and other technologies to persist data, Redis is quite easy to learn and is still worth learning.",
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/7/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/7/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/real-time-web-with-node-js/level/7/video/1' target='_blank'>http://campus.codeschool.com/courses/real-time-web-with-node-js/level/7/video/1</a> and complete the section."
]
},
{
"name": "Dive Deeper into Express.js",
@ -529,7 +538,8 @@
"challengeNumber": 43,
"steps": [
"Code School has one of the first comprehensive courses on Express.js. Note that this course requires a Code School subscription, but that you can get a free two-day membership to Code School by going to <a href='https://www.codeschool.com/hall_passes/213f3fedb6b9/claim_shared' target='_blank'>https://www.codeschool.com/hall_passes/213f3fedb6b9/claim_shared</a>. If you've already used your Code School two-day membership, go to the Free Code Camp main chat room and ask how you can get some extra time to work through this course. Alternatively, you could subscribe to Code School for one month, then take your time in completing these challenges.",
"Go to <a href='http://campus.codeschool.com/courses/building-blocks-of-express-js/level/1/video/1' target='_blank'>http://campus.codeschool.com/courses/building-blocks-of-express-js/level/1/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/building-blocks-of-express-js/level/1/video/1' target='_blank'>http://campus.codeschool.com/courses/building-blocks-of-express-js/level/1/video/1</a> and complete the section."
]
},
{
@ -549,7 +559,7 @@
"video": "114684537",
"challengeNumber": 45,
"steps": [
"Have you've ever noticed a question mark in your browser's address bar, followed by a series of string? Those are parameters. Parameters are an efficient way to pass information to the server between page loads.",
"Have you ever noticed a question mark in your browser's address bar, followed by a series of strings? Those are parameters. Parameters are an efficient way to pass information to the server between page loads.",
"We'll learn about parameters, along with a powerful Express.js feature called Dynamic Routing, in this exciting Code School lesson.",
"Go to <a href='http://campus.codeschool.com/courses/building-blocks-of-express-js/level/3/video/1' target='_blank'>http://campus.codeschool.com/courses/building-blocks-of-express-js/level/3/video/1</a> and complete the section."
]
@ -594,7 +604,8 @@
"steps": [
"Code School has a short, free Angular.js course. This will give us a quick tour of Angular.js's mechanics and features.",
"In this course, we'll build a virtual shop entirely in Angular.js.",
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/1/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/1/section/1/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/1/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/1/section/1/video/1</a> and complete the section."
]
},
{
"name": "Apply Angular.js Directives",
@ -615,7 +626,8 @@
"steps": [
"One area where Angular.js really shines is its powerful web forms.",
"Learn how to create reactive Angular.js forms, including real-time form validation.",
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/3/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/3/section/1/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/3/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/3/section/1/video/1</a> and complete the section."
]
},
{
"name": "Customize Angular.js Directives",
@ -624,7 +636,8 @@
"challengeNumber": 52,
"steps": [
"Now we'll learn how to modify existing Angular.js directives, and even build directives of your own.",
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/4/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/4/section/1/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/4/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/4/section/1/video/1</a> and complete the section."
]
},
{
"name": "Create Angular.js Services",
@ -634,6 +647,7 @@
"steps": [
"Services are functions that you can use and reuse throughout your Angular.js app to get things done.",
"We'll learn how to use services in this final Code School Angular.js challenge.",
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/5/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/5/section/1/video/1</a> and complete the section."]
"Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/5/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/5/section/1/video/1</a> and complete the section."
]
}
]

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
extends ../layout
block content
script.
var challengeName = 'Account View'
.panel.panel-primary.min-height-1000(ng-controller="profileValidationController")
.panel-heading.text-center Update your profile here:
.panel-body

View File

@ -24,8 +24,6 @@ block content
a.ion-social-linkedin.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedinProfile, target='_blank')
- if (codepenProfile)
a.ion-social-codepen.text-primary(title="@#{username}'s CodePen Profile", href=codepenProfile, target='_blank')
- if (coderbyteProfile)
a.ion-social-javascript.text-primary(title="@#{username}'s CoderByte Profile", href=coderbyteProfile, target='_blank')
.visible-md.visible-lg
.col-xs-12.col-sm-12.col-md-4.text-justify
h1.flat-top.wrappable= name

View File

@ -42,4 +42,4 @@ block content
br
ul#testSuite.list-group
br
script(src='/js/lib/bonfire/bonfireFramework_v0.1.0.js')
script(src='/js/lib/bonfire/bonfireFramework_v0.1.2.js')

View File

@ -87,7 +87,6 @@ block content
script(type="text/javascript").
var tests = !{JSON.stringify(tests)};
var challengeSeed = !{JSON.stringify(challengeSeed)};
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
var passedBonfireHash = !{JSON.stringify(bonfireHash)};
var challengeName = !{JSON.stringify(name)};
var started = Math.floor(Date.now() / 1000);
@ -96,7 +95,7 @@ block content
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true)
script(src='/js/lib/bonfire/bonfireFramework_v0.1.0.js')
script(src='/js/lib/bonfire/bonfireFramework_v0.1.2.js')

View File

@ -25,7 +25,7 @@ block content
.col-xs-12
h2.text-center= name
.bonfire-instructions
p= brief
p!= brief
#brief-instructions
.text-center
button#more-info.btn.btn-info
@ -39,16 +39,26 @@ block content
button#less-info.btn.btn-info
span.ion-help-circled
| Less information
div.hidden
#submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter)
br
form.code
.form-group.codeMirrorView
textarea#codeOutput
- if (cc)
a.btn.btn-primary.btn-lg.btn-block#next-courseware-button
| Go to my next challenge
br
#testSuite
| (ctrl + enter)
script.
var userLoggedIn = true;
- else
a.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
script.
var userLoggedIn = false;
br
ul#testSuite.list-group
br
script(type="text/javascript").
$('#next-courseware-button').attr('disabled', 'disabled');
var tests = !{JSON.stringify(tests)};
var challengeSeed = !{JSON.stringify(challengeSeed)};
var passedCoursewareHash = !{JSON.stringify(coursewareHash)};
@ -60,7 +70,6 @@ block content
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true)
script(src='/js/lib/coursewares/coursewaresFramework_v0.1.0.js')
.col-md-4.col-lg-3
.hidden-xs.hidden-sm
img.iphone-position(src="https://s3.amazonaws.com/freecodecamp/iphone6-frame.png")
@ -77,11 +86,5 @@ block content
.text-center
.animated.zoomInDown.delay-half
span.completion-icon.ion-checkmark-circled.text-primary
- if (cc)
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-courseware-button(name='_csrf', value=_csrf, aria-hidden='true') Go to my next challenge (ctrl + enter)
- if (points && points > 2)
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Challenge%20%23#{number}:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{number}&hashtags=LearnToCode, JavaScript" target="_blank")
i.fa.fa-twitter &nbsp;
= phrase
- else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
script(src="/js/lib/coursewares/coursewaresHCJQFramework_v0.1.1.js")

View File

@ -0,0 +1,76 @@
extends ../layout-wide
block content
script(src='/js/lib/codemirror/lib/codemirror.js')
script(src='/js/lib/codemirror/addon/edit/closebrackets.js')
script(src='/js/lib/codemirror/addon/edit/matchbrackets.js')
script(src='/js/lib/codemirror/addon/lint/lint.js')
script(src='/js/lib/codemirror/addon/lint/javascript-lint.js')
script(src='//ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js')
script(src='/js/lib/chai/chai.js')
link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono")
script(src='/js/lib/codemirror/mode/javascript/javascript.js')
script(src='/js/lib/jailed/jailed.js')
script(src='/js/lib/bonfire/bonfireInit.js')
.row
.col-xs-12.col-sm-12.col-md-4.bonfire-top
#testCreatePanel
h1.text-center= name
.well
.row
.col-xs-12
.bonfire-instructions
p= brief
#brief-instructions
.text-center
button#more-info.btn.btn-info
span.ion-help-circled
| More information
#long-instructions.row.hide
.col-xs-12
for sentence in details
p!= sentence
.text-center
button#less-info.btn.btn-info
span.ion-help-circled
| Less information
#submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter)
br
form.code
.form-group.codeMirrorView
textarea#codeOutput
br
#testSuite
br
script(type="text/javascript").
var tests = !{JSON.stringify(tests)};
var challengeSeed = !{JSON.stringify(challengeSeed)};
var passedBonfireHash = !{JSON.stringify(coursewareHash)};
var challengeName = !{JSON.stringify(name)};
var started = Math.floor(Date.now() / 1000);
.col-xs-12.col-sm-12.col-md-8
#mainEditorPanel
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true)
script(src='/js/lib/coursewares/coursewaresJSFramework.js')
#complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation
.modal-content
.modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body(ng-controller="pairedWithController")
.text-center
.animated.zoomInDown.delay-half
span.completion-icon.ion-checkmark-circled.text-primary
- if (cc)
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Go to my next challenge (ctrl + enter)
- if (points && points > 2)
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Bonfire:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/bonfires/#{dashedName}&hashtags=LearnToCode, JavaScript" target="_blank")
i.fa.fa-twitter &nbsp;
= phrase
- else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress

View File

@ -0,0 +1,49 @@
extends ../layout-wide
block content
.row
.col-xs-12.col-sm-12.col-md-4.bonfire-top
h1.text-center= name
.well
h4
ol
for step in details
li!= step
.col-xs-12.col-sm-12.col-md-8
.embed-responsive.embed-responsive-16by9
iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
br
- if (cc)
a.btn.btn-primary.btn-lg.btn-block#next-courseware-button Go to my next challenge (ctrl + enter)
script.
var userLoggedIn = true;
- else
a.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
script.
var userLoggedIn = false;
br
script(type="text/javascript").
var tests = !{JSON.stringify(tests)};
var passedCoursewareHash = !{JSON.stringify(coursewareHash)};
var challengeName = !{JSON.stringify(name)};
var started = Math.floor(Date.now() / 1000);
#complete-courseware-dialog.modal(tabindex='-1')
.modal-dialog.animated.zoomIn.fast-animation
.modal-content
.modal-header.challenge-list-header= compliment
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body(ng-controller="pairedWithController")
.text-center
.animated.zoomInDown.delay-half
span.completion-icon.ion-checkmark-circled.text-primary
- if (cc)
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Go to my next challenge (ctrl + enter)
- if (points && points > 2)
a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Bonfire:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/bonfires/#{dashedName}&hashtags=LearnToCode, JavaScript" target="_blank")
i.fa.fa-twitter &nbsp;
= phrase
- else
a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress
h1 #{name}
script.
var challengeName = !{JSON.stringify(name)};
var passedCoursewareHash = !{JSON.stringify(coursewareHash)};

View File

@ -20,7 +20,7 @@
p.negative-10 "I code whenever I'm not sleeping or in school. Making computers obey me is a dream come true."
.col-xs-12.col-sm-4.col-md-3.team-member
h3.negative-10.text-nowrap Branden Byers
h4.negative-10.text-nowrap Community Builder
h4.negative-10.text-nowrap Instructional Designer
img.profile-image(src='https://s3.amazonaws.com/freecodecamp/branden-byers.jpg' alt="Branden Byers picture")
h4.text-nowrap Madison, Wisconsin
p.negative-10 "Cookbook author and stay-at-home-dad. Started coding as a kid, got distracted, but now I'm back in full JavaScript force!"
@ -68,7 +68,7 @@
p.negative-10 "I love origami, piano, and playing minecraft with my kids. My JavaScript grows stronger every day."
.col-xs-12.col-sm-4.col-md-3.team-member
h3.negative-10.text-nowrap Charles Watson
h4.negative-10.text-nowrap iOS Engineer
h4.negative-10.text-nowrap JavaScript Engineer
img.profile-image(src='https://s3.amazonaws.com/freecodecamp/charles-watson.jpg' alt="Charles Watson's picture")
h4.text-nowrap Minneapolis, Minnesota
p.negative-10 "I skipped college. I build iOS apps. I love the obstacles and puzzles that coding presents me."

View File

@ -1,19 +1,20 @@
.fcc-footer
.col-xs-12
a.ion-speakerphone(title="Free Code Camp's Blog", href='http://blog.freecodecamp.com', target='_blank')
| &nbsp;
a.ion-social-twitch-outline(title="Free Code Camp Live Pair Programming on Twitch.TV", href="http://www.twitch.tv/freecodecamp", target='_blank')
| &nbsp;
a.ion-social-github(title="Free Code Camp on GitHub", href="http://github.com/freecodecamp", target='_blank')
| &nbsp;
a.ion-social-twitter(title="Free Code Camp on Twitter", href="http://twitter.com/freecodecamp", target='_blank')
| &nbsp;
a.ion-social-facebook(title="Free Code Camp on Facebook", href="http://facebook.com/freecodecamp", target='_blank')
| &nbsp;
a.ion-social-linkedin(title="Free Code Camp on LinkedIn", href="http://linkedin.com/company/4831032?free-code-camp", target='_blank')
| &nbsp;
a.ion-information-circled(title="About Free Code Camp", href="/learn-to-code")
| &nbsp;
a.ion-locked(title="Free Code Camp's Privacy Policy", href="/privacy")
| &nbsp;
a.ion-code-working(title="Bonfire Coding Playground", href="/playground")
a.ion-speakerphone(href='http://blog.freecodecamp.com', target='_blank')
span.sr-only Free Code Camp's Blog
a.ion-social-twitch-outline(href="http://www.twitch.tv/freecodecamp", target='_blank')
span.sr-only Free Code Camp Live Pair Programming on Twitch.tv
a.ion-social-github(href="http://github.com/freecodecamp", target='_blank')
span.sr-only Free Code Camp on GitHub
a.ion-social-twitter(href="http://twitter.com/freecodecamp", target='_blank')
span.sr-only Free Code Camp on Twitter
a.ion-social-facebook(href="http://facebook.com/freecodecamp", target='_blank')
span.sr-only Free Code Camp on Facebook
a.ion-social-linkedin(href="http://linkedin.com/company/4831032?free-code-camp", target='_blank')
span.sr-only Free Code Camp on LinkedIn
a.ion-information-circled(href="/learn-to-code")
span.sr-only About Free Code Camp
a.ion-locked(href="/privacy")
span.sr-only Free Code Camp's Privacy Policy
a.ion-code-working(href="/playground")
span.sr-only Code Editor Playground

View File

@ -1,8 +1,12 @@
extends ../layout-wide
block content
.text-center
h1 Live Pair Programming
h2 Our next session will be February 3rd, 2015 at 9 p.m. EST!
h2#next-session
h2 Watch the live stream below or on our &nbsp;
a(href="http://twitch.tv/freecodecamp", target='_blank') Twitch.tv channel
| .
@ -46,3 +50,7 @@ block content
br
br
br
script(src="/js/lib/moment/moment.js")
script(src="/js/lib/moment/nextTuesday.js")
script.
$('#next-session').text(nextSession());

View File

@ -14,8 +14,10 @@ block content
li Read this document, which will answer many questions you may have about our nonprofit projects: &nbsp;
a(href="http://forum.freecodecamp.com/t/an-introduction-to-our-nonprofit-projects/856" target="_blank") http://forum.freecodecamp.com/t/an-introduction-to-our-nonprofit-projects/856
| .
li We'll send you an invite to our Nonprofit Projects Trello board. Once we do, go there and add yourself to each of the nonprofit projects that interests you.
li Finish any unfinished easy and medium coderbyte challenges. These challenges serve as the Free Code Camp "exit test". You must be complete these before you can start working on nonprofit projects.
li We'll send you an invite to our Nonprofit Projects Trello board. Once we do, go there and add yourself to at least 3 nonprofit projects that interest you.
li Finish any unfinished Bonfire challenges. These challenges serve as the Free Code Camp "exit test". You must complete these before you can start working on nonprofit projects. If you completed CoderByte or CodeWars challenges instead of Bonfire, email us and we'll take a look:&nbsp;
a(href="mailto:team@freecodecamp.com") team@freecodecamp.com
| .
h4 Please email us if you have further questions: &nbsp;
a(href="mailto:team@freecodecamp.com") team@freecodecamp.com
| .

View File

@ -1,27 +0,0 @@
extends ../layout
block content
.row
.col-sm-12.col-md-8.col-xs-12
.panel.panel-primary
.panel-heading #{name} (takes #{time} minutes)
.panel.panel-body
//.embed-responsive.embed-responsive-16by9
// iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
h3 Steps:
h4
ol
for step in steps
li!= step
a.btn.btn-primary.btn-big.btn-block.completed-challenge(href='/challenges/34') Take me back to the Pair Programming Challenge
.panel-footer.text-center
span Need a break? Check out our:&nbsp;
a(href="https://gitter.im/FreeCodeCamp/FreeCodeCamp", target="_blank") Chat Room
| &nbsp;,&nbsp;
a(href="http://blog.freecodecamp.com", target="_blank") Blog
| &nbsp;,&nbsp;
a(href="https://twitter.com/freecodecamp", target="_blank") Twitter Feed
| &nbsp;,&nbsp;or&nbsp;
a(href="https://reddit.com/r/freecodecamp", target="_blank") Subreddit
| .
.col-sm-12.col-md-4.col-xs-12
include ../partials/challenges