Merge remote-tracking branch 'upstream/staging' into staging
Conflicts: seed/challenges/html5-and-css.json
This commit is contained in:
@ -685,7 +685,7 @@ thead {
|
|||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
&:hover {
|
&:hover {
|
||||||
padding-top: 14px;
|
padding-top: 14px;
|
||||||
padding-bottom: 14px;
|
padding-bottom: 12px;
|
||||||
color: #4a2b0f;
|
color: #4a2b0f;
|
||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -252,14 +252,15 @@ var allSeeds = '';
|
|||||||
|
|
||||||
editorValue = (codeStorage.isAlive())? codeStorage.getEditorValue() : allSeeds;
|
editorValue = (codeStorage.isAlive())? codeStorage.getEditorValue() : allSeeds;
|
||||||
|
|
||||||
editor.setValue(editorValue);
|
editor.setValue(editorValue.replace((/fccss/gi), '<script>').replace((/fcces/gi), '</script>'));
|
||||||
|
editor.refresh();
|
||||||
|
|
||||||
var resetEditor = function resetEditor() {
|
var resetEditor = function resetEditor() {
|
||||||
editor.setValue(allSeeds);
|
editor.setValue(allSeeds.replace((/fccss/gi), '<script>').replace((/fcces/gi), '</script>'));
|
||||||
updatePreview();
|
updatePreview();
|
||||||
codeStorage.updateStorage();
|
codeStorage.updateStorage();
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
var challengeSeed = challengeSeed || null;
|
var challengeSeed = challengeSeed || null;
|
||||||
var allSeeds = '';
|
var allSeeds = '';
|
||||||
(function() {
|
(function() {
|
||||||
@ -273,3 +274,4 @@ var allSeeds = '';
|
|||||||
}, 200);
|
}, 200);
|
||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
|
*/
|
||||||
|
@ -159,12 +159,107 @@ $(document).ready(function() {
|
|||||||
$('#complete-zipline-or-basejump-dialog').modal('show');
|
$('#complete-zipline-or-basejump-dialog').modal('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#completed-courseware-dialog').unbind('click');
|
$('#next-courseware-button').unbind('click');
|
||||||
|
$('#next-courseware-button').on('click', function() {
|
||||||
|
$('#next-courseware-button').unbind('click');
|
||||||
|
if ($('.signup-btn-nav').length < 1) {
|
||||||
|
switch (challengeType) {
|
||||||
|
case challengeTypes.HTML_CSS_JQ:
|
||||||
|
case challengeTypes.JAVASCRIPT:
|
||||||
|
case challengeTypes.VIDEO:
|
||||||
|
$.post(
|
||||||
|
'/completed-challenge/',
|
||||||
|
{
|
||||||
|
challengeInfo: {
|
||||||
|
challengeId: challenge_Id,
|
||||||
|
challengeName: challenge_Name
|
||||||
|
}
|
||||||
|
}).success(
|
||||||
|
function(res) {
|
||||||
|
if (res) {
|
||||||
|
window.location.href = '/challenges/next-challenge';
|
||||||
|
}
|
||||||
|
}).fail(
|
||||||
|
function() {
|
||||||
|
window.location.href="/challenges";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case challengeTypes.ZIPLINE:
|
||||||
|
var didCompleteWith = $('#completed-with').val() || null;
|
||||||
|
var publicURL = $('#public-url').val() || null;
|
||||||
|
$.post(
|
||||||
|
'/completed-zipline-or-basejump/',
|
||||||
|
{
|
||||||
|
challengeInfo: {
|
||||||
|
challengeId: challenge_Id,
|
||||||
|
challengeName: challenge_Name,
|
||||||
|
completedWith: didCompleteWith,
|
||||||
|
publicURL: publicURL,
|
||||||
|
challengeType: challengeType
|
||||||
|
}
|
||||||
|
}).success(
|
||||||
|
function() {
|
||||||
|
window.location.href = '/challenges/next-challenge';
|
||||||
|
}).fail(
|
||||||
|
function() {
|
||||||
|
window.location.href = '/challenges';
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case challengeTypes.BASEJUMP:
|
||||||
|
var didCompleteWith = $('#completed-with').val() || null;
|
||||||
|
var publicURL = $('#public-url').val() || null;
|
||||||
|
var githubURL = $('#github-url').val() || null;
|
||||||
|
$.post(
|
||||||
|
'/completed-zipline-or-basejump/',
|
||||||
|
{
|
||||||
|
challengeInfo: {
|
||||||
|
challengeId: challenge_Id,
|
||||||
|
challengeName: challenge_Name,
|
||||||
|
completedWith: didCompleteWith,
|
||||||
|
publicURL: publicURL,
|
||||||
|
githubURL: githubURL,
|
||||||
|
challengeType: challengeType,
|
||||||
|
verified: false
|
||||||
|
}
|
||||||
|
}).success(function() {
|
||||||
|
window.location.href = '/challenges/next-challenge';
|
||||||
|
}).fail(function() {
|
||||||
|
window.location.replace(window.location.href);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case challengeTypes.BONFIRE:
|
||||||
|
window.location.href = '/challenges/next-challenge';
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.next-challenge-button').unbind('click');
|
||||||
|
$('.next-challenge-button').on('click', function() {
|
||||||
|
l = location.pathname.split('/');
|
||||||
|
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bonfire instructions functions
|
||||||
|
$('#more-info').unbind('click');
|
||||||
|
$('#more-info').on('click', function() {
|
||||||
|
ga('send', 'event', 'Challenge', 'more-info', challengeName);
|
||||||
|
$('#brief-instructions').hide();
|
||||||
|
$('#long-instructions').show().removeClass('hide');
|
||||||
|
|
||||||
|
});
|
||||||
|
$('#less-info').unbind('click');
|
||||||
|
$('#less-info').on('click', function() {
|
||||||
|
$('#brief-instructions').show();
|
||||||
|
$('#long-instructions').hide();
|
||||||
|
});
|
||||||
|
|
||||||
$('#complete-courseware-dialog').on('hidden.bs.modal', function() {
|
$('#complete-courseware-dialog').on('hidden.bs.modal', function() {
|
||||||
editor.focus();
|
editor.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#completed-zipline-or-basejump').unbind('click');
|
|
||||||
$('#complete-zipline-or-basejump').on('hidden.bs.modal', function() {
|
$('#complete-zipline-or-basejump').on('hidden.bs.modal', function() {
|
||||||
editor.focus();
|
editor.focus();
|
||||||
});
|
});
|
||||||
@ -186,98 +281,6 @@ $(document).ready(function() {
|
|||||||
'BASEJUMP': '4',
|
'BASEJUMP': '4',
|
||||||
'BONFIRE': '5'
|
'BONFIRE': '5'
|
||||||
};
|
};
|
||||||
$('#next-courseware-button').on('click', function() {
|
|
||||||
$('#next-courseware-button').unbind('click');
|
|
||||||
if ($('.signup-btn-nav').length < 1) {
|
|
||||||
switch (challengeType) {
|
|
||||||
case challengeTypes.HTML_CSS_JQ:
|
|
||||||
case challengeTypes.JAVASCRIPT:
|
|
||||||
case challengeTypes.VIDEO:
|
|
||||||
$.post(
|
|
||||||
'/completed-challenge/',
|
|
||||||
{
|
|
||||||
challengeInfo: {
|
|
||||||
challengeId: challenge_Id,
|
|
||||||
challengeName: challenge_Name
|
|
||||||
}
|
|
||||||
}).success(
|
|
||||||
function(res) {
|
|
||||||
if (res) {
|
|
||||||
window.location.href = '/challenges/next-challenge';
|
|
||||||
}
|
|
||||||
}).fail(
|
|
||||||
function() {
|
|
||||||
window.location.href="/challenges";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case challengeTypes.ZIPLINE:
|
|
||||||
var didCompleteWith = $('#completed-with').val() || null;
|
|
||||||
var publicURL = $('#public-url').val() || null;
|
|
||||||
$.post(
|
|
||||||
'/completed-zipline-or-basejump/',
|
|
||||||
{
|
|
||||||
challengeInfo: {
|
|
||||||
challengeId: challenge_Id,
|
|
||||||
challengeName: challenge_Name,
|
|
||||||
completedWith: didCompleteWith,
|
|
||||||
publicURL: publicURL,
|
|
||||||
challengeType: challengeType
|
|
||||||
}
|
|
||||||
}).success(
|
|
||||||
function() {
|
|
||||||
window.location.href = '/challenges/next-challenge';
|
|
||||||
}).fail(
|
|
||||||
function() {
|
|
||||||
window.location.href = '/challenges';
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case challengeTypes.BASEJUMP:
|
|
||||||
var didCompleteWith = $('#completed-with').val() || null;
|
|
||||||
var publicURL = $('#public-url').val() || null;
|
|
||||||
var githubURL = $('#github-url').val() || null;
|
|
||||||
$.post(
|
|
||||||
'/completed-zipline-or-basejump/',
|
|
||||||
{
|
|
||||||
challengeInfo: {
|
|
||||||
challengeId: challenge_Id,
|
|
||||||
challengeName: challenge_Name,
|
|
||||||
completedWith: didCompleteWith,
|
|
||||||
publicURL: publicURL,
|
|
||||||
githubURL: githubURL,
|
|
||||||
challengeType: challengeType,
|
|
||||||
verified: false
|
|
||||||
}
|
|
||||||
}).success(function() {
|
|
||||||
window.location.href = '/challenges/next-challenge';
|
|
||||||
}).fail(function() {
|
|
||||||
window.location.replace(window.location.href);
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case challengeTypes.BONFIRE:
|
|
||||||
window.location.href = '/challenges/next-challenge';
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.next-challenge-button').on('click', function() {
|
|
||||||
l = location.pathname.split('/');
|
|
||||||
window.location = '/challenges/' + (parseInt(l[l.length - 1]) + 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Bonfire instructions functions
|
|
||||||
$('#more-info').on('click', function() {
|
|
||||||
ga('send', 'event', 'Challenge', 'more-info', challengeName);
|
|
||||||
$('#brief-instructions').hide();
|
|
||||||
$('#long-instructions').show().removeClass('hide');
|
|
||||||
|
|
||||||
});
|
|
||||||
$('#less-info').on('click', function() {
|
|
||||||
$('#brief-instructions').show();
|
|
||||||
$('#long-instructions').hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
function upvoteHandler(e) {
|
function upvoteHandler(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
"description": [
|
"description": [
|
||||||
"<code>data structures</code> have <code>properties</code>. For example, <code>strings</code> have a property called <code>.length</code> that will tell you how many characters are in the string.",
|
"<code>data structures</code> have <code>properties</code>. For example, <code>strings</code> have a property called <code>.length</code> that will tell you how many characters are in the string.",
|
||||||
"For example, if we created a variable <code>var firstName = \"Charles\"</code>, we could find out how long the string \"Charles\" is by using the <code>firstName.length</code> property.",
|
"For example, if we created a variable <code>var firstName = \"Charles\"</code>, we could find out how long the string \"Charles\" is by using the <code>firstName.length</code> property.",
|
||||||
"Use the <code>.length</code> property to count the number of characters in the <code>lastNameLength</code> variable."
|
"Use the <code>.length</code> property to count the number of characters in the <code>lastName</code> variable."
|
||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"assert((function(){if(typeof(lastNameLength) !== \"undefined\" && typeof(lastNameLength) === \"number\" && lastNameLength === 8){return(true);}else{return(false);}})(), 'lastNameLength should be equal to eight.');",
|
"assert((function(){if(typeof(lastNameLength) !== \"undefined\" && typeof(lastNameLength) === \"number\" && lastNameLength === 8){return(true);}else{return(false);}})(), 'lastNameLength should be equal to eight.');",
|
||||||
@ -150,7 +150,7 @@
|
|||||||
"<code>Bracket notation</code> is a way to get a character at a specific <code>index</code> within a string.",
|
"<code>Bracket notation</code> is a way to get a character at a specific <code>index</code> within a string.",
|
||||||
"Computers don't start counting at 1 like humans do. They start at 0.",
|
"Computers don't start counting at 1 like humans do. They start at 0.",
|
||||||
"For example, the character at index 0 in the word \"Charles\" is \"C\". So if <code>var firstName = \"Charles\"</code>, you can get the value of the first letter of the string by using <code>firstName[0]</code>.",
|
"For example, the character at index 0 in the word \"Charles\" is \"C\". So if <code>var firstName = \"Charles\"</code>, you can get the value of the first letter of the string by using <code>firstName[0]</code>.",
|
||||||
"Use <code>bracket notation</code> to find the first character in a the <code>firstLetterOfLastName</code> variable.",
|
"Use <code>bracket notation</code> to find the first character in the <code>firstLetterOfLastName</code> variable.",
|
||||||
"Try looking at the <code>firstLetterOfFirstName</code> variable declaration if you get stuck."
|
"Try looking at the <code>firstLetterOfFirstName</code> variable declaration if you get stuck."
|
||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
@ -216,7 +216,7 @@
|
|||||||
"In order to get the last letter of a string, you can subtract one from the string's length.",
|
"In order to get the last letter of a string, you can subtract one from the string's length.",
|
||||||
"For example, if <code>var firstName = \"Charles\"</code>, you can get the value of the last letter of the string by using <code>firstName[firstName.length - 1]</code>.",
|
"For example, if <code>var firstName = \"Charles\"</code>, you can get the value of the last letter of the string by using <code>firstName[firstName.length - 1]</code>.",
|
||||||
"Use <code>bracket notation</code> to find the last character in the <code>lastName</code> variable.",
|
"Use <code>bracket notation</code> to find the last character in the <code>lastName</code> variable.",
|
||||||
"Try looking at the <code>lastLetterOfLastName</code> variable declaration if you get stuck."
|
"Try looking at the <code>lastLetterOfFirstName</code> variable declaration if you get stuck."
|
||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"assert(lastLetterOfLastName === \"e\", 'lastLetterOfLastName should be \"e\"');",
|
"assert(lastLetterOfLastName === \"e\", 'lastLetterOfLastName should be \"e\"');",
|
||||||
@ -496,7 +496,7 @@
|
|||||||
"// Only change code above this line.",
|
"// Only change code above this line.",
|
||||||
"// We use this function to show you the value of your variable in your output box.",
|
"// We use this function to show you the value of your variable in your output box.",
|
||||||
"// You'll learn about functions soon.",
|
"// You'll learn about functions soon.",
|
||||||
"if(typeof(myArray) !== \"undefined\" && typeof(data) !== \"undefined\"){(function(y,z){return('myArray = ' + JSON.stringify(y) + ', data = ' + JSON.stringify(z));})(myArray, data);}"
|
"if(typeof(myArray) !== \"undefined\" && typeof(myData) !== \"undefined\"){(function(y,z){return('myArray = ' + JSON.stringify(y) + ', myData = ' + JSON.stringify(z));})(myArray, myData);}"
|
||||||
],
|
],
|
||||||
"type": "waypoint",
|
"type": "waypoint",
|
||||||
"challengeType": 1
|
"challengeType": 1
|
||||||
@ -755,7 +755,7 @@
|
|||||||
"title": "Manipulate JavaScript Objects",
|
"title": "Manipulate JavaScript Objects",
|
||||||
"difficulty":"9.9823",
|
"difficulty":"9.9823",
|
||||||
"description":[
|
"description":[
|
||||||
"There are many ways to add and add and remove properties from objects.",
|
"There are many ways to add and remove properties from objects.",
|
||||||
"For example, we can add properties to objects like this:",
|
"For example, we can add properties to objects like this:",
|
||||||
"<code>myObject.myProperty = \"myValue\";</code>",
|
"<code>myObject.myProperty = \"myValue\";</code>",
|
||||||
"We can also delete them like this:",
|
"We can also delete them like this:",
|
||||||
@ -832,7 +832,7 @@
|
|||||||
"difficulty":"9.9825",
|
"difficulty":"9.9825",
|
||||||
"description":[
|
"description":[
|
||||||
"You can run the same code multiple times by using a loop.",
|
"You can run the same code multiple times by using a loop.",
|
||||||
"Another type of JavaScript loop is called a \"while loop\" because it runs \"while\" something is true, and stops once that something is no longer true.",
|
"Another type of JavaScript loop is called a \"while loop\", because it runs \"while\" something is true and stops once that something is no longer true.",
|
||||||
"<code>var ourArray = [];</code>",
|
"<code>var ourArray = [];</code>",
|
||||||
"<code>var i = 0;</code>",
|
"<code>var i = 0;</code>",
|
||||||
"<code>while(i < 5) {</code>",
|
"<code>while(i < 5) {</code>",
|
||||||
@ -859,7 +859,7 @@
|
|||||||
"title": "Generate Random Fractions with JavaScript",
|
"title": "Generate Random Fractions with JavaScript",
|
||||||
"difficulty":"9.9827",
|
"difficulty":"9.9827",
|
||||||
"description":[
|
"description":[
|
||||||
"Random numbers are useful for creating random behaviours and games.",
|
"Random numbers are useful for creating random behavior.",
|
||||||
"JavaScript has a <code>Math.random()</code> function that generates a random decimal number.",
|
"JavaScript has a <code>Math.random()</code> function that generates a random decimal number.",
|
||||||
"Use <code>Math.random()</code> to get <code>myFunction</code> to return a random number."
|
"Use <code>Math.random()</code> to get <code>myFunction</code> to return a random number."
|
||||||
],
|
],
|
||||||
@ -956,16 +956,16 @@
|
|||||||
"difficulty":"9.983",
|
"difficulty":"9.983",
|
||||||
"description":[
|
"description":[
|
||||||
"We can use if statements in JavaScript to only execute code if a certain condition is met.",
|
"We can use if statements in JavaScript to only execute code if a certain condition is met.",
|
||||||
"if statements require some sort of boolean condition evaluate.",
|
"if statements require some sort of boolean condition to evaluate.",
|
||||||
"Example:",
|
"Example:",
|
||||||
"<code> if (1 == 2) {</code>",
|
"<code> if (1 === 2) {</code>",
|
||||||
"<code>  return(true);</code>",
|
"<code>  return(true);</code>",
|
||||||
"<code>}</code>",
|
"<code>}</code>",
|
||||||
"<code>else {</code>",
|
"<code>else {</code>",
|
||||||
"<code>  return(false);</code>",
|
"<code>  return(false);</code>",
|
||||||
"<code>}</code>",
|
"<code>}</code>",
|
||||||
"Let's use <code>if</code> and <code>else</code> statements to make a coin-flip game.",
|
"Let's use <code>if</code> and <code>else</code> statements to make a coin-flip game.",
|
||||||
"Create an <code>if-else statement</code> to return <code>heads</code> if the flip var is zero and to return <code>tails</code> if it's not."
|
"Create an <code>if-else statement</code> to return <code>heads</code> if the flip var is zero, or else return <code>tails</code> if it's not."
|
||||||
],
|
],
|
||||||
"tests":[
|
"tests":[
|
||||||
"assert((function(){if(myFunction() === \"heads\" || myFunction() === \"tails\"){return(true);}else{return(false);}})(), 'myFunction should either return heads or tails');",
|
"assert((function(){if(myFunction() === \"heads\" || myFunction() === \"tails\"){return(true);}else{return(false);}})(), 'myFunction should either return heads or tails');",
|
||||||
@ -975,7 +975,7 @@
|
|||||||
"challengeSeed":[
|
"challengeSeed":[
|
||||||
"function myFunction(){",
|
"function myFunction(){",
|
||||||
" var flip = Math.floor(Math.random() * (1 - 0 + 1)) + 0;",
|
" var flip = Math.floor(Math.random() * (1 - 0 + 1)) + 0;",
|
||||||
" // Create and if else statement here to return \"heads\" if flip is 0. Otherwise return \"tails\".",
|
" // Create an if-else statement here to return \"heads\" if flip is 0. Otherwise return \"tails\".",
|
||||||
"",
|
"",
|
||||||
" // Only change code below this line.",
|
" // Only change code below this line.",
|
||||||
"",
|
"",
|
||||||
@ -1002,7 +1002,7 @@
|
|||||||
"<code>g</code> means that we want to search the entire string for this pattern.",
|
"<code>g</code> means that we want to search the entire string for this pattern.",
|
||||||
"<code>i</code> means that we want to ignore the case (uppercase or lowercase) when searching for the pattern.",
|
"<code>i</code> means that we want to ignore the case (uppercase or lowercase) when searching for the pattern.",
|
||||||
"<code>Regular expressions</code> are usually surrounded by <code>/</code> symbols.",
|
"<code>Regular expressions</code> are usually surrounded by <code>/</code> symbols.",
|
||||||
"Let's try selecting all the occurances of the word <code>and</code> in the string <code>George Boole and Alan Turing went to the shop and got some milk</code>. We can do this by replacing the <code>.+</code> part of our regular expression with the current <code>regular expression</code> with the word <code>and</code>."
|
"Let's try selecting all the occurrences of the word <code>and</code> in the string <code>George Boole and Alan Turing went to the shop and got some milk</code>. We can do this by replacing the <code>.+</code> part of our regular expression with the current <code>regular expression</code> with the word <code>and</code>."
|
||||||
],
|
],
|
||||||
"tests":[
|
"tests":[
|
||||||
"assert(test==2, 'Your <code>regular expression</code> should find two occurrences of the word <code>and</code>');",
|
"assert(test==2, 'Your <code>regular expression</code> should find two occurrences of the word <code>and</code>');",
|
||||||
@ -1040,7 +1040,7 @@
|
|||||||
],
|
],
|
||||||
"challengeSeed":[
|
"challengeSeed":[
|
||||||
"var test = (function() {",
|
"var test = (function() {",
|
||||||
" var testString = \"There's 3 cats but 4 dogs.\";",
|
" var testString = \"There are 3 cats but 4 dogs.\";",
|
||||||
"",
|
"",
|
||||||
" // Only change code below this line.",
|
" // Only change code below this line.",
|
||||||
"",
|
"",
|
||||||
@ -1093,12 +1093,12 @@
|
|||||||
"You can invert any match by using the uppercase version of the selector <code>\\s</code> versus <code>\\S</code> for example."
|
"You can invert any match by using the uppercase version of the selector <code>\\s</code> versus <code>\\S</code> for example."
|
||||||
],
|
],
|
||||||
"tests":[
|
"tests":[
|
||||||
"assert(test === 36, 'Your RegEx should have found seven spaces in the <code>testString</code>.');",
|
"assert(test === 49, 'Your RegEx should have found forty nine non-space characters in the <code>testString</code>.');",
|
||||||
"assert(editor.getValue().match(/\\/\\\\S\\/gi/gi), 'You should be using the following expression <code>/\\+S/gi</code> to find the spaces in the <code>testString</code>.');"
|
"assert(editor.getValue().match(/\\/\\\\S\\/gi/gi), 'You should be using the following expression <code>/\\S/gi</code> to find non-space characters in the <code>testString</code>.');"
|
||||||
],
|
],
|
||||||
"challengeSeed":[
|
"challengeSeed":[
|
||||||
"var test = (function(){",
|
"var test = (function(){",
|
||||||
" var testString = \"How many spaces are there in this sentence?\";",
|
" var testString = \"How many non-space characters are there in this sentence?\";",
|
||||||
"",
|
"",
|
||||||
" // Only change code below this line.",
|
" // Only change code below this line.",
|
||||||
"",
|
"",
|
||||||
|
@ -48,11 +48,11 @@
|
|||||||
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
|
"Here are the <a href='http://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> you must enable, and optional bonus user stories:",
|
||||||
"<span class='text-info'>User Story:</span> As a user, I can access all of the portfolio webpage's content just by scrolling.",
|
"<span class='text-info'>User Story:</span> As a user, I can access all of the portfolio webpage's content just by scrolling.",
|
||||||
"<span class='text-info'>User Story:</span> As a user, I can click different buttons that will take me to the portfolio creator's different social media pages.",
|
"<span class='text-info'>User Story:</span> As a user, I can click different buttons that will take me to the portfolio creator's different social media pages.",
|
||||||
"<span class='text-info'>User Story:</span> As a user, I can see thumbnail images of different projects the portfolio creator has built (if you don't haven't built any websites before, use placeholders.)",
|
"<span class='text-info'>User Story:</span> As a user, I can see thumbnail images of different projects the portfolio creator has built (if you haven't built any websites before, use placeholders.)",
|
||||||
"<span class='text-info'>Bonus User Story:</span> As a user, I navigate to different sections of the webpage by clicking buttons in the navigation.",
|
"<span class='text-info'>Bonus User Story:</span> As a user, I navigate to different sections of the webpage by clicking buttons in the navigation.",
|
||||||
"Don't worry if you don't have anything to showcase on your portfolio yet - you will build several several apps on the next few CodePen challenges, and can come back and update your portfolio later.",
|
"Don't worry if you don't have anything to showcase on your portfolio yet - you will build several several apps on the next few CodePen challenges, and can come back and update your portfolio later.",
|
||||||
"There are many great portfolio templates out there, but for this challenge, you'll need to build a portfolio page yourself. Using Bootstrap will make this much easier for you.",
|
"There are many great portfolio templates out there, but for this challenge, you'll need to build a portfolio page yourself. Using Bootstrap will make this much easier for you.",
|
||||||
"Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jquery, you will need to target invisible anchor elements like this one: <code><a target='_blank'&rt;</a>.",
|
"Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jquery, you will need to target invisible anchor elements like this one: <code><a target='_blank'></a></code>.",
|
||||||
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
|
"Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>Read-Search-Ask</a> if you get stuck.",
|
||||||
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
|
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.",
|
||||||
"If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
|
"If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.<br><br><a class='btn btn-primary btn-block' href='https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20%0A%20%23LearnToCode%20%23JavaScript' target='_blank'>Click here then add your link to your tweet's text</a>"
|
||||||
|
@ -133,7 +133,7 @@
|
|||||||
"",
|
"",
|
||||||
" <p>Click here for <a href=\"#\">cat photos</a>.</p>",
|
" <p>Click here for <a href=\"#\">cat photos</a>.</p>",
|
||||||
"",
|
"",
|
||||||
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\"></a>",
|
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"http://bit.ly/fcc-relaxing-cat\"></a>",
|
||||||
"",
|
"",
|
||||||
" <p>Things cats love:</p>",
|
" <p>Things cats love:</p>",
|
||||||
" <ul>",
|
" <ul>",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -263,7 +263,7 @@
|
|||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"assert(editor.match(/\\$\\(.*button/g), 'Use the <code>$(\"button\")</code> selector.')",
|
"assert(editor.match(/\\$\\(.*button/g), 'Use the <code>$(\"button\")</code> selector.')",
|
||||||
"assert(editor.match(/\\$\\(.*.btn/g), 'Use the <code>$(\".btn\")</code> selector.')",
|
"assert(editor.match(/\\$\\(.*\\.btn/g), 'Use the <code>$(\".btn\")</code> selector.')",
|
||||||
"assert(editor.match(/\\$\\(.*#target1/g), 'Use the <code>$(\"#target1\")</code> selector.')",
|
"assert(editor.match(/\\$\\(.*#target1/g), 'Use the <code>$(\"#target1\")</code> selector.')",
|
||||||
"assert(editor.match(/addClass/g) && editor.match(/addClass/g).length > 2, 'Only add one class with each of your three selectors.')",
|
"assert(editor.match(/addClass/g) && editor.match(/addClass/g).length > 2, 'Only add one class with each of your three selectors.')",
|
||||||
"assert($(\"#target1\").hasClass(\"animated\") && $(\"#target1\").hasClass(\"shake\") && $(\"#target1\").hasClass(\"btn-primary\"), 'Your <code>#target1</code> element should have the classes <code>animated</code>‚ <code>shake</code> and <code>btn-primary</code>.')",
|
"assert($(\"#target1\").hasClass(\"animated\") && $(\"#target1\").hasClass(\"shake\") && $(\"#target1\").hasClass(\"btn-primary\"), 'Your <code>#target1</code> element should have the classes <code>animated</code>‚ <code>shake</code> and <code>btn-primary</code>.')",
|
||||||
@ -314,7 +314,7 @@
|
|||||||
],
|
],
|
||||||
"tests": [
|
"tests": [
|
||||||
"assert($(\".btn-default\").length === 0, 'Remove the <code>btn-default</code> class from all of your <code>button</code> elements.')",
|
"assert($(\".btn-default\").length === 0, 'Remove the <code>btn-default</code> class from all of your <code>button</code> elements.')",
|
||||||
"assert(editor.match(/btn btn-default/g), 'Only use jQuery to add these classes to the element.')"
|
"assert(editor.match(/btn btn-default/g), 'Only use jQuery to remove this class from the element.')"
|
||||||
],
|
],
|
||||||
"challengeSeed": [
|
"challengeSeed": [
|
||||||
"fccss",
|
"fccss",
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
"difficulty":0,
|
"difficulty":0,
|
||||||
"description":[
|
"description":[
|
||||||
"Before we dive into Object Oriented Programming, let's revisit JavaScript objects.",
|
"Before we dive into Object Oriented Programming, let's revisit JavaScript objects.",
|
||||||
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engine</code> and <code>seats</code> attribute and set them to numbers."
|
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers."
|
||||||
],
|
],
|
||||||
"tests":[
|
"tests":[
|
||||||
"assert(typeof(motorBike.engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');",
|
"assert(typeof(motorBike.engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');",
|
||||||
@ -54,7 +54,7 @@
|
|||||||
"difficulty":0,
|
"difficulty":0,
|
||||||
"description":[
|
"description":[
|
||||||
"We are also able to create objects using <code>constructor</code> functions.",
|
"We are also able to create objects using <code>constructor</code> functions.",
|
||||||
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engine</code> and <code>seats</code> attribute and set them to numbers."
|
"Give your <code>motorBike</code> object a <code>wheels</code>, <code>engines</code> and <code>seats</code> attribute and set them to numbers."
|
||||||
],
|
],
|
||||||
"tests":[
|
"tests":[
|
||||||
"assert(typeof((new MotorBike()).engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');",
|
"assert(typeof((new MotorBike()).engines) === 'number', '<code>engines</code> should be have a <code>engines</code> attribute set to a number.');",
|
||||||
@ -62,7 +62,7 @@
|
|||||||
"assert(typeof((new MotorBike()).seats) === 'number', '<code>seats</code> should be have a <code>engines</code> attribute set to a number.');"
|
"assert(typeof((new MotorBike()).seats) === 'number', '<code>seats</code> should be have a <code>engines</code> attribute set to a number.');"
|
||||||
],
|
],
|
||||||
"challengeSeed":[
|
"challengeSeed":[
|
||||||
"// Let's add the properties engine and seats to the car in the same way that the property wheels has been added below. They should both be numbers.",
|
"// Let's add the properties engines and seats to the car in the same way that the property wheels has been added below. They should both be numbers.",
|
||||||
"var Car = function() {",
|
"var Car = function() {",
|
||||||
" this.wheels = 4;",
|
" this.wheels = 4;",
|
||||||
" this.engines = 1;",
|
" this.engines = 1;",
|
||||||
|
@ -63,6 +63,7 @@ module.exports = function(app) {
|
|||||||
const findChallenge$ = observeMethod(Challenge, 'find');
|
const findChallenge$ = observeMethod(Challenge, 'find');
|
||||||
// create a stream of all the challenges
|
// create a stream of all the challenges
|
||||||
const challenge$ = findChallenge$(challengesQuery)
|
const challenge$ = findChallenge$(challengesQuery)
|
||||||
|
.doOnNext(() => debug('query challenges'))
|
||||||
.flatMap(challenges => Observable.from(challenges))
|
.flatMap(challenges => Observable.from(challenges))
|
||||||
.shareReplay();
|
.shareReplay();
|
||||||
|
|
||||||
@ -128,18 +129,12 @@ module.exports = function(app) {
|
|||||||
app.use(router);
|
app.use(router);
|
||||||
|
|
||||||
function returnNextChallenge(req, res, next) {
|
function returnNextChallenge(req, res, next) {
|
||||||
|
|
||||||
// find the user's current challenge and block
|
|
||||||
// look in that block and find the index of their current challenge
|
|
||||||
// if index + 1 < block.challenges.length
|
|
||||||
// serve index + 1 challenge
|
|
||||||
// otherwise increment block key and serve the first challenge in that block
|
|
||||||
// unless the next block is undefined, which means no next block
|
|
||||||
let nextChallengeName = firstChallenge;
|
let nextChallengeName = firstChallenge;
|
||||||
|
|
||||||
const challengeId = req.user.currentChallenge ?
|
const challengeId = req.user.currentChallenge ?
|
||||||
req.user.currentChallenge.challengeId :
|
req.user.currentChallenge.challengeId :
|
||||||
'bd7123c8c441eddfaeb5bdef';
|
'bd7123c8c441eddfaeb5bdef';
|
||||||
|
|
||||||
// find challenge
|
// find challenge
|
||||||
return challenge$
|
return challenge$
|
||||||
.map(challenge => challenge.toJSON())
|
.map(challenge => challenge.toJSON())
|
||||||
|
@ -4,24 +4,36 @@ var _ = require('lodash'),
|
|||||||
debug = require('debug')('freecc:cntr:userController');
|
debug = require('debug')('freecc:cntr:userController');
|
||||||
|
|
||||||
|
|
||||||
|
const daysBetween = 1.5;
|
||||||
|
|
||||||
function calcCurrentStreak(cals) {
|
function calcCurrentStreak(cals) {
|
||||||
const revCals = cals.slice().reverse();
|
const revCals = cals.slice().reverse();
|
||||||
let streakBroken = false;
|
let streakBroken = false;
|
||||||
return revCals
|
const lastDayInStreak = revCals
|
||||||
.reduce((current, cal, index) => {
|
.reduce((current, cal, index) => {
|
||||||
// if streak not borken and diff between this cal and the call after it
|
debug('cal', cal);
|
||||||
// is equal to zero
|
debug('broken', streakBroken);
|
||||||
// moment.diff will return the days between rounded down
|
const before = revCals[index === 0 ? 0 : index - 1];
|
||||||
if (
|
if (
|
||||||
!streakBroken &&
|
!streakBroken &&
|
||||||
moment(revCals[index === 0 ? 0 : index - 1]).diff(cal, 'days') === 0
|
moment(before).diff(cal, 'days', true) < daysBetween
|
||||||
) {
|
) {
|
||||||
return current + 1;
|
return index;
|
||||||
}
|
}
|
||||||
return 1;
|
streakBroken = true;
|
||||||
}, 1);
|
return current;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const lastTimestamp = revCals[lastDayInStreak];
|
||||||
|
return Math.ceil(moment().diff(lastTimestamp, 'days', true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(berks): calc longest streak
|
||||||
|
/*
|
||||||
|
function longestStreak(cals) {
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
module.exports = function(app) {
|
module.exports = function(app) {
|
||||||
var router = app.loopback.Router();
|
var router = app.loopback.Router();
|
||||||
var User = app.models.User;
|
var User = app.models.User;
|
||||||
@ -129,9 +141,7 @@ module.exports = function(app) {
|
|||||||
objOrNum :
|
objOrNum :
|
||||||
objOrNum.timestamp;
|
objOrNum.timestamp;
|
||||||
})
|
})
|
||||||
.map(time => {
|
.sort();
|
||||||
return moment(time).format('YYYY-MM-DD');
|
|
||||||
});
|
|
||||||
|
|
||||||
user.currentStreak = calcCurrentStreak(cals);
|
user.currentStreak = calcCurrentStreak(cals);
|
||||||
|
|
||||||
@ -146,6 +156,9 @@ module.exports = function(app) {
|
|||||||
objOrNum :
|
objOrNum :
|
||||||
objOrNum.timestamp;
|
objOrNum.timestamp;
|
||||||
})
|
})
|
||||||
|
.filter((timestamp) => {
|
||||||
|
return !!timestamp;
|
||||||
|
})
|
||||||
.reduce((data, timeStamp) => {
|
.reduce((data, timeStamp) => {
|
||||||
data[(timeStamp / 1000)] = 1;
|
data[(timeStamp / 1000)] = 1;
|
||||||
return data;
|
return data;
|
||||||
|
@ -2,6 +2,14 @@
|
|||||||
"initial:before": {
|
"initial:before": {
|
||||||
"loopback#favicon": {
|
"loopback#favicon": {
|
||||||
"params": "$!../public/favicon.ico"
|
"params": "$!../public/favicon.ico"
|
||||||
|
},
|
||||||
|
"loopback#static": {
|
||||||
|
"params": [
|
||||||
|
"$!../public",
|
||||||
|
{
|
||||||
|
"maxAge": "86400000"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"initial": {
|
"initial": {
|
||||||
@ -42,14 +50,6 @@
|
|||||||
"routes": {
|
"routes": {
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"loopback#static": {
|
|
||||||
"params": [
|
|
||||||
"$!../public",
|
|
||||||
{
|
|
||||||
"maxAge": "86400000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"final": {
|
"final": {
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,7 @@ script.
|
|||||||
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js")
|
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js")
|
||||||
script.
|
script.
|
||||||
if (typeof window.angular === 'undefined') {
|
if (typeof window.angular === 'undefined') {
|
||||||
document.write('<script src="/bower_components/angular/angular.min.js"><\/script>')
|
document.write('<script src="/bower_components/angular/angular.min.js"><\/script>');
|
||||||
}
|
}
|
||||||
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap.min.js")
|
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap.min.js")
|
||||||
script.
|
script.
|
||||||
|
Reference in New Issue
Block a user