From a3e50050587c6585a397483ec9373d27a9ede0f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Djordje=20Lacmanovi=C4=87?= <djordje.lacmanovic@gmail.com>
Date: Tue, 4 Aug 2015 16:51:10 +0200
Subject: [PATCH 01/47] fixed issue #1511 - now checking for words longer than
 9 chars

closes #1511
---
 seed/challenges/basic-bonfires.json | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/seed/challenges/basic-bonfires.json b/seed/challenges/basic-bonfires.json
index 8d97403..8fb64bc 100644
--- a/seed/challenges/basic-bonfires.json
+++ b/seed/challenges/basic-bonfires.json
@@ -231,7 +231,8 @@
         "expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.equal(6);",
         "expect(findLongestWord('May the force be with you')).to.equal(5);",
         "expect(findLongestWord('Google do a barrel roll')).to.equal(6);",
-        "expect(findLongestWord('What is the average airspeed velocity of an unladen swallow')).to.equal(8);"
+        "expect(findLongestWord('What is the average airspeed velocity of an unladen swallow')).to.equal(8);",
+        "expect(findLongestWord('What if we try a super-long word such as otorhinolaryngology')).to.equal(19);"
       ],
       "MDNlinks": [
         "String.split()",

From 064fc68b304cb3ae44005da008313e91a760743e Mon Sep 17 00:00:00 2001
From: Ben <ben.f.linn@gmail.com>
Date: Tue, 4 Aug 2015 11:04:40 -0500
Subject: [PATCH 02/47] Update bootstrap.json

fixed line 1886, changed col-xs-12 to col-xs-6
"assert($('.col-xs-6').children('h4') && $('.col-xs-6').children('h4').length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class=\\'col-xs-6\\'&#62;</code> elements.');",
---
 seed/challenges/bootstrap.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index c0b4014..68d6c70 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -1883,7 +1883,7 @@
         "Above your right-well, inside its \"col-xs-6\" <code>div</code> element, add a <code>h4</code> element with the text \"#right-well\"."
       ],
       "tests": [
-        "assert($('.col-xs-12').children('h4') && $('.col-xs-12').children('h4').length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class=\\'col-xs-6\\'&#62;</code> elements.');",
+        "assert($('.col-xs-6').children('h4') && $('.col-xs-6').children('h4').length > 1, 'Add an <code>h4</code> element to each of your <code>&#60;div class=\\'col-xs-6\\'&#62;</code> elements.');",
         "assert(new RegExp('#left-well','gi').test($('h4').text()), 'One <code>h4</code> element should have the text \"#left-well\".');",
         "assert(new RegExp('#right-well','gi').test($('h4').text()), 'One <code>h4</code> element should have the text \"#right-well\".');"
       ],

From 52300b9648ce9267f94b6f8f0975ccdfc6e2ce81 Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Thu, 6 Aug 2015 22:07:52 +0200
Subject: [PATCH 03/47] Changed test order & added <code> in 'img to link'

---
 seed/challenges/html5-and-css.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/html5-and-css.json b/seed/challenges/html5-and-css.json
index f4a1158..cad97a4 100644
--- a/seed/challenges/html5-and-css.json
+++ b/seed/challenges/html5-and-css.json
@@ -1259,8 +1259,8 @@
         "Once you've done this, hover over your image with your cursor. Your cursor's normal pointer should become the link clicking pointer. The photo is now a link."
       ],
       "tests": [
+        "assert($('a').children('img').length > 0, 'Nest your <code>img</code> element within an <code>a</code> element.')",
         "assert(new RegExp('#').test($('a').children('img').parent().attr('href')), 'Your <code>a</code> element should be a dead link with a <code>href</code> attribute set to \"#\".')",
-        "assert($('a').children('img').length > 0, 'Nest your image element within an <code>a</code> element.')",
         "assert(editor.match(/<\\/a>/g) && editor.match(/<a/g) && editor.match(/<\\/a>/g).length === editor.match(/<a/g).length, 'Make sure each of your <code>a</code> elements has a closing tag.')"
       ],
       "challengeSeed": [

From b2d714112fc9f77c90622757569a36cd8815779e Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Thu, 6 Aug 2015 22:22:58 +0200
Subject: [PATCH 04/47] Updated test case comment in 'fluid containers'

---
 seed/challenges/bootstrap.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index def874e..c921a15 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -15,7 +15,7 @@
         "To get started, we should nest all of our HTML in a <code>div</code> element with the class \"container-fluid\"."
       ],
       "tests": [
-        "assert($('div').hasClass('container-fluid'), 'Your <code>div</code> element should have the class \"row\"')",
+        "assert($('div').hasClass('container-fluid'), 'Your <code>div</code> element should have the class \"container-fluid\"')",
         "assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure each of your <code>div</code> elements has a closing tag.')"
       ],
       "challengeSeed": [

From fb2599b8fe63e8215adb5764864bfbed39863c4e Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Thu, 6 Aug 2015 22:27:01 +0200
Subject: [PATCH 05/47] Grammatical error in 'Use Hex Code for Specific Colors'

---
 seed/challenges/html5-and-css.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/html5-and-css.json b/seed/challenges/html5-and-css.json
index f4a1158..a08b900 100644
--- a/seed/challenges/html5-and-css.json
+++ b/seed/challenges/html5-and-css.json
@@ -3402,7 +3402,7 @@
       "dashedName": "waypoint-use-hex-code-for-specific-colors",
       "difficulty": 1.54,
       "description": [
-        "Did you know there other ways to represent colors in CSS? One of these ways is called hexadecimal code, or \"hex code\" for short.",
+        "Did you know there are other ways to represent colors in CSS? One of these ways is called hexadecimal code, or \"hex code\" for short.",
         "\"Decimal\" means the numbers zero through nine - the numbers that people use in everyday life. \"Hexadecimal\" includes these 10 numbers, plus the letters A, B, C, D, E and F. This means that Hexidecimal has a total of 16 possible values, instead of the 10 possible values that our normal base-10 number system gives us.",
         "With CSS, we use 6 hexidecimal number to represent colors. For example, <code>#000000</code> is the lowest possible value, and it represents the color black.",
         "Replace the word \"black\" in our <code>body</code> element's background-color with its \"hex code\" representation, <code>#000000</code>. "

From 42321f5cef01e4795effda07e7bb8200401b35de Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Thu, 6 Aug 2015 22:41:45 +0200
Subject: [PATCH 06/47] Wrong element in jQuery targeting waypoint

---
 seed/challenges/jquery-ajax-and-json.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/jquery-ajax-and-json.json b/seed/challenges/jquery-ajax-and-json.json
index dad707f..6c1fe00 100644
--- a/seed/challenges/jquery-ajax-and-json.json
+++ b/seed/challenges/jquery-ajax-and-json.json
@@ -60,7 +60,7 @@
         "For example, let's make all of your <code>button</code> elements bounce. Just add this code inside your \"document ready function\": <code>$('button').addClass('animated bounce')</code>."
       ],
       "tests": [
-        "assert($('button').hasClass('animated') && $('button').hasClass('bounce'), 'Use the jQuery <code>addClass()</code> function to give the classes \"animated\" and \"bounce\" to your <code>img</code> element.')",
+        "assert($('button').hasClass('animated') && $('button').hasClass('bounce'), 'Use the jQuery <code>addClass()</code> function to give the classes \"animated\" and \"bounce\" to your <code>button</code> element.')",
         "assert(!editor.match(/class.*animated/g), 'Only use jQuery to add these classes to the element.')"
       ],
       "challengeSeed": [

From e7c8589d0820a9fad611224932604a35be7f1d69 Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Sat, 8 Aug 2015 02:38:16 +0200
Subject: [PATCH 07/47] Everything is horrible

---
 seed/challenges/advanced-bonfires.json             |  11 +-
 seed/challenges/angularjs.json                     |  17 +-
 .../automated-testing-and-debugging.json           |   2 +-
 seed/challenges/basejumps.json                     |  20 +-
 seed/challenges/basic-bonfires.json                |  56 ++----
 seed/challenges/basic-javascript.json              | 124 ++++--------
 seed/challenges/basic-ziplines.json                |  20 +-
 seed/challenges/bootstrap.json                     |  92 +++------
 seed/challenges/expert-bonfires.json               |  20 +-
 seed/challenges/get-set-for-free-code-camp.json    |  29 +--
 seed/challenges/git.json                           |   5 +-
 seed/challenges/hikes.json                         |  65 +++----
 seed/challenges/html5-and-css.json                 | 210 +++++++--------------
 seed/challenges/intermediate-bonfires.json         |  63 +++----
 seed/challenges/intermediate-ziplines.json         |  17 +-
 seed/challenges/jquery-ajax-and-json.json          |  65 ++-----
 seed/challenges/json-apis-and-ajax.json            |   3 +-
 seed/challenges/mongodb.json                       |   5 +-
 seed/challenges/nodejs-and-expressjs.json          |  17 +-
 ...object-oriented-and-functional-programming.json |  11 +-
 seed/index.js                                      |   4 +-
 server/utils/index.js                              |   4 +-
 22 files changed, 290 insertions(+), 570 deletions(-)

diff --git a/seed/challenges/advanced-bonfires.json b/seed/challenges/advanced-bonfires.json
index c071bfb..86b0c3f 100644
--- a/seed/challenges/advanced-bonfires.json
+++ b/seed/challenges/advanced-bonfires.json
@@ -1,11 +1,10 @@
 {
-  "name": "Advanced Algorithm Scripting",
+  "title": "Advanced Algorithm Scripting",
   "order": 0.011,
   "challenges": [
     {
       "id": "a2f1d72d9b908d0bd72bb9f6",
-      "name": "Bonfire: Make a Person",
-      "dashedName": "bonfire-make-a-person",
+      "title": "Bonfire: Make a Person",
       "difficulty": "3.01",
       "description": [
         "Fill in the object constructor with the methods specified in the tests.",
@@ -56,8 +55,7 @@
     },
     {
       "id": "af4afb223120f7348cdfc9fd",
-      "name": "Bonfire: Map the Debris",
-      "dashedName": "bonfire-map-the-debris",
+      "title": "Bonfire: Map the Debris",
       "difficulty": "3.02",
       "description": [
         "Return a new array that transforms the element's average altitude into their orbital periods.",
@@ -97,8 +95,7 @@
     },
     {
       "id": "a3f503de51cfab748ff001aa",
-      "name": "Bonfire: Pairwise",
-      "dashedName": "bonfire-pairwise",
+      "title": "Bonfire: Pairwise",
       "difficulty": "3.03",
       "description": [
         "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
diff --git a/seed/challenges/angularjs.json b/seed/challenges/angularjs.json
index 910a744..48ad048 100644
--- a/seed/challenges/angularjs.json
+++ b/seed/challenges/angularjs.json
@@ -1,11 +1,10 @@
 {
-  "name": "AngularJS",
+  "title": "AngularJS",
   "order": 0.017,
   "challenges": [
     {
       "id": "bd7154d8c441eddfaeb5bdef",
-      "name": "Waypoint: Get Started with Angular.js",
-      "dashedName": "waypoint-get-started-with-angularjs",
+      "title": "Waypoint: Get Started with Angular.js",
       "difficulty": 0.34,
       "challengeSeed": ["114684726"],
       "description": [
@@ -28,8 +27,7 @@
     },
     {
       "id": "bd7155d8c441eddfaeb5bdef",
-      "name": "Waypoint: Apply Angular.js Directives",
-      "dashedName": "waypoint-apply-angularjs-directives",
+      "title": "Waypoint: Apply Angular.js Directives",
       "difficulty": 0.35,
       "challengeSeed": ["114684727"],
       "description": [
@@ -52,8 +50,7 @@
     },
     {
       "id": "bd7156d8c441eddfaeb5bdef",
-      "name": "Waypoint: Power Forms with Angular.js",
-      "dashedName": "waypoint-power-forms-with-angularjs",
+      "title": "Waypoint: Power Forms with Angular.js",
       "difficulty": 0.36,
       "challengeSeed": ["114684729"],
       "description": [
@@ -76,8 +73,7 @@
     },
     {
       "id": "bd7157d8c441eddfaeb5bdef",
-      "name": "Waypoint: Customize Angular.js Directives",
-      "dashedName": "waypoint-customize-angularjs-directives",
+      "title": "Waypoint: Customize Angular.js Directives",
       "difficulty": 0.37,
       "challengeSeed": ["114685062"],
       "description": [
@@ -99,8 +95,7 @@
     },
     {
       "id": "bd7158d8c441eddfaeb5bdef",
-      "name": "Waypoint: Create Angular.js Services",
-      "dashedName": "waypoint-create-angularjs-services",
+      "title": "Waypoint: Create Angular.js Services",
       "difficulty": 0.38,
       "challengeSeed": ["114685060"],
       "description": [
diff --git a/seed/challenges/automated-testing-and-debugging.json b/seed/challenges/automated-testing-and-debugging.json
index 2755fd7..00181f0 100644
--- a/seed/challenges/automated-testing-and-debugging.json
+++ b/seed/challenges/automated-testing-and-debugging.json
@@ -1,5 +1,5 @@
 {
-  "name": "Automated Testing and Debugging - Coming Soon",
+  "title": "Automated Testing and Debugging - Coming Soon",
   "order": 0.012,
   "challenges": [
   ]
diff --git a/seed/challenges/basejumps.json b/seed/challenges/basejumps.json
index 137e679..67c9023 100644
--- a/seed/challenges/basejumps.json
+++ b/seed/challenges/basejumps.json
@@ -1,11 +1,10 @@
 {
-  "name": "Full Stack JavaScript Projects",
+  "title": "Full Stack JavaScript Projects",
   "order": 0.019,
   "challenges": [
     {
       "id": "bd7158d8c443eddfaeb5bcef",
-      "name": "Waypoint: Get Set for Basejumps",
-      "dashedName": "waypoint-get-set-for-basejumps",
+      "title": "Waypoint: Get Set for Basejumps",
       "difficulty": 2.00,
       "challengeSeed": ["128451852"],
       "description": [
@@ -65,8 +64,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bdef",
-      "name": "Basejump: Build a Voting App",
-      "dashedName": "basejump-build-a-voting-app",
+      "title": "Basejump: Build a Voting App",
       "difficulty": 2.01,
       "challengeSeed": ["133315786"],
       "description": [
@@ -102,8 +100,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bdff",
-      "name": "Basejump: Build a Nightlife Coordination App",
-      "dashedName": "basejump-build-a-nightlife-coordination-app",
+      "title": "Basejump: Build a Nightlife Coordination App",
       "difficulty": 2.02,
       "challengeSeed": ["133315781"],
       "description": [
@@ -136,8 +133,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bd0e",
-      "name": "Basejump: Chart the Stock Market",
-      "dashedName": "basejump-chart-the-stock-market",
+      "title": "Basejump: Chart the Stock Market",
       "difficulty": 2.03,
       "challengeSeed": ["133315787"],
       "description": [
@@ -169,8 +165,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bd0f",
-      "name": "Basejump: Manage a Book Trading Club",
-      "dashedName": "basejump-manage-a-book-trading-club",
+      "title": "Basejump: Manage a Book Trading Club",
       "difficulty": 2.04,
       "challengeSeed": ["133316032"],
       "description": [
@@ -202,8 +197,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bdee",
-      "name": "Basejump: Build a Pinterest Clone",
-      "dashedName": "basejump-build-a-pinterest-clone",
+      "title": "Basejump: Build a Pinterest Clone",
       "difficulty": 2.05,
       "challengeSeed": ["133315784"],
       "description": [
diff --git a/seed/challenges/basic-bonfires.json b/seed/challenges/basic-bonfires.json
index af9c9a3..4c2c7d8 100644
--- a/seed/challenges/basic-bonfires.json
+++ b/seed/challenges/basic-bonfires.json
@@ -1,11 +1,10 @@
 {
-  "name": "Basic Algorithm Scripting",
+  "title": "Basic Algorithm Scripting",
   "order": 0.006,
   "challenges": [
     {
       "id": "bd7139d8c441eddfaeb5bdef",
-      "name": "Waypoint: Pair Program on Bonfires",
-      "dashedName": "waypoint-pair-program-on-bonfires",
+      "title": "Waypoint: Pair Program on Bonfires",
       "difficulty": 0.44,
       "challengeSeed": [
         "119657641"
@@ -44,8 +43,7 @@
     },
     {
       "id": "ad7123c8c441eddfaeb5bdef",
-      "name": "Bonfire: Meet Bonfire",
-      "dashedName": "bonfire-meet-bonfire",
+      "title": "Bonfire: Meet Bonfire",
       "difficulty": "0",
       "description": [
         "Your goal is to fix the failing test.",
@@ -83,8 +81,7 @@
     },
     {
       "id": "a202eed8fc186c8434cb6d61",
-      "name": "Bonfire: Reverse a String",
-      "dashedName": "bonfire-reverse-a-string",
+      "title": "Bonfire: Reverse a String",
       "difficulty": "1.01",
       "tests": [
         "expect(reverseString('hello')).to.be.a('String');",
@@ -125,8 +122,7 @@
     },
     {
       "id": "a302f7aae1aa3152a5b413bc",
-      "name": "Bonfire: Factorialize a Number",
-      "dashedName": "bonfire-factorialize-a-number",
+      "title": "Bonfire: Factorialize a Number",
       "tests": [
         "expect(factorialize(5)).to.be.a(\"Number\");",
         "expect(factorialize(5)).to.equal(120);",
@@ -165,8 +161,7 @@
     },
     {
       "id": "aaa48de84e1ecc7c742e1124",
-      "name": "Bonfire: Check for Palindromes",
-      "dashedName": "bonfire-check-for-palindromes",
+      "title": "Bonfire: Check for Palindromes",
       "difficulty": "1.03",
       "description": [
         "Return true if the given string is a palindrome. Otherwise, return false.",
@@ -213,8 +208,7 @@
     },
     {
       "id": "a26cbbe9ad8655a977e1ceb5",
-      "name": "Bonfire: Find the Longest Word in a String",
-      "dashedName": "bonfire-find-the-longest-word-in-a-string",
+      "title": "Bonfire: Find the Longest Word in a String",
       "difficulty": "1.04",
       "description": [
         "Return the length of the longest word in the provided sentence.",
@@ -253,8 +247,7 @@
     },
     {
       "id": "ab6137d4e35944e21037b769",
-      "name": "Bonfire: Title Case a Sentence",
-      "dashedName": "bonfire-title-case-a-sentence",
+      "title": "Bonfire: Title Case a Sentence",
       "difficulty": "1.05",
       "description": [
         "Return the provided string with the first letter of each word capitalized.",
@@ -291,8 +284,7 @@
     },
     {
       "id": "a789b3483989747d63b0e427",
-      "name": "Bonfire: Return Largest Numbers in Arrays",
-      "dashedName": "bonfire-return-largest-numbers-in-arrays",
+      "title": "Bonfire: Return Largest Numbers in Arrays",
       "difficulty": "1.06",
       "description": [
         "Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.",
@@ -330,8 +322,7 @@
     },
     {
       "id": "acda2fb1324d9b0fa741e6b5",
-      "name": "Bonfire: Confirm the Ending",
-      "dashedName": "bonfire-confirm-the-ending",
+      "title": "Bonfire: Confirm the Ending",
       "difficulty": "1.07",
       "description": [
         "Check if a string (first argument) ends with the given target string (second argument).",
@@ -370,8 +361,7 @@
     },
     {
       "id": "afcc8d540bea9ea2669306b6",
-      "name": "Bonfire: Repeat a string repeat a string",
-      "dashedName": "bonfire-repeat-a-string-repeat-a-string",
+      "title": "Bonfire: 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.",
@@ -407,8 +397,7 @@
     },
     {
       "id": "ac6993d51946422351508a41",
-      "name": "Bonfire: Truncate a string",
-      "dashedName": "bonfire-truncate-a-string",
+      "title": "Bonfire: 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.",
@@ -446,8 +435,7 @@
     },
     {
       "id": "a9bd25c716030ec90084d8a1",
-      "name": "Bonfire: Chunky Monkey",
-      "dashedName": "bonfire-chunky-monkey",
+      "title": "Bonfire: 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.",
@@ -484,8 +472,7 @@
     },
     {
       "id": "ab31c21b530c0dafa9e241ee",
-      "name": "Bonfire: Slasher Flick",
-      "dashedName": "bonfire-slasher-flick",
+      "title": "Bonfire: Slasher Flick",
       "difficulty": "1.11",
       "description": [
         "Return the remaining elements of an array after chopping off n elements from the head.",
@@ -522,8 +509,7 @@
     },
     {
       "id": "af2170cad53daa0770fabdea",
-      "name": "Bonfire: Mutations",
-      "dashedName": "bonfire-mutations",
+      "title": "Bonfire: Mutations",
       "difficulty": "1.12",
       "description": [
         "Return true if the string in the first element of the array contains all of the letters of the string in the second element of the array.",
@@ -565,8 +551,7 @@
     },
     {
       "id": "adf08ec01beb4f99fc7a68f2",
-      "name": "Bonfire: Falsey Bouncer",
-      "dashedName": "bonfire-falsey-bouncer",
+      "title": "Bonfire: Falsey Bouncer",
       "difficulty": "1.50",
       "description": [
         "Remove all falsey values from an array.",
@@ -604,8 +589,7 @@
     },
     {
       "id": "a8e512fbe388ac2f9198f0fa",
-      "name": "Bonfire: Where art thou",
-      "dashedName": "bonfire-where-art-thou",
+      "title": "Bonfire: Where art thou",
       "difficulty": "1.55",
       "description": [
         "Make a function that looks through an array (first argument) and returns an array of all objects that have equivalent property values (second argument).",
@@ -643,8 +627,7 @@
     },
     {
       "id": "a39963a4c10bc8b4d4f06d7e",
-      "name": "Bonfire: Seek and Destroy",
-      "dashedName": "bonfire-seek-and-destroy",
+      "title": "Bonfire: Seek and Destroy",
       "difficulty": "1.60",
       "description": [
         "You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.",
@@ -683,8 +666,7 @@
     },
     {
       "id": "a24c1a4622e3c05097f71d67",
-      "name": "Bonfire: Where do I belong",
-      "dashedName": "bonfire-where-do-i-belong",
+      "title": "Bonfire: 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).",
diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index b8e088a..4566d48 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -1,11 +1,10 @@
 {
-  "name": "Basic JavaScript",
+  "title": "Basic JavaScript",
   "order": 0.005,
   "challenges": [
     {
       "id":"bd7123c9c441eddfaeb4bdef",
-      "name": "Waypoint: Comment your JavaScript Code",
-      "dashedName": "waypoint-comment-your-javascript-code",
+      "title": "Waypoint: Comment your JavaScript Code",
       "difficulty":"9.98",
       "description":[
         "A comment is a very useful line of code that is not actually ran by the machine executing it. With this property comments are the perfect way of creating notes to yourself or anyone else who reads your code describing what the code does",
@@ -23,14 +22,12 @@
         "assert(editor.getValue().match(/(\\/\\/)...../g), 'Make sure that there is at least one \\/\\/ style comment with at least five letters in it');"
       ],
       "challengeSeed":[
-
       ],
       "challengeType": 1
     },
     {
       "id": "bd7123c9c441eddfaeb5bdef",
-      "name": "Waypoint: Understand Boolean Values",
-      "dashedName": "waypoint-understand-boolean-values",
+      "title": "Waypoint: Understand Boolean Values",
       "difficulty": "9.98001",
       "description": [
         "Return true",
@@ -55,8 +52,7 @@
     },
     {
       "id": "bd7123c9c443eddfaeb5bdef",
-      "name": "Waypoint: Declare JavaScript Variables",
-      "dashedName": "waypoint-declare-javascript-variables",
+      "title": "Waypoint: Declare JavaScript Variables",
       "difficulty": "9.9801",
       "description": [
         "Now, use the <code>var</code> keyword to create a <code>variable</code> called <code>myName</code>. Set its value to your name.",
@@ -82,8 +78,7 @@
     },
     {
       "id": "bd7123c9c444eddfaeb5bdef",
-      "name": "Waypoint: Declare String Variables",
-      "dashedName": "waypoint-declare-string-variables",
+      "title": "Waypoint: Declare String Variables",
       "difficulty": "9.9802",
       "description": [
         "Programs will almost always have several different variables that are used to keep track of several different pieces of data",
@@ -109,8 +104,7 @@
     },
     {
       "id": "bd7123c9c448eddfaeb5bdef",
-      "name": "Waypoint: Check the Length Property of a String Variable",
-      "dashedName": "waypoint-check-the-length-property-of-a-string-variable",
+      "title": "Waypoint: Check the Length Property of a String Variable",
       "difficulty": "9.9809",
       "description": [
         "Use the <code>.length</code> property to count the number of characters in the <code>lastNameLength</code> variable.",
@@ -142,8 +136,7 @@
     },
     {
       "id": "bd7123c9c549eddfaeb5bdef",
-      "name": "Waypoint: Use Bracket Notation to Find the First Character in a String",
-      "dashedName": "waypoint-use-bracket-notation-to-find-the-first-character-in-a-string",
+      "title": "Waypoint: Use Bracket Notation to Find the First Character in a String",
       "difficulty": "9.9810",
       "description": [
         "Use <code>bracket notation</code> to find the first character in a the <code>firstLetterOfLastName</code> variable.",
@@ -177,8 +170,7 @@
     },
     {
       "id": "bd7123c9c450eddfaeb5bdef",
-      "name": "Waypoint: Use Bracket Notation to Find the Nth Character in a String",
-      "dashedName": "waypoint-use-bracket-notation-to-find-the-nth-character-in-a-string",
+      "title": "Waypoint: Use Bracket Notation to Find the Nth Character in a String",
       "difficulty": "9.9811",
       "description": [
         "Just like the last lesson where we used <code>Bracket Notation</code>to access the first letter we can use the same method to get the letters ar other positions",
@@ -208,8 +200,7 @@
     },
     {
       "id": "bd7123c9c451eddfaeb5bdef",
-      "name": "Waypoint: Use Bracket Notation to Find the Last Character in a String",
-      "dashedName": "waypoint-use-bracket-notation-to-find-the-last-character-in-a-string",
+      "title": "Waypoint: Use Bracket Notation to Find the Last Character in a String",
       "difficulty": "9.9812",
       "description": [
         "Use <code>bracket notation</code> to find the last character in the <code>lastName</code> variable.",
@@ -238,8 +229,7 @@
     },
     {
       "id": "bd7123c9c452eddfaeb5bdef",
-      "name": "Waypoint: Use Bracket Notation to Find the Nth-to-Last Character in a String",
-      "dashedName": "waypoint-use-bracket-notation-to-find-the-nth-to-last-character-in-a-string",
+      "title": "Waypoint: Use Bracket Notation to Find the Nth-to-Last Character in a String",
       "difficulty": "9.9813",
       "description": [
         "Use <code>bracket notation</code> to find the second-to-last character in the <code>lastName</code> variable.",
@@ -268,8 +258,7 @@
     },
     {
       "id": "cf1111c1c11feddfaeb3bdef",
-      "name": "Waypoint: Add Two Numbers with JavaScript",
-      "dashedName": "waypoint-add-two-numbers-with-javascript",
+      "title": "Waypoint: Add Two Numbers with JavaScript",
       "difficulty": "9.98141",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -291,8 +280,7 @@
     },
     {
       "id": "cf1111c1c11feddfaeb4bdef",
-      "name": "Waypoint: Subtract One Number from Another with JavaScript",
-      "dashedName": "waypoint-subtract-one-number-from-another-with-javascript",
+      "title": "Waypoint: Subtract One Number from Another with JavaScript",
       "difficulty": "9.98142",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -314,8 +302,7 @@
     },
     {
       "id": "cf1231c1c11feddfaeb5bdef",
-      "name": "Waypoint: Multiply Two Numbers with JavaScript",
-      "dashedName": "waypoint-multiply-two-numbers-with-javascript",
+      "title": "Waypoint: Multiply Two Numbers with JavaScript",
       "difficulty": "9.98143",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -337,8 +324,7 @@
     },
     {
       "id": "cf1111c1c11feddfaeb6bdef",
-      "name": "Waypoint: Divide One Number by Another with JavaScript",
-      "dashedName": "waypoint-divide-one-number-by-another-with-javascript",
+      "title": "Waypoint: Divide One Number by Another with JavaScript",
       "difficulty": "9.9814",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -360,8 +346,7 @@
     },
     {
       "id": "cf1391c1c11feddfaeb4bdef",
-      "name": "Waypoint: Create Decimal Numbers with JavaScript",
-      "dashedName": "waypoint-create-decimal-numbers-with-javascript",
+      "title": "Waypoint: Create Decimal Numbers with JavaScript",
       "difficulty": "9.9815",
       "description": [
         "in JavaScript we can can work with decimal numbers",
@@ -383,8 +368,7 @@
     },
     {
       "id": "bd7993c9c69feddfaeb7bdef",
-      "name": "Waypoint: Perform Arithmetic Operations on Decimals with JavaScript",
-      "dashedName": "waypoint-perform-arithmetic-operations-on-decimals-with-javascript",
+      "title": "Waypoint: Perform Arithmetic Operations on Decimals with JavaScript",
       "difficulty": "9.98151",
       "description": [
         "In JavaScript we can can work with decimal numbers."
@@ -405,8 +389,7 @@
     },
     {
       "id": "bd7993c9c69feddfaeb8bdef",
-      "name": "Waypoint: Store Multiple Values in one Variable using JavaScript Arrays",
-      "dashedName": "waypoint-store-multiple-values-in-one-variable-using-javascript-arrays",
+      "title": "Waypoint: Store Multiple Values in one Variable using JavaScript Arrays",
       "difficulty": "9.9816",
       "description": [
         "In JavaScript we can store lists or collections of data in what are called arrays",
@@ -432,8 +415,7 @@
     },
     {
       "id":"cf1111c1c11feddfaeb7bdef",
-      "name": "Waypoint: Nest one Array within Another Array",
-      "dashedName": "waypoint-nest-one-array-within-another-array",
+      "title": "Waypoint: Nest one Array within Another Array",
       "difficulty":"9.98161",
       "description":[
         "We are also able to create arrays within arrays. This technique is called <code>nesting</code>.",
@@ -452,8 +434,7 @@
     },
     {
       "id":"bg9997c9c79feddfaeb9bdef",
-      "name": "Waypoint: Access Array Data with Indexes",
-      "dashedName": "waypoint-access-array-data-with-indexes",
+      "title": "Waypoint: Access Array Data with Indexes",
       "difficulty":"9.9817",
       "description":[
         "Once an array has been created we can access the data we have stored in them using indexes",
@@ -483,8 +464,7 @@
     },
     {
       "id":"cf1111c1c11feddfaeb8bdef",
-      "name": "Waypoint: Modify Array Data With Indexes",
-      "dashedName": "waypoint-modify-array-data-with-indexes",
+      "title": "Waypoint: Modify Array Data With Indexes",
       "difficulty":"9.98171",
       "description":[
         "We are able to modify the data stored in an array by using indexes",
@@ -515,8 +495,7 @@
     },
     {
       "id": "bg9994c9c69feddfaeb9bdef",
-      "name": "Waypoint: Manipulate Arrays With pop()",
-      "dashedName": "waypoint-manipulate-arrays-with-pop",
+      "title": "Waypoint: Manipulate Arrays With pop()",
       "difficulty": "9.9818",
       "description": [
         "When an array has been defined we still have the ability to make changes to it afterwards",
@@ -546,8 +525,7 @@
     },
     {
       "id": "bg9995c9c69feddfaeb9bdef",
-      "name": "Waypoint: Manipulate Arrays With push()",
-      "dashedName": "waypoint-manipulate-arrays-with-push",
+      "title": "Waypoint: Manipulate Arrays With push()",
       "difficulty": "9.9818",
       "description": [
         "Now that we've learned how to <code>pop</code>things from the end of the array, we need to learn how to <code>push</code>stuff back to the end",
@@ -568,8 +546,7 @@
     },
     {
       "id": "bg9996c9c69feddfaeb9bdef",
-      "name": "Waypoint: Manipulate Arrays With shift()",
-      "dashedName": "waypoint-manipulate-arrays-with-shift",
+      "title": "Waypoint: Manipulate Arrays With shift()",
       "difficulty": "9.9817",
       "description": [
         "Another common way in which we can manipulate the data in an array is through <code>.shift() </code>",
@@ -591,8 +568,7 @@
     },
     {
       "id": "bg9997c9c69feddfaeb9bdef",
-      "name": "Waypoint: Manipulate Arrays With unshift()",
-      "dashedName": "waypoint-manipulate-arrays-with-unshift",
+      "title": "Waypoint: Manipulate Arrays With unshift()",
       "difficulty": "9.9818",
       "description": [
         "Now that we've learned how to <code>shift</code>things from the start of the array, we need to learn how to <code>unshift</code>stuff back to the start",
@@ -613,8 +589,7 @@
     },
     {
       "id":"bg9997c9c89feddfaeb9bdef",
-      "name": "Waypoint: Write Reusable JavaScript with Functions",
-      "dashedName": "waypoint-write-reusable-javascript-with-functions",
+      "title": "Waypoint: Write Reusable JavaScript with Functions",
       "difficulty":"9.9819",
       "description":[
         "In JavaScript we can divide up our code into separate and reusable parts called functions",
@@ -650,8 +625,7 @@
     },
     {
       "id":"bg9998c9c99feddfaeb9bdef",
-      "name": "Waypoint: Build JavaScript Objects",
-      "dashedName": "waypoint-build-javascript-objects",
+      "title": "Waypoint: Build JavaScript Objects",
       "difficulty":"9.9822",
       "description":[
         "A very important data type in javascript is the <code>Object</code>",
@@ -667,7 +641,6 @@
         "</code>",
         "Objects are useful for storing data in a structured way or in a way that represents a real world object like a cat.",
         "Let's try to make an Object that represents a dog called myDog!"
-
       ],
       "tests":[
         "assert((function(z){if(z.hasOwnProperty('name') && z.name != undefined && typeof(z.name) == 'string'){return(true);}else{return(false);}})(myDog), 'myDog should contain the property name and it should be a string');",
@@ -696,8 +669,7 @@
     },
     {
       "id":"bg9999c9c99feddfaeb9bdef",
-      "name": "Waypoint: Manipulate JavaScript Objects",
-      "dashedName": "waypoint-manipulate-javascript-objects",
+      "title": "Waypoint: Manipulate JavaScript Objects",
       "difficulty":"9.9823",
       "description":[
         "Now that we have an objects we need to know how to add and remove properties from it",
@@ -741,8 +713,7 @@
     },
     {
       "id":"cf1111c1c11feddfaeb5bdef",
-      "name": "Waypoint: Iterate with JavaScript For Loops",
-      "dashedName": "waypoint-iterate-with-javascript-for-loops",
+      "title": "Waypoint: Iterate with JavaScript For Loops",
       "difficulty":"9.9824",
       "description":[
         "Loops are a critical part of any program! The next few challenges",
@@ -770,8 +741,7 @@
     },
     {
       "id":"cf1111c1c11feddfaeb1bdef",
-      "name": "Waypoint: Iterate with JavaScript While Loops",
-      "dashedName": "waypoint-iterate-with-javascript-while-loops",
+      "title": "Waypoint: Iterate with JavaScript While Loops",
       "difficulty":"9.9825",
       "description":[
         "Loops are a critical part of any program! The next few challenges",
@@ -800,8 +770,7 @@
     },
     {
       "id":"cf1111c1c11feddfaeb2bdef",
-      "name": "Waypoint: Iterate with JavaScript Do-While Loops",
-      "dashedName": "waypoint-iterate-with-javascript-do-while-loops",
+      "title": "Waypoint: Iterate with JavaScript Do-While Loops",
       "difficulty":"9.9826",
       "description":[
         "Let's now take a look at the do - while loop",
@@ -830,8 +799,7 @@
     },
     {
       "id":"cf1111c1c11feddfaeb9bdef",
-      "name": "Waypoint: Generate Random Fractions with JavaScript",
-      "dashedName": "waypoint-generate-random-fractions-with-javascript",
+      "title": "Waypoint: Generate Random Fractions with JavaScript",
       "difficulty":"9.9827",
       "description":[
         "Random numbers are very useful for creating random behaviours and games",
@@ -856,8 +824,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb1bdef",
-      "name": "Waypoint: Generate Random Whole Numbers with JavaScript",
-      "dashedName": "waypoint-generate-random-whole-numbers-with-javascript",
+      "title": "Waypoint: Generate Random Whole Numbers with JavaScript",
       "difficulty":"9.9828",
       "description":[
         "While it's great that we can create random decimal numbers it's a lot more useful to generate a random whole number",
@@ -885,8 +852,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb2bdef",
-      "name": "Waypoint: Generate Random Whole Numbers within a Range",
-      "dashedName": "waypoint-generate-random-whole-numbers-within-a-range",
+      "title": "Waypoint: Generate Random Whole Numbers within a Range",
       "difficulty":"9.9829",
       "description":[
         "We can use a certain mathematical expression to get a random number between between twp numbers.",
@@ -913,8 +879,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb3bdef",
-      "name": "Waypoint: Use Conditional Logic with If-Else Statements",
-      "dashedName": "waypoint-use-conditional-logic-with-if-else-statements",
+      "title": "Waypoint: Use Conditional Logic with If-Else Statements",
       "difficulty":"9.983",
       "description":[
         "We can use if statements in JavaScript to only execute code if a certain condition is met",
@@ -947,8 +912,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb6bdef",
-      "name": "Waypoint: Sift through Text with Regular Expressions",
-      "dashedName": "waypoint-sift-through-text-with-regular-expressions",
+      "title": "Waypoint: Sift through Text with Regular Expressions",
       "difficulty":"9.984",
       "description":[
         "RegEx is a powerful tool we can use to find certain words or patterns in strings",
@@ -983,8 +947,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb7bdef",
-      "name": "Waypoint: Find Numbers with Regular Expressions",
-      "dashedName": "waypoint-find-numbers-with-regular-expressions",
+      "title": "Waypoint: Find Numbers with Regular Expressions",
       "difficulty":"9.985",
       "description":[
         "We can use special selectors in RegEx to select a particular type of value",
@@ -1013,8 +976,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb8bdef",
-      "name": "Waypoint: Find White Space with Regular Expressions",
-      "dashedName": "waypoint-find-white-space-with-regular-expressions",
+      "title": "Waypoint: Find White Space with Regular Expressions",
       "difficulty":"9.986",
       "description":[
         "We can also use selectors like <code>\\s</code> to find spaces in a string",
@@ -1042,8 +1004,7 @@
     },
     {
       "id":"cf1111c1c13feddfaeb3bdef",
-      "name": "Waypoint: Invert Regular Expression Matches with JavaScript",
-      "dashedName": "waypoint-invert-regular-expression-matches-with-javaScript",
+      "title": "Waypoint: Invert Regular Expression Matches with JavaScript",
       "difficulty":"9.987",
       "description":[
         "Use <code>/\\S/gi;</code> to match everything that isn't a space in the string",
@@ -1070,8 +1031,7 @@
     },
     {
       "id":"cf1111c1c12feddfaeb9bdef",
-      "name": "Waypoint: Create a JavaScript Slot Machine",
-      "dashedName": "waypoint-create-a-javascript-slot-machine",
+      "title": "Waypoint: Create a JavaScript Slot Machine",
       "difficulty":"9.988",
       "description":[
         "We are now going to try and combine some of the stuff we've just learnt abd create the logic for a slot machine game",
@@ -1224,8 +1184,7 @@
     },
     {
       "id":"cf1111c1c13feddfaeb1bdef",
-      "name": "Waypoint: Add your JavaScript Slot Machine Slots",
-      "dashedName": "waypoint-add-your-javascript-slot-machine-slots",
+      "title": "Waypoint: Add your JavaScript Slot Machine Slots",
       "difficulty":"9.989",
       "description":[
         "Now that we have our random numbers we need to go and check for when they are all the same that means we should count it as a win",
@@ -1383,8 +1342,7 @@
     },
     {
       "id":"cf1111c1c13feddfaeb2bdef",
-      "name": "Waypoint: Bring your JavaScript Slot Machine to Life",
-      "dashedName": "waypoint-bring-your-javascript-slot-machine-to-life",
+      "title": "Waypoint: Bring your JavaScript Slot Machine to Life",
       "difficulty":"9.990",
       "description":[
         "Now we can detect a win let's get the slot machine to look like it works",
diff --git a/seed/challenges/basic-ziplines.json b/seed/challenges/basic-ziplines.json
index e6418a3..5a9efb9 100644
--- a/seed/challenges/basic-ziplines.json
+++ b/seed/challenges/basic-ziplines.json
@@ -1,11 +1,10 @@
 {
-  "name": "Basic Front End Development Projects",
+  "title": "Basic Front End Development Projects",
   "order": 0.008,
   "challenges": [
     {
       "id": "bd7158d8c442eddfbeb5bd1f",
-      "name": "Waypoint: Get Set for Ziplines",
-      "dashedName": "waypoint-get-set-for-ziplines",
+      "title": "Waypoint: Get Set for Ziplines",
       "difficulty": 1.00,
       "challengeSeed": ["125658022"],
       "description": [
@@ -39,8 +38,7 @@
     },
     {
       "id": "bd7158d8c242eddfaeb5bd13",
-      "name": "Zipline: Build a Personal Portfolio Webpage",
-      "dashedName": "zipline-build-a-personal-portfolio-webpage",
+      "title": "Zipline: Build a Personal Portfolio Webpage",
       "difficulty": 1.01,
       "challengeSeed": ["133315782"],
       "description": [
@@ -75,8 +73,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd13",
-      "name": "Zipline: Build a Random Quote Machine",
-      "dashedName": "zipline-build-a-random-quote-machine",
+      "title": "Zipline: Build a Random Quote Machine",
       "difficulty": 1.02,
       "challengeSeed": ["126415122"],
       "description": [
@@ -107,8 +104,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd10",
-      "name": "Zipline: Show the Local Weather",
-      "dashedName": "zipline-show-the-local-weather",
+      "title": "Zipline: Show the Local Weather",
       "difficulty": 1.03,
       "challengeSeed": ["126415127"],
       "description": [
@@ -140,8 +136,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd0f",
-      "name": "Zipline: Build a Pomodoro Clock",
-      "dashedName": "zipline-build-a-pomodoro-clock",
+      "title": "Zipline: Build a Pomodoro Clock",
       "difficulty": 1.04,
       "challengeSeed": ["126411567"],
       "description": [
@@ -172,8 +167,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd1f",
-      "name": "Zipline: Use the Twitch.tv JSON API",
-      "dashedName": "zipline-use-the-twitchtv-json-api",
+      "title": "Zipline: Use the Twitch.tv JSON API",
       "difficulty": 1.05,
       "challengeSeed": ["126411564"],
       "description": [
diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index 800f64d..146857a 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -1,11 +1,10 @@
 {
-  "name": "Responsive Design with Bootstrap",
+  "title": "Responsive Design with Bootstrap",
   "order": 0.003,
   "challenges": [
     {
       "id": "bad87fee1348bd9acde08712",
-      "name": "Waypoint: Use Responsive Design with Bootstrap Fluid Containers",
-      "dashedName": "waypoint-use-responsive-design-with-bootstrap-fluid-containers",
+      "title": "Waypoint: Use Responsive Design with Bootstrap Fluid Containers",
       "difficulty": 2.01,
       "description": [
         "Now let's go back to our Cat Photo App. This time, we'll style it using the popular Bootstrap responsive CSS framework.",
@@ -88,8 +87,7 @@
     },
     {
       "id": "bad87fee1348bd9acde08812",
-      "name": "Waypoint: Make Images Mobile Responsive",
-      "dashedName": "waypoint-make-images-mobile-responsive",
+      "title": "Waypoint: Make Images Mobile Responsive",
       "difficulty": 2.02,
       "description": [
         "First, Add a new image with the <code>src</code> attribute of \"http://bit.ly/fcc-kittens2\".",
@@ -173,8 +171,7 @@
     },
     {
       "id": "bad87fee1348bd8acde08812",
-      "name": "Waypoint: Center Text with Bootstrap",
-      "dashedName": "waypoint-center-text-with-bootstrap",
+      "title": "Waypoint: Center Text with Bootstrap",
       "difficulty": 2.03,
       "description": [
         "Now that we're using Bootstrap, we can center our heading elements to make them look better. All we need to do is add the class <code>text-center</code> to our <code>h1</code> and <code>h2</code> elements.",
@@ -256,8 +253,7 @@
     },
     {
       "id": "bad87fee1348cd8acdf08812",
-      "name": "Waypoint: Create a Bootstrap Button",
-      "dashedName": "waypoint-create-a-bootstrap-button",
+      "title": "Waypoint: Create a Bootstrap Button",
       "difficulty": 2.04,
       "description": [
         "Bootstrap has its own styles for <code>button</code> elements, which look much better than the plain HTML ones.",
@@ -341,8 +337,7 @@
     },
     {
       "id": "bad87fee1348cd8acef08812",
-      "name": "Waypoint: Create a Block Element Bootstrap Button",
-      "dashedName": "waypoint-create-a-block-element-bootstrap-button",
+      "title": "Waypoint: Create a Block Element Bootstrap Button",
       "difficulty": 2.05,
       "description": [
         "Normally, your <code>button</code> elements are only as wide as the text that they contain. By making them block elements, your button will stretch to fill your page's entire horizontal space.",
@@ -430,8 +425,7 @@
     },
     {
       "id": "bad87fee1348cd8acef08811",
-      "name": "Waypoint: Taste the Bootstrap Button Color Rainbow",
-      "dashedName": "waypoint-taste-the-bootstrap-button-color-rainbow",
+      "title": "Waypoint: Taste the Bootstrap Button Color Rainbow",
       "difficulty": 2.06,
       "description": [
         "The \"btn-primary\" class is the main color you'll use in your app. It is useful for highlighting actions you want your user to take.",
@@ -517,8 +511,7 @@
     },
     {
       "id": "bad87fee1348cd8acef08813",
-      "name": "Waypoint: Call out Optional Actions with Button Info",
-      "dashedName": "waypoint-call-out-optional-actions-with-button-info",
+      "title": "Waypoint: Call out Optional Actions with Button Info",
       "difficulty": 2.07,
       "description": [
         "Bootstrap comes with several pre-defined colors for buttons. The \"btn-info\" class is used to call attention to optional actions that the user can take.",
@@ -605,8 +598,7 @@
     },
     {
       "id": "bad87fee1348ce8acef08814",
-      "name": "Waypoint: Warn your Users of a Dangerous Action",
-      "dashedName": "waypoint-warn-your-users-of-a-dangerous-action",
+      "title": "Waypoint: Warn your Users of a Dangerous Action",
       "difficulty": 2.08,
       "description": [
         "Bootstrap comes with several pre-defined colors for buttons. The \"btn-danger\" class is the button color you'll use to notify users that the button performs a destructive action, such as deleting a cat photo.",
@@ -694,8 +686,7 @@
     },
     {
       "id": "bad88fee1348ce8acef08815",
-      "name": "Waypoint: Use the Bootstrap Grid to Put Elements Side By Side",
-      "dashedName": "waypoint-use-the-bootstrap-grid-to-put-elements-side-by-side",
+      "title": "Waypoint: Use the Bootstrap Grid to Put Elements Side By Side",
       "difficulty": 2.09,
       "description": [
         "Bootstrap uses a responsive grid system, which makes it easy to put elements into rows and specify each element's relative width. Most of Bootstrap's classes can be applied to a <code>div</code> element.",
@@ -788,8 +779,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08845",
-      "name": "Waypoint: Ditch Custom CSS for Bootstrap",
-      "dashedName": "waypoint-ditch-custom-css-for-bootstrap",
+      "title": "Waypoint: Ditch Custom CSS for Bootstrap",
       "difficulty": 2.10,
       "description": [
         "We can clean up our code and make our Cat Photo App look more conventional by using Bootstrap's built-in styles instead of the custom styles we created earlier.",
@@ -887,8 +877,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08845",
-      "name": "Waypoint: Create a Custom Heading",
-      "dashedName": "waypoint-create-a-custom-heading",
+      "title": "Waypoint: Create a Custom Heading",
       "difficulty": 2.11,
       "description": [
         "We will make a simple heading for our Cat Photo App by putting them in the same row.",
@@ -976,8 +965,7 @@
     },
     {
       "id": "bad87fee1348bd9aedd08845",
-      "name": "Waypoint: Add Font Awesome Icons to our Buttons",
-      "dashedName": "waypoint-add-font-awesome-icons-to-our-buttons",
+      "title": "Waypoint: Add Font Awesome Icons to our Buttons",
       "difficulty": 2.12,
       "description": [
         "Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the \".svg\" file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.",
@@ -1061,8 +1049,7 @@
     },
     {
       "id": "bad87fee1348bd9aedc08845",
-      "name": "Waypoint: Add Font Awesome Icons to all of our Buttons",
-      "dashedName": "waypoint-add-font-awesome-icons-to-all-of-our-Buttons",
+      "title": "Waypoint: Add Font Awesome Icons to all of our Buttons",
       "difficulty": 2.13,
       "description": [
         "Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the \".svg\" file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.",
@@ -1146,8 +1133,7 @@
     },
     {
       "id": "bad87fee1348bd9aedb08845",
-      "name": "Waypoint: Responsively Style Radio Buttons",
-      "dashedName": "waypoint-responsively-style-radio-buttons",
+      "title": "Waypoint: Responsively Style Radio Buttons",
       "difficulty": 2.14,
       "description": [
         "You can use Bootstrap's \"col-xs-*\" classes on <code>form</code> elements, too! This way, our radio buttons will be evenly spread out across the page, regardless of how wide the screen resolution is.",
@@ -1231,8 +1217,7 @@
     },
     {
       "id": "bad87fee1348bd9aeda08845",
-      "name": "Waypoint: Responsively Style Checkboxes",
-      "dashedName": "waypoint-responsively-style-checkboxes",
+      "title": "Waypoint: Responsively Style Checkboxes",
       "difficulty": 2.15,
       "description": [
         "You can use Bootstrap's \"col-xs-*\" classes on <code>form</code> elements, too! This way, our checkboxes will be evenly spread out across the page, regardless of how wide the screen resolution is.",
@@ -1323,8 +1308,7 @@
     },
     {
       "id": "bad87fee1348bd9aed908845",
-      "name": "Waypoint: Style Text Inputs as Form Controls",
-      "dashedName": "waypoint-style-text-inputs-as-form-controls",
+      "title": "Waypoint: Style Text Inputs as Form Controls",
       "difficulty": 2.16,
       "description": [
         "You can add the \"fa-paper-plane\" Font Awesome icon by adding <code>&#60;i class=\"fa fa-paper-plane\"&#62;&#60;/i&#62;</code> within your submit <code>button</code> element.",
@@ -1424,8 +1408,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908845",
-      "name": "Waypoint: Line up Form Elements Responsively with Bootstrap",
-      "dashedName": "waypoint-line-up-form-elements-responsively-with-bootstrap",
+      "title": "Waypoint: Line up Form Elements Responsively with Bootstrap",
       "difficulty": 2.17,
       "description": [
         "Now let's get your form <code>input</code> and your submission <code>button</code> on the same line. We'll do this the same way we have previously: by using a <code>div</code> element with the class \"row\", and other <code>div</code> elements within it using the \"col-xs-*\" class.",
@@ -1526,8 +1509,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908846",
-      "name": "Waypoint: Create a Bootstrap Headline",
-      "dashedName": "waypoint-create-a-bootstrap-headline",
+      "title": "Waypoint: Create a Bootstrap Headline",
       "difficulty": 2.18,
       "description": [
         "Now let's build something from scratch to practice our HTML, CSS and Bootstrap skills.",
@@ -1561,8 +1543,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908746",
-      "name": "Waypoint: House our page within a Bootstrap Container Fluid Div",
-      "dashedName": "waypoint-house-our-page-within-a-bootstrap-container-fluid-div",
+      "title": "Waypoint: House our page within a Bootstrap Container Fluid Div",
       "difficulty": 2.18,
       "description": [
         "Now let's make sure all the content on your page is mobile-responsive.",
@@ -1591,8 +1572,7 @@
     },
     {
       "id": "bad87fee1348bd9bec908846",
-      "name": "Waypoint: Create a Bootstrap Row",
-      "dashedName": "waypoint-create-a-bootstrap-row",
+      "title": "Waypoint: Create a Bootstrap Row",
       "difficulty": 2.19,
       "description": [
         "Now we'll create a Bootstrap row for our inline elements.",
@@ -1624,8 +1604,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908847",
-      "name": "Waypoint: Split your Bootstrap Row",
-      "dashedName": "waypoint-split-your-bootstrap-row",
+      "title": "Waypoint: Split your Bootstrap Row",
       "difficulty": 2.20,
       "description": [
         "Now that we have a Bootstrap Row, let's split it into two columns to house our elements.",
@@ -1656,8 +1635,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908848",
-      "name": "Waypoint: Create Bootstrap Wells",
-      "dashedName": "waypoint-create-bootstrap-wells",
+      "title": "Waypoint: Create Bootstrap Wells",
       "difficulty": 2.21,
       "description": [
         "Bootstrap has a class called \"well\" that can create a visual sense of depth for your columns.",
@@ -1694,8 +1672,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908849",
-      "name": "Waypoint: Add Elements within your Bootstrap Wells",
-      "dashedName": "waypoint-add-elements-within-your-bootstrap-wells",
+      "title": "Waypoint: Add Elements within your Bootstrap Wells",
       "difficulty": 2.22,
       "description": [
         "Now we're several <code>div</code> elements deep on each column of our row. This is as deep as we'll need to go. Now we can add our <code>button</code> elements.",
@@ -1734,8 +1711,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908850",
-      "name": "Waypoint: Apply the Default Bootstrap Button Style",
-      "dashedName": "waypoint-apply-the-default-bootstrap-button-style",
+      "title": "Waypoint: Apply the Default Bootstrap Button Style",
       "difficulty": 2.23,
       "description": [
         "Bootstrap has another button class called \"btn-default\"",
@@ -1780,8 +1756,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908852",
-      "name": "Waypoint: Create a Class to Target with jQuery Selectors",
-      "dashedName": "waypoint-create-a-class-to-target-with-jquery-selectors",
+      "title": "Waypoint: Create a Class to Target with jQuery Selectors",
       "difficulty": 2.24,
       "description": [
         "Not every class needs to have corresponding CSS. Sometimes we create classes just for the purpose of selecting these elements more easily using jQuery.",
@@ -1825,8 +1800,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908853",
-      "name": "Waypoint: Add ID Attributes to Bootstrap Elements",
-      "dashedName": "waypoint-add-id-attributes-to-bootstrap-elements",
+      "title": "Waypoint: Add ID Attributes to Bootstrap Elements",
       "difficulty": 2.25,
       "description": [
         "Recall that in addition to class attributes, you can give each of your elements an id attribute.",
@@ -1874,8 +1848,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908854",
-      "name": "Waypoint: Label Bootstrap Wells",
-      "dashedName": "waypoint-label-bootstrap-wells",
+      "title": "Waypoint: Label Bootstrap Wells",
       "difficulty": 2.26,
       "description": [
         "For the sake of clarity, let's label both of our wells with their ids.",
@@ -1922,8 +1895,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908855",
-      "name": "Waypoint: Give Each Element a Unique ID",
-      "dashedName": "waypoint-give-each-element-a-unique-id",
+      "title": "Waypoint: Give Each Element a Unique ID",
       "difficulty": 2.27,
       "description": [
         "We will also want to be able to use jQuery to target each button by its unique id.",
@@ -1974,8 +1946,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908856",
-      "name": "Waypoint: Label Bootstrap Buttons",
-      "dashedName": "waypoint-label-bootstrap-buttons",
+      "title": "Waypoint: Label Bootstrap Buttons",
       "difficulty": 2.28,
       "description": [
         "Just like we labled our wells, we want to label our buttons.",
@@ -2026,8 +1997,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908857",
-      "name": "Waypoint: Use Comments to Clarify Code",
-      "dashedName": "waypoint-use-comments-to-clarify-code",
+      "title": "Waypoint: Use Comments to Clarify Code",
       "difficulty": 2.29,
       "description": [
         "When we start using jQuery, we will modify HTML elements without needing to actually change them in HTML.",
diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
index 50bbe89..6709b24 100644
--- a/seed/challenges/expert-bonfires.json
+++ b/seed/challenges/expert-bonfires.json
@@ -1,11 +1,10 @@
 {
-  "name": "Expert Algorithm Scripting",
+  "title": "Expert Algorithm Scripting",
   "order": 0.013,
   "challenges": [
     {
       "id": "aff0395860f5d3034dc0bfc9",
-      "name": "Bonfire: Validate US Telephone Numbers",
-      "dashedName": "bonfire-validate-us-telephone-numbers",
+      "title": "Bonfire: Validate US Telephone Numbers",
       "difficulty": "4.01",
       "description": [
         "Return true if the passed string is a valid US phone number",
@@ -65,8 +64,7 @@
     },
     {
       "id": "a3f503de51cf954ede28891d",
-      "name": "Bonfire: Symmetric Difference",
-      "dashedName": "bonfire-symmetric-difference",
+      "title": "Bonfire: Symmetric Difference",
       "difficulty": "4.02",
       "description": [
         "Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.",
@@ -104,8 +102,7 @@
     },
     {
       "id": "aa2e6f85cab2ab736c9a9b24",
-      "name": "Bonfire: Exact Change",
-      "dashedName": "bonfire-exact-change",
+      "title": "Bonfire: Exact Change",
       "difficulty": "4.03",
       "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.",
@@ -160,8 +157,7 @@
     },
     {
       "id": "a56138aff60341a09ed6c480",
-      "name": "Bonfire: Inventory Update",
-      "dashedName": "bonfire-inventory-update",
+      "title": "Bonfire: Inventory Update",
       "difficulty": "4.04",
       "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.",
@@ -215,8 +211,7 @@
     },
     {
       "id": "a7bf700cd123b9a54eef01d5",
-      "name": "Bonfire: No repeats please",
-      "dashedName": "bonfire-no-repeats-please",
+      "title": "Bonfire: No repeats please",
       "difficulty": "4.05",
       "description": [
         "Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
@@ -257,8 +252,7 @@
     },
     {
       "id": "a19f0fbe1872186acd434d5a",
-      "name": "Bonfire: Friendly Date Ranges",
-      "dashedName": "bonfire-friendly-date-ranges",
+      "title": "Bonfire: Friendly Date Ranges",
       "difficulty": "4.06",
       "description": [
         "Implement a way of converting two dates into a more friendly date range that could be presented to a user.",
diff --git a/seed/challenges/get-set-for-free-code-camp.json b/seed/challenges/get-set-for-free-code-camp.json
index ae22da9..7be7730 100644
--- a/seed/challenges/get-set-for-free-code-camp.json
+++ b/seed/challenges/get-set-for-free-code-camp.json
@@ -1,11 +1,10 @@
 {
-  "name": "Get Set for Free Code Camp",
+  "title": "Get Set for Free Code Camp",
   "order": 0.001,
   "challenges": [
     {
       "id": "bd7124d8c441eddfaeb5bdef",
-      "name": "Waypoint: Learn how Free Code Camp Works",
-      "dashedName": "waypoint-learn-how-free-code-camp-works",
+      "title": "Waypoint: Learn how Free Code Camp Works",
       "difficulty": 0.01,
       "challengeSeed": ["125407438"],
       "description": [
@@ -56,8 +55,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bd0f",
-      "name": "Waypoint: Join Our Chat Room",
-      "dashedName": "waypoint-join-our-chat-room",
+      "title": "Waypoint: Join Our Chat Room",
       "difficulty": 0.02,
       "challengeSeed": ["131574135"],
       "description": [
@@ -118,8 +116,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bdff",
-      "name": "Waypoint: Preview our Challenge Map",
-      "dashedName": "waypoint-preview-our-challenge-map",
+      "title": "Waypoint: Preview our Challenge Map",
       "difficulty": 0.03,
       "challengeSeed": ["125407437"],
       "description": [
@@ -160,8 +157,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bd1f",
-      "name": "Waypoint: Browse our Wiki",
-      "dashedName": "waypoint-browse-our-wiki",
+      "title": "Waypoint: Browse our Wiki",
       "difficulty": 0.04,
       "challengeSeed": ["125407435"],
       "description": [
@@ -200,8 +196,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bd2f",
-      "name": "Waypoint: Customize your Portfolio Page",
-      "dashedName": "waypoint-customize-your-portfolio-page",
+      "title": "Waypoint: Customize your Portfolio Page",
       "difficulty": 0.05,
       "challengeSeed": ["125407433"],
       "description": [
@@ -246,8 +241,7 @@
     },
     {
       "id": "bd7126d8c441eddfaeb5bd3f",
-      "name": "Waypoint: Try Camper News",
-      "dashedName": "waypoint-try-camper-news",
+      "title": "Waypoint: Try Camper News",
       "difficulty": 0.06,
       "challengeSeed": ["124553410"],
       "description": [
@@ -297,8 +291,7 @@
     },
     {
       "id": "bd7126d8c441eddfaeb5bd3e",
-      "name": "Waypoint: Meet Other Campers in your City",
-      "dashedName": "waypoint-meet-other-campers-in-your-city",
+      "title": "Waypoint: Meet Other Campers in your City",
       "difficulty": 0.07,
       "challengeSeed": ["127358841"],
       "description": [
@@ -345,8 +338,7 @@
     },
     {
       "id": "bd7126d8c431eddfaeb5bd3e",
-      "name": "Waypoint: Add Free Code Camp to your LinkedIn Profile",
-      "dashedName": "waypoint-add-free-code-camp-to-your-linkedin-profile",
+      "title": "Waypoint: Add Free Code Camp to your LinkedIn Profile",
       "difficulty": 0.08,
       "challengeSeed": ["131574134"],
       "description": [
@@ -376,8 +368,7 @@
     },
     {
       "id": "bd7137d8c441eddfaeb5bdef",
-      "name": "Waypoint: Get Help the Hacker Way with RSAP",
-      "dashedName": "waypoint-get-help-the-hacker-way-with-rsap",
+      "title": "Waypoint: Get Help the Hacker Way with RSAP",
       "difficulty": 0.09,
       "challengeSeed": ["125407432"],
       "description": [
diff --git a/seed/challenges/git.json b/seed/challenges/git.json
index f20d01f..cafffcd 100644
--- a/seed/challenges/git.json
+++ b/seed/challenges/git.json
@@ -1,11 +1,10 @@
 {
-  "name": "Git",
+  "title": "Git",
   "order" : 0.014,
   "challenges": [
     {
       "id": "bd7353d8c341eddeaeb5bd0f",
-      "name": "Waypoint: Save your Code Revisions Forever with Git",
-      "dashedName": "waypoint-save-your-code-revisions-forever-with-git",
+      "title": "Waypoint: Save your Code Revisions Forever with Git",
       "difficulty": 0.01,
       "challengeSeed": ["133316034"],
       "description": [
diff --git a/seed/challenges/hikes.json b/seed/challenges/hikes.json
index 2b67379..bb80106 100644
--- a/seed/challenges/hikes.json
+++ b/seed/challenges/hikes.json
@@ -1,11 +1,10 @@
 {
-  "name": "Hikes",
+  "title": "Hikes",
   "order": 0.050,
   "challenges": [
     {
       "id": "bd7128d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 1: The 4 Basic Parts of a Computer",
-      "dashedName": "hike-computer-basics-1-the-4-basic-parts-of-a-computer",
+      "title": "Hike: Computer Basics 1: The 4 Basic Parts of a Computer",
       "difficulty": 9.01,
       "challengeSeed": [
         "132542064"
@@ -44,8 +43,7 @@
     },
     {
       "id": "bd7127d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 2: More Computer Hardware",
-      "dashedName": "hike-computer-basics-2-more-computer-hardware",
+      "title": "Hike: Computer Basics 2: More Computer Hardware",
       "difficulty": 9.02,
       "challengeSeed": [
         "132542458"
@@ -83,8 +81,7 @@
     },
     {
       "id": "bd7126d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 3: Intro to Binary Code",
-      "dashedName": "hike-computer-basics-3-intro-to-binary-code",
+      "title": "Hike: Computer Basics 3: Intro to Binary Code",
       "difficulty": 9.03,
       "challengeSeed": [
         "132542757"
@@ -117,8 +114,7 @@
     },
     {
       "id": "bd7125d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 4: Decoding a Binary Number",
-      "dashedName": "hike-computer-basics-4-decoding-a-binary-number",
+      "title": "Hike: Computer Basics 4: Decoding a Binary Number",
       "difficulty": 9.04,
       "challengeSeed": [
         "132543332"
@@ -153,8 +149,7 @@
     },
     {
       "id": "bd7124d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 5: How To Measure Data Size",
-      "dashedName": "hike-computer-basics-5-how-to-measure-data-size",
+      "title": "Hike: Computer Basics 5: How To Measure Data Size",
       "difficulty": 9.05,
       "challengeSeed": [
         "132543959"
@@ -192,8 +187,7 @@
     },
     {
       "id": "bd7123d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 6: Measuring Data Speed",
-      "dashedName": "hike-computer-basics-6-measuring-data-speed",
+      "title": "Hike: Computer Basics 6: Measuring Data Speed",
       "difficulty": 9.06,
       "challengeSeed": [
         "132545171"
@@ -229,8 +223,7 @@
     },
     {
       "id": "bd7122d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 7: Binary Bytes",
-      "dashedName": "hike-computer-basics-7-binary-bytes",
+      "title": "Hike: Computer Basics 7: Binary Bytes",
       "difficulty": 9.07,
       "challengeSeed": [
         "132545417"
@@ -263,8 +256,7 @@
     },
     {
       "id": "bd7121d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 8: Types of Computers",
-      "dashedName": "hike-computer-basics-8-types-of-computers",
+      "title": "Hike: Computer Basics 8: Types of Computers",
       "difficulty": 9.08,
       "challengeSeed": [
         "132546182"
@@ -302,8 +294,7 @@
     },
     {
       "id": "bd7120d8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 9: More on the Motherboard",
-      "dashedName": "hike-computer-basics-9-more-on-the-motherboard",
+      "title": "Hike: Computer Basics 9: More on the Motherboard",
       "difficulty": 9.09,
       "challengeSeed": [
         "132547285"
@@ -343,8 +334,7 @@
     },
     {
       "id": "bd712fd8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 10: Data Networks",
-      "dashedName": "hike-computer-basics-10-data-networks",
+      "title": "Hike: Computer Basics 10: Data Networks",
       "difficulty": 9.10,
       "challengeSeed": [
         "132547590"
@@ -383,8 +373,7 @@
     },
     {
       "id": "bd712ed8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 11: IP Addresses",
-      "dashedName": "hike-computer-basics-11-ip-addresses",
+      "title": "Hike: Computer Basics 11: IP Addresses",
       "difficulty": 9.11,
       "challengeSeed": [
         "132548071"
@@ -422,8 +411,7 @@
     },
     {
       "id": "bd712dd8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 12: How the Internet Works",
-      "dashedName": "hike-computer-basics-12-how-the-internet-works",
+      "title": "Hike: Computer Basics 12: How the Internet Works",
       "difficulty": 9.12,
       "challengeSeed": [
         "132548579"
@@ -461,8 +449,7 @@
     },
     {
       "id": "bd712cd8c441eddfbeb5bddf",
-      "name": "Hike: Computer Basics 13: Software",
-      "dashedName": "hike-computer-basics-13-software",
+      "title": "Hike: Computer Basics 13: Software",
       "difficulty": 9.13,
       "challengeSeed": [
         "132548908"
@@ -494,8 +481,7 @@
     },
     {
       "id": "bd712bd8c441eddfbeb5bddf",
-      "name": "Hike: What Do Programmers Do?",
-      "dashedName": "hike-what-do-programmers-do",
+      "title": "Hike: What Do Programmers Do?",
       "difficulty": 9.14,
       "challengeSeed": [
         "133166912"
@@ -531,8 +517,7 @@
     },
     {
       "id": "bd712ad8c441eddfbeb5bddf",
-      "name": "Hike: Console and Logging",
-      "dashedName": "hike-console-and-logging",
+      "title": "Hike: Console and Logging",
       "difficulty": 9.15,
       "challengeSeed": [
         "133170880"
@@ -568,8 +553,7 @@
     },
     {
       "id": "bd7119d8c441eddfbeb5bddf",
-      "name": "Hike: Variables In Code",
-      "dashedName": "hike-variables-in-code",
+      "title": "Hike: Variables In Code",
       "difficulty": 9.16,
       "challengeSeed": [
         "133172920"
@@ -601,8 +585,7 @@
     },
     {
       "id": "bd7029d8c441eddfbeb5bddf",
-      "name": "Hike: Source Code",
-      "dashedName": "hike-source-code",
+      "title": "Hike: Source Code",
       "difficulty": 9.17,
       "challengeSeed": [
         "133177129"
@@ -646,8 +629,7 @@
     },
     {
       "id": "bd7129d8b441eddfbeb5bddf",
-      "name": "Hike: Routers and Packets",
-      "dashedName": "hike-routers-and-packets",
+      "title": "Hike: Routers and Packets",
       "difficulty": 9.18,
       "challengeSeed": [
         "133181251"
@@ -697,8 +679,7 @@
     },
     {
       "id": "bd7129d8a441eddfbeb5bddf",
-      "name": "Hike: Hardware: Chips and Moore's Law",
-      "dashedName": "hike-chips-and-moores-law",
+      "title": "Hike: Hardware: Chips and Moore's Law",
       "difficulty": 9.19,
       "challengeSeed": [
         "133182057"
@@ -734,8 +715,7 @@
     },
     {
       "id": "bd7129d80441eddfbeb5bddf",
-      "name": "Hike: Analog vs Digital and File Compression",
-      "dashedName": "hike-analog-vs-digital-and-file-compression",
+      "title": "Hike: Analog vs Digital and File Compression",
       "difficulty": 9.20,
       "challengeSeed": [
         "133182587"
@@ -773,8 +753,7 @@
     },
     {
       "id": "bd7129d89441eddfbeb5bddf",
-      "name": "Hike: Computer Security",
-      "dashedName": "hike-computer-security",
+      "title": "Hike: Computer Security",
       "difficulty": 9.21,
       "challengeSeed": [
         "133186284"
diff --git a/seed/challenges/html5-and-css.json b/seed/challenges/html5-and-css.json
index 3896334..69236fd 100644
--- a/seed/challenges/html5-and-css.json
+++ b/seed/challenges/html5-and-css.json
@@ -1,11 +1,10 @@
 {
-  "name": "HTML5 and CSS",
+  "title": "HTML5 and CSS",
   "order": 0.002,
   "challenges": [
     {
       "id": "bd7123c8c441eddfaeb5bdef",
-      "name": "Waypoint: Say Hello to HTML Elements",
-      "dashedName": "waypoint-say-hello-to-html-elements",
+      "title": "Waypoint: Say Hello to HTML Elements",
       "difficulty": 1.01,
       "description": [
         "Welcome to Free Code Camp's first coding challenge!",
@@ -53,8 +52,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf0887a",
-      "name": "Waypoint: Headline with the h2 Element",
-      "dashedName": "waypoint-headline-with-the-h2-element",
+      "title": "Waypoint: Headline with the h2 Element",
       "difficulty": 1.02,
       "description": [
         "Add an <code>h2</code> tag that says \"CatPhotoApp\" to create a second HTML <code>element</code> below your \"Hello World\" <code>h1</code> element.",
@@ -97,8 +95,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08801",
-      "name": "Waypoint: Inform with the Paragraph Element",
-      "dashedName": "waypoint-inform-with-the-paragraph-element",
+      "title": "Waypoint: Inform with the Paragraph Element",
       "difficulty": 1.03,
       "description": [
         "Create a <code>p</code> element below your <code>h2</code> element, and give it the text \"Hello Paragraph\".",
@@ -138,8 +135,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08802",
-      "name": "Waypoint: Uncomment HTML",
-      "dashedName": "waypoint-uncomment-html",
+      "title": "Waypoint: Uncomment HTML",
       "difficulty": 1.04,
       "description": [
         "Uncomment your <code>h1</code>, <code>h2</code> and <code>p</code> elements.",
@@ -188,8 +184,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08804",
-      "name": "Waypoint: Comment out HTML",
-      "dashedName": "waypoint-comment-out-html",
+      "title": "Waypoint: Comment out HTML",
       "difficulty": 1.05,
       "description": [
         "Comment out your <code>h1</code> element and your <code>p</code> element, but leave your <code>h2</code> element uncommented.",
@@ -235,8 +230,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08833",
-      "name": "Waypoint: Fill in the Blank with Placeholder Text",
-      "dashedName": "waypoint-fill-in-the-blank-with-placeholder-text",
+      "title": "Waypoint: Fill in the Blank with Placeholder Text",
       "difficulty": 1.06,
       "description": [
         "Web developers traditionally use \"Lorem Ipsum\" text as placeholder text. It's called \"Lorem Ipsum\" text because those are the first two words of a famous passage by Cicero of Ancient Rome.",
@@ -282,8 +276,7 @@
     },
     {
       "id": "bad87fed1348bd9aedf08833",
-      "name": "Waypoint: Delete HTML Elements",
-      "dashedName": "waypoint-delete-html-elements",
+      "title": "Waypoint: Delete HTML Elements",
       "difficulty": 1.07,
       "description": [
         "Delete your <code>h1</code> element so we can simplify our view.",
@@ -326,8 +319,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08803",
-      "name": "Waypoint: Change the Color of Text",
-      "dashedName": "waypoint-change-the-color-of-text",
+      "title": "Waypoint: Change the Color of Text",
       "difficulty": 1.08,
       "description": [
         "Change your <code>h2</code> element's style so that its text color is red.",
@@ -368,8 +360,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08805",
-      "name": "Waypoint: Use CSS Selectors to Style Elements",
-      "dashedName": "waypoint-use-css-selectors-to-style-elements",
+      "title": "Waypoint: Use CSS Selectors to Style Elements",
       "difficulty": 1.09,
       "description": [
         "Delete your <code>h2</code> element's style attribute and instead create a CSS <code>style</code> element. Add the necessary CSS to turn all <code>h2</code> elements blue.",
@@ -423,8 +414,7 @@
     },
     {
       "id": "bad87fee1348bd9aecf08806",
-      "name": "Waypoint: Use a CSS Class to Style an Element",
-      "dashedName": "waypoint-use-a-css-class-to-style-an-element",
+      "title": "Waypoint: Use a CSS Class to Style an Element",
       "difficulty": 1.11,
       "description": [
         "Create a CSS class called \"red-text\" and apply it to your <code>h2</code> element.",
@@ -477,8 +467,7 @@
     },
     {
       "id": "bad87fee1348bd9aefe08806",
-      "name": "Waypoint: Style Multiple Elements with a CSS Class",
-      "dashedName": "waypoint－style－multiple-elements-with-a-css-class",
+      "title": "Waypoint: Style Multiple Elements with a CSS Class",
       "difficulty": 1.12,
       "description": [
         "Apply the \"red-text\" class to your <code>h2</code> and <code>p</code> elements.",
@@ -522,8 +511,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08806",
-      "name": "Waypoint: Change the Font Size of an Element",
-      "dashedName": "waypoint-change-the-font-size-of-an-element",
+      "title": "Waypoint: Change the Font Size of an Element",
       "difficulty": 1.13,
       "description": [
         "Create a second <code>p</code> element with the following Kitty Ipsum text: <code>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</code>",
@@ -569,8 +557,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08807",
-      "name": "Waypoint: Set the Font Family of an Element",
-      "dashedName": "waypoint-set-the-font-family-of-an-element",
+      "title": "Waypoint: Set the Font Family of an Element",
       "difficulty": 1.14,
       "description": [
         "Make all of your <code>p</code> elements use the \"Monospace\" font.",
@@ -616,8 +603,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08807",
-      "name": "Waypoint: Import a Google Font",
-      "dashedName": "waypoint-import-a-google-font",
+      "title": "Waypoint: Import a Google Font",
       "difficulty": 1.15,
       "description": [
         "Apply the <code>font-family</code> of \"Lobster\" to your <code>h2</code> element.",
@@ -670,8 +656,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08808",
-      "name": "Waypoint: Specify How Fonts Should Degrade",
-      "dashedName": "waypoint-specify-how-fonts-should-degrade",
+      "title": "Waypoint: Specify How Fonts Should Degrade",
       "difficulty": 1.16,
       "description": [
         "There are several default fonts that are available in all browsers. These include \"Monospace\", \"Serif\" and \"Sans-Serif\". Leave \"Lobster\" as the font-family for your <code>h2</code> elements. Make them \"degrade\" to \"Monospace\" when \"Lobster\" isn't available.",
@@ -728,8 +713,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08812",
-      "name": "Waypoint: Add Images to your Website",
-      "dashedName": "waypoint-add-images-to-your-website",
+      "title": "Waypoint: Add Images to your Website",
       "difficulty": 1.17,
       "description": [
         "You can add images to your website by using the <code>img</code> element, and point to an specific image's URL using the <code>src</code> attribute.",
@@ -783,8 +767,7 @@
     },
     {
       "id": "bad87fee1348bd9acdf08812",
-      "name": "Waypoint: Size your Images",
-      "dashedName": "waypoint-size-your-images",
+      "title": "Waypoint: Size your Images",
       "difficulty": 1.18,
       "description": [
         "CSS has an attribute called <code>width</code> that controls an element's width. Just like with fonts, we'll use pixels(px) to specify the image's width.",
@@ -839,8 +822,7 @@
     },
     {
       "id": "bad87fee1348bd9bedf08813",
-      "name": "Waypoint: Add Borders Around your Elements",
-      "dashedName": "waypoint-add-borders-around-your-elements",
+      "title": "Waypoint: Add Borders Around your Elements",
       "difficulty": 1.19,
       "description": [
         "CSS borders have attributes like style, color and width.",
@@ -902,8 +884,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08814",
-      "name": "Waypoint: Add Rounded Corners with a Border Radius",
-      "dashedName": "waypoint-add-rounded-corners-with-a-border-radius",
+      "title": "Waypoint: Add Rounded Corners with a Border Radius",
       "difficulty": 1.20,
       "description": [
         "Your cat photo currently has sharp corners. We can round out those corners with a CSS attribute called <code>border-radius</code>.",
@@ -968,8 +949,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08815",
-      "name": "Waypoint: Make Circular Images with a Border Radius",
-      "dashedName": "waypoint-make-circular-images-with-a-border-radius",
+      "title": "Waypoint: Make Circular Images with a Border Radius",
       "difficulty": 1.21,
       "description": [
         "In addition to pixels, you can also specify a <code>border-radius</code> using a percentage.",
@@ -1033,8 +1013,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08816",
-      "name": "Waypoint: Link to External Pages with Anchor Elements",
-      "dashedName": "waypoint-link-to-external-pages-with-anchor-elements",
+      "title": "Waypoint: Link to External Pages with Anchor Elements",
       "difficulty": 1.22,
       "description": [
         "<code>a</code> elements or \"anchor\" elements, are used to link to content outside of the current page.",
@@ -1104,8 +1083,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08817",
-      "name": "Waypoint: Nest an Anchor Element within a Paragraph",
-      "dashedName": "waypoint-nest-an-anchor-element-within-a-paragraph",
+      "title": "Waypoint: Nest an Anchor Element within a Paragraph",
       "difficulty": 1.23,
       "description": [
         "Again, here's a diagram of an <code>a</code> element for your reference:",
@@ -1180,8 +1158,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08817",
-      "name": "Waypoint: Make Dead Links using the Hash Symbol",
-      "dashedName": "waypoint-make-dead-links-using-the-hash-symbol",
+      "title": "Waypoint: Make Dead Links using the Hash Symbol",
       "difficulty": 1.24,
       "description": [
         "Sometimes you want to add <code>a</code> elements to your website before you know where they will link.",
@@ -1249,8 +1226,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08820",
-      "name": "Waypoint: Turn an Image into a Link",
-      "dashedName": "waypoint-turn-an-image-into-a-link",
+      "title": "Waypoint: Turn an Image into a Link",
       "difficulty": 1.25,
       "description": [
         "You can make elements into links by nesting them within an <code>a</code> element.",
@@ -1322,8 +1298,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08818",
-      "name": "Waypoint: Add Alt Text to an Image for Accessibility",
-      "dashedName": "waypoint-add-alt-text-to-an-image-for-accessibility",
+      "title": "Waypoint: Add Alt Text to an Image for Accessibility",
       "difficulty": 1.26,
       "description": [
         "<code>alt</code> attributes, also known as \"alt text\", are what browsers will display if they fail to load the image. <code>alt</code> attributes are also important for blind or visually impaired users to understand what an image portrays. And search engines also look at <code>alt</code> attributes.",
@@ -1393,8 +1368,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08827",
-      "name": "Waypoint: Create a Bulleted Unordered List",
-      "dashedName": "waypoint-create-a-bulleted-unordered-list",
+      "title": "Waypoint: Create a Bulleted Unordered List",
       "difficulty": 1.27,
       "description": [
         "HTML has a special element for creating unordered lists, or bullet point-style lists.",
@@ -1471,8 +1445,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08828",
-      "name": "Waypoint: Create an Ordered List",
-      "dashedName": "waypoint-create-an-ordered-list",
+      "title": "Waypoint: Create an Ordered List",
       "difficulty": 1.28,
       "description": [
         "HTML has a special element for creating ordered lists, or numbered-style lists.",
@@ -1552,8 +1525,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08829",
-      "name": "Waypoint: Create a Text Field",
-      "dashedName": "waypoint-create-a-text-field",
+      "title": "Waypoint: Create a Text Field",
       "difficulty": 1.29,
       "description": [
         "Now let's create a web form.",
@@ -1631,8 +1603,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08830",
-      "name": "Waypoint: Add Placeholder Text to a Text Field",
-      "dashedName": "waypoint-add-placeholder-text-to-a-text-field",
+      "title": "Waypoint: Add Placeholder Text to a Text Field",
       "difficulty": 1.30,
       "description": [
         "Your placeholder text is what appears in your text <code>input</code> before your user has inputed anything.",
@@ -1711,8 +1682,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08830",
-      "name": "Waypoint: Create a Form Element",
-      "dashedName": "waypoint-create-a-form-element",
+      "title": "Waypoint: Create a Form Element",
       "difficulty": 1.31,
       "description": [
         "You can build web forms that actually submit data to a server using nothing more than pure HTML. You can do this by specifying an action on your <code>form</code> element.",
@@ -1793,8 +1763,7 @@
     },
     {
       "id": "bad87fee1348bd9aedd08830",
-      "name": "Waypoint: Add a Submit Button to a Form",
-      "dashedName": "waypoint-add-a-submit-button-to-a-form",
+      "title": "Waypoint: Add a Submit Button to a Form",
       "difficulty": 1.32,
       "description": [
         "Let's add a submit button to your form. Clicking this button will send the data from your form to the URL you specified with your form's <code>action</code> attribute.",
@@ -1877,8 +1846,7 @@
     },
     {
       "id": "bad87fee1348bd9aedc08830",
-      "name": "Waypoint: Use HTML5 to Require a Field",
-      "dashedName": "waypoint-use-html5-to-require-a-field",
+      "title": "Waypoint: Use HTML5 to Require a Field",
       "difficulty": 1.33,
       "description": [
         "You can require specific form fields so that your user will not be able to submit your form until he or she has filled them out.",
@@ -1959,8 +1927,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08834",
-      "name": "Waypoint: Create a Set of Radio Buttons",
-      "dashedName": "waypoint-create-a-set-of-radio-buttons",
+      "title": "Waypoint: Create a Set of Radio Buttons",
       "difficulty": 1.34,
       "description": [
         "You can use \"radio buttons\" for questions where you want the user to only give you one answer.",
@@ -2052,8 +2019,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08835",
-      "name": "Waypoint: Create a Set of Checkboxes",
-      "dashedName": "waypoint-create-a-set-of-checkboxes",
+      "title": "Waypoint: Create a Set of Checkboxes",
       "difficulty": 1.35,
       "description": [
         "Forms commonly use \"checkboxes\" for questions that may have more than one answer.",
@@ -2142,8 +2108,7 @@
     },
     {
       "id": "bad87fee1348bd9aedd08835",
-      "name": "Waypoint: Check Radio Buttons and Checkboxes by Default",
-      "dashedName": "waypoint-check-radio-buttons-and-checkboxes-by-default",
+      "title": "Waypoint: Check Radio Buttons and Checkboxes by Default",
       "difficulty": 1.37,
       "description": [
         "You can set a checkbox or radio button to be checked by default using the <code>checked</code> attribute.",
@@ -2230,8 +2195,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08835",
-      "name": "Waypoint: Nest Many Elements within a Single Div Element",
-      "dashedName": "waypoint-nest-many-elements-within-a-single-div-element",
+      "title": "Waypoint: Nest Many Elements within a Single Div Element",
       "difficulty": 1.38,
       "description": [
         "The <code>div</code> element, or \"Division\" element, is a general purpose container for other elements.",
@@ -2325,8 +2289,7 @@
     },
     {
       "id": "bad87fed1348bd9aede07836",
-      "name": "Waypoint: Give a Background Color to a Div Element",
-      "dashedName": "waypoint-give-a-background-color-to-a-div-element",
+      "title": "Waypoint: Give a Background Color to a Div Element",
       "difficulty": 1.39,
       "description": [
         "You can set an element's background color with the \"background-color\" attribute.",
@@ -2412,8 +2375,7 @@
     },
     {
       "id": "bad87eee1348bd9aede07836",
-      "name": "Waypoint: Set the ID of an Element",
-      "dashedName": "waypoint-set-the-id-of-an-element",
+      "title": "Waypoint: Set the ID of an Element",
       "difficulty": 1.391,
       "description": [
         "In addition to classes, each HTML element can also have an <code>id</code> attribute.",
@@ -2500,8 +2462,7 @@
     },
     {
       "id": "bad87dee1348bd9aede07836",
-      "name": "Waypoint: Use an ID Attribute to Style an Element",
-      "dashedName": "waypoint-use-an-id-attribute-to-style-an-element",
+      "title": "Waypoint: Use an ID Attribute to Style an Element",
       "difficulty": 1.392,
       "description": [
         "One cool thing about <code>id</code> attributes is that, like classes, you can style them using CSS.",
@@ -2590,8 +2551,7 @@
     },
     {
       "id": "bad88fee1348bd9aedf08825",
-      "name": "Waypoint: Adjusting the Padding of an Element",
-      "dashedName": "waypoint-adjusting-the-padding-of-an-element",
+      "title": "Waypoint: Adjusting the Padding of an Element",
       "difficulty": 1.40,
       "description": [
         "You may have already noticed this, but all HTML elements are essentially little rectangles.",
@@ -2661,8 +2621,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08822",
-      "name": "Waypoint: Adjust the Margin of an Element",
-      "dashedName": "waypoint-adjust-the-margin-of-an-element",
+      "title": "Waypoint: Adjust the Margin of an Element",
       "difficulty": 1.41,
       "description": [
         "An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
@@ -2732,8 +2691,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08823",
-      "name": "Waypoint: Add a Negative Margin to an Element",
-      "dashedName": "waypoint-add-a-negative-margin-to-an-element",
+      "title": "Waypoint: Add a Negative Margin to an Element",
       "difficulty": 1.42,
       "description": [
         "An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
@@ -2802,8 +2760,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08824",
-      "name": "Waypoint: Add Different Padding to Each Side of an Element",
-      "dashedName": "waypoint-add-different-padding-to-each-side-of-an-element",
+      "title": "Waypoint: Add Different Padding to Each Side of an Element",
       "difficulty": 1.43,
       "description": [
         "Sometimes you will want to customize an element so that it has different <code>padding</code> on each of its sides.",
@@ -2874,8 +2831,7 @@
     },
     {
       "id": "bad87fee1248bd9aedf08824",
-      "name": "Waypoint: Add Different Margins to Each Side of an Element",
-      "dashedName": "waypoint-add-different-margins-to-each-side-of-an-element",
+      "title": "Waypoint: Add Different Margins to Each Side of an Element",
       "difficulty": 1.44,
       "description": [
         "Give the green box a <code>margin</code> of 40 pixels on its top and left side, but only 20 pixels on its bottom and right side.",
@@ -2945,8 +2901,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08826",
-      "name": "Waypoint: Use Clockwise Notation to Specify the Padding of an Element",
-      "dashedName": "waypoint-use-clockwise-notation-to-specify-the-padding-of-an-element",
+      "title": "Waypoint: Use Clockwise Notation to Specify the Padding of an Element",
       "difficulty": 1.44,
       "description": [
         "Instead of specifying an element's <code>padding-top</code>, <code>padding-right</code>, <code>padding-bottom</code>, and <code>padding-left</code> attributes, you can specify them all in one line, like this: <code>padding: 10px 20px 10px 20px;</code>.",
@@ -3014,8 +2969,7 @@
     },
     {
       "id": "bad87fee1348bd9afdf08726",
-      "name": "Waypoint: Use Clockwise Notation to Specify the Margin of an Element",
-      "dashedName": "waypoint-use-clockwise-notation-to-specify-the-margin-of-an-element",
+      "title": "Waypoint: Use Clockwise Notation to Specify the Margin of an Element",
       "difficulty": 1.45,
       "description": [
         "Let's try this again, but with <code>margin</code> this time.",
@@ -3028,7 +2982,6 @@
         "assert($('.green-box').css('margin-right') === '20px', 'Your <code>green-box</code> class should give the right of elements 20px of <code>margin</code>.')",
         "assert($('.green-box').css('margin-bottom') === '20px', 'Your <code>green-box</code> class should give the bottom of elements 20px of <code>margin</code>.')",
         "assert($('.green-box').css('margin-left') === '40px', 'Your <code>green-box</code> class should give the left of elements 40px of <code>margin</code>.')"
-
       ],
       "challengeSeed": [
         "<style>",
@@ -3085,8 +3038,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08736",
-      "name": "Waypoint: Style the HTML Body Element",
-      "dashedName": "waypoint-style-the-html-body-element",
+      "title": "Waypoint: Style the HTML Body Element",
       "difficulty": 1.46,
       "description": [
         "Now let's start fresh and talk about CSS inheritance.",
@@ -3118,8 +3070,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08746",
-      "name": "Waypoint: Inherit Styles from the Body Element",
-      "dashedName": "waypoint-inherit-styles-from-the-body-element",
+      "title": "Waypoint: Inherit Styles from the Body Element",
       "difficulty": 1.47,
       "description": [
         "Now we've proven that every HTML page has a <code>body</code> element, and that its <code>body</code> element can also be styled with CSS.",
@@ -3161,8 +3112,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08756",
-      "name": "Waypoint: Prioritize One Style Over Another",
-      "dashedName": "waypoint-prioritize-one-style-over-another",
+      "title": "Waypoint: Prioritize One Style Over Another",
       "difficulty": 1.48,
       "description": [
         "Sometimes your HTML elements will receive multiple styles that conflict with one another.",
@@ -3201,8 +3151,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf04756",
-      "name": "Waypoint: Override Styles in Subsequent CSS",
-      "dashedName": "waypoint-override-styles-in-subsequent-css",
+      "title": "Waypoint: Override Styles in Subsequent CSS",
       "difficulty": 1.49,
       "description": [
         "Our \"pink-text\" class overrode our <code>body</code> element's CSS declaration!",
@@ -3244,8 +3193,7 @@
     },
     {
       "id": "bad87fee1348bd8aedf06756",
-      "name": "Waypoint: Override Class Declarations by Styling ID Attributes",
-      "dashedName": "waypoint-override-class-declarations-by-styling-id-attributes",
+      "title": "Waypoint: Override Class Declarations by Styling ID Attributes",
       "difficulty": 1.52,
       "description": [
         "We just proved that browsers read CSS from top to bottom. That means that, in the event of a conflict, the browser will use whichever CSS declaration came last.",
@@ -3293,8 +3241,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf06756",
-      "name": "Waypoint: Override Class Declarations with Inline Styles",
-      "dashedName": "waypoint-override-class-declarations-with-inline-styles",
+      "title": "Waypoint: Override Class Declarations with Inline Styles",
       "difficulty": 1.52,
       "description": [
         "So we've proven that id declarations override class declarations, regardless of where they are declared in your <code>style</code> element CSS.",
@@ -3344,8 +3291,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf07756",
-      "name": "Waypoint: Override All Other Styles by using Important",
-      "dashedName": "waypoint-override-all-other-styles-by-using-important",
+      "title": "Waypoint: Override All Other Styles by using Important",
       "difficulty": 1.53,
       "description": [
         "Yay! We just proved that in-line styles will override all the CSS declarations in your <code>style</code> element.",
@@ -3398,8 +3344,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08726",
-      "name": "Waypoint: Use Hex Code for Specific Colors",
-      "dashedName": "waypoint-use-hex-code-for-specific-colors",
+      "title": "Waypoint: Use Hex Code for Specific Colors",
       "difficulty": 1.54,
       "description": [
         "Did you know there other ways to represent colors in CSS? One of these ways is called hexadecimal code, or \"hex code\" for short.",
@@ -3434,8 +3379,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08725",
-      "name": "Waypoint: Use Hex Code to Color Elements White",
-      "dashedName": "waypoint-use-hex-code-to-color-elements-white",
+      "title": "Waypoint: Use Hex Code to Color Elements White",
       "difficulty": 1.55,
       "description": [
         "0 is the lowest number in hex code, and represents a complete absence of color.",
@@ -3469,8 +3413,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08724",
-      "name": "Waypoint: Use Hex Code to Color Elements Red",
-      "dashedName": "waypoint-use-hex-code-to-color-elements-red",
+      "title": "Waypoint: Use Hex Code to Color Elements Red",
       "difficulty": 1.56,
       "description": [
         "You may be wondering why we use 6 digits to represent a color instead of just one or two. The answer is that using 6 digits gives us a huge variety.",
@@ -3506,8 +3449,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08723",
-      "name": "Waypoint: Use Hex Code to Color Elements Green",
-      "dashedName": "waypoint-use-hex-code-to-color-elements-green",
+      "title": "Waypoint: Use Hex Code to Color Elements Green",
       "difficulty": 1.57,
       "description": [
         "Remember that hex code follows the red-green-blue, or \"RGB\" format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
@@ -3541,8 +3483,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08722",
-      "name": "Waypoint: Use Hex Code to Color Elements Blue",
-      "dashedName": "waypoint-use-hex-code-to-color-elements-blue",
+      "title": "Waypoint: Use Hex Code to Color Elements Blue",
       "difficulty": 1.58,
       "description": [
         "Hex code follows the red-green-blue, or \"RGB\" format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
@@ -3576,8 +3517,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08721",
-      "name": "Waypoint: Use Hex Code to Mix Colors",
-      "dashedName": "waypoint-use-hex-code-to-mix-colors",
+      "title": "Waypoint: Use Hex Code to Mix Colors",
       "difficulty": 1.59,
       "description": [
         "From these three pure colors (red, green and blue), we can create 16 million other colors.",
@@ -3611,8 +3551,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08720",
-      "name": "Waypoint: Use Hex Code to Color Elements Gray",
-      "dashedName": "waypoint-use-hex-code-to-color-elements-gray",
+      "title": "Waypoint: Use Hex Code to Color Elements Gray",
       "difficulty": 1.60,
       "description": [
         "From these three pure colors (red, green and blue), we can create 16 million other colors.",
@@ -3646,8 +3585,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08720",
-      "name": "Waypoint: Use Hex Code for Specific Shades of Gray",
-      "dashedName": "waypoint-use-hex-code-for-specific-shades-of-gray",
+      "title": "Waypoint: Use Hex Code for Specific Shades of Gray",
       "difficulty": 1.61,
       "description": [
         "We can also create other shades of gray by evenly mixing all three colors. We can go very close to true black.",
@@ -3680,8 +3618,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08719",
-      "name": "Waypoint: Use Abbreviated Hex Code",
-      "dashedName": "waypoint-use-abbreviated-hex-code",
+      "title": "Waypoint: Use Abbreviated Hex Code",
       "difficulty": 1.62,
       "description": [
         "Many people feel overwhelmed by the possibilities of more than 16 million colors. And it's difficult to remember hex code. Fortunately, you can shorten it.",
@@ -3716,8 +3653,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08718",
-      "name": "Waypoint: Use RGB values to Color Elements",
-      "dashedName": "waypoint-use-rgb-values-to-color-elements",
+      "title": "Waypoint: Use RGB values to Color Elements",
       "difficulty": 1.63,
       "description": [
         "Another way you can represent colors in CSS is by using RGB values.",
@@ -3753,8 +3689,7 @@
     },
     {
       "id": "bad88fee1348bd9aedf08726",
-      "name": "Waypoint: Use RGB to Color Elements White",
-      "dashedName": "waypoint-use-rgb-to-color-elements-white",
+      "title": "Waypoint: Use RGB to Color Elements White",
       "difficulty": 1.64,
       "description": [
         "RGB values look like this: <code>rgb(0, 0, 0)</code> for black and <code>rgb(255, 255, 255)<code> for white.",
@@ -3788,8 +3723,7 @@
     },
     {
       "id": "bad89fee1348bd9aedf08724",
-      "name": "Waypoint: Use RGB to Color Elements Red",
-      "dashedName": "waypoint-use-rgb-to-color-elements-red",
+      "title": "Waypoint: Use RGB to Color Elements Red",
       "difficulty": 1.65,
       "description": [
         "Just like with hex code, you can represent different colors in RGB by using combinations of different values.",
@@ -3823,8 +3757,7 @@
     },
     {
       "id": "bad80fee1348bd9aedf08723",
-      "name": "Waypoint: Use RGB to Color Elements Green",
-      "dashedName": "waypoint-use-rgb-to-color-elements-green",
+      "title": "Waypoint: Use RGB to Color Elements Green",
       "difficulty": 1.66,
       "description": [
         "Now change the <code>body</code> element's background color to the RGB value green: <code>rgb(0, 255, 0)</code>"
@@ -3856,8 +3789,7 @@
     },
     {
       "id": "bad81fee1348bd9aedf08722",
-      "name": "Waypoint: Use RGB to Color Elements Blue",
-      "dashedName": "waypoint-use-rgb-to-color-elements-blue",
+      "title": "Waypoint: Use RGB to Color Elements Blue",
       "difficulty": 1.67,
       "description": [
         "Change the <code>body</code> element's background color to the RGB value blue: <code>rgb(0, 0, 255)</code>"
@@ -3889,8 +3821,7 @@
     },
     {
       "id": "bad82fee1348bd9aedf08721",
-      "name": "Waypoint: Use RGB to Mix Colors",
-      "dashedName": "waypoint-use-rgb-to-mix-colors",
+      "title": "Waypoint: Use RGB to Mix Colors",
       "difficulty": 1.68,
       "description": [
         "Just like with hex code, you can mix colors in RGB by using combinations of different values.",
@@ -3923,8 +3854,7 @@
     },
     {
       "id": "bad83fee1348bd9aede08720",
-      "name": "Waypoint: Use RGB to Color Elements Gray",
-      "dashedName": "waypoint-use-rgb-to-color-elements-gray",
+      "title": "Waypoint: Use RGB to Color Elements Gray",
       "difficulty": 1.69,
       "description": [
         "With RGB values, we can make an element gray by using combinations of the same value for all three colors.",
diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index 184a648..36da68a 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -1,11 +1,10 @@
 {
-  "name": "Intermediate Algorithm Scripting",
+  "title": "Intermediate Algorithm Scripting",
   "order": 0.009,
   "challenges": [
     {
       "id": "a3566b1109230028080c9345",
-      "name": "Bonfire: Sum All Numbers in a Range",
-      "dashedName": "bonfire-sum-all-numbers-in-a-range",
+      "title": "Bonfire: Sum All Numbers in a Range",
       "difficulty": "2.00",
       "description": [
         "We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.",
@@ -45,8 +44,7 @@
     },
     {
       "id": "a5de63ebea8dbee56860f4f2",
-      "name": "Bonfire: Diff Two Arrays",
-      "dashedName": "bonfire-diff-two-arrays",
+      "title": "Bonfire: 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.",
@@ -91,8 +89,7 @@
     },
     {
       "id": "a7f4d8f2483413a6ce226cac",
-      "name": "Bonfire: Roman Numeral Converter",
-      "dashedName": "bonfire-roman-numeral-converter",
+      "title": "Bonfire: Roman Numeral Converter",
       "tests": [
         "expect(convert(12)).to.equal(\"XII\");",
         "expect(convert(5)).to.equal(\"V\");",
@@ -132,8 +129,7 @@
     },
     {
       "id": "a0b5010f579e69b815e7c5d6",
-      "name": "Bonfire: Search and Replace",
-      "dashedName": "bonfire-search-and-replace",
+      "title": "Bonfire: Search and Replace",
       "tests": [
         "expect(replace(\"Let us go to the store\", \"store\", \"mall\")).to.equal(\"Let us go to the mall\");",
         "expect(replace(\"He is Sleeping on the couch\", \"Sleeping\", \"sitting\")).to.equal(\"He is Sitting on the couch\");",
@@ -176,8 +172,7 @@
     },
     {
       "id": "aa7697ea2477d1316795783b",
-      "name": "Bonfire: Pig Latin",
-      "dashedName": "bonfire-pig-latin",
+      "title": "Bonfire: Pig Latin",
       "tests": [
         "expect(translate(\"california\")).to.equal(\"aliforniacay\");",
         "expect(translate(\"paragraphs\")).to.equal(\"aragraphspay\");",
@@ -220,8 +215,7 @@
     },
     {
       "id": "afd15382cdfb22c9efe8b7de",
-      "name": "Bonfire: DNA Pairing",
-      "dashedName": "bonfire-dna-pairing",
+      "title": "Bonfire: DNA Pairing",
       "tests": [
         "assert.deepEqual(pair(\"ATCGA\"),[['A','T'],['T','A'],['C','G'],['G','C'],['A','T']], 'should return the dna pair');",
         "assert.deepEqual(pair(\"TTGAG\"),[['T','A'],['T','A'],['G','C'],['A','T'],['G','C']], 'should return the dna pair');",
@@ -259,8 +253,7 @@
     },
     {
       "id": "af7588ade1100bde429baf20",
-      "name": "Bonfire: Missing letters",
-      "dashedName": "bonfire-missing-letters",
+      "title": "Bonfire: Missing letters",
       "difficulty": "2.05",
       "description": [
         "Find the missing letter in the passed letter range and return it.",
@@ -298,8 +291,7 @@
     },
     {
       "id": "a77dbc43c33f39daa4429b4f",
-      "name": "Bonfire: Boo who",
-      "dashedName": "bonfire-boo-who",
+      "title": "Bonfire: Boo who",
       "difficulty": "2.06",
       "description": [
         "Check if a value is classified as a boolean primitive. Return true or false.",
@@ -341,8 +333,7 @@
     },
     {
       "id": "a105e963526e7de52b219be9",
-      "name": "Bonfire: Sorted Union",
-      "dashedName": "bonfire-sorted-union",
+      "title": "Bonfire: 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.",
@@ -382,8 +373,7 @@
     },
     {
       "id": "a6b0bb188d873cb2c8729495",
-      "name": "Bonfire: Convert HTML Entities",
-      "dashedName": "bonfire-convert-html-entities",
+      "title": "Bonfire: Convert HTML Entities",
       "difficulty": "2.07",
       "description": [
         "Convert the characters \"&\", \"<\", \">\", '\"' (double quote), and \"'\" (apostrophe), in a string to their corresponding HTML entities.",
@@ -424,8 +414,7 @@
     },
     {
       "id": "a103376db3ba46b2d50db289",
-      "name": "Bonfire: Spinal Tap Case",
-      "dashedName": "bonfire-spinal-tap-case",
+      "title": "Bonfire: Spinal Tap Case",
       "difficulty": "2.08",
       "description": [
         "Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes.",
@@ -464,8 +453,7 @@
     },
     {
       "id": "a5229172f011153519423690",
-      "name": "Bonfire: Sum All Odd Fibonacci Numbers",
-      "dashedName": "bonfire-sum-all-odd-fibonacci-numbers",
+      "title": "Bonfire: 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.",
@@ -505,8 +493,7 @@
     },
     {
       "id": "a3bfc1673c0526e06d3ac698",
-      "name": "Bonfire: Sum All Primes",
-      "dashedName": "bonfire-sum-all-primes",
+      "title": "Bonfire: Sum All Primes",
       "difficulty": "2.10",
       "description": [
         "Sum all the prime numbers up to and including the provided number.",
@@ -544,8 +531,7 @@
     },
     {
       "id": "ae9defd7acaf69703ab432ea",
-      "name": "Bonfire: Smallest Common Multiple",
-      "dashedName": "bonfire-smallest-common-multiple",
+      "title": "Bonfire: Smallest Common Multiple",
       "difficulty": "2.11",
       "description": [
         "Find the smallest number that is evenly divisible by all numbers in the provided range.",
@@ -583,8 +569,7 @@
     },
     {
       "id": "a6e40f1041b06c996f7b2406",
-      "name": "Bonfire: Finders Keepers",
-      "dashedName": "bonfire-finders-keepers",
+      "title": "Bonfire: 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).",
@@ -619,8 +604,7 @@
     },
     {
       "id": "a5deed1811a43193f9f1c841",
-      "name": "Bonfire: Drop it",
-      "dashedName": "bonfire-drop-it",
+      "title": "Bonfire: Drop it",
       "difficulty": "2.13",
       "description": [
         "Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true.",
@@ -657,8 +641,7 @@
     },
     {
       "id": "ab306dbdcc907c7ddfc30830",
-      "name": "Bonfire: Steamroller",
-      "dashedName": "bonfire-steamroller",
+      "title": "Bonfire: Steamroller",
       "difficulty": "2.14",
       "description": [
         "Flatten a nested array. You must account for varying levels of nesting.",
@@ -695,8 +678,7 @@
     },
     {
       "id": "a8d97bd4c764e91f9d2bda01",
-      "name": "Bonfire: Binary Agents",
-      "dashedName": "bonfire-binary-agents",
+      "title": "Bonfire: Binary Agents",
       "difficulty": "2.15",
       "description": [
         "Return an English translated sentence of the passed binary string.",
@@ -732,8 +714,7 @@
     },
     {
       "id": "a10d2431ad0c6a099a4b8b52",
-      "name": "Bonfire: Everything Be True",
-      "dashedName": "bonfire-everything-be-true",
+      "title": "Bonfire: Everything Be True",
       "difficulty": "2.21",
       "description": [
         "Check if the predicate (second argument) returns truthy (defined) for all elements of a collection (first argument).",
@@ -753,7 +734,6 @@
         "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');",
         "assert.strictEqual(every([{'user': 'Tinky-Winky', 'sex': 'female'}, {'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');"
-
       ],
       "MDNlinks": [
         "Object.hasOwnProperty()",
@@ -773,8 +753,7 @@
     },
     {
       "id": "a97fd23d9b809dac9921074f",
-      "name": "Bonfire: Arguments Optional",
-      "dashedName": "bonfire-arguments-optional",
+      "title": "Bonfire: Arguments Optional",
       "difficulty": "2.22",
       "description": [
         "Create a function that sums two arguments together. If only one argument is provided, return a function that expects one additional argument and will return the sum.",
diff --git a/seed/challenges/intermediate-ziplines.json b/seed/challenges/intermediate-ziplines.json
index f8a267e..28537fa 100644
--- a/seed/challenges/intermediate-ziplines.json
+++ b/seed/challenges/intermediate-ziplines.json
@@ -1,11 +1,10 @@
 {
-  "name": "Intermediate Front End Development Projects",
+  "title": "Intermediate Front End Development Projects",
   "order": 0.018,
   "challenges": [
     {
       "id": "bd7158d8c442eddfaeb5bd18",
-      "name": "Zipline: Stylize Stories on Camper News",
-      "dashedName": "zipline-stylize-stories-on-camper-news",
+      "title": "Zipline: Stylize Stories on Camper News",
       "difficulty": 1.02,
       "challengeSeed": ["126415129"],
       "description": [
@@ -38,8 +37,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd19",
-      "name": "Zipline: Wikipedia Viewer",
-      "dashedName": "zipline-wikipedia-viewer",
+      "title": "Zipline: Wikipedia Viewer",
       "difficulty": 1.03,
       "challengeSeed": ["126415131"],
       "description": [
@@ -71,8 +69,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd17",
-      "name": "Zipline: Build a JavaScript Calculator",
-      "dashedName": "zipline-build-a-javascript-calculator",
+      "title": "Zipline: Build a JavaScript Calculator",
       "difficulty": 1.05,
       "challengeSeed": ["126411565"],
       "description": [
@@ -103,8 +100,7 @@
     },
     {
       "id": "bd7158d8c442eedfaeb5bd1c",
-      "name": "Zipline: Build a Tic Tac Toe Game",
-      "dashedName": "zipline-build-a-tic-tac-toe-game",
+      "title": "Zipline: Build a Tic Tac Toe Game",
       "difficulty": 1.06,
       "challengeSeed": ["126415123"],
       "description": [
@@ -136,8 +132,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd1c",
-      "name": "Zipline: Build a Simon Game",
-      "dashedName": "zipline-build-a-simon-game",
+      "title": "Zipline: Build a Simon Game",
       "difficulty": 1.07,
       "challengeSeed": ["126415123"],
       "description": [
diff --git a/seed/challenges/jquery-ajax-and-json.json b/seed/challenges/jquery-ajax-and-json.json
index abf05bc..23ec394 100644
--- a/seed/challenges/jquery-ajax-and-json.json
+++ b/seed/challenges/jquery-ajax-and-json.json
@@ -1,12 +1,10 @@
 {
-  "name":  "jQuery",
-  "dashedName":  "jquery",
+  "title":  "jQuery",
   "order": 0.004,
   "challenges": [
     {
       "id": "bad87fee1348bd9acdd08826",
-      "name":  "Waypoint: Learn how Script Tags and Document Ready Work",
-      "dashedName":  "waypoint-learn-how-script-tags-and-document-ready-work",
+      "title":  "Waypoint: Learn how Script Tags and Document Ready Work",
       "difficulty": 3.01,
       "description": [
         "Now we're ready to learn jQuery, the most popular JavaScript tool of all time. Don't worry about JavaScript itself - we will cover it soon.",
@@ -46,11 +44,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9bedc08826",
-      "name":  "Waypoint: Target HTML Elements with Selectors Using jQuery",
-      "dashedName":  "waypoint-target-html-elements-with-selectors-using-jquery",
+      "title":  "Waypoint: Target HTML Elements with Selectors Using jQuery",
       "difficulty": 3.02,
       "description": [
         "Now we have a \"document ready function\". We'll learn more about functions later. The important thing to know is that code you put inside this function will run as soon as your browser has loaded your page.",
@@ -96,11 +92,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aedc08826",
-      "name":  "Waypoint: Target Elements by Class Using jQuery",
-      "dashedName":  "waypoint-target-elements-by-class-using-jquery",
+      "title":  "Waypoint: Target Elements by Class Using jQuery",
       "difficulty": 3.03,
       "description": [
         "You see how we made all of your <code>button</code> elements bounce? We selected them with <code>$('button')</code>, then we added some CSS classes to them with <code>.addClass('animated bounce');</code>.",
@@ -149,8 +143,7 @@
     },
     {
       "id": "bad87fee1348bd9aeda08826",
-      "name":  "Waypoint: Target Elements by ID Using jQuery",
-      "dashedName":  "waypoint-target-elements-by-id-using-jquery",
+      "title":  "Waypoint: Target Elements by ID Using jQuery",
       "difficulty": 3.04,
       "description": [
         "You can also target elements by their id attributes.",
@@ -198,11 +191,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aeda08726",
-      "name":  "Waypoint: Delete your jQuery Functions",
-      "dashedName":  "waypoint-delete-your-jquery-functions",
+      "title":  "Waypoint: Delete your jQuery Functions",
       "difficulty": 3.05,
       "description": [
         "These animations were cool at first, but now they're getting kind of distracting.",
@@ -253,8 +244,7 @@
     },
     {
       "id": "bad87fee1348bd9aed908626",
-      "name":  "Waypoint: Target the same element with multiple jQuery Selectors",
-      "dashedName":  "waypoint-target-the-same-element-with-multiple-jQuery-Selectors",
+      "title":  "Waypoint: Target the same element with multiple jQuery Selectors",
       "difficulty": 3.06,
       "description": [
         "Now you know three ways of targeting elements: by type <code>$('button')</code>, by class <code>$('.btn')</code>), and by id <code>$('#target1')</code>).",
@@ -304,8 +294,7 @@
     },
     {
       "id": "bad87fee1348bd9aed918626",
-      "name":  "Waypoint: Remove Classes from an element with jQuery",
-      "dashedName":  "waypoint-remove-classes-from-an-element-with-jquery",
+      "title":  "Waypoint: Remove Classes from an element with jQuery",
       "difficulty": 3.07,
       "description": [
         "In the same way you can add classes to an element with jQuery's <code>addClass()</code> function, you can remove them with jQuery's <code>removeClass()</code> function.",
@@ -354,8 +343,7 @@
     },
     {
       "id": "bad87fee1348bd9aed908826",
-      "name":  "Waypoint: Change the CSS of an Element Using jQuery",
-      "dashedName":  "waypoint-change-the-css-of-an-element-using-jquery",
+      "title":  "Waypoint: Change the CSS of an Element Using jQuery",
       "difficulty": 3.08,
       "description": [
         "We can also change the CSS of an HTML element directly with jQuery.",
@@ -406,11 +394,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed808826",
-      "name":  "Waypoint: Disable an Element Using jQuery",
-      "dashedName":  "waypoint-disable-an-element-using-jquery",
+      "title":  "Waypoint: Disable an Element Using jQuery",
       "difficulty": 3.09,
       "description": [
         "You can also change the non-CSS properties of HTML elements with jQuery. For example, you can disable buttons.",
@@ -458,11 +444,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed708826",
-      "name":  "Waypoint: Remove an Element Using jQuery",
-      "dashedName":  "waypoint-remove-an-element-using-jquery",
+      "title":  "Waypoint: Remove an Element Using jQuery",
       "difficulty": 3.10,
       "description": [
         "Now let's remove an HTML element from your page using jQuery.",
@@ -507,11 +491,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed608826",
-      "name":  "Waypoint: Use appendTo to Move Elements with jQuery",
-      "dashedName":  "waypoint-use-appendto-to-move-elements-with-jquery",
+      "title":  "Waypoint: Use appendTo to Move Elements with jQuery",
       "difficulty": 3.11,
       "description": [
         "Now let's try moving elements from one <code>div</code> to another.",
@@ -560,11 +542,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed508826",
-      "name":  "Waypoint: Clone an Element Using jQuery",
-      "dashedName":  "waypoint-clone-an-element-using-jquery",
+      "title":  "Waypoint: Clone an Element Using jQuery",
       "difficulty": 3.12,
       "description": [
         "In addition to moving elements, you can also copy them from one place to another.",
@@ -615,11 +595,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed308826",
-      "name":  "Waypoint: Target the Parent of an Element Using jQuery",
-      "dashedName":  "waypoint-target-the-parent-of-an-element-using-jquery",
+      "title":  "Waypoint: Target the Parent of an Element Using jQuery",
       "difficulty": 3.13,
       "description": [
         "Every HTML elements has a \"parent\" element from which it \"inherits\" properties.",
@@ -671,11 +649,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed208826",
-      "name":  "Waypoint: Target the Children of an Element Using jQuery",
-      "dashedName":  "waypoint-target-the-children-of-an-element-using-jquery",
+      "title":  "Waypoint: Target the Children of an Element Using jQuery",
       "difficulty": 3.14,
       "description": [
         "Many HTML elements has a \"children\" element from which they \"inherits\" properties.",
@@ -730,8 +706,7 @@
     },
     {
       "id": "bad87fee1348bd9aed108826",
-      "name":  "Waypoint: Target a Specific Child of an Element Using jQuery",
-      "dashedName":  "waypoint-target-a-specific-child-of-an-element-using-jquery",
+      "title":  "Waypoint: Target a Specific Child of an Element Using jQuery",
       "difficulty": 3.15,
       "description": [
         "You've seen why id attributes are so convenient for targeting with jQuery selectors. But you won't always have such neat ids to work with.",
@@ -785,11 +760,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aed008826",
-      "name":  "Waypoint: Target Even Numbered Elements Using jQuery",
-      "dashedName":  "waypoint-target-even-numbered-elements-using-jquery",
+      "title":  "Waypoint: Target Even Numbered Elements Using jQuery",
       "difficulty": 3.16,
       "description": [
         "You can also target all the even-numbered elements.",
@@ -845,11 +818,9 @@
       ],
       "challengeType": 0
     },
-
     {
       "id": "bad87fee1348bd9aecb08826",
-      "name":  "Waypoint: Use jQuery to Modify the Entire Page",
-      "dashedName":  "waypoint-use-jquery-to-modify-the-entire-page",
+      "title":  "Waypoint: Use jQuery to Modify the Entire Page",
       "difficulty": 3.20,
       "description": [
         "We're done playing with our jQuery playground. Let's tear it down!",
diff --git a/seed/challenges/json-apis-and-ajax.json b/seed/challenges/json-apis-and-ajax.json
index d6b39f9..d0bc291 100644
--- a/seed/challenges/json-apis-and-ajax.json
+++ b/seed/challenges/json-apis-and-ajax.json
@@ -1,6 +1,5 @@
 {
-  "name":  "JSON APIs and Ajax - Coming Soon",
-  "dashedName":  "json-apis-and-ajax",
+  "title":  "JSON APIs and Ajax - Coming Soon",
   "order": 0.007,
   "challenges": [
   ]
diff --git a/seed/challenges/mongodb.json b/seed/challenges/mongodb.json
index a632eaf..a583182 100644
--- a/seed/challenges/mongodb.json
+++ b/seed/challenges/mongodb.json
@@ -1,11 +1,10 @@
 {
-  "name": "MongoDB",
+  "title": "MongoDB",
   "order" : 0.016,
   "challenges": [
     {
       "id": "bd7243d8c341eddeaeb5bd0f",
-      "name": "Waypoint: Store Data in MongoDB",
-      "dashedName": "waypoint-store-data-in-mongodb",
+      "title": "Waypoint: Store Data in MongoDB",
       "difficulty": 0.01,
       "challengeSeed": ["133316035"],
       "description": [
diff --git a/seed/challenges/nodejs-and-expressjs.json b/seed/challenges/nodejs-and-expressjs.json
index ac307b5..710f484 100644
--- a/seed/challenges/nodejs-and-expressjs.json
+++ b/seed/challenges/nodejs-and-expressjs.json
@@ -1,11 +1,10 @@
 {
-  "name": "Node.js and Express.js",
+  "title": "Node.js and Express.js",
   "order" : 0.015,
   "challenges": [
     {
       "id": "bd7153d8c441eddfaeb5bd0f",
-      "name": "Waypoint: Manage Packages with NPM",
-      "dashedName": "waypoint-manage-packages-with-npm",
+      "title": "Waypoint: Manage Packages with NPM",
       "difficulty": 0.39,
       "challengeSeed": ["126433450"],
       "description": [
@@ -58,8 +57,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bdff",
-      "name": "Waypoint: Start a Node.js Server",
-      "dashedName": "waypoint-start-a-nodejs-server",
+      "title": "Waypoint: Start a Node.js Server",
       "difficulty": 0.40,
       "challengeSeed": ["126411561"],
       "description": [
@@ -100,8 +98,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bdfe",
-      "name": "Waypoint: Continue working with Node.js Servers",
-      "dashedName": "waypoint-continue-working-with-nodejs-servers",
+      "title": "Waypoint: Continue working with Node.js Servers",
       "difficulty": 0.41,
       "challengeSeed": ["128836506"],
       "description": [
@@ -129,8 +126,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bdfd",
-      "name": "Waypoint: Finish working with Node.js Servers",
-      "dashedName": "waypoint-finish-working-with-nodejs-servers",
+      "title": "Waypoint: Finish working with Node.js Servers",
       "difficulty": 0.42,
       "challengeSeed": ["128836507"],
       "description": [
@@ -158,8 +154,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bd1f",
-      "name": "Waypoint: Build Web Apps with Express.js",
-      "dashedName": "waypoint-build-web-apps-with-expressjs",
+      "title": "Waypoint: Build Web Apps with Express.js",
       "difficulty": 0.43,
       "challengeSeed": [
         "126411559"
diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index d3a16cc..78d5437 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -1,11 +1,10 @@
 {
-  "name": "Object Oriented and Functional Programming",
+  "title": "Object Oriented and Functional Programming",
   "order" : 0.010,
   "challenges": [
     {
       "id": "bd7153d8c44eeddfaeb5bd0f",
-      "name": "Waypoint: Learn Scope Chains and Closures",
-      "dashedName": "waypoint-learn-scope-chains-and-closures",
+      "title": "Waypoint: Learn Scope Chains and Closures",
       "difficulty": 0.01,
       "challengeSeed": ["133316031"],
       "description": [
@@ -44,8 +43,7 @@
     },
     {
       "id": "bd7153d8b44eeddfaeb5bd0f",
-      "name": "Waypoint: Use Prototypes for Inheriting Properties",
-      "dashedName": "waypoint-use-prototypes-for-inheriting-properties",
+      "title": "Waypoint: Use Prototypes for Inheriting Properties",
       "difficulty": 0.02,
       "challengeSeed": ["133316036"],
       "description": [
@@ -89,8 +87,7 @@
     },
     {
       "id": "bd7129d8c441eddfbeb5bddf",
-      "name": "Waypoint: Practice Functional Programming",
-      "dashedName": "waypoint-practice-functional-programming",
+      "title": "Waypoint: Practice Functional Programming",
       "difficulty": 0.01,
       "challengeSeed": ["129169463"],
       "description": [
diff --git a/seed/index.js b/seed/index.js
index 8c9b8e9..fdbdf1f 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -41,7 +41,9 @@ Challenge.destroyAll(function(err, info) {
     var challenges = require('./challenges/' + file).challenges
       .map(function(challenge) {
         // NOTE(berks): add title for displaying in views
-        challenge.title = challenge.name.replace(challangesRegex, '').trim();
+        //challenge.title = challenge.name.replace(challangesRegex, '').trim();
+        challenge.name = challenge.title.replace(/[^a-zA-Z0-9 ]/g, ''); // Remove non-alphanumwhitespace chars
+        challenge.dashedName = challenge.name.replace(/\s/g, '-'); // Replace with dasherize();
         return challenge;
       });
 
diff --git a/server/utils/index.js b/server/utils/index.js
index 784aa71..2fd19d0 100644
--- a/server/utils/index.js
+++ b/server/utils/index.js
@@ -75,8 +75,8 @@ module.exports = {
       challengeMapForDisplay = {};
       Object.keys(challengeMap).forEach(function(key) {
         challengeMapForDisplay[key] = {
-          name: challengeMap[key].name,
-          dashedName: challengeMap[key].name.replace(/\s/g, '-'),
+          name: challengeMap[key].title,
+          dashedName: challengeMap[key].title.replace(/\s/g, '-'),
           challenges: challengeMap[key].challenges,
           completedCount: challengeMap[key].challenges
         };

From f241a362d5090658ccbde97652776f2f571de323 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Fri, 7 Aug 2015 18:43:45 -0700
Subject: [PATCH 08/47] rename top level `title` to name

---
 seed/challenges/advanced-bonfires.json                          | 2 +-
 seed/challenges/angularjs.json                                  | 2 +-
 seed/challenges/automated-testing-and-debugging.json            | 2 +-
 seed/challenges/basejumps.json                                  | 2 +-
 seed/challenges/basic-bonfires.json                             | 2 +-
 seed/challenges/basic-javascript.json                           | 2 +-
 seed/challenges/basic-ziplines.json                             | 2 +-
 seed/challenges/bootstrap.json                                  | 2 +-
 seed/challenges/expert-bonfires.json                            | 2 +-
 seed/challenges/get-set-for-free-code-camp.json                 | 2 +-
 seed/challenges/git.json                                        | 2 +-
 seed/challenges/hikes.json                                      | 2 +-
 seed/challenges/html5-and-css.json                              | 2 +-
 seed/challenges/intermediate-bonfires.json                      | 2 +-
 seed/challenges/intermediate-ziplines.json                      | 2 +-
 seed/challenges/jquery-ajax-and-json.json                       | 2 +-
 seed/challenges/json-apis-and-ajax.json                         | 2 +-
 seed/challenges/mongodb.json                                    | 2 +-
 seed/challenges/nodejs-and-expressjs.json                       | 2 +-
 seed/challenges/object-oriented-and-functional-programming.json | 2 +-
 20 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/seed/challenges/advanced-bonfires.json b/seed/challenges/advanced-bonfires.json
index 86b0c3f..9f51884 100644
--- a/seed/challenges/advanced-bonfires.json
+++ b/seed/challenges/advanced-bonfires.json
@@ -1,5 +1,5 @@
 {
-  "title": "Advanced Algorithm Scripting",
+  "name": "Advanced Algorithm Scripting",
   "order": 0.011,
   "challenges": [
     {
diff --git a/seed/challenges/angularjs.json b/seed/challenges/angularjs.json
index 48ad048..2e6815f 100644
--- a/seed/challenges/angularjs.json
+++ b/seed/challenges/angularjs.json
@@ -1,5 +1,5 @@
 {
-  "title": "AngularJS",
+  "name": "AngularJS",
   "order": 0.017,
   "challenges": [
     {
diff --git a/seed/challenges/automated-testing-and-debugging.json b/seed/challenges/automated-testing-and-debugging.json
index 00181f0..2755fd7 100644
--- a/seed/challenges/automated-testing-and-debugging.json
+++ b/seed/challenges/automated-testing-and-debugging.json
@@ -1,5 +1,5 @@
 {
-  "title": "Automated Testing and Debugging - Coming Soon",
+  "name": "Automated Testing and Debugging - Coming Soon",
   "order": 0.012,
   "challenges": [
   ]
diff --git a/seed/challenges/basejumps.json b/seed/challenges/basejumps.json
index 67c9023..528b4da 100644
--- a/seed/challenges/basejumps.json
+++ b/seed/challenges/basejumps.json
@@ -1,5 +1,5 @@
 {
-  "title": "Full Stack JavaScript Projects",
+  "name": "Full Stack JavaScript Projects",
   "order": 0.019,
   "challenges": [
     {
diff --git a/seed/challenges/basic-bonfires.json b/seed/challenges/basic-bonfires.json
index 4c2c7d8..1821ad5 100644
--- a/seed/challenges/basic-bonfires.json
+++ b/seed/challenges/basic-bonfires.json
@@ -1,5 +1,5 @@
 {
-  "title": "Basic Algorithm Scripting",
+  "name": "Basic Algorithm Scripting",
   "order": 0.006,
   "challenges": [
     {
diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index 4566d48..80971b7 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -1,5 +1,5 @@
 {
-  "title": "Basic JavaScript",
+  "name": "Basic JavaScript",
   "order": 0.005,
   "challenges": [
     {
diff --git a/seed/challenges/basic-ziplines.json b/seed/challenges/basic-ziplines.json
index 5a9efb9..ea667f7 100644
--- a/seed/challenges/basic-ziplines.json
+++ b/seed/challenges/basic-ziplines.json
@@ -1,5 +1,5 @@
 {
-  "title": "Basic Front End Development Projects",
+  "name": "Basic Front End Development Projects",
   "order": 0.008,
   "challenges": [
     {
diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index 146857a..d9ac143 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -1,5 +1,5 @@
 {
-  "title": "Responsive Design with Bootstrap",
+  "name": "Responsive Design with Bootstrap",
   "order": 0.003,
   "challenges": [
     {
diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
index 6709b24..8c5af39 100644
--- a/seed/challenges/expert-bonfires.json
+++ b/seed/challenges/expert-bonfires.json
@@ -1,5 +1,5 @@
 {
-  "title": "Expert Algorithm Scripting",
+  "name": "Expert Algorithm Scripting",
   "order": 0.013,
   "challenges": [
     {
diff --git a/seed/challenges/get-set-for-free-code-camp.json b/seed/challenges/get-set-for-free-code-camp.json
index 7be7730..1276335 100644
--- a/seed/challenges/get-set-for-free-code-camp.json
+++ b/seed/challenges/get-set-for-free-code-camp.json
@@ -1,5 +1,5 @@
 {
-  "title": "Get Set for Free Code Camp",
+  "name": "Get Set for Free Code Camp",
   "order": 0.001,
   "challenges": [
     {
diff --git a/seed/challenges/git.json b/seed/challenges/git.json
index cafffcd..e87eb4b 100644
--- a/seed/challenges/git.json
+++ b/seed/challenges/git.json
@@ -1,5 +1,5 @@
 {
-  "title": "Git",
+  "name": "Git",
   "order" : 0.014,
   "challenges": [
     {
diff --git a/seed/challenges/hikes.json b/seed/challenges/hikes.json
index bb80106..8855b0e 100644
--- a/seed/challenges/hikes.json
+++ b/seed/challenges/hikes.json
@@ -1,5 +1,5 @@
 {
-  "title": "Hikes",
+  "name": "Hikes",
   "order": 0.050,
   "challenges": [
     {
diff --git a/seed/challenges/html5-and-css.json b/seed/challenges/html5-and-css.json
index 69236fd..77df5f4 100644
--- a/seed/challenges/html5-and-css.json
+++ b/seed/challenges/html5-and-css.json
@@ -1,5 +1,5 @@
 {
-  "title": "HTML5 and CSS",
+  "name": "HTML5 and CSS",
   "order": 0.002,
   "challenges": [
     {
diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index 36da68a..b9e9882 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -1,5 +1,5 @@
 {
-  "title": "Intermediate Algorithm Scripting",
+  "name": "Intermediate Algorithm Scripting",
   "order": 0.009,
   "challenges": [
     {
diff --git a/seed/challenges/intermediate-ziplines.json b/seed/challenges/intermediate-ziplines.json
index 28537fa..ff900aa 100644
--- a/seed/challenges/intermediate-ziplines.json
+++ b/seed/challenges/intermediate-ziplines.json
@@ -1,5 +1,5 @@
 {
-  "title": "Intermediate Front End Development Projects",
+  "name": "Intermediate Front End Development Projects",
   "order": 0.018,
   "challenges": [
     {
diff --git a/seed/challenges/jquery-ajax-and-json.json b/seed/challenges/jquery-ajax-and-json.json
index 23ec394..a5db78c 100644
--- a/seed/challenges/jquery-ajax-and-json.json
+++ b/seed/challenges/jquery-ajax-and-json.json
@@ -1,5 +1,5 @@
 {
-  "title":  "jQuery",
+  "name":  "jQuery",
   "order": 0.004,
   "challenges": [
     {
diff --git a/seed/challenges/json-apis-and-ajax.json b/seed/challenges/json-apis-and-ajax.json
index d0bc291..cefd0f0 100644
--- a/seed/challenges/json-apis-and-ajax.json
+++ b/seed/challenges/json-apis-and-ajax.json
@@ -1,5 +1,5 @@
 {
-  "title":  "JSON APIs and Ajax - Coming Soon",
+  "name":  "JSON APIs and Ajax - Coming Soon",
   "order": 0.007,
   "challenges": [
   ]
diff --git a/seed/challenges/mongodb.json b/seed/challenges/mongodb.json
index a583182..75b24f2 100644
--- a/seed/challenges/mongodb.json
+++ b/seed/challenges/mongodb.json
@@ -1,5 +1,5 @@
 {
-  "title": "MongoDB",
+  "name": "MongoDB",
   "order" : 0.016,
   "challenges": [
     {
diff --git a/seed/challenges/nodejs-and-expressjs.json b/seed/challenges/nodejs-and-expressjs.json
index 710f484..34d5401 100644
--- a/seed/challenges/nodejs-and-expressjs.json
+++ b/seed/challenges/nodejs-and-expressjs.json
@@ -1,5 +1,5 @@
 {
-  "title": "Node.js and Express.js",
+  "name": "Node.js and Express.js",
   "order" : 0.015,
   "challenges": [
     {
diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index 78d5437..90042d6 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -1,5 +1,5 @@
 {
-  "title": "Object Oriented and Functional Programming",
+  "name": "Object Oriented and Functional Programming",
   "order" : 0.010,
   "challenges": [
     {

From 26e69c8621827ccffc81a83e37ee83add4238bfd Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Fri, 7 Aug 2015 23:37:32 -0700
Subject: [PATCH 09/47] add type to challenges

---
 common/models/challenge.json                       |   3 +
 seed/challenges/advanced-bonfires.json             |   9 +-
 seed/challenges/angularjs.json                     |  15 +-
 seed/challenges/basejumps.json                     |  18 +-
 seed/challenges/basic-bonfires.json                |  54 ++++--
 seed/challenges/basic-javascript.json              | 120 ++++++++----
 seed/challenges/basic-ziplines.json                |  18 +-
 seed/challenges/bootstrap.json                     |  90 ++++++---
 seed/challenges/expert-bonfires.json               |  18 +-
 seed/challenges/get-set-for-free-code-camp.json    |  27 ++-
 seed/challenges/git.json                           |   3 +-
 seed/challenges/hikes.json                         |  63 ++++---
 seed/challenges/html5-and-css.json                 | 207 ++++++++++++++-------
 seed/challenges/intermediate-bonfires.json         |  60 ++++--
 seed/challenges/intermediate-ziplines.json         |  15 +-
 seed/challenges/jquery-ajax-and-json.json          |  53 ++++--
 seed/challenges/json-apis-and-ajax.json            |   2 +-
 seed/challenges/mongodb.json                       |   3 +-
 seed/challenges/nodejs-and-expressjs.json          |  15 +-
 ...object-oriented-and-functional-programming.json |   9 +-
 20 files changed, 535 insertions(+), 267 deletions(-)

diff --git a/common/models/challenge.json b/common/models/challenge.json
index baa78a4..910b61d 100644
--- a/common/models/challenge.json
+++ b/common/models/challenge.json
@@ -16,6 +16,9 @@
     "title": {
       "type": "string"
     },
+    "type": {
+      "type": "string"
+    },
     "dashedName": {
       "type": "string"
     },
diff --git a/seed/challenges/advanced-bonfires.json b/seed/challenges/advanced-bonfires.json
index 9f51884..1b4e7dc 100644
--- a/seed/challenges/advanced-bonfires.json
+++ b/seed/challenges/advanced-bonfires.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "a2f1d72d9b908d0bd72bb9f6",
-      "title": "Bonfire: Make a Person",
+      "title": "Make a Person",
       "difficulty": "3.01",
       "description": [
         "Fill in the object constructor with the methods specified in the tests.",
@@ -41,6 +41,7 @@
         "Closures",
         "Details of the Object Model"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -55,7 +56,7 @@
     },
     {
       "id": "af4afb223120f7348cdfc9fd",
-      "title": "Bonfire: Map the Debris",
+      "title": "Map the Debris",
       "difficulty": "3.02",
       "description": [
         "Return a new array that transforms the element's average altitude into their orbital periods.",
@@ -81,6 +82,7 @@
       "MDNlinks": [
         "Math.pow()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -95,7 +97,7 @@
     },
     {
       "id": "a3f503de51cfab748ff001aa",
-      "title": "Bonfire: Pairwise",
+      "title": "Pairwise",
       "difficulty": "3.03",
       "description": [
         "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
@@ -120,6 +122,7 @@
       "MDNlinks": [
         "Array.reduce()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
diff --git a/seed/challenges/angularjs.json b/seed/challenges/angularjs.json
index 2e6815f..ba6071a 100644
--- a/seed/challenges/angularjs.json
+++ b/seed/challenges/angularjs.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7154d8c441eddfaeb5bdef",
-      "title": "Waypoint: Get Started with Angular.js",
+      "title": "Get Started with Angular.js",
       "difficulty": 0.34,
       "challengeSeed": ["114684726"],
       "description": [
@@ -12,6 +12,7 @@
         "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."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -27,7 +28,7 @@
     },
     {
       "id": "bd7155d8c441eddfaeb5bdef",
-      "title": "Waypoint: Apply Angular.js Directives",
+      "title": "Apply Angular.js Directives",
       "difficulty": 0.35,
       "challengeSeed": ["114684727"],
       "description": [
@@ -35,6 +36,7 @@
         "Let's learn how these powerful directives work, and how to use them to make your web apps more dynamic",
         "Go to <a href='http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/2/section/1/video/1' target='_blank'>http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/2/section/1/video/1</a> and complete the section."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -50,7 +52,7 @@
     },
     {
       "id": "bd7156d8c441eddfaeb5bdef",
-      "title": "Waypoint: Power Forms with Angular.js",
+      "title": "Power Forms with Angular.js",
       "difficulty": 0.36,
       "challengeSeed": ["114684729"],
       "description": [
@@ -58,6 +60,7 @@
         "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."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -73,13 +76,14 @@
     },
     {
       "id": "bd7157d8c441eddfaeb5bdef",
-      "title": "Waypoint: Customize Angular.js Directives",
+      "title": "Customize Angular.js Directives",
       "difficulty": 0.37,
       "challengeSeed": ["114685062"],
       "description": [
         "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."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -95,7 +99,7 @@
     },
     {
       "id": "bd7158d8c441eddfaeb5bdef",
-      "title": "Waypoint: Create Angular.js Services",
+      "title": "Create Angular.js Services",
       "difficulty": 0.38,
       "challengeSeed": ["114685060"],
       "description": [
@@ -103,6 +107,7 @@
         "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."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/basejumps.json b/seed/challenges/basejumps.json
index 528b4da..fcad55c 100644
--- a/seed/challenges/basejumps.json
+++ b/seed/challenges/basejumps.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7158d8c443eddfaeb5bcef",
-      "title": "Waypoint: Get Set for Basejumps",
+      "title": "Get Set for Basejumps",
       "difficulty": 2.00,
       "challengeSeed": ["128451852"],
       "description": [
@@ -59,12 +59,13 @@
         "If you need further guidance on using Yeoman Angular-Fullstack Generator, check out: <a href='https://github.com/clnhll/guidetobasejumps' target='_blank'>https://github.com/clnhll/guidetobasejumps</a>.",
         "Now you're ready to move on to your first Basejump. Click the \"I've completed this challenge\" and move on."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": []
     },
     {
       "id": "bd7158d8c443eddfaeb5bdef",
-      "title": "Basejump: Build a Voting App",
+      "title": "Build a Voting App",
       "difficulty": 2.01,
       "challengeSeed": ["133315786"],
       "description": [
@@ -85,6 +86,7 @@
         "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
         "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku 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>"
       ],
+      "type": "basejumps",
       "challengeType": 4,
       "tests": [],
       "nameCn": "",
@@ -100,7 +102,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bdff",
-      "title": "Basejump: Build a Nightlife Coordination App",
+      "title": "Build a Nightlife Coordination App",
       "difficulty": 2.02,
       "challengeSeed": ["133315781"],
       "description": [
@@ -118,6 +120,7 @@
         "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
         "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku 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>"
       ],
+      "type": "basejumps",
       "challengeType": 4,
       "tests": [],
       "nameCn": "",
@@ -133,7 +136,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bd0e",
-      "title": "Basejump: Chart the Stock Market",
+      "title": "Chart the Stock Market",
       "difficulty": 2.03,
       "challengeSeed": ["133315787"],
       "description": [
@@ -150,6 +153,7 @@
         "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
         "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku 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>"
       ],
+      "type": "basejumps",
       "challengeType": 4,
       "tests": [],
       "nameCn": "",
@@ -165,7 +169,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bd0f",
-      "title": "Basejump: Manage a Book Trading Club",
+      "title": "Manage a Book Trading Club",
       "difficulty": 2.04,
       "challengeSeed": ["133316032"],
       "description": [
@@ -182,6 +186,7 @@
         "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
         "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku 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>"
       ],
+      "type": "basejumps",
       "challengeType": 4,
       "tests": [],
       "nameCn": "",
@@ -197,7 +202,7 @@
     },
     {
       "id": "bd7158d8c443eddfaeb5bdee",
-      "title": "Basejump: Build a Pinterest Clone",
+      "title": "Build a Pinterest Clone",
       "difficulty": 2.05,
       "challengeSeed": ["133315784"],
       "description": [
@@ -217,6 +222,7 @@
         "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku. If you pair programmed with a friend, enter his or her Free Code Camp username as well so that you both get credit for completing it.",
         "If you'd like immediate feedback on your project, click this button and paste in a link to your Heroku 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>"
       ],
+      "type": "basejumps",
       "challengeType": 4,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/basic-bonfires.json b/seed/challenges/basic-bonfires.json
index 1821ad5..3b411ef 100644
--- a/seed/challenges/basic-bonfires.json
+++ b/seed/challenges/basic-bonfires.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7139d8c441eddfaeb5bdef",
-      "title": "Waypoint: Pair Program on Bonfires",
+      "title": "Pair Program on Bonfires",
       "difficulty": 0.44,
       "challengeSeed": [
         "119657641"
@@ -28,6 +28,7 @@
         "Pair program as much as possible with different campers until you've completed all the Bonfire challenges. This is a big time investment, but the JavaScript practice you get will be well worth it!",
         "Mark this Waypoint complete and move on."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -43,7 +44,7 @@
     },
     {
       "id": "ad7123c8c441eddfaeb5bdef",
-      "title": "Bonfire: Meet Bonfire",
+      "title": "Meet Bonfire",
       "difficulty": "0",
       "description": [
         "Your goal is to fix the failing test.",
@@ -67,6 +68,7 @@
         "",
         "meetBonfire(\"You can do this!\");"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -81,7 +83,7 @@
     },
     {
       "id": "a202eed8fc186c8434cb6d61",
-      "title": "Bonfire: Reverse a String",
+      "title": "Reverse a String",
       "difficulty": "1.01",
       "tests": [
         "expect(reverseString('hello')).to.be.a('String');",
@@ -108,6 +110,7 @@
         "Array.reverse()",
         "Array.join()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -122,7 +125,7 @@
     },
     {
       "id": "a302f7aae1aa3152a5b413bc",
-      "title": "Bonfire: Factorialize a Number",
+      "title": "Factorialize a Number",
       "tests": [
         "expect(factorialize(5)).to.be.a(\"Number\");",
         "expect(factorialize(5)).to.equal(120);",
@@ -147,6 +150,7 @@
       "MDNlinks": [
         "Arithmetic Operators"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -161,7 +165,7 @@
     },
     {
       "id": "aaa48de84e1ecc7c742e1124",
-      "title": "Bonfire: Check for Palindromes",
+      "title": "Check for Palindromes",
       "difficulty": "1.03",
       "description": [
         "Return true if the given string is a palindrome. Otherwise, return false.",
@@ -194,6 +198,7 @@
         "String.replace()",
         "String.toLowerCase()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -208,7 +213,7 @@
     },
     {
       "id": "a26cbbe9ad8655a977e1ceb5",
-      "title": "Bonfire: Find the Longest Word in a String",
+      "title": "Find the Longest Word in a String",
       "difficulty": "1.04",
       "description": [
         "Return the length of the longest word in the provided sentence.",
@@ -233,6 +238,7 @@
         "String.split()",
         "String.length"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -247,7 +253,7 @@
     },
     {
       "id": "ab6137d4e35944e21037b769",
-      "title": "Bonfire: Title Case a Sentence",
+      "title": "Title Case a Sentence",
       "difficulty": "1.05",
       "description": [
         "Return the provided string with the first letter of each word capitalized.",
@@ -270,6 +276,7 @@
       "MDNlinks": [
         "String.charAt()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -284,7 +291,7 @@
     },
     {
       "id": "a789b3483989747d63b0e427",
-      "title": "Bonfire: Return Largest Numbers in Arrays",
+      "title": "Return Largest Numbers in Arrays",
       "difficulty": "1.06",
       "description": [
         "Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.",
@@ -308,6 +315,7 @@
       "MDNlinks": [
         "Comparison Operators"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -322,7 +330,7 @@
     },
     {
       "id": "acda2fb1324d9b0fa741e6b5",
-      "title": "Bonfire: Confirm the Ending",
+      "title": "Confirm the Ending",
       "difficulty": "1.07",
       "description": [
         "Check if a string (first argument) ends with the given target string (second argument).",
@@ -347,6 +355,7 @@
       "MDNlinks": [
         "String.substr()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -361,7 +370,7 @@
     },
     {
       "id": "afcc8d540bea9ea2669306b6",
-      "title": "Bonfire: Repeat a string repeat a string",
+      "title": "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.",
@@ -383,6 +392,7 @@
       "MDNlinks": [
         "Global String Object"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -397,7 +407,7 @@
     },
     {
       "id": "ac6993d51946422351508a41",
-      "title": "Bonfire: Truncate a string",
+      "title": "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.",
@@ -421,6 +431,7 @@
       "MDNlinks": [
         "String.slice()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -435,7 +446,7 @@
     },
     {
       "id": "a9bd25c716030ec90084d8a1",
-      "title": "Bonfire: Chunky Monkey",
+      "title": "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.",
@@ -458,6 +469,7 @@
       "MDNlinks": [
         "Array.push()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -472,7 +484,7 @@
     },
     {
       "id": "ab31c21b530c0dafa9e241ee",
-      "title": "Bonfire: Slasher Flick",
+      "title": "Slasher Flick",
       "difficulty": "1.11",
       "description": [
         "Return the remaining elements of an array after chopping off n elements from the head.",
@@ -495,6 +507,7 @@
         "Array.slice()",
         "Array.splice()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -509,7 +522,7 @@
     },
     {
       "id": "af2170cad53daa0770fabdea",
-      "title": "Bonfire: Mutations",
+      "title": "Mutations",
       "difficulty": "1.12",
       "description": [
         "Return true if the string in the first element of the array contains all of the letters of the string in the second element of the array.",
@@ -537,6 +550,7 @@
       "MDNlinks": [
         "Array.indexOf()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -551,7 +565,7 @@
     },
     {
       "id": "adf08ec01beb4f99fc7a68f2",
-      "title": "Bonfire: Falsey Bouncer",
+      "title": "Falsey Bouncer",
       "difficulty": "1.50",
       "description": [
         "Remove all falsey values from an array.",
@@ -575,6 +589,7 @@
         "Boolean Objects",
         "Array.filter()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -589,7 +604,7 @@
     },
     {
       "id": "a8e512fbe388ac2f9198f0fa",
-      "title": "Bonfire: Where art thou",
+      "title": "Where art thou",
       "difficulty": "1.55",
       "description": [
         "Make a function that looks through an array (first argument) and returns an array of all objects that have equivalent property values (second argument).",
@@ -613,6 +628,7 @@
         "Object.hasOwnProperty()",
         "Object.keys()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -627,7 +643,7 @@
     },
     {
       "id": "a39963a4c10bc8b4d4f06d7e",
-      "title": "Bonfire: Seek and Destroy",
+      "title": "Seek and Destroy",
       "difficulty": "1.60",
       "description": [
         "You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.",
@@ -652,6 +668,7 @@
         "Arguments object",
         "Array.filter()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -666,7 +683,7 @@
     },
     {
       "id": "a24c1a4622e3c05097f71d67",
-      "title": "Bonfire: Where do I belong",
+      "title": "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).",
@@ -688,6 +705,7 @@
         "expect(where([10, 20, 30, 40, 50], 35)).to.equal(3);",
         "expect(where([10, 20, 30, 40, 50], 30)).to.equal(2);"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index 80971b7..1fa0d2c 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id":"bd7123c9c441eddfaeb4bdef",
-      "title": "Waypoint: Comment your JavaScript Code",
+      "title": "Comment your JavaScript Code",
       "difficulty":"9.98",
       "description":[
         "A comment is a very useful line of code that is not actually ran by the machine executing it. With this property comments are the perfect way of creating notes to yourself or anyone else who reads your code describing what the code does",
@@ -23,11 +23,12 @@
       ],
       "challengeSeed":[
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c441eddfaeb5bdef",
-      "title": "Waypoint: Understand Boolean Values",
+      "title": "Understand Boolean Values",
       "difficulty": "9.98001",
       "description": [
         "Return true",
@@ -48,11 +49,12 @@
         "",
         "welcomeToBooleans();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c443eddfaeb5bdef",
-      "title": "Waypoint: Declare JavaScript Variables",
+      "title": "Declare JavaScript Variables",
       "difficulty": "9.9801",
       "description": [
         "Now, use the <code>var</code> keyword to create a <code>variable</code> called <code>myName</code>. Set its value to your name.",
@@ -74,11 +76,12 @@
         "",
         "if(typeof(myName) !== 'undefined'){(function(v){return(v);})(myName);}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c444eddfaeb5bdef",
-      "title": "Waypoint: Declare String Variables",
+      "title": "Declare String Variables",
       "difficulty": "9.9802",
       "description": [
         "Programs will almost always have several different variables that are used to keep track of several different pieces of data",
@@ -100,11 +103,12 @@
         "// We'll learn about functions soon.",
         "if(typeof(myFirstName) !== 'undefined' && typeof(myLastName) !== 'undefined'){(function(y,z){return(y + ', ' + z);})(myFirstName, myLastName);}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c448eddfaeb5bdef",
-      "title": "Waypoint: Check the Length Property of a String Variable",
+      "title": "Check the Length Property of a String Variable",
       "difficulty": "9.9809",
       "description": [
         "Use the <code>.length</code> property to count the number of characters in the <code>lastNameLength</code> variable.",
@@ -132,11 +136,12 @@
         "// We'll learn about functions soon.",
         "if(typeof(lastNameLength) != 'undefined'){(function(v){return(v);})(lastNameLength);}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c549eddfaeb5bdef",
-      "title": "Waypoint: Use Bracket Notation to Find the First Character in a String",
+      "title": "Use Bracket Notation to Find the First Character in a String",
       "difficulty": "9.9810",
       "description": [
         "Use <code>bracket notation</code> to find the first character in a the <code>firstLetterOfLastName</code> variable.",
@@ -166,11 +171,12 @@
         "// We'll learn about functions soon.",
         "(function(v){return(v);})(firstLetterOfLastName);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c450eddfaeb5bdef",
-      "title": "Waypoint: Use Bracket Notation to Find the Nth Character in a String",
+      "title": "Use Bracket Notation to Find the Nth Character in a String",
       "difficulty": "9.9811",
       "description": [
         "Just like the last lesson where we used <code>Bracket Notation</code>to access the first letter we can use the same method to get the letters ar other positions",
@@ -196,11 +202,12 @@
         "// We'll learn about functions soon.",
         "(function(v){return(v);})(thirdLetterOfLastName);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c451eddfaeb5bdef",
-      "title": "Waypoint: Use Bracket Notation to Find the Last Character in a String",
+      "title": "Use Bracket Notation to Find the Last Character in a String",
       "difficulty": "9.9812",
       "description": [
         "Use <code>bracket notation</code> to find the last character in the <code>lastName</code> variable.",
@@ -225,11 +232,12 @@
         "",
         "(function(v){return(v);})(lastLetterOfLastName);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7123c9c452eddfaeb5bdef",
-      "title": "Waypoint: Use Bracket Notation to Find the Nth-to-Last Character in a String",
+      "title": "Use Bracket Notation to Find the Nth-to-Last Character in a String",
       "difficulty": "9.9813",
       "description": [
         "Use <code>bracket notation</code> to find the second-to-last character in the <code>lastName</code> variable.",
@@ -254,11 +262,12 @@
         "",
         "(function(v){return(v);})(secondToLastLetterOfLastName);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "cf1111c1c11feddfaeb3bdef",
-      "title": "Waypoint: Add Two Numbers with JavaScript",
+      "title": "Add Two Numbers with JavaScript",
       "difficulty": "9.98141",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -276,11 +285,12 @@
         "",
         "(function(z){return('add='+z);})(add);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "cf1111c1c11feddfaeb4bdef",
-      "title": "Waypoint: Subtract One Number from Another with JavaScript",
+      "title": "Subtract One Number from Another with JavaScript",
       "difficulty": "9.98142",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -298,11 +308,12 @@
         "",
         "(function(z){return('subtract='+z);})(subtract);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "cf1231c1c11feddfaeb5bdef",
-      "title": "Waypoint: Multiply Two Numbers with JavaScript",
+      "title": "Multiply Two Numbers with JavaScript",
       "difficulty": "9.98143",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -320,11 +331,12 @@
         "",
         "(function(z){return('multiply='+z);})(multiply);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "cf1111c1c11feddfaeb6bdef",
-      "title": "Waypoint: Divide One Number by Another with JavaScript",
+      "title": "Divide One Number by Another with JavaScript",
       "difficulty": "9.9814",
       "description": [
         "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
@@ -342,11 +354,12 @@
         "",
         "(function(z){return('divide='+z);})(divide);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "cf1391c1c11feddfaeb4bdef",
-      "title": "Waypoint: Create Decimal Numbers with JavaScript",
+      "title": "Create Decimal Numbers with JavaScript",
       "difficulty": "9.9815",
       "description": [
         "in JavaScript we can can work with decimal numbers",
@@ -364,11 +377,12 @@
         "",
         "(function(){if(typeof(myDecimal) != 'undefined'){return(myDecimal);}})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7993c9c69feddfaeb7bdef",
-      "title": "Waypoint: Perform Arithmetic Operations on Decimals with JavaScript",
+      "title": "Perform Arithmetic Operations on Decimals with JavaScript",
       "difficulty": "9.98151",
       "description": [
         "In JavaScript we can can work with decimal numbers."
@@ -385,11 +399,12 @@
         "",
         "(function(y,z){return('multiply='+y+', divide='+z);})(multiply,divide);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bd7993c9c69feddfaeb8bdef",
-      "title": "Waypoint: Store Multiple Values in one Variable using JavaScript Arrays",
+      "title": "Store Multiple Values in one Variable using JavaScript Arrays",
       "difficulty": "9.9816",
       "description": [
         "In JavaScript we can store lists or collections of data in what are called arrays",
@@ -411,11 +426,12 @@
         "",
         "(function(z){return(z);})(myArray);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c11feddfaeb7bdef",
-      "title": "Waypoint: Nest one Array within Another Array",
+      "title": "Nest one Array within Another Array",
       "difficulty":"9.98161",
       "description":[
         "We are also able to create arrays within arrays. This technique is called <code>nesting</code>.",
@@ -430,11 +446,12 @@
         "",
         "if(typeof(myArray) !== 'undefined'){(function(){return(myArray);})();}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"bg9997c9c79feddfaeb9bdef",
-      "title": "Waypoint: Access Array Data with Indexes",
+      "title": "Access Array Data with Indexes",
       "difficulty":"9.9817",
       "description":[
         "Once an array has been created we can access the data we have stored in them using indexes",
@@ -460,11 +477,12 @@
         "",
         "if(typeof(myArray) != 'undefined' && typeof(data) != 'undefined'){(function(y,z){return('myArray = ' + JSON.stringify(y) + ', data = ' + JSON.stringify(z));})(myArray, data);}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c11feddfaeb8bdef",
-      "title": "Waypoint: Modify Array Data With Indexes",
+      "title": "Modify Array Data With Indexes",
       "difficulty":"9.98171",
       "description":[
         "We are able to modify the data stored in an array by using indexes",
@@ -491,11 +509,12 @@
         "",
         "if(typeof(myArray) != 'undefined'){(function(){return(myArray);})();}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bg9994c9c69feddfaeb9bdef",
-      "title": "Waypoint: Manipulate Arrays With pop()",
+      "title": "Manipulate Arrays With pop()",
       "difficulty": "9.9818",
       "description": [
         "When an array has been defined we still have the ability to make changes to it afterwards",
@@ -521,11 +540,12 @@
         "",
         "(function(y, z){return('myArray = ' + JSON.stringify(y) + ' & removed = ' + JSON.stringify(z));})(myArray, removed);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bg9995c9c69feddfaeb9bdef",
-      "title": "Waypoint: Manipulate Arrays With push()",
+      "title": "Manipulate Arrays With push()",
       "difficulty": "9.9818",
       "description": [
         "Now that we've learned how to <code>pop</code>things from the end of the array, we need to learn how to <code>push</code>stuff back to the end",
@@ -542,11 +562,12 @@
         "",
         "(function(z){return('myArray = ' + JSON.stringify(z));})(myArray);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bg9996c9c69feddfaeb9bdef",
-      "title": "Waypoint: Manipulate Arrays With shift()",
+      "title": "Manipulate Arrays With shift()",
       "difficulty": "9.9817",
       "description": [
         "Another common way in which we can manipulate the data in an array is through <code>.shift() </code>",
@@ -564,11 +585,12 @@
         "",
         "(function(y, z){return('myArray = ' + JSON.stringify(y) + ' & removed = ' + JSON.stringify(z));})(myArray, removed);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id": "bg9997c9c69feddfaeb9bdef",
-      "title": "Waypoint: Manipulate Arrays With unshift()",
+      "title": "Manipulate Arrays With unshift()",
       "difficulty": "9.9818",
       "description": [
         "Now that we've learned how to <code>shift</code>things from the start of the array, we need to learn how to <code>unshift</code>stuff back to the start",
@@ -585,11 +607,12 @@
         "",
         "(function(y, z){return('myArray = ' + JSON.stringify(y));})(myArray);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"bg9997c9c89feddfaeb9bdef",
-      "title": "Waypoint: Write Reusable JavaScript with Functions",
+      "title": "Write Reusable JavaScript with Functions",
       "difficulty":"9.9819",
       "description":[
         "In JavaScript we can divide up our code into separate and reusable parts called functions",
@@ -621,11 +644,12 @@
         "(function(){return(f);})();",
         "}"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"bg9998c9c99feddfaeb9bdef",
-      "title": "Waypoint: Build JavaScript Objects",
+      "title": "Build JavaScript Objects",
       "difficulty":"9.9822",
       "description":[
         "A very important data type in javascript is the <code>Object</code>",
@@ -665,11 +689,12 @@
         "",
         "(function(z){return(z);})(myDog);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"bg9999c9c99feddfaeb9bdef",
-      "title": "Waypoint: Manipulate JavaScript Objects",
+      "title": "Manipulate JavaScript Objects",
       "difficulty":"9.9823",
       "description":[
         "Now that we have an objects we need to know how to add and remove properties from it",
@@ -709,11 +734,12 @@
         "",
         "(function(z){return(z);})(myDog);"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c11feddfaeb5bdef",
-      "title": "Waypoint: Iterate with JavaScript For Loops",
+      "title": "Iterate with JavaScript For Loops",
       "difficulty":"9.9824",
       "description":[
         "Loops are a critical part of any program! The next few challenges",
@@ -737,11 +763,12 @@
         "",
         ""
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c11feddfaeb1bdef",
-      "title": "Waypoint: Iterate with JavaScript While Loops",
+      "title": "Iterate with JavaScript While Loops",
       "difficulty":"9.9825",
       "description":[
         "Loops are a critical part of any program! The next few challenges",
@@ -766,11 +793,12 @@
         "",
         ""
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c11feddfaeb2bdef",
-      "title": "Waypoint: Iterate with JavaScript Do-While Loops",
+      "title": "Iterate with JavaScript Do-While Loops",
       "difficulty":"9.9826",
       "description":[
         "Let's now take a look at the do - while loop",
@@ -795,11 +823,12 @@
         "",
         ""
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c11feddfaeb9bdef",
-      "title": "Waypoint: Generate Random Fractions with JavaScript",
+      "title": "Generate Random Fractions with JavaScript",
       "difficulty":"9.9827",
       "description":[
         "Random numbers are very useful for creating random behaviours and games",
@@ -820,11 +849,12 @@
         "",
         "(function(){return(myFunction());})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c12feddfaeb1bdef",
-      "title": "Waypoint: Generate Random Whole Numbers with JavaScript",
+      "title": "Generate Random Whole Numbers with JavaScript",
       "difficulty":"9.9828",
       "description":[
         "While it's great that we can create random decimal numbers it's a lot more useful to generate a random whole number",
@@ -848,11 +878,12 @@
         "",
         "(function(){return(myFunction());})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c12feddfaeb2bdef",
-      "title": "Waypoint: Generate Random Whole Numbers within a Range",
+      "title": "Generate Random Whole Numbers within a Range",
       "difficulty":"9.9829",
       "description":[
         "We can use a certain mathematical expression to get a random number between between twp numbers.",
@@ -875,11 +906,12 @@
         "",
         "(function(){return(myFunction());})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c12feddfaeb3bdef",
-      "title": "Waypoint: Use Conditional Logic with If-Else Statements",
+      "title": "Use Conditional Logic with If-Else Statements",
       "difficulty":"9.983",
       "description":[
         "We can use if statements in JavaScript to only execute code if a certain condition is met",
@@ -908,11 +940,12 @@
         "",
         "(function(){return(myFunction());})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c12feddfaeb6bdef",
-      "title": "Waypoint: Sift through Text with Regular Expressions",
+      "title": "Sift through Text with Regular Expressions",
       "difficulty":"9.984",
       "description":[
         "RegEx is a powerful tool we can use to find certain words or patterns in strings",
@@ -943,11 +976,12 @@
         " return(testString.match(expression).length);",
         "})();(function(){return(test);})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c12feddfaeb7bdef",
-      "title": "Waypoint: Find Numbers with Regular Expressions",
+      "title": "Find Numbers with Regular Expressions",
       "difficulty":"9.985",
       "description":[
         "We can use special selectors in RegEx to select a particular type of value",
@@ -972,11 +1006,12 @@
         " return(testString.match(expression).length);",
         "})();(function(){return(test);})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c12feddfaeb8bdef",
-      "title": "Waypoint: Find White Space with Regular Expressions",
+      "title": "Find White Space with Regular Expressions",
       "difficulty":"9.986",
       "description":[
         "We can also use selectors like <code>\\s</code> to find spaces in a string",
@@ -1000,11 +1035,12 @@
         " return(testString.match(expression).length);",
         "})();(function(){return(test);})();"
       ],
+      "type": "waypoint",
       "challengeType": 1
     },
     {
       "id":"cf1111c1c13feddfaeb3bdef",
-      "title": "Waypoint: Invert Regular Expression Matches with JavaScript",
+      "title": "Invert Regular Expression Matches with JavaScript",
       "difficulty":"9.987",
       "description":[
         "Use <code>/\\S/gi;</code> to match everything that isn't a space in the string",
@@ -1027,11 +1063,12 @@
         " return(testString.match(expression).length);",
         "})();(function(){return(test);})();"
       ],
+      "type": "waypoint",
       "challengeType":1
     },
     {
       "id":"cf1111c1c12feddfaeb9bdef",
-      "title": "Waypoint: Create a JavaScript Slot Machine",
+      "title": "Create a JavaScript Slot Machine",
       "difficulty":"9.988",
       "description":[
         "We are now going to try and combine some of the stuff we've just learnt abd create the logic for a slot machine game",
@@ -1180,11 +1217,12 @@
         " }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id":"cf1111c1c13feddfaeb1bdef",
-      "title": "Waypoint: Add your JavaScript Slot Machine Slots",
+      "title": "Add your JavaScript Slot Machine Slots",
       "difficulty":"9.989",
       "description":[
         "Now that we have our random numbers we need to go and check for when they are all the same that means we should count it as a win",
@@ -1338,11 +1376,12 @@
         " }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id":"cf1111c1c13feddfaeb2bdef",
-      "title": "Waypoint: Bring your JavaScript Slot Machine to Life",
+      "title": "Bring your JavaScript Slot Machine to Life",
       "difficulty":"9.990",
       "description":[
         "Now we can detect a win let's get the slot machine to look like it works",
@@ -1504,6 +1543,7 @@
         " }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     }
   ]
diff --git a/seed/challenges/basic-ziplines.json b/seed/challenges/basic-ziplines.json
index ea667f7..b96619b 100644
--- a/seed/challenges/basic-ziplines.json
+++ b/seed/challenges/basic-ziplines.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7158d8c442eddfbeb5bd1f",
-      "title": "Waypoint: Get Set for Ziplines",
+      "title": "Get Set for Ziplines",
       "difficulty": 1.00,
       "challengeSeed": ["125658022"],
       "description": [
@@ -23,6 +23,7 @@
         "You can use this CodePen that you've just created as a starting point for your Ziplines. Just click the \"fork\" button at the top of your CodePen and it will create a duplicate CodePen.",
         "Now you're ready for your first Zipline. Click the \"I've completed this challenge\" button."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -38,7 +39,7 @@
     },
     {
       "id": "bd7158d8c242eddfaeb5bd13",
-      "title": "Zipline: Build a Personal Portfolio Webpage",
+      "title": "Build a Personal Portfolio Webpage",
       "difficulty": 1.01,
       "challengeSeed": ["133315782"],
       "description": [
@@ -58,6 +59,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -73,7 +75,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd13",
-      "title": "Zipline: Build a Random Quote Machine",
+      "title": "Build a Random Quote Machine",
       "difficulty": 1.02,
       "challengeSeed": ["126415122"],
       "description": [
@@ -89,6 +91,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -104,7 +107,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd10",
-      "title": "Zipline: Show the Local Weather",
+      "title": "Show the Local Weather",
       "difficulty": 1.03,
       "challengeSeed": ["126415127"],
       "description": [
@@ -121,6 +124,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -136,7 +140,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd0f",
-      "title": "Zipline: Build a Pomodoro Clock",
+      "title": "Build a Pomodoro Clock",
       "difficulty": 1.04,
       "challengeSeed": ["126411567"],
       "description": [
@@ -152,6 +156,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -167,7 +172,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd1f",
-      "title": "Zipline: Use the Twitch.tv JSON API",
+      "title": "Use the Twitch.tv JSON API",
       "difficulty": 1.05,
       "challengeSeed": ["126411564"],
       "description": [
@@ -187,6 +192,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index d9ac143..4efee80 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bad87fee1348bd9acde08712",
-      "title": "Waypoint: Use Responsive Design with Bootstrap Fluid Containers",
+      "title": "Use Responsive Design with Bootstrap Fluid Containers",
       "difficulty": 2.01,
       "description": [
         "Now let's go back to our Cat Photo App. This time, we'll style it using the popular Bootstrap responsive CSS framework.",
@@ -73,6 +73,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -87,7 +88,7 @@
     },
     {
       "id": "bad87fee1348bd9acde08812",
-      "title": "Waypoint: Make Images Mobile Responsive",
+      "title": "Make Images Mobile Responsive",
       "difficulty": 2.02,
       "description": [
         "First, Add a new image with the <code>src</code> attribute of \"http://bit.ly/fcc-kittens2\".",
@@ -157,6 +158,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -171,7 +173,7 @@
     },
     {
       "id": "bad87fee1348bd8acde08812",
-      "title": "Waypoint: Center Text with Bootstrap",
+      "title": "Center Text with Bootstrap",
       "difficulty": 2.03,
       "description": [
         "Now that we're using Bootstrap, we can center our heading elements to make them look better. All we need to do is add the class <code>text-center</code> to our <code>h1</code> and <code>h2</code> elements.",
@@ -239,6 +241,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -253,7 +256,7 @@
     },
     {
       "id": "bad87fee1348cd8acdf08812",
-      "title": "Waypoint: Create a Bootstrap Button",
+      "title": "Create a Bootstrap Button",
       "difficulty": 2.04,
       "description": [
         "Bootstrap has its own styles for <code>button</code> elements, which look much better than the plain HTML ones.",
@@ -323,6 +326,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -337,7 +341,7 @@
     },
     {
       "id": "bad87fee1348cd8acef08812",
-      "title": "Waypoint: Create a Block Element Bootstrap Button",
+      "title": "Create a Block Element Bootstrap Button",
       "difficulty": 2.05,
       "description": [
         "Normally, your <code>button</code> elements are only as wide as the text that they contain. By making them block elements, your button will stretch to fill your page's entire horizontal space.",
@@ -411,6 +415,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -425,7 +430,7 @@
     },
     {
       "id": "bad87fee1348cd8acef08811",
-      "title": "Waypoint: Taste the Bootstrap Button Color Rainbow",
+      "title": "Taste the Bootstrap Button Color Rainbow",
       "difficulty": 2.06,
       "description": [
         "The \"btn-primary\" class is the main color you'll use in your app. It is useful for highlighting actions you want your user to take.",
@@ -497,6 +502,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -511,7 +517,7 @@
     },
     {
       "id": "bad87fee1348cd8acef08813",
-      "title": "Waypoint: Call out Optional Actions with Button Info",
+      "title": "Call out Optional Actions with Button Info",
       "difficulty": 2.07,
       "description": [
         "Bootstrap comes with several pre-defined colors for buttons. The \"btn-info\" class is used to call attention to optional actions that the user can take.",
@@ -584,6 +590,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -598,7 +605,7 @@
     },
     {
       "id": "bad87fee1348ce8acef08814",
-      "title": "Waypoint: Warn your Users of a Dangerous Action",
+      "title": "Warn your Users of a Dangerous Action",
       "difficulty": 2.08,
       "description": [
         "Bootstrap comes with several pre-defined colors for buttons. The \"btn-danger\" class is the button color you'll use to notify users that the button performs a destructive action, such as deleting a cat photo.",
@@ -672,6 +679,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -686,7 +694,7 @@
     },
     {
       "id": "bad88fee1348ce8acef08815",
-      "title": "Waypoint: Use the Bootstrap Grid to Put Elements Side By Side",
+      "title": "Use the Bootstrap Grid to Put Elements Side By Side",
       "difficulty": 2.09,
       "description": [
         "Bootstrap uses a responsive grid system, which makes it easy to put elements into rows and specify each element's relative width. Most of Bootstrap's classes can be applied to a <code>div</code> element.",
@@ -765,6 +773,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -779,7 +788,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08845",
-      "title": "Waypoint: Ditch Custom CSS for Bootstrap",
+      "title": "Ditch Custom CSS for Bootstrap",
       "difficulty": 2.10,
       "description": [
         "We can clean up our code and make our Cat Photo App look more conventional by using Bootstrap's built-in styles instead of the custom styles we created earlier.",
@@ -863,6 +872,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -877,7 +887,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08845",
-      "title": "Waypoint: Create a Custom Heading",
+      "title": "Create a Custom Heading",
       "difficulty": 2.11,
       "description": [
         "We will make a simple heading for our Cat Photo App by putting them in the same row.",
@@ -951,6 +961,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -965,7 +976,7 @@
     },
     {
       "id": "bad87fee1348bd9aedd08845",
-      "title": "Waypoint: Add Font Awesome Icons to our Buttons",
+      "title": "Add Font Awesome Icons to our Buttons",
       "difficulty": 2.12,
       "description": [
         "Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the \".svg\" file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.",
@@ -1035,6 +1046,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1049,7 +1061,7 @@
     },
     {
       "id": "bad87fee1348bd9aedc08845",
-      "title": "Waypoint: Add Font Awesome Icons to all of our Buttons",
+      "title": "Add Font Awesome Icons to all of our Buttons",
       "difficulty": 2.13,
       "description": [
         "Font Awesome is a convenient library of icons. These icons are vector graphics, stored in the \".svg\" file format. These icons are treated just like fonts. You can specify their size using pixels, and they will assume the font size of their parent HTML elements.",
@@ -1119,6 +1131,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1133,7 +1146,7 @@
     },
     {
       "id": "bad87fee1348bd9aedb08845",
-      "title": "Waypoint: Responsively Style Radio Buttons",
+      "title": "Responsively Style Radio Buttons",
       "difficulty": 2.14,
       "description": [
         "You can use Bootstrap's \"col-xs-*\" classes on <code>form</code> elements, too! This way, our radio buttons will be evenly spread out across the page, regardless of how wide the screen resolution is.",
@@ -1203,6 +1216,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1217,7 +1231,7 @@
     },
     {
       "id": "bad87fee1348bd9aeda08845",
-      "title": "Waypoint: Responsively Style Checkboxes",
+      "title": "Responsively Style Checkboxes",
       "difficulty": 2.15,
       "description": [
         "You can use Bootstrap's \"col-xs-*\" classes on <code>form</code> elements, too! This way, our checkboxes will be evenly spread out across the page, regardless of how wide the screen resolution is.",
@@ -1294,6 +1308,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1308,7 +1323,7 @@
     },
     {
       "id": "bad87fee1348bd9aed908845",
-      "title": "Waypoint: Style Text Inputs as Form Controls",
+      "title": "Style Text Inputs as Form Controls",
       "difficulty": 2.16,
       "description": [
         "You can add the \"fa-paper-plane\" Font Awesome icon by adding <code>&#60;i class=\"fa fa-paper-plane\"&#62;&#60;/i&#62;</code> within your submit <code>button</code> element.",
@@ -1394,6 +1409,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1408,7 +1424,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908845",
-      "title": "Waypoint: Line up Form Elements Responsively with Bootstrap",
+      "title": "Line up Form Elements Responsively with Bootstrap",
       "difficulty": 2.17,
       "description": [
         "Now let's get your form <code>input</code> and your submission <code>button</code> on the same line. We'll do this the same way we have previously: by using a <code>div</code> element with the class \"row\", and other <code>div</code> elements within it using the \"col-xs-*\" class.",
@@ -1495,6 +1511,7 @@
         "  </form>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1509,7 +1526,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908846",
-      "title": "Waypoint: Create a Bootstrap Headline",
+      "title": "Create a Bootstrap Headline",
       "difficulty": 2.18,
       "description": [
         "Now let's build something from scratch to practice our HTML, CSS and Bootstrap skills.",
@@ -1529,6 +1546,7 @@
         "",
         ""
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1543,7 +1561,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908746",
-      "title": "Waypoint: House our page within a Bootstrap Container Fluid Div",
+      "title": "House our page within a Bootstrap Container Fluid Div",
       "difficulty": 2.18,
       "description": [
         "Now let's make sure all the content on your page is mobile-responsive.",
@@ -1558,6 +1576,7 @@
         "",
         ""
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1572,7 +1591,7 @@
     },
     {
       "id": "bad87fee1348bd9bec908846",
-      "title": "Waypoint: Create a Bootstrap Row",
+      "title": "Create a Bootstrap Row",
       "difficulty": 2.19,
       "description": [
         "Now we'll create a Bootstrap row for our inline elements.",
@@ -1590,6 +1609,7 @@
         "",
         ""
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1604,7 +1624,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908847",
-      "title": "Waypoint: Split your Bootstrap Row",
+      "title": "Split your Bootstrap Row",
       "difficulty": 2.20,
       "description": [
         "Now that we have a Bootstrap Row, let's split it into two columns to house our elements.",
@@ -1621,6 +1641,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1635,7 +1656,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908848",
-      "title": "Waypoint: Create Bootstrap Wells",
+      "title": "Create Bootstrap Wells",
       "difficulty": 2.21,
       "description": [
         "Bootstrap has a class called \"well\" that can create a visual sense of depth for your columns.",
@@ -1658,6 +1679,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1672,7 +1694,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908849",
-      "title": "Waypoint: Add Elements within your Bootstrap Wells",
+      "title": "Add Elements within your Bootstrap Wells",
       "difficulty": 2.22,
       "description": [
         "Now we're several <code>div</code> elements deep on each column of our row. This is as deep as we'll need to go. Now we can add our <code>button</code> elements.",
@@ -1697,6 +1719,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1711,7 +1734,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908850",
-      "title": "Waypoint: Apply the Default Bootstrap Button Style",
+      "title": "Apply the Default Bootstrap Button Style",
       "difficulty": 2.23,
       "description": [
         "Bootstrap has another button class called \"btn-default\"",
@@ -1742,6 +1765,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1756,7 +1780,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908852",
-      "title": "Waypoint: Create a Class to Target with jQuery Selectors",
+      "title": "Create a Class to Target with jQuery Selectors",
       "difficulty": 2.24,
       "description": [
         "Not every class needs to have corresponding CSS. Sometimes we create classes just for the purpose of selecting these elements more easily using jQuery.",
@@ -1786,6 +1810,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1800,7 +1825,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908853",
-      "title": "Waypoint: Add ID Attributes to Bootstrap Elements",
+      "title": "Add ID Attributes to Bootstrap Elements",
       "difficulty": 2.25,
       "description": [
         "Recall that in addition to class attributes, you can give each of your elements an id attribute.",
@@ -1834,6 +1859,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1848,7 +1874,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908854",
-      "title": "Waypoint: Label Bootstrap Wells",
+      "title": "Label Bootstrap Wells",
       "difficulty": 2.26,
       "description": [
         "For the sake of clarity, let's label both of our wells with their ids.",
@@ -1881,6 +1907,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1895,7 +1922,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908855",
-      "title": "Waypoint: Give Each Element a Unique ID",
+      "title": "Give Each Element a Unique ID",
       "difficulty": 2.27,
       "description": [
         "We will also want to be able to use jQuery to target each button by its unique id.",
@@ -1932,6 +1959,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1946,7 +1974,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908856",
-      "title": "Waypoint: Label Bootstrap Buttons",
+      "title": "Label Bootstrap Buttons",
       "difficulty": 2.28,
       "description": [
         "Just like we labled our wells, we want to label our buttons.",
@@ -1983,6 +2011,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1997,7 +2026,7 @@
     },
     {
       "id": "bad87fee1348bd9aec908857",
-      "title": "Waypoint: Use Comments to Clarify Code",
+      "title": "Use Comments to Clarify Code",
       "difficulty": 2.29,
       "description": [
         "When we start using jQuery, we will modify HTML elements without needing to actually change them in HTML.",
@@ -2033,6 +2062,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
index 8c5af39..06ab698 100644
--- a/seed/challenges/expert-bonfires.json
+++ b/seed/challenges/expert-bonfires.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "aff0395860f5d3034dc0bfc9",
-      "title": "Bonfire: Validate US Telephone Numbers",
+      "title": "Validate US Telephone Numbers",
       "difficulty": "4.01",
       "description": [
         "Return true if the passed string is a valid US phone number",
@@ -50,6 +50,7 @@
       "MDNlinks": [
         "RegExp"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -64,7 +65,7 @@
     },
     {
       "id": "a3f503de51cf954ede28891d",
-      "title": "Bonfire: Symmetric Difference",
+      "title": "Symmetric Difference",
       "difficulty": "4.02",
       "description": [
         "Create a function that takes two or more arrays and returns an array of the symmetric difference of the provided arrays.",
@@ -88,6 +89,7 @@
         "Array.reduce()",
         "Symmetric Difference"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -102,7 +104,7 @@
     },
     {
       "id": "aa2e6f85cab2ab736c9a9b24",
-      "title": "Bonfire: Exact Change",
+      "title": "Exact Change",
       "difficulty": "4.03",
       "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.",
@@ -143,6 +145,7 @@
       "MDNlinks": [
         "Global Object"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -157,7 +160,7 @@
     },
     {
       "id": "a56138aff60341a09ed6c480",
-      "title": "Bonfire: Inventory Update",
+      "title": "Inventory Update",
       "difficulty": "4.04",
       "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.",
@@ -197,6 +200,7 @@
       "MDNlinks": [
         "Global Array Object"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -211,7 +215,7 @@
     },
     {
       "id": "a7bf700cd123b9a54eef01d5",
-      "title": "Bonfire: No repeats please",
+      "title": "No repeats please",
       "difficulty": "4.05",
       "description": [
         "Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
@@ -238,6 +242,7 @@
         "Permutations",
         "RegExp"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -252,7 +257,7 @@
     },
     {
       "id": "a19f0fbe1872186acd434d5a",
-      "title": "Bonfire: Friendly Date Ranges",
+      "title": "Friendly Date Ranges",
       "difficulty": "4.06",
       "description": [
         "Implement a way of converting two dates into a more friendly date range that could be presented to a user.",
@@ -282,6 +287,7 @@
         "String.substr()",
         "parseInt()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
diff --git a/seed/challenges/get-set-for-free-code-camp.json b/seed/challenges/get-set-for-free-code-camp.json
index 1276335..74a1776 100644
--- a/seed/challenges/get-set-for-free-code-camp.json
+++ b/seed/challenges/get-set-for-free-code-camp.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7124d8c441eddfaeb5bdef",
-      "title": "Waypoint: Learn how Free Code Camp Works",
+      "title": "Learn how Free Code Camp Works",
       "difficulty": 0.01,
       "challengeSeed": ["125407438"],
       "description": [
@@ -20,6 +20,7 @@
         "We'll provide you with the most rigorous curriculum and the most supportive community on earth. All you need to do sit down, day after day, and put in the hard work.",
         "Now it's time to join our chat room. Click the \"I've completed this challenge\" button to move on to your next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -55,7 +56,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bd0f",
-      "title": "Waypoint: Join Our Chat Room",
+      "title": "Join Our Chat Room",
       "difficulty": 0.02,
       "challengeSeed": ["131574135"],
       "description": [
@@ -77,6 +78,7 @@
         "In order to keep our community a friendly and positive place to learn to code, please read and follow our Code of Conduct: <a href='https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct' target='_blank'>https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct</a>",
         "Now you're ready to move on. Click the \"I've completed this challenge\" button to move on to your next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -116,7 +118,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bdff",
-      "title": "Waypoint: Preview our Challenge Map",
+      "title": "Preview our Challenge Map",
       "difficulty": 0.03,
       "challengeSeed": ["125407437"],
       "description": [
@@ -126,6 +128,7 @@
         "In addition to our Waypoint challenges, like the one you're doing now, we have algorithm practice challenges (Bonfires), front end development challenges (Ziplines) and full stack development challenges (Basejumps). After you finish all of these, you'll start building projects for nonprofits.",
         "Please note that our open-source curriculum is a work in progress. Our volunteer community is constantly improving it. If you think you've encountered a bug, typo, or something that seems confusing, be sure to click the \"bug\" button to create a GitHub issue."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -157,7 +160,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bd1f",
-      "title": "Waypoint: Browse our Wiki",
+      "title": "Browse our Wiki",
       "difficulty": 0.04,
       "challengeSeed": ["125407435"],
       "description": [
@@ -167,6 +170,7 @@
         "All of our Wiki articles are contributed by our community. You can update our wiki articles, and even create wiki articles of your own.",
         "Now you can move on to your next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -196,7 +200,7 @@
     },
     {
       "id": "bd7125d8c441eddfaeb5bd2f",
-      "title": "Waypoint: Customize your Portfolio Page",
+      "title": "Customize your Portfolio Page",
       "difficulty": 0.05,
       "challengeSeed": ["125407433"],
       "description": [
@@ -208,6 +212,7 @@
         "Your portfolio page also shows off your progress through Free Code Camp. If you get Brownie Points on several days in a row, you'll get streak.",
         "Once you're happy with your portfolio page, you can move on to your next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -241,7 +246,7 @@
     },
     {
       "id": "bd7126d8c441eddfaeb5bd3f",
-      "title": "Waypoint: Try Camper News",
+      "title": "Try Camper News",
       "difficulty": 0.06,
       "challengeSeed": ["124553410"],
       "description": [
@@ -254,6 +259,7 @@
         "When you submit a link, you'll get a Brownie Point. You'll also get a Brownie Point each time someone upvotes your link.",
         "Now that you've learned how to use Camper News, let's move on to your next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -291,7 +297,7 @@
     },
     {
       "id": "bd7126d8c441eddfaeb5bd3e",
-      "title": "Waypoint: Meet Other Campers in your City",
+      "title": "Meet Other Campers in your City",
       "difficulty": 0.07,
       "challengeSeed": ["127358841"],
       "description": [
@@ -303,6 +309,7 @@
         "Our Campsites allow you to create events, coordinate those events, and share photos from the events afterward.",
         "Whether you're hosting a study group, pair programming at your local library, or going to a weekend hackathon, your city's Campsite will help you make it happen."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -338,7 +345,7 @@
     },
     {
       "id": "bd7126d8c431eddfaeb5bd3e",
-      "title": "Waypoint: Add Free Code Camp to your LinkedIn Profile",
+      "title": "Add Free Code Camp to your LinkedIn Profile",
       "difficulty": 0.08,
       "challengeSeed": ["131574134"],
       "description": [
@@ -353,6 +360,7 @@
         "Make your LinkedIn profile as complete as possible. Unlike other social networks, with LinkedIn, it's perfectly fine if you don't want to add a photo.",
         "Let's keep moving. We're almost ready to start coding!"
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -368,7 +376,7 @@
     },
     {
       "id": "bd7137d8c441eddfaeb5bdef",
-      "title": "Waypoint: Get Help the Hacker Way with RSAP",
+      "title": "Get Help the Hacker Way with RSAP",
       "difficulty": 0.09,
       "challengeSeed": ["125407432"],
       "description": [
@@ -381,6 +389,7 @@
         "Here's our detailed wiki article on getting help: <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>http://freecodecamp.com//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck</a>.",
         "Now you have a clear algorithm to follow when you need help! Let's start coding! Move on to your next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/git.json b/seed/challenges/git.json
index e87eb4b..3141e65 100644
--- a/seed/challenges/git.json
+++ b/seed/challenges/git.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7353d8c341eddeaeb5bd0f",
-      "title": "Waypoint: Save your Code Revisions Forever with Git",
+      "title": "Save your Code Revisions Forever with Git",
       "difficulty": 0.01,
       "challengeSeed": ["133316034"],
       "description": [
@@ -34,6 +34,7 @@
         "Complete \"Merge Tada!\"",
         "Once you've completed these steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/hikes.json b/seed/challenges/hikes.json
index 8855b0e..e24da79 100644
--- a/seed/challenges/hikes.json
+++ b/seed/challenges/hikes.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7128d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 1: The 4 Basic Parts of a Computer",
+      "title": "Computer Basics 1: The 4 Basic Parts of a Computer",
       "difficulty": 9.01,
       "challengeSeed": [
         "132542064"
@@ -24,6 +24,7 @@
         "You can't get to the memory from the input or the output without the use of the CPU.",
         "So, just to review, we've got 4 basic parts of the computer: the input, the output, CPU, and memory."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["The computer has 3 basic parts.", false, "The computer has 4 basic parts: input, output, CPU, and memory"],
@@ -43,7 +44,7 @@
     },
     {
       "id": "bd7127d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 2: More Computer Hardware",
+      "title": "Computer Basics 2: More Computer Hardware",
       "difficulty": 9.02,
       "challengeSeed": [
         "132542458"
@@ -62,6 +63,7 @@
         "So let's do a quick review.",
         "In addition to the four basic parts of input, output, CPU, and memory, we also usually have a motherboard, expansion cards, and a power supply."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["The power supply isn't a necessary part of a computer since it's not one of the 4 main parts.", false, "The computer needs power!"],
@@ -81,7 +83,7 @@
     },
     {
       "id": "bd7126d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 3: Intro to Binary Code",
+      "title": "Computer Basics 3: Intro to Binary Code",
       "difficulty": 9.03,
       "challengeSeed": [
         "132542757"
@@ -95,6 +97,7 @@
         "We're going to go into how you decode a number in binary, but as you can probably guess, translating binary can be done with a quick google search.",
         "The most important part of this is you undrestand the concept that even simple things like 1's and 0's can translate into something really complex that is the basis for all of the computer languages that exist today."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["1's and 0's are how we talk about little switches being on and off.", true],
@@ -114,7 +117,7 @@
     },
     {
       "id": "bd7125d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 4: Decoding a Binary Number",
+      "title": "Computer Basics 4: Decoding a Binary Number",
       "difficulty": 9.04,
       "challengeSeed": [
         "132543332"
@@ -130,6 +133,7 @@
         "If it's a 0, we disregard it.",
         "In this video, our number adds up to 75."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["1 === on and 0 ===off", true],
@@ -149,7 +153,7 @@
     },
     {
       "id": "bd7124d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 5: How To Measure Data Size",
+      "title": "Computer Basics 5: How To Measure Data Size",
       "difficulty": 9.05,
       "challengeSeed": [
         "132543959"
@@ -168,6 +172,7 @@
         "Then it's Gigabyte, 1024 Bytes to the power of three; Terabyte, 1024 Bytes to the power of 4, and Petabyte, 1024 to the power of 5.",
         "These get much bigger really quickly!"
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["A Byte is the smallest possible amount of data.", false, "A Byte is 8 bits."],
@@ -187,7 +192,7 @@
     },
     {
       "id": "bd7123d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 6: Measuring Data Speed",
+      "title": "Computer Basics 6: Measuring Data Speed",
       "difficulty": 9.06,
       "challengeSeed": [
         "132545171"
@@ -205,6 +210,7 @@
         "The main takeaway here is that speed is usually measured in bits and size is measured in Bytes.",
         "Additionally, if you have an internet speed that says however many bits per second, keep in mind they are talking about something 8 times less than Bytes, how you are thinking about data."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Data speed is measured in bits.", true],
@@ -223,7 +229,7 @@
     },
     {
       "id": "bd7122d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 7: Binary Bytes",
+      "title": "Computer Basics 7: Binary Bytes",
       "difficulty": 9.07,
       "challengeSeed": [
         "132545417"
@@ -237,6 +243,7 @@
         "So, all of the numbers, letters, and symbols in your javascript can be translated.",
         "There are a lot of languages that computers can work with, and what I want you to get away from this video is that all data in your computer boils down to binary Bytes."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["All digits, letters, and symbols have a binary Byte translation.", true],
@@ -256,7 +263,7 @@
     },
     {
       "id": "bd7121d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 8: Types of Computers",
+      "title": "Computer Basics 8: Types of Computers",
       "difficulty": 9.08,
       "challengeSeed": [
         "132546182"
@@ -275,6 +282,7 @@
         "It's both a Mac and a PC.",
         "The last type of computer we'll talk about is a microcontroller, the type of computer you might have in your car that is really good at a small specialized task, but wouldn't be used the same way a PC would be."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["The most common type of computer is a Personal Computer, a PC.", true],
@@ -294,7 +302,7 @@
     },
     {
       "id": "bd7120d8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 9: More on the Motherboard",
+      "title": "Computer Basics 9: More on the Motherboard",
       "difficulty": 9.09,
       "challengeSeed": [
         "132547285"
@@ -315,6 +323,7 @@
         "On your computer, you probably know there's a place to connect USB, firewire, SD card, ethernet, even an audio plug-in to listen through headphones.",
         "These are all considered ports, a place on the motherboard where you can connect the CPU to some outside source to either get or give information."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["A motherboard must connect the CPU, the memory, and the network.", false, "A motherboard is a motherboard as long as it connects the CPU and the memory."],
@@ -334,7 +343,7 @@
     },
     {
       "id": "bd712fd8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 10: Data Networks",
+      "title": "Computer Basics 10: Data Networks",
       "difficulty": 9.10,
       "challengeSeed": [
         "132547590"
@@ -354,6 +363,7 @@
         "You might think that these are connected over the internet, and in the case of a VPN (Virtual Private Network, which is basically the same conceptionally as a WAN), you're right.",
         "However, a WAN usually rents a cable from an internet company to creat the connection."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["You can connect to a LAN from far away.", false, "To connect to a LAN you must be physically near to it."],
@@ -373,7 +383,7 @@
     },
     {
       "id": "bd712ed8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 11: IP Addresses",
+      "title": "Computer Basics 11: IP Addresses",
       "difficulty": 9.11,
       "challengeSeed": [
         "132548071"
@@ -393,6 +403,7 @@
         "However, it is specific enough that you could google \"Where's the best ice cream near me\" and google could give you information close to your location.",
         "This is done using your IP address."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["IP addresses are necessary to use and participate in the internet.", true],
@@ -411,7 +422,7 @@
     },
     {
       "id": "bd712dd8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 12: How the Internet Works",
+      "title": "Computer Basics 12: How the Internet Works",
       "difficulty": 9.12,
       "challengeSeed": [
         "132548579"
@@ -431,6 +442,7 @@
         "Now, this explaination is really quite basic.",
         "For more information, check out web.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Your computer sends a request for information.", true],
@@ -449,7 +461,7 @@
     },
     {
       "id": "bd712cd8c441eddfbeb5bddf",
-      "title": "Hike: Computer Basics 13: Software",
+      "title": "Computer Basics 13: Software",
       "difficulty": 9.13,
       "challengeSeed": [
         "132548908"
@@ -464,6 +476,7 @@
         "There are three main operating systems: Windows, Mac, and Linux.",
         "Applications comprise all other software, like your web browser, games, things like Photoshop, how you view your mail, editing documents, etc."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Safari, Chrome, and Firefox are all examples of application software.", true]
@@ -481,7 +494,7 @@
     },
     {
       "id": "bd712bd8c441eddfbeb5bddf",
-      "title": "Hike: What Do Programmers Do?",
+      "title": "What Do Programmers Do?",
       "difficulty": 9.14,
       "challengeSeed": [
         "133166912"
@@ -498,6 +511,7 @@
         "Computers just read straight down like you would read a book.",
         "Programmers are the ones responsible for breaking their ideas down into the little tiny steps and writing them in a way that computers can understand them."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Computers look at code one line at a time", true],
@@ -517,7 +531,7 @@
     },
     {
       "id": "bd712ad8c441eddfbeb5bddf",
-      "title": "Hike: Console and Logging",
+      "title": "Console and Logging",
       "difficulty": 9.15,
       "challengeSeed": [
         "133170880"
@@ -535,6 +549,7 @@
         "This will also work with numbers and booleans, which are true/false statements.",
         "When consoling words, it's important to put it inside of quotations so it recognizes it's a string."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["The console serves only small, unnecessary purposes.", false, "The console's main purpose is to debug, which is a vital step in creating code."],
@@ -553,7 +568,7 @@
     },
     {
       "id": "bd7119d8c441eddfbeb5bddf",
-      "title": "Hike: Variables In Code",
+      "title": "Variables In Code",
       "difficulty": 9.16,
       "challengeSeed": [
         "133172920"
@@ -567,6 +582,7 @@
         "But be careful - if we put console.log(\"x\"), with the x in quotation marks, it will output the letter \"x\".",
         "What I want you to take away from this video is that variables exist in code, and you can store everything from a simple string all the way up to a function, all within a simple name."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Variables are useful in coding languages like JavaScript.", true],
@@ -585,7 +601,7 @@
     },
     {
       "id": "bd7029d8c441eddfbeb5bddf",
-      "title": "Hike: Source Code",
+      "title": "Source Code",
       "difficulty": 9.17,
       "challengeSeed": [
         "133177129"
@@ -610,6 +626,7 @@
         "It's a great way for websites and software to grow in a strong and fast way because of the community working together to improve it.",
         "One unwritten rule of contributing to open source projects is that you should generally submit your improvements to also be open source, and by giving that improvement back to the public, you let others use your improvement as well."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Source code is a text document.", true],
@@ -629,7 +646,7 @@
     },
     {
       "id": "bd7129d8b441eddfbeb5bddf",
-      "title": "Hike: Routers and Packets",
+      "title": "Routers and Packets",
       "difficulty": 9.18,
       "challengeSeed": [
         "133181251"
@@ -660,6 +677,7 @@
         "They can take whichever route is open, whichever is fastest, and since they have the end IP address, all of the routers know where to send them.",
         "Once they get to the end destination, that computer knows how to put all of the information back together."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Routers have to know the whole internet.", false, "Routers just have to know the stops around them to send information in the right direction."],
@@ -679,7 +697,7 @@
     },
     {
       "id": "bd7129d8a441eddfbeb5bddf",
-      "title": "Hike: Hardware: Chips and Moore's Law",
+      "title": "Hardware: Chips and Moore's Law",
       "difficulty": 9.19,
       "challengeSeed": [
         "133182057"
@@ -696,6 +714,7 @@
         "Moore's Law is the observation that the amount of transistors fit on each chip has doubled every two years since 1965.",
         "This is important because it's making technology more affordable and accessible."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Chips have transistors, little switches that can store a 1 or a 0.", true],
@@ -715,7 +734,7 @@
     },
     {
       "id": "bd7129d80441eddfbeb5bddf",
-      "title": "Hike: Analog vs Digital and File Compression",
+      "title": "Analog vs Digital and File Compression",
       "difficulty": 9.20,
       "challengeSeed": [
         "133182587"
@@ -735,6 +754,7 @@
         "In images, it's done by measuring groups of pixels by 16 instead of individually.",
         "The takeaway from this video is that you'll want to use digital files as they're a higher quality, and when you're looking at compression, you want to decide how far you are willing to go to ensure the user still has the best possible experience."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Digital files can be made from analog sounds and analog sounds can be made from digital files.", true],
@@ -753,7 +773,7 @@
     },
     {
       "id": "bd7129d89441eddfbeb5bddf",
-      "title": "Hike: Computer Security",
+      "title": "Computer Security",
       "difficulty": 9.21,
       "challengeSeed": [
         "133186284"
@@ -787,6 +807,7 @@
         "Those bugs have been patched in newer versions, so if you keep everything updated, you'll avoid lots of problems.",
         "These are all very basic things you should know about how to keep your information safe on your computer."
       ],
+      "type": "hike",
       "challengeType": 6,
       "tests": [
         ["Passwords should be shared with all of your accounts.", false, "Don't reuse important passwords"],
diff --git a/seed/challenges/html5-and-css.json b/seed/challenges/html5-and-css.json
index 77df5f4..2ceadb9 100644
--- a/seed/challenges/html5-and-css.json
+++ b/seed/challenges/html5-and-css.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7123c8c441eddfaeb5bdef",
-      "title": "Waypoint: Say Hello to HTML Elements",
+      "title": "Say Hello to HTML Elements",
       "difficulty": 1.01,
       "description": [
         "Welcome to Free Code Camp's first coding challenge!",
@@ -20,6 +20,7 @@
       "challengeSeed": [
         "<h1>Hello</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -52,7 +53,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf0887a",
-      "title": "Waypoint: Headline with the h2 Element",
+      "title": "Headline with the h2 Element",
       "difficulty": 1.02,
       "description": [
         "Add an <code>h2</code> tag that says \"CatPhotoApp\" to create a second HTML <code>element</code> below your \"Hello World\" <code>h1</code> element.",
@@ -69,6 +70,7 @@
       "challengeSeed": [
         "<h1>Hello World</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -95,7 +97,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08801",
-      "title": "Waypoint: Inform with the Paragraph Element",
+      "title": "Inform with the Paragraph Element",
       "difficulty": 1.03,
       "description": [
         "Create a <code>p</code> element below your <code>h2</code> element, and give it the text \"Hello Paragraph\".",
@@ -111,6 +113,7 @@
         "<h1>Hello World</h1>",
         "<h2>CatPhotoApp</h2>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -135,7 +138,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08802",
-      "title": "Waypoint: Uncomment HTML",
+      "title": "Uncomment HTML",
       "difficulty": 1.04,
       "description": [
         "Uncomment your <code>h1</code>, <code>h2</code> and <code>p</code> elements.",
@@ -158,6 +161,7 @@
         "<p>Hello Paragraph</p>",
         "-->"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -184,7 +188,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08804",
-      "title": "Waypoint: Comment out HTML",
+      "title": "Comment out HTML",
       "difficulty": 1.05,
       "description": [
         "Comment out your <code>h1</code> element and your <code>p</code> element, but leave your <code>h2</code> element uncommented.",
@@ -206,6 +210,7 @@
         "<p>Hello Paragraph</p>",
         "-->"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -230,7 +235,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08833",
-      "title": "Waypoint: Fill in the Blank with Placeholder Text",
+      "title": "Fill in the Blank with Placeholder Text",
       "difficulty": 1.06,
       "description": [
         "Web developers traditionally use \"Lorem Ipsum\" text as placeholder text. It's called \"Lorem Ipsum\" text because those are the first two words of a famous passage by Cicero of Ancient Rome.",
@@ -248,6 +253,7 @@
         "",
         "<p>Hello Paragraph</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -276,7 +282,7 @@
     },
     {
       "id": "bad87fed1348bd9aedf08833",
-      "title": "Waypoint: Delete HTML Elements",
+      "title": "Delete HTML Elements",
       "difficulty": 1.07,
       "description": [
         "Delete your <code>h1</code> element so we can simplify our view.",
@@ -295,6 +301,7 @@
         "",
         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -319,7 +326,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08803",
-      "title": "Waypoint: Change the Color of Text",
+      "title": "Change the Color of Text",
       "difficulty": 1.08,
       "description": [
         "Change your <code>h2</code> element's style so that its text color is red.",
@@ -335,6 +342,7 @@
         "",
         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -360,7 +368,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08805",
-      "title": "Waypoint: Use CSS Selectors to Style Elements",
+      "title": "Use CSS Selectors to Style Elements",
       "difficulty": 1.09,
       "description": [
         "Delete your <code>h2</code> element's style attribute and instead create a CSS <code>style</code> element. Add the necessary CSS to turn all <code>h2</code> elements blue.",
@@ -382,6 +390,7 @@
         "",
         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -414,7 +423,7 @@
     },
     {
       "id": "bad87fee1348bd9aecf08806",
-      "title": "Waypoint: Use a CSS Class to Style an Element",
+      "title": "Use a CSS Class to Style an Element",
       "difficulty": 1.11,
       "description": [
         "Create a CSS class called \"red-text\" and apply it to your <code>h2</code> element.",
@@ -442,6 +451,7 @@
         "",
         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -467,7 +477,7 @@
     },
     {
       "id": "bad87fee1348bd9aefe08806",
-      "title": "Waypoint: Style Multiple Elements with a CSS Class",
+      "title": "Style Multiple Elements with a CSS Class",
       "difficulty": 1.12,
       "description": [
         "Apply the \"red-text\" class to your <code>h2</code> and <code>p</code> elements.",
@@ -491,6 +501,7 @@
         "",
         "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -511,7 +522,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08806",
-      "title": "Waypoint: Change the Font Size of an Element",
+      "title": "Change the Font Size of an Element",
       "difficulty": 1.13,
       "description": [
         "Create a second <code>p</code> element with the following Kitty Ipsum text: <code>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</code>",
@@ -536,6 +547,7 @@
         "",
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -557,7 +569,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08807",
-      "title": "Waypoint: Set the Font Family of an Element",
+      "title": "Set the Font Family of an Element",
       "difficulty": 1.14,
       "description": [
         "Make all of your <code>p</code> elements use the \"Monospace\" font.",
@@ -583,6 +595,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -603,7 +616,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08807",
-      "title": "Waypoint: Import a Google Font",
+      "title": "Import a Google Font",
       "difficulty": 1.15,
       "description": [
         "Apply the <code>font-family</code> of \"Lobster\" to your <code>h2</code> element.",
@@ -634,6 +647,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -656,7 +670,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08808",
-      "title": "Waypoint: Specify How Fonts Should Degrade",
+      "title": "Specify How Fonts Should Degrade",
       "difficulty": 1.16,
       "description": [
         "There are several default fonts that are available in all browsers. These include \"Monospace\", \"Serif\" and \"Sans-Serif\". Leave \"Lobster\" as the font-family for your <code>h2</code> elements. Make them \"degrade\" to \"Monospace\" when \"Lobster\" isn't available.",
@@ -691,6 +705,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -713,7 +728,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08812",
-      "title": "Waypoint: Add Images to your Website",
+      "title": "Add Images to your Website",
       "difficulty": 1.17,
       "description": [
         "You can add images to your website by using the <code>img</code> element, and point to an specific image's URL using the <code>src</code> attribute.",
@@ -746,6 +761,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -767,7 +783,7 @@
     },
     {
       "id": "bad87fee1348bd9acdf08812",
-      "title": "Waypoint: Size your Images",
+      "title": "Size your Images",
       "difficulty": 1.18,
       "description": [
         "CSS has an attribute called <code>width</code> that controls an element's width. Just like with fonts, we'll use pixels(px) to specify the image's width.",
@@ -802,6 +818,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -822,7 +839,7 @@
     },
     {
       "id": "bad87fee1348bd9bedf08813",
-      "title": "Waypoint: Add Borders Around your Elements",
+      "title": "Add Borders Around your Elements",
       "difficulty": 1.19,
       "description": [
         "CSS borders have attributes like style, color and width.",
@@ -864,6 +881,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -884,7 +902,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08814",
-      "title": "Waypoint: Add Rounded Corners with a Border Radius",
+      "title": "Add Rounded Corners with a Border Radius",
       "difficulty": 1.20,
       "description": [
         "Your cat photo currently has sharp corners. We can round out those corners with a CSS attribute called <code>border-radius</code>.",
@@ -929,6 +947,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -949,7 +968,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08815",
-      "title": "Waypoint: Make Circular Images with a Border Radius",
+      "title": "Make Circular Images with a Border Radius",
       "difficulty": 1.21,
       "description": [
         "In addition to pixels, you can also specify a <code>border-radius</code> using a percentage.",
@@ -994,6 +1013,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1013,7 +1033,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08816",
-      "title": "Waypoint: Link to External Pages with Anchor Elements",
+      "title": "Link to External Pages with Anchor Elements",
       "difficulty": 1.22,
       "description": [
         "<code>a</code> elements or \"anchor\" elements, are used to link to content outside of the current page.",
@@ -1062,6 +1082,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1083,7 +1104,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08817",
-      "title": "Waypoint: Nest an Anchor Element within a Paragraph",
+      "title": "Nest an Anchor Element within a Paragraph",
       "difficulty": 1.23,
       "description": [
         "Again, here's a diagram of an <code>a</code> element for your reference:",
@@ -1138,6 +1159,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1158,7 +1180,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08817",
-      "title": "Waypoint: Make Dead Links using the Hash Symbol",
+      "title": "Make Dead Links using the Hash Symbol",
       "difficulty": 1.24,
       "description": [
         "Sometimes you want to add <code>a</code> elements to your website before you know where they will link.",
@@ -1205,6 +1227,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1226,7 +1249,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08820",
-      "title": "Waypoint: Turn an Image into a Link",
+      "title": "Turn an Image into a Link",
       "difficulty": 1.25,
       "description": [
         "You can make elements into links by nesting them within an <code>a</code> element.",
@@ -1276,6 +1299,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1298,7 +1322,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08818",
-      "title": "Waypoint: Add Alt Text to an Image for Accessibility",
+      "title": "Add Alt Text to an Image for Accessibility",
       "difficulty": 1.26,
       "description": [
         "<code>alt</code> attributes, also known as \"alt text\", are what browsers will display if they fail to load the image. <code>alt</code> attributes are also important for blind or visually impaired users to understand what an image portrays. And search engines also look at <code>alt</code> attributes.",
@@ -1346,6 +1370,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1368,7 +1393,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08827",
-      "title": "Waypoint: Create a Bulleted Unordered List",
+      "title": "Create a Bulleted Unordered List",
       "difficulty": 1.27,
       "description": [
         "HTML has a special element for creating unordered lists, or bullet point-style lists.",
@@ -1424,6 +1449,7 @@
         "<p class='red-text'>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
         "<p class='red-text'>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1445,7 +1471,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08828",
-      "title": "Waypoint: Create an Ordered List",
+      "title": "Create an Ordered List",
       "difficulty": 1.28,
       "description": [
         "HTML has a special element for creating ordered lists, or numbered-style lists.",
@@ -1504,6 +1530,7 @@
         "</ul>",
         "<p>Top 3 things cats hate:</p>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1525,7 +1552,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08829",
-      "title": "Waypoint: Create a Text Field",
+      "title": "Create a Text Field",
       "difficulty": 1.29,
       "description": [
         "Now let's create a web form.",
@@ -1583,6 +1610,7 @@
         "  <li>other cats</li>",
         "</ol>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1603,7 +1631,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08830",
-      "title": "Waypoint: Add Placeholder Text to a Text Field",
+      "title": "Add Placeholder Text to a Text Field",
       "difficulty": 1.30,
       "description": [
         "Your placeholder text is what appears in your text <code>input</code> before your user has inputed anything.",
@@ -1662,6 +1690,7 @@
         "</ol>",
         "<input type='text'>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1682,7 +1711,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08830",
-      "title": "Waypoint: Create a Form Element",
+      "title": "Create a Form Element",
       "difficulty": 1.31,
       "description": [
         "You can build web forms that actually submit data to a server using nothing more than pure HTML. You can do this by specifying an action on your <code>form</code> element.",
@@ -1743,6 +1772,7 @@
         "</ol>",
         "<input type='text' placeholder='cat photo URL'>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1763,7 +1793,7 @@
     },
     {
       "id": "bad87fee1348bd9aedd08830",
-      "title": "Waypoint: Add a Submit Button to a Form",
+      "title": "Add a Submit Button to a Form",
       "difficulty": 1.32,
       "description": [
         "Let's add a submit button to your form. Clicking this button will send the data from your form to the URL you specified with your form's <code>action</code> attribute.",
@@ -1826,6 +1856,7 @@
         "  <input type='text' placeholder='cat photo URL'>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1846,7 +1877,7 @@
     },
     {
       "id": "bad87fee1348bd9aedc08830",
-      "title": "Waypoint: Use HTML5 to Require a Field",
+      "title": "Use HTML5 to Require a Field",
       "difficulty": 1.33,
       "description": [
         "You can require specific form fields so that your user will not be able to submit your form until he or she has filled them out.",
@@ -1907,6 +1938,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -1927,7 +1959,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08834",
-      "title": "Waypoint: Create a Set of Radio Buttons",
+      "title": "Create a Set of Radio Buttons",
       "difficulty": 1.34,
       "description": [
         "You can use \"radio buttons\" for questions where you want the user to only give you one answer.",
@@ -1996,6 +2028,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2019,7 +2052,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08835",
-      "title": "Waypoint: Create a Set of Checkboxes",
+      "title": "Create a Set of Checkboxes",
       "difficulty": 1.35,
       "description": [
         "Forms commonly use \"checkboxes\" for questions that may have more than one answer.",
@@ -2088,6 +2121,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2108,7 +2142,7 @@
     },
     {
       "id": "bad87fee1348bd9aedd08835",
-      "title": "Waypoint: Check Radio Buttons and Checkboxes by Default",
+      "title": "Check Radio Buttons and Checkboxes by Default",
       "difficulty": 1.37,
       "description": [
         "You can set a checkbox or radio button to be checked by default using the <code>checked</code> attribute.",
@@ -2175,6 +2209,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2195,7 +2230,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08835",
-      "title": "Waypoint: Nest Many Elements within a Single Div Element",
+      "title": "Nest Many Elements within a Single Div Element",
       "difficulty": 1.38,
       "description": [
         "The <code>div</code> element, or \"Division\" element, is a general purpose container for other elements.",
@@ -2267,6 +2302,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2289,7 +2325,7 @@
     },
     {
       "id": "bad87fed1348bd9aede07836",
-      "title": "Waypoint: Give a Background Color to a Div Element",
+      "title": "Give a Background Color to a Div Element",
       "difficulty": 1.39,
       "description": [
         "You can set an element's background color with the \"background-color\" attribute.",
@@ -2359,6 +2395,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2375,7 +2412,7 @@
     },
     {
       "id": "bad87eee1348bd9aede07836",
-      "title": "Waypoint: Set the ID of an Element",
+      "title": "Set the ID of an Element",
       "difficulty": 1.391,
       "description": [
         "In addition to classes, each HTML element can also have an <code>id</code> attribute.",
@@ -2446,6 +2483,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2462,7 +2500,7 @@
     },
     {
       "id": "bad87dee1348bd9aede07836",
-      "title": "Waypoint: Use an ID Attribute to Style an Element",
+      "title": "Use an ID Attribute to Style an Element",
       "difficulty": 1.392,
       "description": [
         "One cool thing about <code>id</code> attributes is that, like classes, you can style them using CSS.",
@@ -2535,6 +2573,7 @@
         "  <button type='submit'>Submit</button>",
         "</form>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2551,7 +2590,7 @@
     },
     {
       "id": "bad88fee1348bd9aedf08825",
-      "title": "Waypoint: Adjusting the Padding of an Element",
+      "title": "Adjusting the Padding of an Element",
       "difficulty": 1.40,
       "description": [
         "You may have already noticed this, but all HTML elements are essentially little rectangles.",
@@ -2600,6 +2639,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2621,7 +2661,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08822",
-      "title": "Waypoint: Adjust the Margin of an Element",
+      "title": "Adjust the Margin of an Element",
       "difficulty": 1.41,
       "description": [
         "An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
@@ -2670,6 +2710,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2691,7 +2732,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08823",
-      "title": "Waypoint: Add a Negative Margin to an Element",
+      "title": "Add a Negative Margin to an Element",
       "difficulty": 1.42,
       "description": [
         "An element's <code>margin</code> controls the amount of space between an element's <code>border</code> and surrounding elements.",
@@ -2739,6 +2780,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2760,7 +2802,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08824",
-      "title": "Waypoint: Add Different Padding to Each Side of an Element",
+      "title": "Add Different Padding to Each Side of an Element",
       "difficulty": 1.43,
       "description": [
         "Sometimes you will want to customize an element so that it has different <code>padding</code> on each of its sides.",
@@ -2811,6 +2853,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2831,7 +2874,7 @@
     },
     {
       "id": "bad87fee1248bd9aedf08824",
-      "title": "Waypoint: Add Different Margins to Each Side of an Element",
+      "title": "Add Different Margins to Each Side of an Element",
       "difficulty": 1.44,
       "description": [
         "Give the green box a <code>margin</code> of 40 pixels on its top and left side, but only 20 pixels on its bottom and right side.",
@@ -2882,6 +2925,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2901,7 +2945,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08826",
-      "title": "Waypoint: Use Clockwise Notation to Specify the Padding of an Element",
+      "title": "Use Clockwise Notation to Specify the Padding of an Element",
       "difficulty": 1.44,
       "description": [
         "Instead of specifying an element's <code>padding-top</code>, <code>padding-right</code>, <code>padding-bottom</code>, and <code>padding-left</code> attributes, you can specify them all in one line, like this: <code>padding: 10px 20px 10px 20px;</code>.",
@@ -2949,6 +2993,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -2969,7 +3014,7 @@
     },
     {
       "id": "bad87fee1348bd9afdf08726",
-      "title": "Waypoint: Use Clockwise Notation to Specify the Margin of an Element",
+      "title": "Use Clockwise Notation to Specify the Margin of an Element",
       "difficulty": 1.45,
       "description": [
         "Let's try this again, but with <code>margin</code> this time.",
@@ -3018,6 +3063,7 @@
         "  <h5 class=\"box green-box\">padding</h5>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3038,7 +3084,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08736",
-      "title": "Waypoint: Style the HTML Body Element",
+      "title": "Style the HTML Body Element",
       "difficulty": 1.46,
       "description": [
         "Now let's start fresh and talk about CSS inheritance.",
@@ -3054,6 +3100,7 @@
         "",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3070,7 +3117,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08746",
-      "title": "Waypoint: Inherit Styles from the Body Element",
+      "title": "Inherit Styles from the Body Element",
       "difficulty": 1.47,
       "description": [
         "Now we've proven that every HTML page has a <code>body</code> element, and that its <code>body</code> element can also be styled with CSS.",
@@ -3096,6 +3143,7 @@
         "",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3112,7 +3160,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08756",
-      "title": "Waypoint: Prioritize One Style Over Another",
+      "title": "Prioritize One Style Over Another",
       "difficulty": 1.48,
       "description": [
         "Sometimes your HTML elements will receive multiple styles that conflict with one another.",
@@ -3135,6 +3183,7 @@
         "</style>",
         "<h1>Hello World!</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3151,7 +3200,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf04756",
-      "title": "Waypoint: Override Styles in Subsequent CSS",
+      "title": "Override Styles in Subsequent CSS",
       "difficulty": 1.49,
       "description": [
         "Our \"pink-text\" class overrode our <code>body</code> element's CSS declaration!",
@@ -3177,6 +3226,7 @@
         "</style>",
         "<h1 class='pink-text'>Hello World!</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3193,7 +3243,7 @@
     },
     {
       "id": "bad87fee1348bd8aedf06756",
-      "title": "Waypoint: Override Class Declarations by Styling ID Attributes",
+      "title": "Override Class Declarations by Styling ID Attributes",
       "difficulty": 1.52,
       "description": [
         "We just proved that browsers read CSS from top to bottom. That means that, in the event of a conflict, the browser will use whichever CSS declaration came last.",
@@ -3225,6 +3275,7 @@
         "</style>",
         "<h1 class='pink-text blue-text'>Hello World!</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3241,7 +3292,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf06756",
-      "title": "Waypoint: Override Class Declarations with Inline Styles",
+      "title": "Override Class Declarations with Inline Styles",
       "difficulty": 1.52,
       "description": [
         "So we've proven that id declarations override class declarations, regardless of where they are declared in your <code>style</code> element CSS.",
@@ -3275,6 +3326,7 @@
         "</style>",
         "<h1 id='orange-text' class='pink-text blue-text'>Hello World!</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3291,7 +3343,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf07756",
-      "title": "Waypoint: Override All Other Styles by using Important",
+      "title": "Override All Other Styles by using Important",
       "difficulty": 1.53,
       "description": [
         "Yay! We just proved that in-line styles will override all the CSS declarations in your <code>style</code> element.",
@@ -3328,6 +3380,7 @@
         "</style>",
         "<h1 id='orange-text' class='pink-text blue-text' style='color: white'>Hello World!</h1>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3344,7 +3397,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08726",
-      "title": "Waypoint: Use Hex Code for Specific Colors",
+      "title": "Use Hex Code for Specific Colors",
       "difficulty": 1.54,
       "description": [
         "Did you know there other ways to represent colors in CSS? One of these ways is called hexadecimal code, or \"hex code\" for short.",
@@ -3363,6 +3416,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3379,7 +3433,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08725",
-      "title": "Waypoint: Use Hex Code to Color Elements White",
+      "title": "Use Hex Code to Color Elements White",
       "difficulty": 1.55,
       "description": [
         "0 is the lowest number in hex code, and represents a complete absence of color.",
@@ -3397,6 +3451,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3413,7 +3468,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08724",
-      "title": "Waypoint: Use Hex Code to Color Elements Red",
+      "title": "Use Hex Code to Color Elements Red",
       "difficulty": 1.56,
       "description": [
         "You may be wondering why we use 6 digits to represent a color instead of just one or two. The answer is that using 6 digits gives us a huge variety.",
@@ -3433,6 +3488,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3449,7 +3505,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08723",
-      "title": "Waypoint: Use Hex Code to Color Elements Green",
+      "title": "Use Hex Code to Color Elements Green",
       "difficulty": 1.57,
       "description": [
         "Remember that hex code follows the red-green-blue, or \"RGB\" format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
@@ -3467,6 +3523,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3483,7 +3540,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08722",
-      "title": "Waypoint: Use Hex Code to Color Elements Blue",
+      "title": "Use Hex Code to Color Elements Blue",
       "difficulty": 1.58,
       "description": [
         "Hex code follows the red-green-blue, or \"RGB\" format. The first two digits of hex code represent the amount of red in the color. The third and fourth digit represent the amount of green. The fifth and sixth represent the amount of blue.",
@@ -3501,6 +3558,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3517,7 +3575,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08721",
-      "title": "Waypoint: Use Hex Code to Mix Colors",
+      "title": "Use Hex Code to Mix Colors",
       "difficulty": 1.59,
       "description": [
         "From these three pure colors (red, green and blue), we can create 16 million other colors.",
@@ -3535,6 +3593,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3551,7 +3610,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08720",
-      "title": "Waypoint: Use Hex Code to Color Elements Gray",
+      "title": "Use Hex Code to Color Elements Gray",
       "difficulty": 1.60,
       "description": [
         "From these three pure colors (red, green and blue), we can create 16 million other colors.",
@@ -3569,6 +3628,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3585,7 +3645,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08720",
-      "title": "Waypoint: Use Hex Code for Specific Shades of Gray",
+      "title": "Use Hex Code for Specific Shades of Gray",
       "difficulty": 1.61,
       "description": [
         "We can also create other shades of gray by evenly mixing all three colors. We can go very close to true black.",
@@ -3602,6 +3662,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3618,7 +3679,7 @@
     },
     {
       "id": "bad87fee1348bd9aedf08719",
-      "title": "Waypoint: Use Abbreviated Hex Code",
+      "title": "Use Abbreviated Hex Code",
       "difficulty": 1.62,
       "description": [
         "Many people feel overwhelmed by the possibilities of more than 16 million colors. And it's difficult to remember hex code. Fortunately, you can shorten it.",
@@ -3637,6 +3698,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3653,7 +3715,7 @@
     },
     {
       "id": "bad87fee1348bd9aede08718",
-      "title": "Waypoint: Use RGB values to Color Elements",
+      "title": "Use RGB values to Color Elements",
       "difficulty": 1.63,
       "description": [
         "Another way you can represent colors in CSS is by using RGB values.",
@@ -3673,6 +3735,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3689,7 +3752,7 @@
     },
     {
       "id": "bad88fee1348bd9aedf08726",
-      "title": "Waypoint: Use RGB to Color Elements White",
+      "title": "Use RGB to Color Elements White",
       "difficulty": 1.64,
       "description": [
         "RGB values look like this: <code>rgb(0, 0, 0)</code> for black and <code>rgb(255, 255, 255)<code> for white.",
@@ -3707,6 +3770,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3723,7 +3787,7 @@
     },
     {
       "id": "bad89fee1348bd9aedf08724",
-      "title": "Waypoint: Use RGB to Color Elements Red",
+      "title": "Use RGB to Color Elements Red",
       "difficulty": 1.65,
       "description": [
         "Just like with hex code, you can represent different colors in RGB by using combinations of different values.",
@@ -3741,6 +3805,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3757,7 +3822,7 @@
     },
     {
       "id": "bad80fee1348bd9aedf08723",
-      "title": "Waypoint: Use RGB to Color Elements Green",
+      "title": "Use RGB to Color Elements Green",
       "difficulty": 1.66,
       "description": [
         "Now change the <code>body</code> element's background color to the RGB value green: <code>rgb(0, 255, 0)</code>"
@@ -3773,6 +3838,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3789,7 +3855,7 @@
     },
     {
       "id": "bad81fee1348bd9aedf08722",
-      "title": "Waypoint: Use RGB to Color Elements Blue",
+      "title": "Use RGB to Color Elements Blue",
       "difficulty": 1.67,
       "description": [
         "Change the <code>body</code> element's background color to the RGB value blue: <code>rgb(0, 0, 255)</code>"
@@ -3805,6 +3871,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3821,7 +3888,7 @@
     },
     {
       "id": "bad82fee1348bd9aedf08721",
-      "title": "Waypoint: Use RGB to Mix Colors",
+      "title": "Use RGB to Mix Colors",
       "difficulty": 1.68,
       "description": [
         "Just like with hex code, you can mix colors in RGB by using combinations of different values.",
@@ -3838,6 +3905,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
@@ -3854,7 +3922,7 @@
     },
     {
       "id": "bad83fee1348bd9aede08720",
-      "title": "Waypoint: Use RGB to Color Elements Gray",
+      "title": "Use RGB to Color Elements Gray",
       "difficulty": 1.69,
       "description": [
         "With RGB values, we can make an element gray by using combinations of the same value for all three colors.",
@@ -3871,6 +3939,7 @@
         "  }",
         "</style>"
       ],
+      "type": "waypoint",
       "challengeType": 0,
       "nameCn": "",
       "descriptionCn": [],
diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index b9e9882..a85f636 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "a3566b1109230028080c9345",
-      "title": "Bonfire: Sum All Numbers in a Range",
+      "title": "Sum All Numbers in a Range",
       "difficulty": "2.00",
       "description": [
         "We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.",
@@ -30,6 +30,7 @@
         "Math.min()",
         "Array.reduce()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -44,7 +45,7 @@
     },
     {
       "id": "a5de63ebea8dbee56860f4f2",
-      "title": "Bonfire: Diff Two Arrays",
+      "title": "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.",
@@ -75,6 +76,7 @@
         "Array.indexOf()",
         "String.concat()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -89,7 +91,7 @@
     },
     {
       "id": "a7f4d8f2483413a6ce226cac",
-      "title": "Bonfire: Roman Numeral Converter",
+      "title": "Roman Numeral Converter",
       "tests": [
         "expect(convert(12)).to.equal(\"XII\");",
         "expect(convert(5)).to.equal(\"V\");",
@@ -115,6 +117,7 @@
         "Array.indexOf()",
         "Array.join()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -129,7 +132,7 @@
     },
     {
       "id": "a0b5010f579e69b815e7c5d6",
-      "title": "Bonfire: Search and Replace",
+      "title": "Search and Replace",
       "tests": [
         "expect(replace(\"Let us go to the store\", \"store\", \"mall\")).to.equal(\"Let us go to the mall\");",
         "expect(replace(\"He is Sleeping on the couch\", \"Sleeping\", \"sitting\")).to.equal(\"He is Sitting on the couch\");",
@@ -158,6 +161,7 @@
         "String.replace()",
         "Array.join()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -172,7 +176,7 @@
     },
     {
       "id": "aa7697ea2477d1316795783b",
-      "title": "Bonfire: Pig Latin",
+      "title": "Pig Latin",
       "tests": [
         "expect(translate(\"california\")).to.equal(\"aliforniacay\");",
         "expect(translate(\"paragraphs\")).to.equal(\"aragraphspay\");",
@@ -201,6 +205,7 @@
         "String.substr()",
         "String.split()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -215,7 +220,7 @@
     },
     {
       "id": "afd15382cdfb22c9efe8b7de",
-      "title": "Bonfire: DNA Pairing",
+      "title": "DNA Pairing",
       "tests": [
         "assert.deepEqual(pair(\"ATCGA\"),[['A','T'],['T','A'],['C','G'],['G','C'],['A','T']], 'should return the dna pair');",
         "assert.deepEqual(pair(\"TTGAG\"),[['T','A'],['T','A'],['G','C'],['A','T'],['G','C']], 'should return the dna pair');",
@@ -239,6 +244,7 @@
         "Array.push()",
         "String.split()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -253,7 +259,7 @@
     },
     {
       "id": "af7588ade1100bde429baf20",
-      "title": "Bonfire: Missing letters",
+      "title": "Missing letters",
       "difficulty": "2.05",
       "description": [
         "Find the missing letter in the passed letter range and return it.",
@@ -277,6 +283,7 @@
         "String.charCodeAt()",
         "String.fromCharCode()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -291,7 +298,7 @@
     },
     {
       "id": "a77dbc43c33f39daa4429b4f",
-      "title": "Bonfire: Boo who",
+      "title": "Boo who",
       "difficulty": "2.06",
       "description": [
         "Check if a value is classified as a boolean primitive. Return true or false.",
@@ -319,6 +326,7 @@
       "MDNlinks": [
         "Boolean Objects"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -333,7 +341,7 @@
     },
     {
       "id": "a105e963526e7de52b219be9",
-      "title": "Bonfire: Sorted Union",
+      "title": "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.",
@@ -359,6 +367,7 @@
         "Arguments object",
         "Array.reduce()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -373,7 +382,7 @@
     },
     {
       "id": "a6b0bb188d873cb2c8729495",
-      "title": "Bonfire: Convert HTML Entities",
+      "title": "Convert HTML Entities",
       "difficulty": "2.07",
       "description": [
         "Convert the characters \"&\", \"<\", \">\", '\"' (double quote), and \"'\" (apostrophe), in a string to their corresponding HTML entities.",
@@ -400,6 +409,7 @@
         "RegExp",
         "HTML Entities"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -414,7 +424,7 @@
     },
     {
       "id": "a103376db3ba46b2d50db289",
-      "title": "Bonfire: Spinal Tap Case",
+      "title": "Spinal Tap Case",
       "difficulty": "2.08",
       "description": [
         "Convert a string to spinal case. Spinal case is all-lowercase-words-joined-by-dashes.",
@@ -439,6 +449,7 @@
         "RegExp",
         "String.replace()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -453,7 +464,7 @@
     },
     {
       "id": "a5229172f011153519423690",
-      "title": "Bonfire: Sum All Odd Fibonacci Numbers",
+      "title": "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.",
@@ -479,6 +490,7 @@
       "MDNlinks": [
         "Remainder"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -493,7 +505,7 @@
     },
     {
       "id": "a3bfc1673c0526e06d3ac698",
-      "title": "Bonfire: Sum All Primes",
+      "title": "Sum All Primes",
       "difficulty": "2.10",
       "description": [
         "Sum all the prime numbers up to and including the provided number.",
@@ -517,6 +529,7 @@
         "For Loops",
         "Array.push()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -531,7 +544,7 @@
     },
     {
       "id": "ae9defd7acaf69703ab432ea",
-      "title": "Bonfire: Smallest Common Multiple",
+      "title": "Smallest Common Multiple",
       "difficulty": "2.11",
       "description": [
         "Find the smallest number that is evenly divisible by all numbers in the provided range.",
@@ -555,6 +568,7 @@
       "MDNlinks": [
         "Smallest Common Multiple"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -569,7 +583,7 @@
     },
     {
       "id": "a6e40f1041b06c996f7b2406",
-      "title": "Bonfire: Finders Keepers",
+      "title": "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).",
@@ -590,6 +604,7 @@
       "MDNlinks": [
         "Array.some()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -604,7 +619,7 @@
     },
     {
       "id": "a5deed1811a43193f9f1c841",
-      "title": "Bonfire: Drop it",
+      "title": "Drop it",
       "difficulty": "2.13",
       "description": [
         "Drop the elements of an array (first argument), starting from the front, until the predicate (second argument) returns true.",
@@ -627,6 +642,7 @@
         "Arguments object",
         "Array.shift()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -641,7 +657,7 @@
     },
     {
       "id": "ab306dbdcc907c7ddfc30830",
-      "title": "Bonfire: Steamroller",
+      "title": "Steamroller",
       "difficulty": "2.14",
       "description": [
         "Flatten a nested array. You must account for varying levels of nesting.",
@@ -664,6 +680,7 @@
       "MDNlinks": [
         "Array.isArray()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -678,7 +695,7 @@
     },
     {
       "id": "a8d97bd4c764e91f9d2bda01",
-      "title": "Bonfire: Binary Agents",
+      "title": "Binary Agents",
       "difficulty": "2.15",
       "description": [
         "Return an English translated sentence of the passed binary string.",
@@ -700,6 +717,7 @@
         "String.charCodeAt()",
         "String.fromCharCode()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -714,7 +732,7 @@
     },
     {
       "id": "a10d2431ad0c6a099a4b8b52",
-      "title": "Bonfire: Everything Be True",
+      "title": "Everything Be True",
       "difficulty": "2.21",
       "description": [
         "Check if the predicate (second argument) returns truthy (defined) for all elements of a collection (first argument).",
@@ -739,6 +757,7 @@
         "Object.hasOwnProperty()",
         "Object.getOwnPropertyNames()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -753,7 +772,7 @@
     },
     {
       "id": "a97fd23d9b809dac9921074f",
-      "title": "Bonfire: Arguments Optional",
+      "title": "Arguments Optional",
       "difficulty": "2.22",
       "description": [
         "Create a function that sums two arguments together. If only one argument is provided, return a function that expects one additional argument and will return the sum.",
@@ -779,6 +798,7 @@
         "Global Function Object",
         "Arguments object"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
diff --git a/seed/challenges/intermediate-ziplines.json b/seed/challenges/intermediate-ziplines.json
index ff900aa..2a2d5af 100644
--- a/seed/challenges/intermediate-ziplines.json
+++ b/seed/challenges/intermediate-ziplines.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7158d8c442eddfaeb5bd18",
-      "title": "Zipline: Stylize Stories on Camper News",
+      "title": "Stylize Stories on Camper News",
       "difficulty": 1.02,
       "challengeSeed": ["126415129"],
       "description": [
@@ -22,6 +22,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -37,7 +38,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd19",
-      "title": "Zipline: Wikipedia Viewer",
+      "title": "Wikipedia Viewer",
       "difficulty": 1.03,
       "challengeSeed": ["126415131"],
       "description": [
@@ -54,6 +55,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -69,7 +71,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd17",
-      "title": "Zipline: Build a JavaScript Calculator",
+      "title": "Build a JavaScript Calculator",
       "difficulty": 1.05,
       "challengeSeed": ["126411565"],
       "description": [
@@ -85,6 +87,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -100,7 +103,7 @@
     },
     {
       "id": "bd7158d8c442eedfaeb5bd1c",
-      "title": "Zipline: Build a Tic Tac Toe Game",
+      "title": "Build a Tic Tac Toe Game",
       "difficulty": 1.06,
       "challengeSeed": ["126415123"],
       "description": [
@@ -117,6 +120,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
@@ -132,7 +136,7 @@
     },
     {
       "id": "bd7158d8c442eddfaeb5bd1c",
-      "title": "Zipline: Build a Simon Game",
+      "title": "Build a Simon Game",
       "difficulty": 1.07,
       "challengeSeed": ["126415123"],
       "description": [
@@ -155,6 +159,7 @@
         "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>"
       ],
+      "type": "zipline",
       "challengeType": 3,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/jquery-ajax-and-json.json b/seed/challenges/jquery-ajax-and-json.json
index a5db78c..fa3f864 100644
--- a/seed/challenges/jquery-ajax-and-json.json
+++ b/seed/challenges/jquery-ajax-and-json.json
@@ -1,10 +1,10 @@
 {
-  "name":  "jQuery",
+  "name": "jQuery",
   "order": 0.004,
   "challenges": [
     {
       "id": "bad87fee1348bd9acdd08826",
-      "title":  "Waypoint: Learn how Script Tags and Document Ready Work",
+      "title": "Learn how Script Tags and Document Ready Work",
       "difficulty": 3.01,
       "description": [
         "Now we're ready to learn jQuery, the most popular JavaScript tool of all time. Don't worry about JavaScript itself - we will cover it soon.",
@@ -42,11 +42,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9bedc08826",
-      "title":  "Waypoint: Target HTML Elements with Selectors Using jQuery",
+      "title": "Target HTML Elements with Selectors Using jQuery",
       "difficulty": 3.02,
       "description": [
         "Now we have a \"document ready function\". We'll learn more about functions later. The important thing to know is that code you put inside this function will run as soon as your browser has loaded your page.",
@@ -90,11 +91,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aedc08826",
-      "title":  "Waypoint: Target Elements by Class Using jQuery",
+      "title": "Target Elements by Class Using jQuery",
       "difficulty": 3.03,
       "description": [
         "You see how we made all of your <code>button</code> elements bounce? We selected them with <code>$('button')</code>, then we added some CSS classes to them with <code>.addClass('animated bounce');</code>.",
@@ -139,11 +141,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aeda08826",
-      "title":  "Waypoint: Target Elements by ID Using jQuery",
+      "title": "Target Elements by ID Using jQuery",
       "difficulty": 3.04,
       "description": [
         "You can also target elements by their id attributes.",
@@ -189,11 +192,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aeda08726",
-      "title":  "Waypoint: Delete your jQuery Functions",
+      "title": "Delete your jQuery Functions",
       "difficulty": 3.05,
       "description": [
         "These animations were cool at first, but now they're getting kind of distracting.",
@@ -240,11 +244,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed908626",
-      "title":  "Waypoint: Target the same element with multiple jQuery Selectors",
+      "title": "Target the same element with multiple jQuery Selectors",
       "difficulty": 3.06,
       "description": [
         "Now you know three ways of targeting elements: by type <code>$('button')</code>, by class <code>$('.btn')</code>), and by id <code>$('#target1')</code>).",
@@ -290,11 +295,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed918626",
-      "title":  "Waypoint: Remove Classes from an element with jQuery",
+      "title": "Remove Classes from an element with jQuery",
       "difficulty": 3.07,
       "description": [
         "In the same way you can add classes to an element with jQuery's <code>addClass()</code> function, you can remove them with jQuery's <code>removeClass()</code> function.",
@@ -339,11 +345,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed908826",
-      "title":  "Waypoint: Change the CSS of an Element Using jQuery",
+      "title": "Change the CSS of an Element Using jQuery",
       "difficulty": 3.08,
       "description": [
         "We can also change the CSS of an HTML element directly with jQuery.",
@@ -392,11 +399,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed808826",
-      "title":  "Waypoint: Disable an Element Using jQuery",
+      "title": "Disable an Element Using jQuery",
       "difficulty": 3.09,
       "description": [
         "You can also change the non-CSS properties of HTML elements with jQuery. For example, you can disable buttons.",
@@ -442,11 +450,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed708826",
-      "title":  "Waypoint: Remove an Element Using jQuery",
+      "title": "Remove an Element Using jQuery",
       "difficulty": 3.10,
       "description": [
         "Now let's remove an HTML element from your page using jQuery.",
@@ -489,11 +498,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed608826",
-      "title":  "Waypoint: Use appendTo to Move Elements with jQuery",
+      "title": "Use appendTo to Move Elements with jQuery",
       "difficulty": 3.11,
       "description": [
         "Now let's try moving elements from one <code>div</code> to another.",
@@ -540,11 +550,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed508826",
-      "title":  "Waypoint: Clone an Element Using jQuery",
+      "title": "Clone an Element Using jQuery",
       "difficulty": 3.12,
       "description": [
         "In addition to moving elements, you can also copy them from one place to another.",
@@ -593,11 +604,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed308826",
-      "title":  "Waypoint: Target the Parent of an Element Using jQuery",
+      "title": "Target the Parent of an Element Using jQuery",
       "difficulty": 3.13,
       "description": [
         "Every HTML elements has a \"parent\" element from which it \"inherits\" properties.",
@@ -647,11 +659,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed208826",
-      "title":  "Waypoint: Target the Children of an Element Using jQuery",
+      "title": "Target the Children of an Element Using jQuery",
       "difficulty": 3.14,
       "description": [
         "Many HTML elements has a \"children\" element from which they \"inherits\" properties.",
@@ -702,11 +715,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed108826",
-      "title":  "Waypoint: Target a Specific Child of an Element Using jQuery",
+      "title": "Target a Specific Child of an Element Using jQuery",
       "difficulty": 3.15,
       "description": [
         "You've seen why id attributes are so convenient for targeting with jQuery selectors. But you won't always have such neat ids to work with.",
@@ -758,11 +772,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aed008826",
-      "title":  "Waypoint: Target Even Numbered Elements Using jQuery",
+      "title": "Target Even Numbered Elements Using jQuery",
       "difficulty": 3.16,
       "description": [
         "You can also target all the even-numbered elements.",
@@ -816,11 +831,12 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     },
     {
       "id": "bad87fee1348bd9aecb08826",
-      "title":  "Waypoint: Use jQuery to Modify the Entire Page",
+      "title": "Use jQuery to Modify the Entire Page",
       "difficulty": 3.20,
       "description": [
         "We're done playing with our jQuery playground. Let's tear it down!",
@@ -872,6 +888,7 @@
         "  </div>",
         "</div>"
       ],
+      "type": "waypoint",
       "challengeType": 0
     }
   ]
diff --git a/seed/challenges/json-apis-and-ajax.json b/seed/challenges/json-apis-and-ajax.json
index cefd0f0..8745e51 100644
--- a/seed/challenges/json-apis-and-ajax.json
+++ b/seed/challenges/json-apis-and-ajax.json
@@ -1,5 +1,5 @@
 {
-  "name":  "JSON APIs and Ajax - Coming Soon",
+  "name": "JSON APIs and Ajax - Coming Soon",
   "order": 0.007,
   "challenges": [
   ]
diff --git a/seed/challenges/mongodb.json b/seed/challenges/mongodb.json
index 75b24f2..1751c61 100644
--- a/seed/challenges/mongodb.json
+++ b/seed/challenges/mongodb.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7243d8c341eddeaeb5bd0f",
-      "title": "Waypoint: Store Data in MongoDB",
+      "title": "Store Data in MongoDB",
       "difficulty": 0.01,
       "challengeSeed": ["133316035"],
       "description": [
@@ -33,6 +33,7 @@
         "Complete \"Aggregate\"",
         "Once you've completed these steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/nodejs-and-expressjs.json b/seed/challenges/nodejs-and-expressjs.json
index 34d5401..ed62989 100644
--- a/seed/challenges/nodejs-and-expressjs.json
+++ b/seed/challenges/nodejs-and-expressjs.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7153d8c441eddfaeb5bd0f",
-      "title": "Waypoint: Manage Packages with NPM",
+      "title": "Manage Packages with NPM",
       "difficulty": 0.39,
       "challengeSeed": ["126433450"],
       "description": [
@@ -42,6 +42,7 @@
         "Complete \"Finale\"",
         "Once you've completed these steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -57,7 +58,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bdff",
-      "title": "Waypoint: Start a Node.js Server",
+      "title": "Start a Node.js Server",
       "difficulty": 0.40,
       "challengeSeed": ["126411561"],
       "description": [
@@ -83,6 +84,7 @@
         "Complete \"HTTP Client\"",
         "Once you've completed these first 7 steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -98,7 +100,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bdfe",
-      "title": "Waypoint: Continue working with Node.js Servers",
+      "title": "Continue working with Node.js Servers",
       "difficulty": 0.41,
       "challengeSeed": ["128836506"],
       "description": [
@@ -111,6 +113,7 @@
         "Complete \"Time Server\"",
         "Once you've completed these 3 steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -126,7 +129,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bdfd",
-      "title": "Waypoint: Finish working with Node.js Servers",
+      "title": "Finish working with Node.js Servers",
       "difficulty": 0.42,
       "challengeSeed": ["128836507"],
       "description": [
@@ -139,6 +142,7 @@
         "Complete \"HTTP JSON API Server\"",
         "Once you've completed these final 3 steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -154,7 +158,7 @@
     },
     {
       "id": "bd7153d8c441eddfaeb5bd1f",
-      "title": "Waypoint: Build Web Apps with Express.js",
+      "title": "Build Web Apps with Express.js",
       "difficulty": 0.43,
       "challengeSeed": [
         "126411559"
@@ -181,6 +185,7 @@
         "Complete \"JSON Me\"",
         "Once you've completed these steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index 90042d6..3faeed2 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -4,7 +4,7 @@
   "challenges": [
     {
       "id": "bd7153d8c44eeddfaeb5bd0f",
-      "title": "Waypoint: Learn Scope Chains and Closures",
+      "title": "Learn Scope Chains and Closures",
       "difficulty": 0.01,
       "challengeSeed": ["133316031"],
       "description": [
@@ -28,6 +28,7 @@
         "Complete \"Garbage Collection\"",
         "Once you've completed these steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -43,7 +44,7 @@
     },
     {
       "id": "bd7153d8b44eeddfaeb5bd0f",
-      "title": "Waypoint: Use Prototypes for Inheriting Properties",
+      "title": "Use Prototypes for Inheriting Properties",
       "difficulty": 0.02,
       "challengeSeed": ["133316036"],
       "description": [
@@ -72,6 +73,7 @@
         "Note that you can skip the last challenge.",
         "Once you've completed these steps, move on to our next challenge."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",
@@ -87,7 +89,7 @@
     },
     {
       "id": "bd7129d8c441eddfbeb5bddf",
-      "title": "Waypoint: Practice Functional Programming",
+      "title": "Practice Functional Programming",
       "difficulty": 0.01,
       "challengeSeed": ["129169463"],
       "description": [
@@ -99,6 +101,7 @@
         "This challenge will take several hours, but don't worry. Jafar's website will save your progress (using your browser's local storage) so you don't need to finish it in one sitting.",
         "If you've spent several minutes on one of these challenges, and still can't figure out its correct answer, you can click \"show answer\", then click \"run\" to advance to the next challenge. Be sure to read the correct answer and make sure you understand it before moving on."
       ],
+      "type": "waypoint",
       "challengeType": 2,
       "tests": [],
       "nameCn": "",

From b1e34f8cc8554458200009fb2b2f2c82b05823f1 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Sat, 8 Aug 2015 07:50:35 -0700
Subject: [PATCH 10/47] create name/dashName at seed

---
 seed/index.js | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/seed/index.js b/seed/index.js
index fdbdf1f..5c5c2bd 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -2,13 +2,12 @@
 require('babel/register');
 require('dotenv').load();
 var fs = require('fs'),
+    _ = require('lodash'),
     path = require('path'),
     app = require('../server/server'),
     nonprofits = require('./nonprofits.json'),
     jobs = require('./jobs.json');
 
-var challangesRegex = /^(bonfire:|waypoint:|zipline:|basejump:|hike:)/i;
-
 function getFilesFor(dir) {
   return fs.readdirSync(path.join(__dirname, '/' + dir));
 }
@@ -38,12 +37,15 @@ Challenge.destroyAll(function(err, info) {
     console.log('Deleted ', info);
   }
   challenges.forEach(function(file) {
-    var challenges = require('./challenges/' + file).challenges
+    var challengeSpec = require('./challenges/' + file);
+    var challenges = challengeSpec.challenges
       .map(function(challenge) {
         // NOTE(berks): add title for displaying in views
-        //challenge.title = challenge.name.replace(challangesRegex, '').trim();
-        challenge.name = challenge.title.replace(/[^a-zA-Z0-9 ]/g, ''); // Remove non-alphanumwhitespace chars
-        challenge.dashedName = challenge.name.replace(/\s/g, '-'); // Replace with dasherize();
+        challenge.name =
+          _.capitalize(challenge.type) +
+          ': ' +
+          challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
+        challenge.dashedName = challenge.name.toLowerCase().replace(/\s/g, '-');
         return challenge;
       });
 

From f22672e6c18fb267cf0ab4314d614a46c87d09c1 Mon Sep 17 00:00:00 2001
From: benmcmahon100 <benmcmahon100@gmail.com>
Date: Sat, 8 Aug 2015 17:21:13 +0100
Subject: [PATCH 11/47] Removed new incomplete JS Challenges and moved to OOPF
 branch.

---
 ...object-oriented-and-functional-programming.json | 196 ---------------------
 1 file changed, 196 deletions(-)

diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index dd00934..93c85cb 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -114,202 +114,6 @@
       "descriptionEs": [],
       "namePt": "",
       "descriptionPt": []
-    },
-    {
-      "id":"cf1111c1c14feddfaeb4bdef",
-      "name":"Creating Classes",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c13feddfaeb4bdef",
-      "name":"Static Properties",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c13feddfaeb5bdef",
-      "name":"Dynamic Properties",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c13feddfaeb6bdef",
-      "name":"Instantiation",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c13feddfaeb7bdef",
-      "name":"Closures",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c13feddfaeb8bdef",
-      "name":"Public Properties",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c13feddfaeb9bdef",
-      "name":"Inheritance",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb1bdef",
-      "name":"Prototypical Inheritance",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb2bdef",
-      "name":"Constructors",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb3bdef",
-      "name":"Factories",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb5bdef",
-      "name":"Pure Functions",
-      "Note":"May need a waypoint before each topic to announce what it is :p",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb6bdef",
-      "name":"Currying Functions",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb7bdef",
-      "name":"Composition",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb8bdef",
-      "name":"Functors",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
-    },
-    {
-      "id":"cf1111c1c14feddfaeb9bdef",
-      "name":"Currying Functions",
-      "dashedName":"#",
-      "difficulty":0,
-      "tests":[
-        "assert(1==2, '');"
-      ],
-      "challengeSeed":[
-        "Under Construction"
-      ],
-      "challengeType":0
     }
   ]
 }

From 5fb1df0d55449ffe5e982376d881ee8e118a3b1a Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Sat, 8 Aug 2015 16:13:23 -0700
Subject: [PATCH 12/47] start onboarding page

---
 public/css/main.less                               |   8 +
 seed/challenges/get-set-for-free-code-camp.json    | 427 ---------------------
 ...object-oriented-and-functional-programming.json |   2 +-
 server/boot/randomAPIs.js                          |   7 +
 server/views/challengeMap/show.jade                |   3 -
 server/views/home.jade                             |   5 +-
 server/views/resources/get-started.jade            | 154 ++++++++
 7 files changed, 171 insertions(+), 435 deletions(-)
 delete mode 100644 seed/challenges/get-set-for-free-code-camp.json
 create mode 100644 server/views/resources/get-started.jade

diff --git a/public/css/main.less b/public/css/main.less
index c828412..d03c73f 100644
--- a/public/css/main.less
+++ b/public/css/main.less
@@ -617,6 +617,14 @@ thead {
   border-radius: 5px;
 }
 
+.gif-block {
+  margin-top: 30px;
+  margin-bottom: 10px;
+}
+
+.gif-caption {
+  font-size: 18px;
+}
 
 .testimonial-copy {
   font-size: 20px;
diff --git a/seed/challenges/get-set-for-free-code-camp.json b/seed/challenges/get-set-for-free-code-camp.json
deleted file mode 100644
index ae22da9..0000000
--- a/seed/challenges/get-set-for-free-code-camp.json
+++ /dev/null
@@ -1,427 +0,0 @@
-{
-  "name": "Get Set for Free Code Camp",
-  "order": 0.001,
-  "challenges": [
-    {
-      "id": "bd7124d8c441eddfaeb5bdef",
-      "name": "Waypoint: Learn how Free Code Camp Works",
-      "dashedName": "waypoint-learn-how-free-code-camp-works",
-      "difficulty": 0.01,
-      "challengeSeed": ["125407438"],
-      "description": [
-        "Watch this 1-minute video, or simply read this summary:",
-        "Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.",
-        "Learning to code is hard. It takes a lot of practice.",
-        "So we've focused on making Free Code Camp as convenient and accessible as possible.",
-        "Free Code Camp is self-paced, browser-based, and free.",
-        "During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.",
-        "During the last 800 hours, you'll build several real-life projects for nonprofits.",
-        "By the time you finish, you'll be a job-ready coder who has a portfolio of apps with happy users to prove it.",
-        "We'll even help you meet other coders in your city and find a coding job.",
-        "We'll provide you with the most rigorous curriculum and the most supportive community on earth. All you need to do sit down, day after day, and put in the hard work.",
-        "Now it's time to join our chat room. Click the \"I've completed this challenge\" button to move on to your next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Aprende sobre como funciona Free Code Camp",
-      "descriptionEs": [
-        "Mira el video de 1 minuto o simplemente lee este resumen:",
-        "Bienvenido a Free Code Camp. Somos una comunidad de personas ocupadas tratando de aprender a programar construyendo proyectos para empresas sin fines de lucro.",
-        "Hemos construido esta comunidad porque aprender a programar es dificil; pero cualquiera que se pueda mantener motivado puede aprender a programar. Para mantenerte motivado, solo necesitas: <ol><li>hacerte amigo o amiga de personas que sepan programar</li><li>programar un poco cada día</li></ol>",
-        "Todos nuestros desafíos son <ol><li>gratuitos</li><li>manejados a tu propio ritmo</li><li>basados en tu navegador</li></ol>",
-        "Estaremos trabajando <ol><li>200 horas aprendiendo a utilizar herramientas como HTML, CSS, JavaScript, Node.js y bases de datos</li><li>600 horas construyendo proyectos prácticos</li><li>800 horas construyendo soluciones full stack para empresas sin fines de lucro</li></ol>",
-        "Al finalizar <ol><li>seremos buenos en programación</li><li>tendremos un portafolio con apps con usuarios contentos que puedan abogar por nuestro trabajo</li></ol>",
-        "Una vez que completes el Free Code Camp, serás capaz de obtener un trabajo como desarrollador. Hay muchas posiciones de trabajo que están en búsqueda de programadores calificados.",
-        "Ahora es el momento de ingresar a nuestra sala de chat. Dale click al botón de \"I've completed this challenge\" para continuar con el siguiente desafío."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Lerne wie Free Code Camp funktioniert",
-      "descriptionDe": [
-        "Sieh dir das kurze Video an oder lies einfach diese Übersicht:",
-        "Willkommen im Free Code Camp. Wir sind eine Community aus eifrigen Personen, die Programmieren lernen, indem sie Projekte für gemeinnützige Organisationen umsetzen.",
-        "Programmieren zu lernen ist hart, weshalb wir diese Community ins Leben gerufen haben. Jeder, der motiviert bleiben kann, ist auch in der Lage Programmieren zu lernen. Und um motiviert zu bleiben, musst du nur: <ol><li>Freunde finden, die programmieren</li><li>jeden Tag ein wenig programmieren</li></ol>",
-        "All unsere Challenges sind <ol><li>kostenlos</li><li>selbstbestimmt</li><li>Browser-basiert</li></ol>",
-        "Wir werden <ol><li>200 Stunden mit Werkzeugen wie HTML, CSS, JavaScript, Node.js und Datenbanken arbeiten</li><li>600 Stunden Projekte umsetzen</li><li>800 Stunden komplette Lösungen für gemeinnützige Organisationen erstellen</li></ol>",
-        "Am Ende werden wir <ol><li>gut im Programmieren sein</li><li>ein Portfolio aus Anwendungen mit zufriedenen Nutzern vorweisen können</li></ol>",
-        "Wenn du das Free Code Camp abgeschlossen hast, wirst du in der Lage sein einen Job in der Branche zu bekommen. Es gibt sehr viel mehr offene Stellen als fähige Programmierer, um sie zu besetzen.",
-        "Jetzt wird es Zeit unserem Chat beizutreten. Klicke auf \"I've completed this challenge\" um zur nächsten Challenge fortzufahren."
-      ]
-    },
-    {
-      "id": "bd7125d8c441eddfaeb5bd0f",
-      "name": "Waypoint: Join Our Chat Room",
-      "dashedName": "waypoint-join-our-chat-room",
-      "difficulty": 0.02,
-      "challengeSeed": ["131574135"],
-      "description": [
-        "Now we're going to join the Free Code Camp chat room. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.",
-        "Create an account with GitHub here: <a href='https://github.com/join' target='_blank'>https://github.com/join</a>.",
-        "Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your personal website if you have one.",
-        "Go to Free Code Camp's open-source repository: <a href='//github.com/freecodecamp/freecodecamp' target='_blank'>https://github.com/freecodecamp/freecodecamp</a>.",
-        "You can \"star\" this repository by clicking the star button in the upper right hand corner.",
-        "Later, you'll be able to fork this repository if you'd like to contribute to our open source codebase.",
-        "Join our main chat room: <a href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank'>https://gitter.im/FreeCodeCamp/FreeCodeCamp</a>.",
-        "Once you're in our chat room, introduce yourself by saying : \"Hello world!\".",
-        "Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
-        "We have a busy chat room, so be sure to configure your notification settings in the top right corner.",
-        "Please note that all of our chat rooms are visible to the public, so if you need to share  sensative information like an email address or phone number, do it in a private message.",
-        "Also Join our help chat room: <a href='https://gitter.im/FreeCodeCamp/help' target='_blank'>https://gitter.im/FreeCodeCamp/help</a>, where you can get help with our challenges in real time.",
-        "Keep our chat room open while you work through our 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.",
-        "You can also download a desktop or mobile chat application here: <a href='https://gitter.im/apps' target='_blank'>https://gitter.im/apps</a>",
-        "You can also access this chat room by clicking the \"Chat\" button in the upper right hand corner.",
-        "In order to keep our community a friendly and positive place to learn to code, please read and follow our Code of Conduct: <a href='https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct' target='_blank'>https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct</a>",
-        "Now you're ready to move on. Click the \"I've completed this challenge\" button to move on to your next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Únete a Nuestra Sala de Chat",
-      "descriptionEs": [
-        "Ahora vamos a unirnos a la sala de chat de Free Code Camp. Puedes ingresar en cualquier momento para pasar el rato, hacer preguntas o para encontrar algún otro camper para programar en pares.",
-        "Asegurate de que tu cuenta de Free Code Camp incluya tu dirección de correo electrónico. Vale recalcar que si bien tu dirección de correo electrónico será invisible para el público, Slack lo hará visible para otros campers en las salas de chat. Puedes ingresar por aquí: <a href='/account' target='_blank'>http://freecodecamp.com/account</a>.",
-        "Dale click a este link, el cual te enviará una invitación a las salas de chat de Free Code Camp: <a href='/api/slack' target='_blank'>http://freecodecamp.com/api/slack</a>.",
-        "Ahora revisa tu buzón de correo y dale click al link del correo electrónico que has recibido de Slack.",
-        "Completa el proceso de registro, actualiza tu información biográfica y sube una imagen. Una foto de tu cara funciona mejor. Esta es la manera como las personas te verán en las salas de chat, asegurate de mostrar tu mejor sonrisa.",
-        "Ahora ingresa al chat #General (Inglés) o #Espanol (Español) e introdúcete escribiendo: \"Hola mundo!\".",
-        "Comentale a otros campers como es que encontraste Free Code Camp. También hablanos sobre las razones por las cuales decidiste aprender a programar.",
-        "Mantén la sala de chat abierta mientras estás trabajando otros desafíos. De esa manera podrás pedir ayuda en caso te quedes atascado en algún de ellos. También puedes socializar cuando sientas que necesitas un descanso.",
-        "Puedes acceder a la sala de chat dándole click al botón de \"Chat\" en la parte superior derecha de la página.",
-        "Para mantener a nuestra comunidad como un lugar de aprendizaje positivo y amigable, por favor lee y sigue nuestro Código de Conducta: <a href='/https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct' target='_blank'>https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct</a>"
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Trete unserem Chat-Raum bei",
-      "descriptionDe": [
-        "Nun werden wir dem Chat-Raum von Free Code Camp beitreten. Du kannst jederzeit vorbei kommen um abzuhängen, Fragen zu stellen oder andere Camper für Paarprogrammierung zu finden.",
-        "Stelle sicher, dass deine Email Adresse in deinem Free Code Camp Account hinterlegt ist. Bitte beachte, dass deine Email Adresse für die Öffentlichkeit nicht einsehbar ist, aber für andere Camper in Slack wird sie sichtbar sein. Du kannst sie hier eintragen: <a href='/account' target='_blank'>http://freecodecamp.com/account</a>.",
-        "Klicke auf diesen Link, um von Slack eine Einladung zu den Chat-Räumen von Free Code Camp zu erhalten: <a href='/api/slack' target='_blank'>http://freecodecamp.com/api/slack</a>.",
-        "Kontrolliere jetzt dein Email Postfach und klicke in der Email von Slack auf den Link.",
-        "Beende die Registrierung und vervollständige dein Profil. Vergiss nicht, dein Profil-Bild hochzuladen. Ein Bild von deinem Gesicht ist am besten. So werden dich andere Personen im Chat sehen, also zeige dich von deiner Schokoladenseite.",
-        "Jetzt betrete den General Chat-Raum und stelle dich den anderen vor, indem du folgendes schreibst: \"Hello world!\".",
-        "Teile den anderen Campern mit, wie du auf Free Code Camp gestoßen bist. Wir interessieren uns auch dafür, warum du Programmieren lernen willst – aber auf englisch bitte, sonst versteht dich kaum einer.",
-        "Behalte den Chat geöffnet, während du an den Challenges arbeitest. Auf diesem Weg kannst du schnell nach Hilfe fragen, wenn du nicht weiter kommst. Du kannst auch jederzeit mit uns chatten, wenn du eine Pause einlegen möchtest.",
-        "Du kannst den Chat auch über die Schaltfläche \"Chat\" oben rechts auf dieser Seite erreichen.",
-        "Damit diese Community ein freundlicher und positiver Ort zum Lernen bleibt, lies und folge bitte unseren Verhaltensregeln: <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct' target='_blank'>https://github.com/FreeCodeCamp/freecodecamp/wiki/Code-of-Conduct</a>"
-      ]
-    },
-    {
-      "id": "bd7125d8c441eddfaeb5bdff",
-      "name": "Waypoint: Preview our Challenge Map",
-      "dashedName": "waypoint-preview-our-challenge-map",
-      "difficulty": 0.03,
-      "challengeSeed": ["125407437"],
-      "description": [
-        "Before you start learning how to code, we'd like to introduce you to a few things.",
-        "Let's look at our Challenge Map. Click on the \"Map\" button in the upper right hand corner. This map shows all the challenges that will teach you how to code.",
-        "You should complete all of these challenges in order.",
-        "In addition to our Waypoint challenges, like the one you're doing now, we have algorithm practice challenges (Bonfires), front end development challenges (Ziplines) and full stack development challenges (Basejumps). After you finish all of these, you'll start building projects for nonprofits.",
-        "Please note that our open-source curriculum is a work in progress. Our volunteer community is constantly improving it. If you think you've encountered a bug, typo, or something that seems confusing, be sure to click the \"bug\" button to create a GitHub issue."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Revisa nuestro Mapa de Desafíos",
-      "descriptionEs": [
-        "Antes de comenzar a aprender a programar, nos gustaría mostrarte algunas cosas.",
-        "Revisemos el Mapa de Desafíos. Dale click al botón de \"Map\" en la parte superior derecha. Este mapa muestra todos los desafíos que te enseñarán a programar.",
-        "Deberías completar todos estos desafíos en orden.",
-        "Una vez que termines con los Waypoints, seguiremos con los Bonfires (práctica de algoritmos), luego Ziplines (práctica de desarrollo front end) y para terminar los Basejumps (práctica de desarrollo full stack). Después de eso, empezarás a desarrollar proyectos para empresas sin fines de lúcro.",
-        "El mapa de desafíos es solamente de referencia. Puedes también presionar el botón de \"Learn\", el cual te llevará directamente al siguiente desafío.",
-        "Para terminar, ten en cuenta que nuestra currícula open-source es un trabajo en progreso. Nuestra comunidad de voluntarios está mejorandola constantemente. Si crees que te has topado con algún bug, error ortográfico o algo que parezca confuso, haznos el favor de abrir un ticket a través de Github: <a href='https://github.com/FreeCodeCamp/freecodecamp/issues'>https://github.com/FreeCodeCamp/freecodecamp/issues</a>."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Besuche die Challenge Map",
-      "descriptionDe": [
-        "Bevor du startest, wollen wir dir ein paar Dinge zeigen.",
-        "Betrachte die Challenge Map. Klicke auf \"Map\" oben rechts auf dieser Seite. Diese Übersicht zeigt dir alle Challenges.",
-        "Du solltest alle Challenges in der gezeigten Reihenfolge abschließen.",
-        "Hast du alle Waypoint-Challenges beendet, folgen die Bonfires (Algorithmen), darauf Ziplines (Frontend Development) und zum Schluss Basejumps (Full Stack Development). Danach wirst du anfangen, Projekte für gemeinnützige Organisationen umzusetzen.",
-        "Diese Challenge Map dient dir als Orientierung. Du kannst einfach auf \"Learn\" klicken und direkt zur nächsten Challenge fortfahren.",
-        "Bitte beachte, dass unser Open Source Lehrplan nicht fertig ist. Unsere freiwillige Community verbessert diesen stetig. Wenn du einen Bug, Rechtschreib-Fehler oder etwas gefunden hast, das dir komisch vorkommt, öffne bitte ein GitHub Issue: <a href='https://github.com/FreeCodeCamp/freecodecamp/issues'>https://github.com/FreeCodeCamp/freecodecamp/issues</a>. Wie gehabt bitte in englischer Sprache."
-      ]
-    },
-    {
-      "id": "bd7125d8c441eddfaeb5bd1f",
-      "name": "Waypoint: Browse our Wiki",
-      "dashedName": "waypoint-browse-our-wiki",
-      "difficulty": 0.04,
-      "challengeSeed": ["125407435"],
-      "description": [
-        "Free Code Camp has an up-to-date wiki that will answer your many questions.",
-        "Click the \"Wiki\" button in the upper right hand corner.",
-        "You can browse our wiki at your convenience. Most of its articles take less than 1 minute to read.",
-        "All of our Wiki articles are contributed by our community. You can update our wiki articles, and even create wiki articles of your own.",
-        "Now you can move on to your next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Revisa nuestro Field Guide",
-      "descriptionEs": [
-        "Free Code Camp tiene un field guide actualizado que respondera tus preguntas.",
-        "Dale click al botón \"Field Guide\" en la parte superior derecha.",
-        "Puedes navegar el Field Guide cuando veas conveniente. La mayoría de los artículos los puedes leer en menos de 1 minuto .",
-        "Cuando le des click al botón de Field Guide, siempre te regresará al último artículo que estuviste leyendo.",
-        "Lee algunos de nuestros artículos, luego continúa con tu siguiente desafío."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Stöbere in unserem Field Guide",
-      "descriptionDe": [
-        "Free Code Camp hat einen aktuellen Field Guide, welcher viele deiner Fragen beantworten wird.",
-        "Klicke oben rechts auf \"Field Guide\".",
-        "Du kannst im Field Guide nach Lust und Laune stöbern. Die meisten der Artikel sind in weniger als einer Minute gelesen.",
-        "Wenn du auf den besagten Field Guide in der Navigation klickst, wirst du direkt zu dem Artikel geleitet, den du als letztes gelesen hast.",
-        "Lies ein paar der Artikel, dann schreite zu deiner nächsten Challenge voran."
-      ]
-    },
-    {
-      "id": "bd7125d8c441eddfaeb5bd2f",
-      "name": "Waypoint: Customize your Portfolio Page",
-      "dashedName": "waypoint-customize-your-portfolio-page",
-      "difficulty": 0.05,
-      "challengeSeed": ["125407433"],
-      "description": [
-        "You and all your fellow campers have portfolio pages.",
-        "Click your picture in the upper right hand corner to go to your account page.",
-        "Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.",
-        "You can also fill out a short biography, and add links to your social media profiles.",
-        "Your portfolio page shows how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms.",
-        "Your portfolio page also shows off your progress through Free Code Camp. If you get Brownie Points on several days in a row, you'll get streak.",
-        "Once you're happy with your portfolio page, you can move on to your next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Personaliza tu página de Portafolio",
-      "descriptionEs": [
-        "Tú y tus otros amigos campers tienen sus propias páginas de portafolio.",
-        "Para visualizar tu página de portafolio, dale click a tu foto en la parte superior derecha.",
-        "Tu página de portafolio mostrará automaticamente tu progreso en Free Code Camp",
-        "Dale click al botón de \"Update my portfolio page or manage my account\"",
-        "Puedes enlazarte con tus cuentas de Github, Twitter y LinkedIn. Si ya has creado alguna página web, puedes enlazarla aquí también.",
-        "Asegurate de darle click al botón de \"Update my Bio\" o \"Update my Social Links\" para agregar esta nueva información a tu portafolio.",
-        "Una vez que estés satisfecho con tu página de portafolio, puedes seguir con el siguiente desafío."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Personalisiere deine Portfolio-Seite",
-      "descriptionDe": [
-        "Du und die anderen Camper habt Portfolio-Seiten.",
-        "Um zu deinem Portfolio zu gelangen, klicke oben rechts auf dein Bild.",
-        "Dein Portfolio wird deinen Fortschritt im Free Code Camp automatisch anzeigen.",
-        "Klicke auf \"Update my portfolio page or manage my account\"",
-        "Du kannst deine GitHub, Twitter und LinkedIn Accounts verlinken. Wenn du bereits ein paar Websites gebaut hast, kannst du sie ebenfalls präsentieren.",
-        "Stelle sicher, dass du auf \"Update my Bio\" oder \"Update my Social Links\" klickst, um diese neuen Informationen zu speichern.",
-        "Sobald du zufrieden mit deinem Portfolio bist, kannst du zur nächsten Challenge fortfahren."
-      ]
-    },
-    {
-      "id": "bd7126d8c441eddfaeb5bd3f",
-      "name": "Waypoint: Try Camper News",
-      "dashedName": "waypoint-try-camper-news",
-      "difficulty": 0.06,
-      "challengeSeed": ["124553410"],
-      "description": [
-        "Camper News is the best place for our campers to share and discuss helpful links.",
-        "Click \"News\" in the upper right hand corner.",
-        "You'll see a variety of links that have been submitted. Their rank is determined by how recently they were submitted and how many upvotes they have.",
-        "If you enjoy a link, you should upvote it.",
-        "You can also submit links that you think will be interesting to other campers.",
-        "You can view the portfolio pages of any camper who has posted links on Camper News. Just click on their photo.",
-        "When you submit a link, you'll get a Brownie Point. You'll also get a Brownie Point each time someone upvotes your link.",
-        "Now that you've learned how to use Camper News, let's move on to your next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Prueba las Noticias de Campers",
-      "descriptionEs": [
-        "Noticias de Campers es el mejor lugar para que nuestros campers puedan discutir y compartir links útiles.",
-        "Dale click a \"News\" en la parte superior derecha.",
-        "Verás una gran variedad de links que han sido enviados. Dale click al botón de \"Discuss\" debajo de uno de ellos.",
-        "Puedes votar por links que te gusten. Esto hará que el ranking de tu link suba.",
-        "Puedes también dejar un comentario a un link. Si alguien responde a tu comentario recibirás un correo electrónico de notificación para que puedas regresar y responderlo.",
-        "También puedes enviar tus propios links. Puedes escoger el título del link, asi como también dejar un comentario inicial sobre él.",
-        "Puedes ver las páginas de portafolio de cualquier camper que ha enviado links o comentarios en las Noticias de Campers. Solo tienes que darle click a su fotografía.",
-        "Cuando envies un link, recibirás un punto. También obtendrás un punto cada vez que otra persona vote por tu link.",
-        "Ahora que has aprendido a utilizar las Noticias de Campers, continuaremos con el siguiente desafío."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Verpasse nicht die Camper News",
-      "descriptionDe": [
-        "Camper News ist der beste Ort für unsere Camper, nützliche Links zu teilen und zu diskutieren.",
-        "Klicke oben rechts auf \"News\".",
-        "Du wirst eine Vielzahl an Links sehen, die bereits geteilt wurden. Klicke auf \"Discuss\" unter einem von ihnen.",
-        "Du kannst Links bewerten. Das wird den Link in der Platzierung weiter nach oben befördern.",
-        "Du kannst einen Link auch kommentieren. Wenn jemand auf deinen Kommentar antwortet, wirst du per Email benachrichtigt, sodass du zurück kommen und reagieren kannst.",
-        "Du kannst ebenfalls Links teilen. Bearbeite den Titel des Links und hinterlasse einen ersten Kommentar, um die Diskussion zu starten.",
-        "Du kannst dir das Portfolio jedes Campers anschauen, der einen Link geteilt hat. Klicke dazu einfach auf ihr Bild.",
-        "Sobald du einen Link teilst, erhältst du einen Punkt. Jedes Mal, wenn jemand deinen Link bewertet, erhältst du zusätzlich einen Punkt.",
-        "Jetzt da du gelernt hast, was Camper News ist, kanns du zur nächsten Challenge gehen."
-      ]
-    },
-    {
-      "id": "bd7126d8c441eddfaeb5bd3e",
-      "name": "Waypoint: Meet Other Campers in your City",
-      "dashedName": "waypoint-meet-other-campers-in-your-city",
-      "difficulty": 0.07,
-      "challengeSeed": ["127358841"],
-      "description": [
-        "One of the best ways to stay motivated when learning to code is to hang out with other campers in-person.",
-        "The easiest way to meet other campers in your city is to join your city's Campsite. Each of these has its own Facebook group and Gitter chat room. Click <a href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank'>here</a> to view our growing list of Campsites. ",
-        "Click the link to your city's Facebook group. Then, once Facebook loads, click \"Join group\".",
-        "If you don't see your city on this list, you should follow <a href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank'>these directions</a> to create a Facebook group for your city.",
-        "If you don't have a Facebook account, we strongly recommend you create one, even if it's just for the purpose of coordinating with campers in your city through your Campsite.",
-        "Our Campsites allow you to create events, coordinate those events, and share photos from the events afterward.",
-        "Whether you're hosting a study group, pair programming at your local library, or going to a weekend hackathon, your city's Campsite will help you make it happen."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Encuentrate con otros Campers en tu Ciudad",
-      "descriptionEs": [
-        "Una de las mejores maneras de mantenerte motivado cuando estás aprendiendo a programar es pasar el rato con otros campers.",
-        "Gitter y Noticias de Campers son una muy buena forma de comunicarte con otros campers, pero no hay ningún substituto para conocerlos en persona.",
-        "La forma más fácil de encontrarte con otros campers en tu ciudad es unirte al grupo de Facebook de tu ciudad o país. Dale click a <a href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank'>here</a> para ver la lista de grupos locales.",
-        "Dale click al link de tu ciudad o país y una vez que Facebook cargue, dale click a \"Join group\".",
-        "Nuestros grupos locales son pocos, asi que en caso no veas tu ciudad o país en la lista, solamente sigue las instrucciones para crear un grupo de Facebook para ello.",
-        "Si no tienes una cuenta de Facebook, te recomendamos que crees una, asi sea solamente con el proposito de coordinar con otros campers en tu ciudad a través del grupo",
-        "Nuestros grupos te dan la potestad de crear eventos y coordinarlos, solamente asegurate de compartir las fotos del evento una vez terminado.",
-        "En caso seas el anfitrión de un grupo de estudio, estes programando en pares en una biblioteca local o piensen en ir a un hackathon de fin de semana, tu grupo local te ayudará a hacerlo."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Treffe andere Camper in deiner Stadt",
-      "descriptionDe": [
-        "Der beste Weg, motiviert am Ball zu bleiben, ist mit anderen Campern abzuhängen.",
-        "Slack und Camper News sind super Wege zur Kommunikation mit anderen Campern. Es gibt aber nichts vergleichbares, Personen im echten Leben zu treffen.",
-        "Um leicht andere Camper in deiner Stadt zu treffen, solltest du der Facebook Gruppe deiner Stadt beitreten. Klicke <a href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank'>hier</a> um unsere wachsende Liste der lokalen Gruppen zu sehen.",
-        "Klicke auf den Link zu deiner Stadt. Sobald Facebook geladen ist, klicke auf \"Gruppe beitreten\".",
-        "Unsere lokalen Gruppen sind neu. Solltest du deine Stadt also nicht in der Liste sehen, erstelle doch bitte eine Facebook Gruppe deiner Stadt indem du den Anweisungen dazu folgst.",
-        "Wenn du keinen Facebook Account hast, empfehlen wir dir einen zu erstellen. Auch wenn dieser nur dazu dient, sich mit anderen Campern in deiner Stadt zu koordinieren.",
-        "Unsere Gruppen erlauben dir, Events zu planen und Fotos davon zu teilen.",
-        "Egal ob du eine Studenten-Gruppe, Paarprogrammierung an deiner lokalen Bibliothek oder einen Hackathon am Wochenende anbieten willst. Die Gruppe deiner Stadt macht das alles möglich."
-      ]
-    },
-    {
-      "id": "bd7126d8c431eddfaeb5bd3e",
-      "name": "Waypoint: Add Free Code Camp to your LinkedIn Profile",
-      "dashedName": "waypoint-add-free-code-camp-to-your-linkedin-profile",
-      "difficulty": 0.08,
-      "challengeSeed": ["131574134"],
-      "description": [
-        "LinkedIn is a critical tool for your job search later on.",
-        "Add Free Code Camp to your LinkedIn profile by going to <a href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank'>https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp</a>.",
-        "Estimate your dates. Keep in mind that Free Code Camp is a rigorous 1,600 hour program, and will probably take at least a year to complete.",
-        "In the \"Degree\" section, type \"Full Stack Web Development\".",
-        "In the \"Field of study\" section, type \"Computer Software Engineering\".",
-        "Click the \"Save Changes\" button.",
-        "Be sure to add your key word skills to LinkedIn's skills section as you learn them, such as HTML, jQuery, Linux and Node.js.",
-        "You can expand your LinkedIn network by inviting friends you meet through Free Code Camp to connect with you on LinkedIn.",
-        "Make your LinkedIn profile as complete as possible. Unlike other social networks, with LinkedIn, it's perfectly fine if you don't want to add a photo.",
-        "Let's keep moving. We're almost ready to start coding!"
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "bd7137d8c441eddfaeb5bdef",
-      "name": "Waypoint: Get Help the Hacker Way with RSAP",
-      "dashedName": "waypoint-get-help-the-hacker-way-with-rsap",
-      "difficulty": 0.09,
-      "challengeSeed": ["125407432"],
-      "description": [
-        "Let's cover one last thing before you start working through our lessons: how to get help.",
-        "Any time you get stuck or don't know what to do next, follow this simple algorithm (procedure): RSAP (Read, Search, Ask, Post).",
-        "First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.",
-        "Next, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.",
-        "Then, if you still haven't found an answer to your question, A - Ask your friends. If you have trouble, you can ask your fellow campers. We have a special chat room specifically for getting help with tools you learn through these Free Code Camp Challenges. Go to <a href='https://gitter.im/FreeCodeCamp/Help' target='_blank'>https://gitter.im/FreeCodeCamp/Help</a>. Keep this chat open while you work on the remaining challenges.",
-        "Finally, P - Post on Stack Overflow. Before you attempt to do this, read Stack Overflow's guide to asking good questions: <a href='http://stackoverflow.com/help/how-to-ask'>http://stackoverflow.com/help/how-to-ask</a>.",
-        "Here's our detailed wiki article on getting help: <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>http://freecodecamp.com//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck</a>.",
-        "Now you have a clear algorithm to follow when you need help! Let's start coding! Move on to your next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "Waypoint: Obtén ayuda del modo Hacker con RSAP",
-      "descriptionEs": [
-        "Cubramos un último punto antes que empieces a trabajar en los cursos: como obtener ayuda.",
-        "Cualquier momento en el que te atasques o no sepas que hacer, sigue este simple algoritmo (procedimiento): RSAP (Read, Search, Ask, Post). Que en español vendría a ser Lee, Busca, Pregunta, Publica.",
-        "Primero, Lee - Lee la documentación o el mensaje de error. El punto fuerte de un buen programador es la habilidad de interpretar y seguir instrucciones.",
-        "Luego, Busca - Busca en Google. Buenas búsquedas o queries requieren bastante práctica. Cuando búsques en Google, idealmente tienes que incluir el lenguaje o framework que estés usando. También tendrás que limitar los resultados de búsqueda a un periodo reciente.",
-        "Ahora, en caso no hayas encontrado la respuesta a tu pregunta, Pregunta - Pregunta a tus amigos. En caso estes en problemas, puedes preguntar a otros campers. Tenemos una sala de chat especificamente para obtener ayuda sobre las herramientas que utilizamos en los desafíos de Free Code Camp. Ingresa a <a href='https://gitter.im/FreeCodeCamp/Help' target='_blank'>https://gitter.im/FreeCodeCamp/Help</a>. Mantén este chat abierto mientras trabajas en los desafíos subsiguientes.",
-        "Finalmente, Publica - Publica tu pregunta en Stack Overflow. Antes de hacer esto lee la guía de Stack Overflow para publicar buenas preguntas: <a href='http://stackoverflow.com/help/how-to-ask'>http://stackoverflow.com/help/how-to-ask</a>. Tendrás que hacerlo en inglés, en caso no sepas como, pide que te ayuden a traducir tu pregunta en el canal #espanol de Slack.",
-        "Aquí está nuestra guia detallada en como obtener ayuda: <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>http://freecodecamp.com//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck</a>.",
-        "Ahora que tienes en claro el procedimiento a seguir cuando necesites ayuda. ¡Empecémos a programar! Continua con el siguiente desafío."
-      ],
-      "namePt": "",
-      "descriptionPt": [],
-      "nameDe": "Waypoint: Der Weg des Hackers – Hilfe erhalten mit RSAP",
-      "descriptionDe": [
-        "Lass uns eine letzte Sache behandeln, bevor du mit den Lektionen beginnst: Wie du Hilfe bekommst.",
-        "Immer wenn du nicht weiter kommst oder du nicht weißt, was als nächstes zu Tun ist, kannst du diesem einfachen Algorithmus (Prozedur) folgen: RSAP (Read, Search, Ask, Post – Lesen, Suchen, Fragen, Posten).",
-        "Erstens, R – Lies die Dokumentation oder die Fehler-Meldung. Eine wichtige Eigenschaft aller Coder ist es, Anweisungen zu interpretieren und zu folgen.",
-        "Danach, S – Suche bei Google. Es bedarf viel Übung, gute Such-Anfragen zu stellen. Wenn du bei Google suchst, solltest du die Sprache oder das Framework angeben, welches du benutzt. Außerdem wirst du die aktuellsten Ergebnisse haben wollen.",
-        "Wenn du keine Antwort auf deine Frage erhalten hast, folge A – Frage deine Freunde. Wenn du Probleme hast, kannst du andere Camper fragen. Wir haben einen speziellen Chat-Raum zur Unterstützung beim Lernen eingerichtet. Gehe zu <a href='https://freecode.slack.com/messages/help/' target='_blank'>https://freecode.slack.com/messages/help/</a>. Behalte diesen Chat offen, solange du an den Challenges arbeitest.",
-        "Und zum Schluss, P – Poste auf Stack Overflow. Bevor du das tust, lies bitte den Leitfaden für gute Fragen auf Stack Overflow: <a href='http://stackoverflow.com/help/how-to-ask'>http://stackoverflow.com/help/how-to-ask</a>.",
-        "Hier ist unser detaillierter Field Guide um Hilfe zu erhalten: <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>http://freecodecamp.com//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck</a>.",
-        "Jetzt hast du einen klaren Algorithmus, dem du folgen kannst wenn du Hilfe benötigst. Fangen wir an zu programmieren! Gehe zur nächsten Challenge."
-      ]
-    }
-  ]
-}
diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index 93c85cb..6ef66c0 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -1,5 +1,5 @@
 {
-  "name": "Object Oriented and Functional Programming - Under Construction From Challenge 4 Onwards",
+  "name": "Object Oriented and Functional Programming",
   "order" : 0.009,
   "challenges": [
     {
diff --git a/server/boot/randomAPIs.js b/server/boot/randomAPIs.js
index 2b879c2..13fd84e 100644
--- a/server/boot/randomAPIs.js
+++ b/server/boot/randomAPIs.js
@@ -30,6 +30,7 @@ module.exports = function(app) {
   router.get('/jobs-form', jobsForm);
   router.get('/unsubscribe/:email', unsubscribe);
   router.get('/unsubscribed', unsubscribed);
+  router.get('/get-started', getStarted);
 
   app.use(router);
 
@@ -259,6 +260,12 @@ module.exports = function(app) {
     });
   }
 
+  function getStarted(req, res) {
+    res.render('resources/get-started', {
+      title: 'How to get started with Free Code Camp'
+    });
+  }
+
   function githubCalls(req, res, next) {
     var githubHeaders = {
       headers: {
diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade
index 77b42ca..1d3f91d 100644
--- a/server/views/challengeMap/show.jade
+++ b/server/views/challengeMap/show.jade
@@ -3,9 +3,6 @@ block content
     script.
         var completedChallenges = !{JSON.stringify(completedChallengeList)};
         var challengeList = !{JSON.stringify(challengeList)};
-    .bg-danger.default-border-radius
-        p &nbsp;&nbsp;&nbsp;&nbsp;
-            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/beta' target='_blank') You're using our experimental beta site. None of your progress here will be saved. Please click this to learn more.
     .panel.panel-info
         .panel-heading.text-center
             h1 Challenge Map
diff --git a/server/views/home.jade b/server/views/home.jade
index e5e09f1..ce7d54d 100644
--- a/server/views/home.jade
+++ b/server/views/home.jade
@@ -1,8 +1,5 @@
 extends layout
 block content
-    .bg-danger.default-border-radius
-      p &nbsp;&nbsp;&nbsp;&nbsp;
-        a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/beta' target='_blank') You're using our experimental beta site. None of your progress here will be saved. Please click this to learn more.
     .jumbotron
         .text-center
             h1.hug-top Code with Us
@@ -10,7 +7,7 @@ block content
             .row
                 .col-xs-12.col-sm-12.col-md-3
                     h3.nowrap Get Connected
-                    img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections for your reto help you get a job')
+                    img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career')
                     p.landing-p Join a community of busy, motivated professionals.
                 .col-xs-12.col-sm-12.col-md-3
                     h3.nowrap Learn JavaScript
diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
new file mode 100644
index 0000000..92858c5
--- /dev/null
+++ b/server/views/resources/get-started.jade
@@ -0,0 +1,154 @@
+extends ../layout
+block content
+    .jumbotron
+        h1.text-center This short guide will get you started
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Learning to code is hard. To succeed, you'll need practice and lots of support. That's why we've created this rigorous curriculum and this supportive community.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Free Code Code camp is self-paced, browser-based and free.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption By the time you finish, you'll be a job-ready coder who has a portfolio of apps with happy users to prove it.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption
+            a(href='https://github.com/join' target='_blank') Create an account with GitHub
+            | . This will be private, so you should use your real email address.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption
+            a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
+            | &thinsp;and "star" it. This is the GitHub equivalent of a "like" button.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Now that you have a GitHub account, you can&thinsp;
+            a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room
+            | .
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck on a challenge. You can also socialize when you feel like taking a break.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption
+            a(href='https://gitter.im/apps' target='_blank') You can also download the chat app for your computer and phone
+            | .
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all the challenges that will teach you how to code. We recommend that you complete these from top to bottom, at a sustainable pace.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Let's check out your portfolio page. Click your picture in the upper right hand corner to go to your account page. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption You can also fill out a short biography, and add links to your social media profiles.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Your portfolio page shows how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. Your portfolio page also shows off your progress through Free Code Camp. If you get Brownie Points on several days in a row, you'll get a streak.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Click "News" button in your upper right hand corner to take you to Camper News. These camper-submitted links are ranked by how new they are and how many upvotes they have. If you enjoy a link, you should click the "upvote" button to upvote it.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Our Campsites allow you meet other campers in your city and code with them. Your city's Campsite will help you coordinate events like study groups at your local library and weekend hackathons.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption
+            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
+            | . Click the "Join group" button to join your city's Facebook group. (If your city isn't on this list,&thinsp;
+            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
+            | .)
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption
+            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
+            | and click your city's Gitter link to join your city's Gitter chat room.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption
+            a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') Add Free Code Camp to your LinkedIn education background
+            | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
+            a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
+            | .
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
+
+        hr
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        p.gif-caption Congratulations! Now you're ready to start working through our Challenge Map. Good luck, and happy coding!
+        hr
+        a.btn.btn-cta.signup-btn.btn-block(href="/map") Go to my Challenge Map and start coding

From 9bed47a763bf230e0b7d3d0390a92f7208305c34 Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Sun, 9 Aug 2015 02:08:42 +0200
Subject: [PATCH 13/47] Disregard order in 'Symmetric Difference' #1402

---
 seed/challenges/expert-bonfires.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
index 50bbe89..bb0294b 100644
--- a/seed/challenges/expert-bonfires.json
+++ b/seed/challenges/expert-bonfires.json
@@ -81,9 +81,9 @@
         "sym([1, 2, 3], [5, 2, 1, 4]);"
       ],
       "tests": [
-        "expect(sym([1, 2, 3], [5, 2, 1, 4])).to.equal([3, 5, 4]);",
-        "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, 2, 3], [5, 2, 1, 4]).sort(), [3, 4, 5], 'should return the symmetric difference of the given arrays');",
+        "assert.deepEqual(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]).sort(), [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]).sort(), [1, 4, 5], 'should return an array of unique values');",
         "assert.deepEqual(sym([1, 1]), [1], 'should return an array of unique values');"
       ],
       "MDNlinks": [

From 6d1ddc759dcc0f9c8d958477eef77673f2c73e20 Mon Sep 17 00:00:00 2001
From: alanmbarr <alan@alanmbarr.com>
Date: Sat, 8 Aug 2015 21:59:03 -0700
Subject: [PATCH 14/47] Update bootstrap.json

---
 seed/challenges/bootstrap.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index 800f64d..d839ef1 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -1435,7 +1435,7 @@
       "tests": [
         "assert($('div.row:has(input[type=\\'text\\'])').length > 0 &&  $('div.row:has(button[type=\\'submit\\'])').length > 0, 'Nest your form submission button and text area in a div with class \"row\".')",
         "assert($('div.col-xs-5:has(button[type=\\'submit\\'])').length > 0, 'Nest your form submission button in a div with the class \"col-xs-5\".')",
-        "assert($('div.col-xs-7:has(input[type=\\'text\\'])').length > 0, 'Nest your form text area in a div with the class \"col-xs-7\".')",
+        "assert($('div.col-xs-7:has(input[type=\\'text\\'])').length > 0, 'Nest your form text input in a div with the class \"col-xs-7\".')",
         "assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure each of your <code>div</code> elements has a closing tag.')"
       ],
       "challengeSeed": [

From 50db4b9aaa0aadf367323623f8d818f526746080 Mon Sep 17 00:00:00 2001
From: alanmbarr <alan@alanmbarr.com>
Date: Sat, 8 Aug 2015 22:10:07 -0700
Subject: [PATCH 15/47] other typo

text input instead of area for clarity
---
 seed/challenges/bootstrap.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/bootstrap.json b/seed/challenges/bootstrap.json
index d839ef1..985a1fa 100644
--- a/seed/challenges/bootstrap.json
+++ b/seed/challenges/bootstrap.json
@@ -1433,7 +1433,7 @@
         "This is the last challenge we'll do for our Cat Photo App for now. We hope you've enjoyed learning Font Awesome, Bootstrap, and responsive design!"
       ],
       "tests": [
-        "assert($('div.row:has(input[type=\\'text\\'])').length > 0 &&  $('div.row:has(button[type=\\'submit\\'])').length > 0, 'Nest your form submission button and text area in a div with class \"row\".')",
+        "assert($('div.row:has(input[type=\\'text\\'])').length > 0 &&  $('div.row:has(button[type=\\'submit\\'])').length > 0, 'Nest your form submission button and text input in a div with class \"row\".')",
         "assert($('div.col-xs-5:has(button[type=\\'submit\\'])').length > 0, 'Nest your form submission button in a div with the class \"col-xs-5\".')",
         "assert($('div.col-xs-7:has(input[type=\\'text\\'])').length > 0, 'Nest your form text input in a div with the class \"col-xs-7\".')",
         "assert(editor.match(/<\\/div>/g) && editor.match(/<div/g) && editor.match(/<\\/div>/g).length === editor.match(/<div/g).length, 'Make sure each of your <code>div</code> elements has a closing tag.')"

From 0994dbaabe244ae03284ae6eb454e3e71418ddfb Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Sat, 8 Aug 2015 22:46:21 -0700
Subject: [PATCH 16/47] finalize copy on get-started

---
 server/views/resources/get-started.jade | 104 ++++++++++++++++----------------
 1 file changed, 52 insertions(+), 52 deletions(-)

diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index 92858c5..c64acef 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -2,153 +2,153 @@ extends ../layout
 block content
     .jumbotron
         h1.text-center This short guide will get you started
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Learning to code is hard. To succeed, you'll need practice and lots of support. That's why we've created this rigorous curriculum and this supportive community.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Free Code Code camp is self-paced, browser-based and free.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Free Code Code camp is self-paced, browser-based, and free.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
         p.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rU7B4sn.jpg' alt='a gif showing how to install this')
         p.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption By the time you finish, you'll be a job-ready coder who has a portfolio of apps with happy users to prove it.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.i.imgur.com/WAxbGZE.gif' alt='a gif showing how to install this')
         p.gif-caption
             a(href='https://github.com/join' target='_blank') Create an account with GitHub
             | . This will be private, so you should use your real email address.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption
             a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
-            | &thinsp;and "star" it. This is the GitHub equivalent of a "like" button.
+            | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Now that you have a GitHub account, you can&thinsp;
-            a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room
+            a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by authenticating with GitHub
             | .
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck on a challenge. You can also socialize when you feel like taking a break.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption
-            a(href='https://gitter.im/apps' target='_blank') You can also download the chat app for your computer and phone
+            a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
             | .
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all the challenges that will teach you how to code. We recommend that you complete these from top to bottom, at a sustainable pace.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Let's check out your portfolio page. Click your picture in the upper right hand corner to go to your account page. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Let's check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption You can also fill out a short biography, and add links to your social media profiles.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption You can also add a short bio, and links to your social media profiles.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Your portfolio page shows how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. Your portfolio page also shows off your progress through Free Code Camp. If you get Brownie Points on several days in a row, you'll get a streak.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Click "News" button in your upper right hand corner to take you to Camper News. These camper-submitted links are ranked by how new they are and how many upvotes they have. If you enjoy a link, you should click the "upvote" button to upvote it.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Our Campsites allow you meet other campers in your city and code with them. Your city's Campsite will help you coordinate events like study groups at your local library and weekend hackathons.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
-            | . Click the "Join group" button to join your city's Facebook group. (If your city isn't on this list,&thinsp;
+            | . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
-            | .)
+            | .
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
-            | and click your city's Gitter link to join your city's Gitter chat room.
+            | and click "Gitter" to join your city's chat room.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption
-            a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') Add Free Code Camp to your LinkedIn education background
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption You can&thinsp;
+            a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
             | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
             a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
             | .
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
 
         hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/u18I9S1.gif' alt='a gif showing how to install this')
-        p.gif-caption Congratulations! Now you're ready to start working through our Challenge Map. Good luck, and happy coding!
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.gif-caption Congratulations! Now you're ready to start working through our Challenge Map. Good luck and happy coding!
         hr
         a.btn.btn-cta.signup-btn.btn-block(href="/map") Go to my Challenge Map and start coding

From 2476f3530989bdb50421810f46d7a42bcdd010b7 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Sun, 9 Aug 2015 07:40:16 -0700
Subject: [PATCH 17/47] add challenge order to individual challenge

---
 common/models/challenge.json | 3 +++
 seed/index.js                | 9 +++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/common/models/challenge.json b/common/models/challenge.json
index 910b61d..a6b71d5 100644
--- a/common/models/challenge.json
+++ b/common/models/challenge.json
@@ -19,6 +19,9 @@
     "type": {
       "type": "string"
     },
+    "order": {
+      "type": "number"
+    },
     "dashedName": {
       "type": "string"
     },
diff --git a/seed/index.js b/seed/index.js
index 5c5c2bd..b2a4e3e 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -38,14 +38,19 @@ Challenge.destroyAll(function(err, info) {
   }
   challenges.forEach(function(file) {
     var challengeSpec = require('./challenges/' + file);
+    var order = challengeSpec.order;
     var challenges = challengeSpec.challenges
-      .map(function(challenge) {
+      .map(function(challenge, index) {
         // NOTE(berks): add title for displaying in views
         challenge.name =
           _.capitalize(challenge.type) +
           ': ' +
           challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
-        challenge.dashedName = challenge.name.toLowerCase().replace(/\s/g, '-');
+        challenge.dashedName = challenge.name
+          .toLowerCase()
+          .replace(/\:/g, '')
+          .replace(/\s/g, '-');
+        challenge.order = +('' + order + (index + 1));
         return challenge;
       });
 

From 76e4fc2d333ade24c4a7af8adf409138ee0181dd Mon Sep 17 00:00:00 2001
From: Isabell Long <isabell@issyl0.co.uk>
Date: Sun, 9 Aug 2015 19:32:10 +0000
Subject: [PATCH 18/47] Fix typos in the Basic Javascript challenge

- Partially fixes #1519 - looks like some of those typos had already
  been fixed.
---
 seed/challenges/basic-javascript.json | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index 888782e..c8cd704 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -35,7 +35,7 @@
         "A boolean is a type of variable that represents either true or false (Named after the British mathematician George Boole).",
         "Booleans are often the result of a function or a comparative operation, for example <code>1==1</code>is true whereas <code>1==2</code>is false.",
         "They are most commonly found inside <code>if</code>statements which we shall cover later",
-        "For now Let's modify our <code>welcomeToBooleans</code>function so that it will return <code>true</code>instead of <code>false</code>when the run button is clicked"
+        "For now let's modify our <code>welcomeToBooleans</code>function so that it will return <code>true</code>instead of <code>false</code>when the run button is clicked"
       ],
       "tests": [
         "assert(typeof(welcomeToBooleans())=='boolean', 'The value returned by welcomeToBooleans() should be a boolean value. (true of false)');",
@@ -59,8 +59,8 @@
       "description": [
         "Now, use the <code>var</code> keyword to create a <code>variable</code> called <code>myName</code>. Set its value to your name.",
         "<code>Variables</code> are used to store values.",
-        "The name variable comes from the fact that it's value, varies!",
-        "Now Let's create our first variable called myName and because it's a name let's make it a string!",
+        "The name variable comes from the fact that its value varies!",
+        "Now let's create our first variable called myName and because it's a name let's make it a string!",
         "Be sure to use lowercase and uppercase letters properly. JavaScript variables are written in <code>camel case</code>. An example of camel case is: camelCase.",
         "Look at the <code>ourName</code> example if you get stuck."
       ],
@@ -362,7 +362,7 @@
       "title": "Create Decimal Numbers with JavaScript",
       "difficulty": "9.9815",
       "description": [
-        "In JavaScript we can can work with decimal numbers.",
+        "In JavaScript we can work with decimal numbers.",
         "Let's create a variable <code>myDecimal</code> and give it a decimal value."
       ],
       "tests": [
@@ -385,7 +385,7 @@
       "title": "Perform Arithmetic Operations on Decimals with JavaScript",
       "difficulty": "9.98151",
       "description": [
-        "In JavaScript we can can work with decimal numbers."
+        "In JavaScript we can work with decimal numbers."
       ],
       "tests": [
         "assert(multiply == 15, 'The result of multiply should be 3.75');",

From e0bd8c6dd2891212f276ed1c0897f638c74c0a26 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Sun, 9 Aug 2015 17:03:49 -0700
Subject: [PATCH 19/47] remove pair programming Bonfire warm up challenge

---
 seed/challenges/basic-bonfires.json | 72 +++++++++----------------------------
 server/views/home.jade              |  2 +-
 2 files changed, 17 insertions(+), 57 deletions(-)

diff --git a/seed/challenges/basic-bonfires.json b/seed/challenges/basic-bonfires.json
index af9c9a3..2737a8f 100644
--- a/seed/challenges/basic-bonfires.json
+++ b/seed/challenges/basic-bonfires.json
@@ -3,46 +3,6 @@
   "order": 0.006,
   "challenges": [
     {
-      "id": "bd7139d8c441eddfaeb5bdef",
-      "name": "Waypoint: Pair Program on Bonfires",
-      "dashedName": "waypoint-pair-program-on-bonfires",
-      "difficulty": 0.44,
-      "challengeSeed": [
-        "119657641"
-      ],
-      "description": [
-        "Please note that the video for this challenge is a little outdated, and doesn't perfectly match these steps. We plan to record a new video soon.",
-        "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 Screenhero. You can download Screenhero 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.",
-        "We have a special chat room for people ready to pair program. Go to our <a href='//gitter.im/FreeCodeCamp/LetsPair' target='_blank'>LetsPair chatroom on Gitter</a> and type \"Hello Pair Programmers!\"",
-        "If someone is available, they will be your \"pair\" - the person you pair programming with.",
-        "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 Screenhero.",
-        "Add them as a new contact in Screenhero, then click the monitor-looking button to attempt to share your screen with them.",
-        "Once the Screenhero session starts, your screen's margins will glow orange. You are now sharing your screen.",
-        "Your pair will have their own cursor, and will be able to type text on his or her keyboard.",
-        "Now it's time to tackle our Bonfires. You can begin them by advancing to the next challenge.",
-        "Once you you finish pair programming, end the session in Screenhero session.",
-        "Congratulations! You have completed your first pair programming session.",
-        "Pair program as much as possible with different campers until you've completed all the Bonfire challenges. This is a big time investment, but the JavaScript practice you get will be well worth it!",
-        "Mark this Waypoint complete and move on."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
       "id": "ad7123c8c441eddfaeb5bdef",
       "name": "Bonfire: Meet Bonfire",
       "dashedName": "bonfire-meet-bonfire",
@@ -96,7 +56,7 @@
         "Reverse the provided string.",
         "You may need to turn the string into an array before you can reverse it.",
         "Your result must be a string.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function reverseString(str) {",
@@ -139,7 +99,7 @@
         "If the integer is represented with the letter n, a factorial is the product of all positive integers less than or equal to n.",
         "Factorials are often represented with the shorthand notation n!",
         "For example: 5! = 1 * 2 * 3 * 4 * 5 = 120f",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function factorialize(num) {",
@@ -173,7 +133,7 @@
         "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "tests": [
         "expect(palindrome(\"eye\")).to.be.a(\"boolean\");",
@@ -219,7 +179,7 @@
       "description": [
         "Return the length of the longest word in the provided sentence.",
         "Your response should be a number.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function findLongestWord(str) {",
@@ -259,7 +219,7 @@
       "description": [
         "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'.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function titleCase(str) {",
@@ -298,7 +258,7 @@
         "Return an array consisting of the largest number from each provided sub-array. For simplicity, the provided array will contain exactly 4 sub-arrays.",
         "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function largestOfFour(arr) {",
@@ -335,7 +295,7 @@
       "difficulty": "1.07",
       "description": [
         "Check if a string (first argument) ends with the given target string (second argument).",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function end(str, target) {",
@@ -375,7 +335,7 @@
       "difficulty": "1.08",
       "description": [
         "Repeat a given string (first argument) n times (second argument). Return an empty string if n is a negative number.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function repeat(str, num) {",
@@ -413,7 +373,7 @@
       "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function truncate(str, num) {",
@@ -451,7 +411,7 @@
       "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function chunk(arr, size) {",
@@ -489,7 +449,7 @@
       "difficulty": "1.11",
       "description": [
         "Return the remaining elements of an array after chopping off n elements from the head.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function slasher(arr, howMany) {",
@@ -530,7 +490,7 @@
         "For example, ['hello', 'Hello'], should return true because all of the letters in the second string are present in the first, ignoring case.",
         "The arguments ['hello', 'hey'] should return false because the string 'hello' does not contain a 'y'.",
         "Lastly, ['Alien', 'line'], should return true because all of the letters in 'line' are present in 'Alien'.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function mutation(arr) {",
@@ -571,7 +531,7 @@
       "description": [
         "Remove all falsey values from an array.",
         "Falsey values in javascript are false, null, 0, \"\", undefined, and NaN.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function bouncer(arr) {",
@@ -609,7 +569,7 @@
       "difficulty": "1.55",
       "description": [
         "Make a function that looks through an array (first argument) and returns an array of all objects that have equivalent property values (second argument).",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function where(collection, source) {",
@@ -648,7 +608,7 @@
       "difficulty": "1.60",
       "description": [
         "You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function destroyer(arr) {",
@@ -689,7 +649,7 @@
       "description": [
         "Return the lowest index at which a value (second argument) should be inserted into a sorted array (first argument).",
         "For example, where([1,2,3,4], 1.5) should return 1 because it is greater than 1 (0th index), but less than 2 (1st index).",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Write your own code."
       ],
       "challengeSeed": [
         "function where(arr, num) {",
diff --git a/server/views/home.jade b/server/views/home.jade
index ce7d54d..8b49275 100644
--- a/server/views/home.jade
+++ b/server/views/home.jade
@@ -30,7 +30,7 @@ block content
                         a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free)
                     .button-spacer
                     a.btn.btn-cta.btn-success.btn-block(href="/nonprofits") My nonprofit needs coding help
-            h2 As seen in:
+            h2 As featured in
             img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png')
             .spacer
             h2 We're a proven way to start your software engineering career:

From 02717582d8ef7303a1e299cb8cbb653ac0fa53ff Mon Sep 17 00:00:00 2001
From: Shouvik Roy <shouvik@techie.com>
Date: Mon, 10 Aug 2015 07:32:57 +0530
Subject: [PATCH 20/47] Update basic-javascript.json to fix #1642

Fixed following issues
#1639 : Fixed ```description``` to have "In JavaScript" instead of "in JavaScript" and added punctuation.
#1640 #1641 Added punctuation and fixed typo to have "perform mathematical functions" instead of "preform mathematical functions".
---
 seed/challenges/basic-javascript.json | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index b8e088a..418a027 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -272,9 +272,9 @@
       "dashedName": "waypoint-add-two-numbers-with-javascript",
       "difficulty": "9.98141",
       "description": [
-        "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
-        "Let's try a few of the most commonly used ones now",
-        "We use <code>+</code>for addition",
+        "In JavaScript whole numbers (called integers) can be easily used to perform mathematical functions.",
+        "Let's try a few of the most commonly used ones now.",
+        "We use <code>+</code>for addition.",
         "Replace the <code>0</code>with correct number to achieve the result in the comment."
       ],
       "tests": [
@@ -295,9 +295,9 @@
       "dashedName": "waypoint-subtract-one-number-from-another-with-javascript",
       "difficulty": "9.98142",
       "description": [
-        "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
-        "Let's try a few of the most commonly used ones now",
-        "We use <code>-</code>for subtraction",
+        "In JavaScript whole numbers (called integers) can be easily used to perform mathematical functions.",
+        "Let's try a few of the most commonly used ones now.",
+        "We use <code>-</code>for subtraction.",
         "Replace the <code>0</code>with correct number to achieve the result in the comment."
       ],
       "tests": [
@@ -318,9 +318,9 @@
       "dashedName": "waypoint-multiply-two-numbers-with-javascript",
       "difficulty": "9.98143",
       "description": [
-        "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
-        "Let's try a few of the most commonly used ones now",
-        "We use <code>*</code>for multiplication",
+        "In JavaScript whole numbers (called integers) can be easily used to perform mathematical functions.",
+        "Let's try a few of the most commonly used ones now.",
+        "We use <code>*</code>for multiplication.",
         "Replace the <code>0</code>with correct number to achieve the result in the comment."
       ],
       "tests": [
@@ -341,9 +341,9 @@
       "dashedName": "waypoint-divide-one-number-by-another-with-javascript",
       "difficulty": "9.9814",
       "description": [
-        "In JavaScript whole numbers (called integers) can be easily used to preform mathematical functions",
-        "Let's try a few of the most commonly used ones now",
-        "We use <code>/</code>for division",
+        "In JavaScript whole numbers (called integers) can be easily used to perform mathematical functions.",
+        "Let's try a few of the most commonly used ones now.",
+        "We use <code>/</code>for division.",
         "Replace the <code>0</code>with correct number to achieve the result in the comment."
       ],
       "tests": [
@@ -364,7 +364,7 @@
       "dashedName": "waypoint-create-decimal-numbers-with-javascript",
       "difficulty": "9.9815",
       "description": [
-        "in JavaScript we can can work with decimal numbers",
+        "In JavaScript we can can work with decimal numbers.",
         "Let's create a variable <code>myDecimal</code> and give it a decimal value."
       ],
       "tests": [

From 4ed041c0db5f89dc4f44611ccea8daac8c2931c2 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Sun, 9 Aug 2015 21:26:26 -0700
Subject: [PATCH 21/47] update curriculum structure again

---
 seed/challenges/advanced-bonfires.json             | 291 +++++++++++++++-----
 seed/challenges/expert-bonfires.json               | 304 ---------------------
 ...object-oriented-and-functional-programming.json | 117 +-------
 seed/challenges/upper-intermediate-bonfires.json   | 139 ++++++++++
 server/views/home.jade                             |   5 +-
 5 files changed, 370 insertions(+), 486 deletions(-)
 delete mode 100644 seed/challenges/expert-bonfires.json
 create mode 100644 seed/challenges/upper-intermediate-bonfires.json

diff --git a/seed/challenges/advanced-bonfires.json b/seed/challenges/advanced-bonfires.json
index c071bfb..b197aad 100644
--- a/seed/challenges/advanced-bonfires.json
+++ b/seed/challenges/advanced-bonfires.json
@@ -1,46 +1,205 @@
 {
   "name": "Advanced Algorithm Scripting",
-  "order": 0.011,
+  "order": 0.013,
   "challenges": [
     {
-      "id": "a2f1d72d9b908d0bd72bb9f6",
-      "name": "Bonfire: Make a Person",
-      "dashedName": "bonfire-make-a-person",
-      "difficulty": "3.01",
+      "id": "aff0395860f5d3034dc0bfc9",
+      "name": "Bonfire: Validate US Telephone Numbers",
+      "dashedName": "bonfire-validate-us-telephone-numbers",
+      "difficulty": "4.01",
       "description": [
-        "Fill in the object constructor with the methods specified in the tests.",
-        "Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).",
-        "All functions that take an argument have an arity of 1, and the argument will be a string.",
-        "These methods must be the only available means for interacting with the object.",
+        "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 is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false.",
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+      ],
+      "tests": [
+        "expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
+        "assert.deepEqual(telephoneCheck(\"1 555-555-5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"1 (555) 555-5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"5555555555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"(555)555-5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"1(555)555-5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"1 555 555 5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
+        "assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);",
+        "assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);",
+        "assert.deepEqual(telephoneCheck(\"55555555\"), false);",
+        "assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
+        "assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"0 (757) 622-7382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"-1 (757) 622-7382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"2 757 622-7382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"10 (757) 622-7382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"27576227382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"(275)76227382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
+        "assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
+      ],
+      "challengeSeed": [
+        "function telephoneCheck(str) {",
+        "  // Good luck!",
+        "  return true;",
+        "}",
+        "",
+        "",
+        "",
+        "telephoneCheck(\"555-555-5555\");"
+      ],
+      "MDNlinks": [
+        "RegExp"
+      ],
+      "challengeType": 5,
+      "nameCn": "",
+      "descriptionCn": [],
+      "nameFr": "",
+      "descriptionFr": [],
+      "nameRu": "",
+      "descriptionRu": [],
+      "nameEs": "",
+      "descriptionEs": [],
+      "namePt": "",
+      "descriptionPt": []
+    },
+    {
+      "id": "a3f503de51cf954ede28891d",
+      "name": "Bonfire: Symmetric Difference",
+      "dashedName": "bonfire-symmetric-difference",
+      "difficulty": "4.02",
+      "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.",
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+      ],
+      "challengeSeed": [
+        "function sym(args) {",
+        "  return arguments;",
+        "}",
+        "",
+        "sym([1, 2, 3], [5, 2, 1, 4]);"
+      ],
+      "tests": [
+        "expect(sym([1, 2, 3], [5, 2, 1, 4])).to.equal([3, 5, 4]);",
+        "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');"
+      ],
+      "MDNlinks": [
+        "Array.reduce()",
+        "Symmetric Difference"
+      ],
+      "challengeType": 5,
+      "nameCn": "",
+      "descriptionCn": [],
+      "nameFr": "",
+      "descriptionFr": [],
+      "nameRu": "",
+      "descriptionRu": [],
+      "nameEs": "",
+      "descriptionEs": [],
+      "namePt": "",
+      "descriptionPt": []
+    },
+    {
+      "id": "aa2e6f85cab2ab736c9a9b24",
+      "name": "Bonfire: Exact Change",
+      "dashedName": "bonfire-exact-change",
+      "difficulty": "4.03",
+      "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 cash-in-drawer is less than the change due. 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.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
       "challengeSeed": [
-        "var Person = function(firstAndLast) {",
-        "    return firstAndLast;",
-        "};",
+        "function drawer(price, cash, cid) {",
+        "  var change;",
+        "  // Here is your change, ma'am.",
+        "  return change;",
+        "}",
+        "",
+        "// Example cash-in-drawer array:",
+        "// [['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]]",
+        "",
+        "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]]);"
+      ],
+      "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');",
+        "expect(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
+        "assert.deepEqual(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]]), [['QUARTER', 0.50]], 'return correct change');",
+        "assert.deepEqual(drawer(3.26, 100.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]]), [['TWENTY', 60.00], ['TEN', 20.00], ['FIVE', 15], ['ONE', 1], ['QUARTER', 0.50], ['DIME', 0.20], ['PENNY', 0.04] ], 'return correct change with multiple coins and bills');",
+        "assert.deepEqual(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]]), 'Insufficient Funds', 'insufficient funds');",
+        "assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), \"Closed\", 'cash-in-drawer equals change');"
+      ],
+      "MDNlinks": [
+        "Global Object"
+      ],
+      "challengeType": 5,
+      "nameCn": "",
+      "descriptionCn": [],
+      "nameFr": "",
+      "descriptionFr": [],
+      "nameRu": "",
+      "descriptionRu": [],
+      "nameEs": "",
+      "descriptionEs": [],
+      "namePt": "",
+      "descriptionPt": []
+    },
+    {
+      "id": "a56138aff60341a09ed6c480",
+      "name": "Bonfire: Inventory Update",
+      "dashedName": "bonfire-inventory-update",
+      "difficulty": "4.04",
+      "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.",
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+      ],
+      "challengeSeed": [
+        "function inventory(arr1, arr2) {",
+        "    // All inventory must be accounted for or you're fired!",
+        "    return arr1;",
+        "}",
+        "",
+        "// Example inventory lists",
+        "var curInv = [",
+        "    [21, 'Bowling Ball'],",
+        "    [2, 'Dirty Sock'],",
+        "    [1, 'Hair Pin'],",
+        "    [5, 'Microphone']",
+        "];",
+        "",
+        "var newInv = [",
+        "    [2, 'Hair Pin'],",
+        "    [3, 'Half-Eaten Apple'],",
+        "    [67, 'Bowling Ball'],",
+        "    [7, 'Toothpaste']",
+        "];",
         "",
-        "var bob = new Person('Bob Ross');",
-        "bob.getFullName();"
+        "inventory(curInv, newInv);"
       ],
       "tests": [
-        "expect(Object.keys(bob).length).to.eql(6);",
-        "expect(bob instanceof Person).to.be.true;",
-        "expect(bob.firstName).to.be.undefined();",
-        "expect(bob.lastName).to.be.undefined();",
-        "expect(bob.getFirstName()).to.eql('Bob');",
-        "expect(bob.getLastName()).to.eql('Ross');",
-        "expect(bob.getFullName()).to.eql('Bob Ross');",
-        "bob.setFirstName('Happy');",
-        "expect(bob.getFirstName()).to.eql('Happy');",
-        "bob.setLastName('Trees');",
-        "expect(bob.getLastName()).to.eql('Trees');",
-        "bob.setFullName('George Carlin');",
-        "expect(bob.getFullName()).to.eql('George Carlin');",
-        "bob.setFullName('Bob Ross');"
+        "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);",
+        "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[88, 'Bowling Ball'], [2, 'Dirty Sock'], [3, 'Hair Pin'], [3, 'Half-Eaten Apple'], [5, 'Microphone'], [7, 'Toothpaste']]);",
+        "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], []), [[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']]);",
+        "assert.deepEqual(inventory([], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[67, 'Bowling Ball'], [2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [7, 'Toothpaste']]);",
+        "assert.deepEqual(inventory([[0, 'Bowling Ball'], [0, 'Dirty Sock'], [0, 'Hair Pin'], [0, 'Microphone']], [[1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [1, 'Bowling Ball'], [1, 'Toothpaste']]), [[1, 'Bowling Ball'], [0, 'Dirty Sock'], [1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [0, 'Microphone'], [1, 'Toothpaste']]);"
       ],
       "MDNlinks": [
-        "Closures",
-        "Details of the Object Model"
+        "Global Array Object"
       ],
       "challengeType": 5,
       "nameCn": "",
@@ -55,33 +214,34 @@
       "descriptionPt": []
     },
     {
-      "id": "af4afb223120f7348cdfc9fd",
-      "name": "Bonfire: Map the Debris",
-      "dashedName": "bonfire-map-the-debris",
-      "difficulty": "3.02",
+      "id": "a7bf700cd123b9a54eef01d5",
+      "name": "Bonfire: No repeats please",
+      "dashedName": "bonfire-no-repeats-please",
+      "difficulty": "4.05",
       "description": [
-        "Return a new array that transforms the element's average altitude into their orbital periods.",
-        "The array will contain objects in the format <code>{name: 'name', avgAlt: avgAlt}</code>.",
-        "You can read about orbital periods <a href=\"http://en.wikipedia.org/wiki/Orbital_period\" target='_blank'>on wikipedia</a>.",
-        "The values should be rounded to the nearest whole number. The body being orbited is Earth.",
-        "The radius of the earth is 6367.4447 kilometers, and the GM value of earth is 398600.4418",
+        "Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
+        "For example, 'aab' should return 2 because it has 6 total permutations, but only 2 of them don't have the same letter (in this case 'a') repeating.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
       "challengeSeed": [
-        "function orbitalPeriod(arr) {",
-        "  var GM = 398600.4418;",
-        "  var earthRadius = 6367.4447;",
-        "  return arr;",
+        "function permAlone(str) {",
+        "  return str;",
         "}",
         "",
-        "orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]);"
+        "permAlone('aab');"
       ],
       "tests": [
-        "expect(orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}])).to.eqls([{name: \"sputnik\", orbitalPeriod: 86400}]);",
-        "expect(orbitalPeriod([{name: \"iss\", avgAlt: 413.6}, {name: \"hubble\", avgAlt: 556.7}, {name: \"moon\", avgAlt: 378632.553}])).to.eqls([{name : \"iss\", orbitalPeriod: 5557}, {name: \"hubble\", orbitalPeriod: 5734}, {name: \"moon\", orbitalPeriod: 2377399}]);"
+        "expect(permAlone('aab')).to.be.a('number');",
+        "expect(permAlone('aab')).to.equal(2);",
+        "expect(permAlone('aaa')).to.equal(0);",
+        "expect(permAlone('aabb')).to.equal(8);",
+        "expect(permAlone('abcdefa')).to.equal(3600);",
+        "expect(permAlone('abfdefa')).to.equal(2640);",
+        "expect(permAlone('zzzzzzzz')).to.equal(0);"
       ],
       "MDNlinks": [
-        "Math.pow()"
+        "Permutations",
+        "RegExp"
       ],
       "challengeType": 5,
       "nameCn": "",
@@ -96,32 +256,37 @@
       "descriptionPt": []
     },
     {
-      "id": "a3f503de51cfab748ff001aa",
-      "name": "Bonfire: Pairwise",
-      "dashedName": "bonfire-pairwise",
-      "difficulty": "3.03",
+      "id": "a19f0fbe1872186acd434d5a",
+      "name": "Bonfire: Friendly Date Ranges",
+      "dashedName": "bonfire-friendly-date-ranges",
+      "difficulty": "4.06",
       "description": [
-        "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
-        "For example, pairwise([1, 4, 2, 3, 0, 5], 7) should return 11 because 4, 2, 3 and 5 can be paired with each other to equal 7.",
-        "pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!",
+        "Implement a way of converting two dates into a more friendly date range that could be presented to a user.",
+        "It must not show any redundant information in the date range.",
+        "For example, if the year and month are the same then only the day range should be displayed.",
+        "Secondly, if the starting year is the current year, and the ending year can be inferred by the reader, the year should be omitted.",
+        "Input date is formatted as YYYY-MM-DD",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
       "challengeSeed": [
-        "function pairwise(arr, arg) {",
-        "  return arg;",
+        "function friendly(str) {",
+        "  return str;",
         "}",
         "",
-        "pairwise([1,4,2,3,0,5], 7);"
+        "friendly(['2015-07-01', '2015-07-04']);"
       ],
       "tests": [
-        "expect(pairwise([1, 4, 2, 3, 0, 5], 7)).to.equal(11);",
-        "expect(pairwise([1, 3, 2, 4], 4)).to.equal(1);",
-        "expect(pairwise([1,1,1], 2)).to.equal(1);",
-        "expect(pairwise([0, 0, 0, 0, 1, 1], 1)).to.equal(10);",
-        "expect(pairwise([], 100)).to.equal(0);"
+        "assert.deepEqual(friendly(['2015-07-01', '2015-07-04']), ['July 1st','4th'], 'ending month should be omitted since it is already mentioned');",
+        "assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'two months apart can be inferred if it is the next year');",
+        "assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017']);",
+        "assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th'], 'one month apart can be inferred it is the same year');",
+        "assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');",
+        "assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);"
       ],
       "MDNlinks": [
-        "Array.reduce()"
+        "String.split()",
+        "String.substr()",
+        "parseInt()"
       ],
       "challengeType": 5,
       "nameCn": "",
diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
deleted file mode 100644
index 50bbe89..0000000
--- a/seed/challenges/expert-bonfires.json
+++ /dev/null
@@ -1,304 +0,0 @@
-{
-  "name": "Expert Algorithm Scripting",
-  "order": 0.013,
-  "challenges": [
-    {
-      "id": "aff0395860f5d3034dc0bfc9",
-      "name": "Bonfire: Validate US Telephone Numbers",
-      "dashedName": "bonfire-validate-us-telephone-numbers",
-      "difficulty": "4.01",
-      "description": [
-        "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 is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "tests": [
-        "expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
-        "assert.deepEqual(telephoneCheck(\"1 555-555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1 (555) 555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"5555555555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"(555)555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1(555)555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1 555 555 5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);",
-        "assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);",
-        "assert.deepEqual(telephoneCheck(\"55555555\"), false);",
-        "assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"0 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"-1 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2 757 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"10 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"27576227382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"(275)76227382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
-      ],
-      "challengeSeed": [
-        "function telephoneCheck(str) {",
-        "  // Good luck!",
-        "  return true;",
-        "}",
-        "",
-        "",
-        "",
-        "telephoneCheck(\"555-555-5555\");"
-      ],
-      "MDNlinks": [
-        "RegExp"
-      ],
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a3f503de51cf954ede28891d",
-      "name": "Bonfire: Symmetric Difference",
-      "dashedName": "bonfire-symmetric-difference",
-      "difficulty": "4.02",
-      "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function sym(args) {",
-        "  return arguments;",
-        "}",
-        "",
-        "sym([1, 2, 3], [5, 2, 1, 4]);"
-      ],
-      "tests": [
-        "expect(sym([1, 2, 3], [5, 2, 1, 4])).to.equal([3, 5, 4]);",
-        "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');"
-      ],
-      "MDNlinks": [
-        "Array.reduce()",
-        "Symmetric Difference"
-      ],
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "aa2e6f85cab2ab736c9a9b24",
-      "name": "Bonfire: Exact Change",
-      "dashedName": "bonfire-exact-change",
-      "difficulty": "4.03",
-      "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 cash-in-drawer is less than the change due. 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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function drawer(price, cash, cid) {",
-        "  var change;",
-        "  // Here is your change, ma'am.",
-        "  return change;",
-        "}",
-        "",
-        "// Example cash-in-drawer array:",
-        "// [['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]]",
-        "",
-        "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]]);"
-      ],
-      "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');",
-        "expect(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
-        "assert.deepEqual(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]]), [['QUARTER', 0.50]], 'return correct change');",
-        "assert.deepEqual(drawer(3.26, 100.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]]), [['TWENTY', 60.00], ['TEN', 20.00], ['FIVE', 15], ['ONE', 1], ['QUARTER', 0.50], ['DIME', 0.20], ['PENNY', 0.04] ], 'return correct change with multiple coins and bills');",
-        "assert.deepEqual(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]]), 'Insufficient Funds', 'insufficient funds');",
-        "assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), \"Closed\", 'cash-in-drawer equals change');"
-      ],
-      "MDNlinks": [
-        "Global Object"
-      ],
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a56138aff60341a09ed6c480",
-      "name": "Bonfire: Inventory Update",
-      "dashedName": "bonfire-inventory-update",
-      "difficulty": "4.04",
-      "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function inventory(arr1, arr2) {",
-        "    // All inventory must be accounted for or you're fired!",
-        "    return arr1;",
-        "}",
-        "",
-        "// Example inventory lists",
-        "var curInv = [",
-        "    [21, 'Bowling Ball'],",
-        "    [2, 'Dirty Sock'],",
-        "    [1, 'Hair Pin'],",
-        "    [5, 'Microphone']",
-        "];",
-        "",
-        "var newInv = [",
-        "    [2, 'Hair Pin'],",
-        "    [3, 'Half-Eaten Apple'],",
-        "    [67, 'Bowling Ball'],",
-        "    [7, 'Toothpaste']",
-        "];",
-        "",
-        "inventory(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);",
-        "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[88, 'Bowling Ball'], [2, 'Dirty Sock'], [3, 'Hair Pin'], [3, 'Half-Eaten Apple'], [5, 'Microphone'], [7, 'Toothpaste']]);",
-        "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], []), [[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']]);",
-        "assert.deepEqual(inventory([], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[67, 'Bowling Ball'], [2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [7, 'Toothpaste']]);",
-        "assert.deepEqual(inventory([[0, 'Bowling Ball'], [0, 'Dirty Sock'], [0, 'Hair Pin'], [0, 'Microphone']], [[1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [1, 'Bowling Ball'], [1, 'Toothpaste']]), [[1, 'Bowling Ball'], [0, 'Dirty Sock'], [1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [0, 'Microphone'], [1, 'Toothpaste']]);"
-      ],
-      "MDNlinks": [
-        "Global Array Object"
-      ],
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a7bf700cd123b9a54eef01d5",
-      "name": "Bonfire: No repeats please",
-      "dashedName": "bonfire-no-repeats-please",
-      "difficulty": "4.05",
-      "description": [
-        "Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
-        "For example, 'aab' should return 2 because it has 6 total permutations, but only 2 of them don't have the same letter (in this case 'a') repeating.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function permAlone(str) {",
-        "  return str;",
-        "}",
-        "",
-        "permAlone('aab');"
-      ],
-      "tests": [
-        "expect(permAlone('aab')).to.be.a('number');",
-        "expect(permAlone('aab')).to.equal(2);",
-        "expect(permAlone('aaa')).to.equal(0);",
-        "expect(permAlone('aabb')).to.equal(8);",
-        "expect(permAlone('abcdefa')).to.equal(3600);",
-        "expect(permAlone('abfdefa')).to.equal(2640);",
-        "expect(permAlone('zzzzzzzz')).to.equal(0);"
-      ],
-      "MDNlinks": [
-        "Permutations",
-        "RegExp"
-      ],
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a19f0fbe1872186acd434d5a",
-      "name": "Bonfire: Friendly Date Ranges",
-      "dashedName": "bonfire-friendly-date-ranges",
-      "difficulty": "4.06",
-      "description": [
-        "Implement a way of converting two dates into a more friendly date range that could be presented to a user.",
-        "It must not show any redundant information in the date range.",
-        "For example, if the year and month are the same then only the day range should be displayed.",
-        "Secondly, if the starting year is the current year, and the ending year can be inferred by the reader, the year should be omitted.",
-        "Input date is formatted as YYYY-MM-DD",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function friendly(str) {",
-        "  return str;",
-        "}",
-        "",
-        "friendly(['2015-07-01', '2015-07-04']);"
-      ],
-      "tests": [
-        "assert.deepEqual(friendly(['2015-07-01', '2015-07-04']), ['July 1st','4th'], 'ending month should be omitted since it is already mentioned');",
-        "assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'two months apart can be inferred if it is the next year');",
-        "assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017']);",
-        "assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th'], 'one month apart can be inferred it is the same year');",
-        "assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');",
-        "assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);"
-      ],
-      "MDNlinks": [
-        "String.split()",
-        "String.substr()",
-        "parseInt()"
-      ],
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    }
-  ]
-}
diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index 93c85cb..54b4606 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -1,119 +1,6 @@
 {
-  "name": "Object Oriented and Functional Programming - Under Construction From Challenge 4 Onwards",
-  "order" : 0.009,
+  "name": "Object Oriented and Functional Programming - Coming Soon",
+  "order" : 0.010,
   "challenges": [
-    {
-      "id": "bd7153d8c44eeddfaeb5bd0f",
-      "name": "Waypoint: Learn Scope Chains and Closures",
-      "dashedName": "waypoint-learn-scope-chains-and-closures",
-      "difficulty": 0.01,
-      "challengeSeed": ["133316031"],
-      "description": [
-        "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
-        "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
-        "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.",
-        "Click on Create New Workspace at the top right of the c9.io page, then click on the \"Create a new workspace\" popup that appears below it the button after you click on it.",
-        "Give your workspace a name.",
-        "Choose Node.js in the selection area below the name field.",
-        "Click the Create button. Then click into your new workspace.",
-        "In the lower right hand corner you should see a terminal window. In this window use the following commands. You don't need to know what these mean at this point.",
-        "Install <code>scope-chains-closures</code> with this command: <code>npm install -g scope-chains-closures</code>",
-        "Now start the tutorial by running <code>scope-chains-closures</code>.",
-        "Note that you can resize the c9.io's windows by dragging their borders.",
-        "Make sure that you are always in your project's \"workspace\" directory. You can always navigate back to this directory by running this command: <code>cd ~/workspace</code>.",
-        "You can view this Node School module's source code on GitHub at <a href='https://github.com/jesstelford/scope-chains-closures'>https://github.com/jesstelford/scope-chains-closures</a>.",
-        "Complete \"Scopes\"",
-        "Complete \"Scope Chains\"",
-        "Complete \"Global Scope and Shadowing\"",
-        "Complete \"Closures\"",
-        "Complete \"Garbage Collection\"",
-        "Once you've completed these steps, move on to our next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "bd7153d8b44eeddfaeb5bd0f",
-      "name": "Waypoint: Use Prototypes for Inheriting Properties",
-      "dashedName": "waypoint-use-prototypes-for-inheriting-properties",
-      "difficulty": 0.02,
-      "challengeSeed": ["133316036"],
-      "description": [
-        "We'll build this Waypoint on Cloud 9, a powerful online code editor with a full Ubuntu Linux workspace, all running in the cloud.",
-        "If you don't already have Cloud 9 account, create one now at <a href='http://c9.io' target='_blank'>http://c9.io</a>.",
-        "Open up <a href='http://c9.io' target='_blank'>http://c9.io</a> and sign in to your account.",
-        "Click on Create New Workspace at the top right of the c9.io page, then click on the \"Create a new workspace\" popup that appears below it the button after you click on it.",
-        "Give your workspace a name.",
-        "Choose Node.js in the selection area below the name field.",
-        "Click the Create button. Then click into your new workspace.",
-        "In the lower right hand corner you should see a terminal window. In this window use the following commands. You don't need to know what these mean at this point.",
-        "Install <code>planetproto</code> with this command: <code>npm install -g planetproto</code>",
-        "Now start the tutorial by running <code>planetproto</code>.",
-        "Note that you can resize the c9.io's windows by dragging their borders.",
-        "Make sure that you are always in your project's \"workspace\" directory. You can always navigate back to this directory by running this command: <code>cd ~/workspace</code>.",
-        "You can view this Node School module's source code on GitHub at <a href='https://github.com/sporto/planetproto'>https://github.com/sporto/planetproto</a>.",
-        "Complete \"Simple Objects\"",
-        "Complete \"Proto\"",
-        "Complete \"Dynamic Lookups\"",
-        "Complete \"Property Assignments\"",
-        "Complete \"Arrays and Objects\"",
-        "Complete \"Object Create\"",
-        "Complete \"Dot New\"",
-        "Complete \"Constructor Functions\"",
-        "Complete \"Implicit This\"",
-        "Note that you can skip the last challenge.",
-        "Once you've completed these steps, move on to our next challenge."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "bd7129d8c441eddfbeb5bddf",
-      "name": "Waypoint: Practice Functional Programming",
-      "dashedName": "waypoint-practice-functional-programming",
-      "difficulty": 0.01,
-      "challengeSeed": ["129169463"],
-      "description": [
-        "Functional programming holds the key to unlocking JavaScript's powerful asynchronous features.",
-        "Jafar Husain's interactive Functional Programming course will familiarize you with the various ways you can recombine these functions.",
-        "Functional programming in JavaScript involves using five key functions: \"map\", \"reduce\", \"filter\", \"concatAll\", and \"zip\".",
-        "Click here to go to the challenge: <a href='http://jhusain.github.io/learnrx/' target='_blank'>http://jhusain.github.io/learnrx/</a>.",
-        "You only need to complete the first 27 steps of this tutorial.",
-        "This challenge will take several hours, but don't worry. Jafar's website will save your progress (using your browser's local storage) so you don't need to finish it in one sitting.",
-        "If you've spent several minutes on one of these challenges, and still can't figure out its correct answer, you can click \"show answer\", then click \"run\" to advance to the next challenge. Be sure to read the correct answer and make sure you understand it before moving on."
-      ],
-      "challengeType": 2,
-      "tests": [],
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    }
   ]
 }
diff --git a/seed/challenges/upper-intermediate-bonfires.json b/seed/challenges/upper-intermediate-bonfires.json
new file mode 100644
index 0000000..bfd765f
--- /dev/null
+++ b/seed/challenges/upper-intermediate-bonfires.json
@@ -0,0 +1,139 @@
+{
+  "name": "Upper Intermediate Algorithm Scripting",
+  "order": 0.011,
+  "challenges": [
+    {
+      "id": "a2f1d72d9b908d0bd72bb9f6",
+      "name": "Bonfire: Make a Person",
+      "dashedName": "bonfire-make-a-person",
+      "difficulty": "3.01",
+      "description": [
+        "Fill in the object constructor with the methods specified in the tests.",
+        "Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).",
+        "All functions that take an argument have an arity of 1, and the argument will be a string.",
+        "These methods must be the only available means for interacting with the object.",
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+      ],
+      "challengeSeed": [
+        "var Person = function(firstAndLast) {",
+        "    return firstAndLast;",
+        "};",
+        "",
+        "var bob = new Person('Bob Ross');",
+        "bob.getFullName();"
+      ],
+      "tests": [
+        "expect(Object.keys(bob).length).to.eql(6);",
+        "expect(bob instanceof Person).to.be.true;",
+        "expect(bob.firstName).to.be.undefined();",
+        "expect(bob.lastName).to.be.undefined();",
+        "expect(bob.getFirstName()).to.eql('Bob');",
+        "expect(bob.getLastName()).to.eql('Ross');",
+        "expect(bob.getFullName()).to.eql('Bob Ross');",
+        "bob.setFirstName('Happy');",
+        "expect(bob.getFirstName()).to.eql('Happy');",
+        "bob.setLastName('Trees');",
+        "expect(bob.getLastName()).to.eql('Trees');",
+        "bob.setFullName('George Carlin');",
+        "expect(bob.getFullName()).to.eql('George Carlin');",
+        "bob.setFullName('Bob Ross');"
+      ],
+      "MDNlinks": [
+        "Closures",
+        "Details of the Object Model"
+      ],
+      "challengeType": 5,
+      "nameCn": "",
+      "descriptionCn": [],
+      "nameFr": "",
+      "descriptionFr": [],
+      "nameRu": "",
+      "descriptionRu": [],
+      "nameEs": "",
+      "descriptionEs": [],
+      "namePt": "",
+      "descriptionPt": []
+    },
+    {
+      "id": "af4afb223120f7348cdfc9fd",
+      "name": "Bonfire: Map the Debris",
+      "dashedName": "bonfire-map-the-debris",
+      "difficulty": "3.02",
+      "description": [
+        "Return a new array that transforms the element's average altitude into their orbital periods.",
+        "The array will contain objects in the format <code>{name: 'name', avgAlt: avgAlt}</code>.",
+        "You can read about orbital periods <a href=\"http://en.wikipedia.org/wiki/Orbital_period\" target='_blank'>on wikipedia</a>.",
+        "The values should be rounded to the nearest whole number. The body being orbited is Earth.",
+        "The radius of the earth is 6367.4447 kilometers, and the GM value of earth is 398600.4418",
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+      ],
+      "challengeSeed": [
+        "function orbitalPeriod(arr) {",
+        "  var GM = 398600.4418;",
+        "  var earthRadius = 6367.4447;",
+        "  return arr;",
+        "}",
+        "",
+        "orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]);"
+      ],
+      "tests": [
+        "expect(orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}])).to.eqls([{name: \"sputnik\", orbitalPeriod: 86400}]);",
+        "expect(orbitalPeriod([{name: \"iss\", avgAlt: 413.6}, {name: \"hubble\", avgAlt: 556.7}, {name: \"moon\", avgAlt: 378632.553}])).to.eqls([{name : \"iss\", orbitalPeriod: 5557}, {name: \"hubble\", orbitalPeriod: 5734}, {name: \"moon\", orbitalPeriod: 2377399}]);"
+      ],
+      "MDNlinks": [
+        "Math.pow()"
+      ],
+      "challengeType": 5,
+      "nameCn": "",
+      "descriptionCn": [],
+      "nameFr": "",
+      "descriptionFr": [],
+      "nameRu": "",
+      "descriptionRu": [],
+      "nameEs": "",
+      "descriptionEs": [],
+      "namePt": "",
+      "descriptionPt": []
+    },
+    {
+      "id": "a3f503de51cfab748ff001aa",
+      "name": "Bonfire: Pairwise",
+      "dashedName": "bonfire-pairwise",
+      "difficulty": "3.03",
+      "description": [
+        "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
+        "For example, pairwise([1, 4, 2, 3, 0, 5], 7) should return 11 because 4, 2, 3 and 5 can be paired with each other to equal 7.",
+        "pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!",
+        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
+      ],
+      "challengeSeed": [
+        "function pairwise(arr, arg) {",
+        "  return arg;",
+        "}",
+        "",
+        "pairwise([1,4,2,3,0,5], 7);"
+      ],
+      "tests": [
+        "expect(pairwise([1, 4, 2, 3, 0, 5], 7)).to.equal(11);",
+        "expect(pairwise([1, 3, 2, 4], 4)).to.equal(1);",
+        "expect(pairwise([1,1,1], 2)).to.equal(1);",
+        "expect(pairwise([0, 0, 0, 0, 1, 1], 1)).to.equal(10);",
+        "expect(pairwise([], 100)).to.equal(0);"
+      ],
+      "MDNlinks": [
+        "Array.reduce()"
+      ],
+      "challengeType": 5,
+      "nameCn": "",
+      "descriptionCn": [],
+      "nameFr": "",
+      "descriptionFr": [],
+      "nameRu": "",
+      "descriptionRu": [],
+      "nameEs": "",
+      "descriptionEs": [],
+      "namePt": "",
+      "descriptionPt": []
+    }
+  ]
+}
diff --git a/server/views/home.jade b/server/views/home.jade
index e5e09f1..157753a 100644
--- a/server/views/home.jade
+++ b/server/views/home.jade
@@ -27,10 +27,7 @@ block content
             .big-break
             .row
                 .col-xs-12.col-sm-8.col-sm-offset-2
-                    if (user)
-                        a.btn.btn-cta.signup-btn.btn-block(href="/challenges") Go to my next challenge
-                    else
-                        a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free)
+                    a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free)
                     .button-spacer
                     a.btn.btn-cta.btn-success.btn-block(href="/nonprofits") My nonprofit needs coding help
             h2 As seen in:

From f3028b0e6a911b5d605461dd0d70180f7f41b38e Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Sun, 9 Aug 2015 21:59:49 -0700
Subject: [PATCH 22/47] continue work on get-started

---
 server/views/resources/get-started.jade | 300 ++++++++++++++++----------------
 1 file changed, 149 insertions(+), 151 deletions(-)

diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index c64acef..d88692a 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -1,154 +1,152 @@
 extends ../layout
 block content
     .jumbotron
-        h1.text-center This short guide will get you started
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Free Code Code camp is self-paced, browser-based, and free.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
-        p.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rU7B4sn.jpg' alt='a gif showing how to install this')
-        p.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.i.imgur.com/WAxbGZE.gif' alt='a gif showing how to install this')
-        p.gif-caption
-            a(href='https://github.com/join' target='_blank') Create an account with GitHub
-            | . This will be private, so you should use your real email address.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption
-            a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
-            | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Now that you have a GitHub account, you can&thinsp;
-            a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by authenticating with GitHub
-            | .
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption
-            a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
-            | .
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Let's check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption You can also add a short bio, and links to your social media profiles.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption
-            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
-            | . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
-            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
-            | .
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption
-            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
-            | and click "Gitter" to join your city's chat room.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption You can&thinsp;
-            a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
-            | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
-            a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
-            | .
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
-
-        hr
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-        p.gif-caption Congratulations! Now you're ready to start working through our Challenge Map. Good luck and happy coding!
-        hr
-        a.btn.btn-cta.signup-btn.btn-block(href="/map") Go to my Challenge Map and start coding
+        h2.text-center Do these steps to get ready for Free Code Camp (this only takes 10 minutes):
+        ol
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Free Code Code camp is self-paced, browser-based, and free.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rU7B4sn.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.i.imgur.com/WAxbGZE.gif' alt='a gif showing how to install this')
+            li.large-li.gif-caption
+                a(href='https://github.com/join' target='_blank') Create an account with GitHub
+                | . This will be private, so you should use your real email address.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption
+                a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
+                | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Now that you have a GitHub account, you can&thinsp;
+                a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by authenticating with GitHub
+                | .
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption
+                a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
+                | .
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Let's check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption You can also add a short bio, and links to your social media profiles.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption
+                a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
+                | . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
+                a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
+                | .
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption
+                a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
+                | and click "Gitter" to join your city's chat room.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption You can&thinsp;
+                a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
+                | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
+                a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
+                | .
+
+            hr
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            li.large-li.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
+
+        h2.text-center Nicely done. Now you have all the tools you need to succeed. Happy coding!
+        a.btn.btn-cta.signup-btn.btn-block(href="/map") Take me to my Challenge Map

From 967f92e6f42aee5fa0bf752e9ad41c0a77fba8f7 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Sun, 9 Aug 2015 22:14:31 -0700
Subject: [PATCH 23/47] fix challenge naming scheme

---
 common/models/challenge.json        |   3 +
 seed/index.js                       |   5 ++
 server/boot/challenge.js            | 170 ++++++++++++++++++++++--------------
 server/utils/index.js               |  11 ---
 server/views/challengeMap/show.jade |  17 ++--
 5 files changed, 121 insertions(+), 85 deletions(-)

diff --git a/common/models/challenge.json b/common/models/challenge.json
index a6b71d5..7433321 100644
--- a/common/models/challenge.json
+++ b/common/models/challenge.json
@@ -25,6 +25,9 @@
     "dashedName": {
       "type": "string"
     },
+    "block": {
+      "type": "string"
+    },
     "difficulty": {
       "type": "string"
     },
diff --git a/seed/index.js b/seed/index.js
index b2a4e3e..3dbbf9d 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -39,6 +39,8 @@ Challenge.destroyAll(function(err, info) {
   challenges.forEach(function(file) {
     var challengeSpec = require('./challenges/' + file);
     var order = challengeSpec.order;
+    var block = challengeSpec.name;
+
     var challenges = challengeSpec.challenges
       .map(function(challenge, index) {
         // NOTE(berks): add title for displaying in views
@@ -46,11 +48,14 @@ Challenge.destroyAll(function(err, info) {
           _.capitalize(challenge.type) +
           ': ' +
           challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
+
         challenge.dashedName = challenge.name
           .toLowerCase()
           .replace(/\:/g, '')
           .replace(/\s/g, '-');
         challenge.order = +('' + order + (index + 1));
+        challenge.block = block;
+
         return challenge;
       });
 
diff --git a/server/boot/challenge.js b/server/boot/challenge.js
index d88f2ac..1fc4342 100644
--- a/server/boot/challenge.js
+++ b/server/boot/challenge.js
@@ -1,17 +1,24 @@
-var R = require('ramda'),
-  Rx = require('rx'),
-  assign = require('object.assign'),
-  debug = require('debug')('freecc:challenges'),
-  utils = require('../utils'),
-
-  // this would be so much cleaner with destructering...
-  saveUser = require('../utils/rx').saveUser,
-  observableQueryFromModel = require('../utils/rx').observableQueryFromModel,
-
-  userMigration = require('../utils/middleware').userMigration,
-  ifNoUserRedirectTo = require('../utils/middleware').ifNoUserRedirectTo,
-  ifNoUserSend = require('../utils/middleware').ifNoUserSend;
-
+import _ from 'lodash';
+import moment from 'moment';
+import R from 'ramda';
+import { Observable } from 'rx';
+import assign from 'object.assign';
+import debugFactory from 'debug';
+import utils from '../utils';
+
+import {
+  saveUser,
+  observeMethod,
+  observableQueryFromModel
+} from '../utils/rx';
+
+import {
+  userMigration,
+  ifNoUserRedirectTo,
+  ifNoUserSend
+} from '../utils/middleware';
+
+const debug = debugFactory('freecc:challenges');
 var challengeMapWithNames = utils.getChallengeMapWithNames();
 var challengeMapWithIds = utils.getChallengeMapWithIds();
 var challengeMapWithDashedNames = utils.getChallengeMapWithDashedNames();
@@ -22,6 +29,10 @@ var unDasherize = utils.unDasherize;
 
 var getMDNLinks = utils.getMDNLinks;
 
+function numberWithCommas(x) {
+  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+}
+
 function updateUserProgress(user, challengeId, completedChallenge) {
   var alreadyCompleted = user.completedChallenges.some(({ id }) => {
     return id === challengeId;
@@ -37,12 +48,18 @@ function updateUserProgress(user, challengeId, completedChallenge) {
 }
 
 module.exports = function(app) {
-  var router = app.loopback.Router();
-  var Challenge = app.models.Challenge;
-  var User = app.models.User;
-  var redirectNonUser =
-    ifNoUserRedirectTo('/challenges/learn-how-free-code-camp-works');
-  var send200toNonUser = ifNoUserSend(true);
+  const router = app.loopback.Router();
+
+  const Challenge = app.models.Challenge;
+  const findChallenge$ = observeMethod(Challenge, 'find');
+
+  const User = app.models.User;
+  const userCount$ = observeMethod(User, 'count');
+
+  const send200toNonUser = ifNoUserSend(true);
+  const redirectNonUser = ifNoUserRedirectTo(
+    '/challenges/learn-how-free-code-camp-works'
+  );
 
   router.post(
     '/completed-challenge/',
@@ -182,7 +199,7 @@ module.exports = function(app) {
                 .map(function(key) {
                   return challengeMapWithIds[key]
                     .filter(function(elem) {
-                      return elem === ('' + challenge.id);
+                      return elem === '' + challenge.id;
                     })
                     .map(function() {
                       return key;
@@ -266,7 +283,7 @@ module.exports = function(app) {
         }
       })
       .withLatestFrom(
-        Rx.Observable.just(req.user),
+        Observable.just(req.user),
         function(pairedWith, user) {
           return {
             user: user,
@@ -289,7 +306,7 @@ module.exports = function(app) {
       // not iterate users
       .flatMap(function(dats) {
         debug('flatmap');
-        return Rx.Observable.from([dats.user, dats.pairedWith]);
+        return Observable.from([dats.user, dats.pairedWith]);
       })
       // save user
       .flatMap(function(user) {
@@ -392,7 +409,7 @@ module.exports = function(app) {
           );
         }
       })
-      .withLatestFrom(Rx.Observable.just(req.user), function(pairedWith, user) {
+      .withLatestFrom(Observable.just(req.user), function(pairedWith, user) {
         return {
           user: user,
           pairedWith: pairedWith
@@ -408,7 +425,7 @@ module.exports = function(app) {
         );
       })
       .flatMap(function({ user, pairedWith }) {
-        return Rx.Observable.from([user, pairedWith]);
+        return Observable.from([user, pairedWith]);
       })
       // save users
       .flatMap(function(user) {
@@ -428,50 +445,73 @@ module.exports = function(app) {
       );
   }
 
-  function challengeMap(req, res, next) {
-    var completedList = [];
+  function challengeMap({ user = {} }, res, next) {
+    const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
 
-    if (req.user) {
-      completedList = req.user.completedChallenges;
-    }
+    // if user
+    // get the id's of all the users completed challenges
+    const completedChallenges = !user.completedChallenges ?
+      [] :
+      _.uniq(user.completedChallenges).map(({ id }) => id);
 
-    var noDuplicatedChallenges = R.uniq(completedList);
+    const camperCount$ = userCount$()
+      .map(camperCount => numberWithCommas(camperCount));
 
-    var completedChallengeList = noDuplicatedChallenges
-      .map(function(challenge) {
-        // backwards compatibility
-        return (challenge.id || challenge._id);
-      });
-    var challengeList = utils.
-      getChallengeMapForDisplay(completedChallengeList);
-
-    Object.keys(challengeList).forEach(function(key) {
-      challengeList[key].completed = challengeList[key]
-        .challenges.filter(function(elem) {
-        // backwards compatibility hack
-        return completedChallengeList.indexOf(elem.id || elem._id) > -1;
-      });
-    });
-
-    function numberWithCommas(x) {
-      return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
-    }
-
-    var date1 = new Date('10/15/2014');
-    var date2 = new Date();
-    var timeDiff = Math.abs(date2.getTime() - date1.getTime());
-    var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
+    const query = {
+      order: 'order ASC'
+    };
 
-    User.count(function(err, camperCount) {
-      if (err) { return next(err); }
+    // create a stream of all the challenges
+    const challenge$ = findChallenge$(query)
+      .flatMap(challenges => Observable.from(challenges))
+      .shareReplay();
+
+    // create a stream of an array of all the challenge blocks
+    const blocks$ = challenge$
+      // mark challenge completed
+      .map(challenge => {
+        if (completedChallenges.indexOf(challenge.id) !== -1) {
+          challenge.completed = true;
+        }
+        return challenge;
+      })
+      // group challenges by block | returns a stream of observables
+      .groupBy(challenge => challenge.block)
+      // turn block group stream into an array
+      .flatMap(block$ => block$.toArray())
+      .map(blockArray => {
+        const completedCount = blockArray.reduce((sum, { completed }) => {
+          if (completed) {
+            return sum + 1;
+          }
+          return sum;
+        });
 
-      res.render('challengeMap/show', {
-        daysRunning: daysRunning,
-        camperCount: numberWithCommas(camperCount),
-        title: "A map of all Free Code Camp's Challenges",
-        challengeList: challengeList,
-        completedChallengeList: completedChallengeList
-      });
-    });
+        return {
+          name: blockArray[0].block,
+          dashedName: dasherize(blockArray[0].block),
+          challenges: blockArray,
+          completed: completedCount / blockArray.length * 100
+        };
+      })
+      // turn stream of blocks into a stream of an array
+      .toArray();
+
+    Observable.combineLatest(
+      camperCount$,
+      blocks$,
+      (camperCount, blocks) => ({ camperCount, blocks })
+    )
+      .subscribe(
+        ({ camperCount, blocks }) => {
+          res.render('challengeMap/show', {
+            blocks,
+            daysRunning,
+            camperCount,
+            title: "A map of all Free Code Camp's Challenges"
+          });
+        },
+        next
+      );
   }
 };
diff --git a/server/utils/index.js b/server/utils/index.js
index 2fd19d0..72b37da 100644
--- a/server/utils/index.js
+++ b/server/utils/index.js
@@ -19,17 +19,6 @@ var allNonprofitNames,
   challengeMapWithNames, allChallengeIds,
   challengeMapWithDashedNames;
 
-Array.zip = function(left, right, combinerFunction) {
-  var counter,
-    results = [];
-
-  for (counter = 0; counter < Math.min(left.length, right.length); counter++) {
-    results.push(combinerFunction(left[counter], right[counter]));
-  }
-
-  return results;
-};
-
 (function() {
   if (!challengeMap) {
     var localChallengeMap = {};
diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade
index 77b42ca..22927bd 100644
--- a/server/views/challengeMap/show.jade
+++ b/server/views/challengeMap/show.jade
@@ -1,8 +1,7 @@
 extends ../layout
 block content
     script.
-        var completedChallenges = !{JSON.stringify(completedChallengeList)};
-        var challengeList = !{JSON.stringify(challengeList)};
+        var challenges = !{JSON.stringify(challenges)};
     .bg-danger.default-border-radius
         p &nbsp;&nbsp;&nbsp;&nbsp;
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/beta' target='_blank') You're using our experimental beta site. None of your progress here will be saved. Please click this to learn more.
@@ -28,10 +27,10 @@ block content
                     .col-xs-12.col-sm-8.col-sm-offset-2
                         h3 800 Hours of Practice:
                 ol
-                    for challengeBlock in challengeList
+                    for challengeBlock in blocks
                         .row
                             if (user)
-                                if (challengeBlock.completed.length === challengeBlock.challenges.length)
+                                if (challengeBlock.completed === 100)
                                     .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.large-p.negative-10
                                     .col-xs-12.col-sm-9.col-md-10
                                         li.large-p.faded.negative-10
@@ -39,7 +38,7 @@ block content
                                 else
                                     .hidden-xs.col-sm-3.col-md-2
                                         .progress.progress-bar-padding.text-center.thin-progress-bar
-                                            .progress-bar(role='progressbar', aria-valuenow=((challengeBlock.completed.length / challengeBlock.challenges.length) * 100), aria-valuemin='0', aria-valuemax='100', style='width: ' + ((challengeBlock.completed.length / challengeBlock.challenges.length) * 100) + '%;')
+                                            .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;')
                                     .col-xs-12.col-sm-9.col-md-10
                                         li.large-p.negative-10
                                             a(href='#' + challengeBlock.dashedName)= challengeBlock.name
@@ -74,7 +73,7 @@ block content
                             li.large-p.negative-10 300-hour Nonprofit Project
                 hr
 
-                for challengeBlock in challengeList
+                for challengeBlock in blocks
                     .row
                         a(href='#' name=challengeBlock.dashedName)
                         .spacer.negative-55
@@ -86,12 +85,12 @@ block content
                         .col-xs-12
                             ol
                                 for challenge in challengeBlock.challenges
-                                    if completedChallengeList.indexOf(challenge.id || challenge._id) > -1
+                                    if challenge.completed
                                         .row
                                             .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.large-p.negative-10
                                             .col-xs-12.col-sm-9.col-md-10
                                                 li.faded.large-p.negative-10
-                                                    a(href="/challenges/#{challenge.dashedName}")= challenge.name
+                                                    a(href="/challenges/#{challenge.dashedName}")= challenge.title
 
                                     else
                                         .row
@@ -99,7 +98,7 @@ block content
                                                 span.negative-10
                                             .col-xs-12.col-sm-9.col-md-10
                                                 li.large-p.negative-10
-                                                    a(href="/challenges/#{challenge.dashedName}")= challenge.name
+                                                    a(href="/challenges/#{challenge.dashedName}")= challenge.title
 
     //#announcementModal.modal(tabindex='-1')
     //    .modal-dialog.animated.fadeInUp.fast-animation

From 5c987cbe9a8bd3e88369b3713e24207596da1075 Mon Sep 17 00:00:00 2001
From: Martin Kwan <martinkkwan@gmail.com>
Date: Mon, 10 Aug 2015 00:40:12 -0700
Subject: [PATCH 24/47] Updated Pig Latin Link

Updated link so it would open in a new tab instead of the current tab
---
 seed/challenges/intermediate-bonfires.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index a85f636..965767f 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -187,7 +187,7 @@
       "difficulty": "2.04",
       "description": [
         "Translate the provided string to pig latin.",
-        "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
+        "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target = "_blank">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
         "If a word begins with a vowel you just add \"way\" to the end.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],

From d56ecd197943dcac8ff7b2c673e91a90bbd72fe6 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 00:42:33 -0700
Subject: [PATCH 25/47] add a bunch of new images to onboarding

---
 server/views/resources/get-started.jade | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index d88692a..a2dde17 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -7,11 +7,11 @@ block content
             li.large-li.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/pYsTbjI.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Gtf8aIq.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Free Code Code camp is self-paced, browser-based, and free.
 
             hr
@@ -19,19 +19,19 @@ block content
             li.large-li.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rU7B4sn.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/dLx8nrg.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/yXyxbDd.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/PprMPUx.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EAR7Lvh.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
 
             hr
@@ -79,7 +79,7 @@ block content
             li.large-li.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/9NJfPQv.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
 
             hr
@@ -103,7 +103,7 @@ block content
             li.large-li.gif-caption Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Elb3dfj.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
 
             hr
@@ -127,7 +127,7 @@ block content
                 | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/6VtsD1K.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
 
             hr

From d7e824ebbefcbbafe294c24b4ee65e351e5c1356 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 00:44:37 -0700
Subject: [PATCH 26/47] done adding static images

---
 server/views/resources/get-started.jade | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index a2dde17..4623f56 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -131,7 +131,7 @@ block content
             li.large-li.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/99BfAcK.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
 
             hr
@@ -145,7 +145,7 @@ block content
                 | .
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rWeBOhF.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
 
         h2.text-center Nicely done. Now you have all the tools you need to succeed. Happy coding!

From aec86805679152971edf1a67a9fbae46a50aef51 Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Mon, 10 Aug 2015 14:42:02 +0200
Subject: [PATCH 27/47] Refactored CompletionMonitor() slightly

---
 seed/challenge-migration.js | 14 --------------
 seed/index.js               | 21 +++++++++++----------
 2 files changed, 11 insertions(+), 24 deletions(-)

diff --git a/seed/challenge-migration.js b/seed/challenge-migration.js
index 5c8fd01..7ef3597 100644
--- a/seed/challenge-migration.js
+++ b/seed/challenge-migration.js
@@ -8,20 +8,6 @@ var bonfires = require('./bonfires.json'),
   oldUri='mongodb://localhost:27017/app30893198',
   coursewares = require('./coursewares.json');
 
-var counter = 0;
-var offerings = 2;
-
-var CompletionMonitor = function() {
-  counter++;
-  console.log('call ' + counter);
-
-  if (counter < offerings) {
-    return;
-  } else {
-    process.exit(0);
-  }
-};
-
 MongoClient.connect(oldUri, function(err, database) {
 
   database.collection('users').find({}).batchSize(20).toArray(function(err, users) {
diff --git a/seed/index.js b/seed/index.js
index 3dbbf9d..8c46b77 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -17,18 +17,19 @@ var Nonprofit = app.models.Nonprofit;
 var Job = app.models.Job;
 var counter = 0;
 var challenges = getFilesFor('challenges');
-var offerings = 2 + challenges.length;
 
-var CompletionMonitor = function() {
+function completionMonitor() {
+  // Increment counter
   counter++;
-  console.log('call ' + counter);
 
-  if (counter < offerings) {
-    return;
-  } else {
+  // Exit if all challenges have been checked
+  if (counter > challenges.length) {
     process.exit(0);
   }
-};
+
+  // Log where in the seed order we're currently at
+  console.log('Call: ' + counter + "/" + challenges.length);
+}
 
 Challenge.destroyAll(function(err, info) {
   if (err) {
@@ -66,7 +67,7 @@ Challenge.destroyAll(function(err, info) {
           console.log(err);
         } else {
           console.log('Successfully parsed %s', file);
-          CompletionMonitor();
+          completionMonitor();
         }
       }
     );
@@ -85,7 +86,7 @@ Nonprofit.destroyAll(function(err, info) {
     } else {
       console.log('Saved ', data);
     }
-    CompletionMonitor();
+    completionMonitor();
     console.log('nonprofits');
   });
 });
@@ -103,6 +104,6 @@ Job.destroyAll(function(err, info) {
       console.log('Saved ', data);
     }
     console.log('jobs');
-    CompletionMonitor();
+    completionMonitor();
   });
 });

From 9513a8b0e5539d2fe851c1aa5121756b00a9715a Mon Sep 17 00:00:00 2001
From: ahstro <anton@lutic.org>
Date: Mon, 10 Aug 2015 20:08:14 +0200
Subject: [PATCH 28/47] Incorrect JSON caused error during seed

---
 seed/challenges/advanced-bonfires.json           | 12 ++++++------
 seed/challenges/upper-intermediate-bonfires.json | 10 +++++-----
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/seed/challenges/advanced-bonfires.json b/seed/challenges/advanced-bonfires.json
index 32e6848..6d67184 100644
--- a/seed/challenges/advanced-bonfires.json
+++ b/seed/challenges/advanced-bonfires.json
@@ -65,14 +65,14 @@
     },
     {
       "id": "a3f503de51cf954ede28891d",
-      "name": "Bonfire: Symmetric Difference",
-      "dashedName": "bonfire-symmetric-difference",
+      "title": "Symmetric Difference",
       "difficulty": "4.02",
       "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.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
+      "type": "bonfire",
       "challengeSeed": [
         "function sym(args) {",
         "  return arguments;",
@@ -104,8 +104,7 @@
     },
     {
       "id": "aa2e6f85cab2ab736c9a9b24",
-      "name": "Bonfire: Exact Change",
-      "dashedName": "bonfire-exact-change",
+      "title": "Exact Change",
       "difficulty": "4.03",
       "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.",
@@ -114,6 +113,7 @@
         "Otherwise, return change in coin and bills, sorted in highest to lowest order.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
+      "type": "bonfire",
       "challengeSeed": [
         "function drawer(price, cash, cid) {",
         "  var change;",
@@ -160,13 +160,13 @@
     },
     {
       "id": "a56138aff60341a09ed6c480",
-      "name": "Bonfire: Inventory Update",
-      "dashedName": "bonfire-inventory-update",
+      "title": "Inventory Update",
       "difficulty": "4.04",
       "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.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
+      "type": "bonfire",
       "challengeSeed": [
         "function inventory(arr1, arr2) {",
         "    // All inventory must be accounted for or you're fired!",
diff --git a/seed/challenges/upper-intermediate-bonfires.json b/seed/challenges/upper-intermediate-bonfires.json
index bfd765f..f99c278 100644
--- a/seed/challenges/upper-intermediate-bonfires.json
+++ b/seed/challenges/upper-intermediate-bonfires.json
@@ -4,8 +4,7 @@
   "challenges": [
     {
       "id": "a2f1d72d9b908d0bd72bb9f6",
-      "name": "Bonfire: Make a Person",
-      "dashedName": "bonfire-make-a-person",
+      "title": "Make a Person",
       "difficulty": "3.01",
       "description": [
         "Fill in the object constructor with the methods specified in the tests.",
@@ -14,6 +13,7 @@
         "These methods must be the only available means for interacting with the object.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
+      "type": "bonfire",
       "challengeSeed": [
         "var Person = function(firstAndLast) {",
         "    return firstAndLast;",
@@ -56,7 +56,7 @@
     },
     {
       "id": "af4afb223120f7348cdfc9fd",
-      "name": "Bonfire: Map the Debris",
+      "title": "Bonfire: Map the Debris",
       "dashedName": "bonfire-map-the-debris",
       "difficulty": "3.02",
       "description": [
@@ -97,8 +97,7 @@
     },
     {
       "id": "a3f503de51cfab748ff001aa",
-      "name": "Bonfire: Pairwise",
-      "dashedName": "bonfire-pairwise",
+      "title": "Pairwise",
       "difficulty": "3.03",
       "description": [
         "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
@@ -106,6 +105,7 @@
         "pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
+      "type": "bonfire",
       "challengeSeed": [
         "function pairwise(arr, arg) {",
         "  return arg;",

From 133c91fd16d2d2b42dfc3699904fa5c730d97b53 Mon Sep 17 00:00:00 2001
From: Brett Guillory <kurzweilfreak@gmail.com>
Date: Mon, 10 Aug 2015 13:20:18 -0500
Subject: [PATCH 29/47] Fix for incorrect RGB test value

RGB test value was testing for (0,0,255) which is B, should be testing for (0, 255,0), which is green.
---
 seed/challenges/jquery-ajax-and-json.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/jquery-ajax-and-json.json b/seed/challenges/jquery-ajax-and-json.json
index fa3f864..b024e4e 100644
--- a/seed/challenges/jquery-ajax-and-json.json
+++ b/seed/challenges/jquery-ajax-and-json.json
@@ -674,7 +674,7 @@
         "Here's an example of how you would use the <code>children()</code> function: <code>$('#left-well').children().css('color', 'blue')</code>"
       ],
       "tests": [
-        "assert($('#target6').css('color') === 'rgb(0, 0, 255)', 'Your \"target6\" element should have green text.')",
+        "assert($('#target6').css('color') === 'rgb(0, 255, 0), 'Your \"target6\" element should have green text.')",
         "assert(!editor.match(/\\.children\\(\\)\\.css/g), 'You should use the <code>children()</code> function to modify these elements.')",
         "assert(!editor.match(/<div class=\\'well\\' id=\\'right-well\\'>/g), 'Only use jQuery to add these classes to the element.')"
       ],

From 97b0ccac8fb2cc633e2b1a50050de6823a075f32 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 11:27:12 -0700
Subject: [PATCH 30/47] fix mising type remove extra bonfire in title

---
 seed/challenges/advanced-bonfires.json           | 7 +++----
 seed/challenges/upper-intermediate-bonfires.json | 7 ++++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/seed/challenges/advanced-bonfires.json b/seed/challenges/advanced-bonfires.json
index 6d67184..9748240 100644
--- a/seed/challenges/advanced-bonfires.json
+++ b/seed/challenges/advanced-bonfires.json
@@ -5,7 +5,6 @@
     {
       "id": "aff0395860f5d3034dc0bfc9",
       "title": "Validate US Telephone Numbers",
-      "type": "bonfire",
       "difficulty": "4.01",
       "description": [
         "Return true if the passed string is a valid US phone number",
@@ -51,6 +50,7 @@
       "MDNlinks": [
         "RegExp"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -72,7 +72,6 @@
         "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.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
-      "type": "bonfire",
       "challengeSeed": [
         "function sym(args) {",
         "  return arguments;",
@@ -90,6 +89,7 @@
         "Array.reduce()",
         "Symmetric Difference"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -113,7 +113,6 @@
         "Otherwise, return change in coin and bills, sorted in highest to lowest order.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
-      "type": "bonfire",
       "challengeSeed": [
         "function drawer(price, cash, cid) {",
         "  var change;",
@@ -146,6 +145,7 @@
       "MDNlinks": [
         "Global Object"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -166,7 +166,6 @@
         "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.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
-      "type": "bonfire",
       "challengeSeed": [
         "function inventory(arr1, arr2) {",
         "    // All inventory must be accounted for or you're fired!",
diff --git a/seed/challenges/upper-intermediate-bonfires.json b/seed/challenges/upper-intermediate-bonfires.json
index f99c278..104b031 100644
--- a/seed/challenges/upper-intermediate-bonfires.json
+++ b/seed/challenges/upper-intermediate-bonfires.json
@@ -13,7 +13,6 @@
         "These methods must be the only available means for interacting with the object.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
-      "type": "bonfire",
       "challengeSeed": [
         "var Person = function(firstAndLast) {",
         "    return firstAndLast;",
@@ -42,6 +41,7 @@
         "Closures",
         "Details of the Object Model"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -56,7 +56,7 @@
     },
     {
       "id": "af4afb223120f7348cdfc9fd",
-      "title": "Bonfire: Map the Debris",
+      "title": "Map the Debris",
       "dashedName": "bonfire-map-the-debris",
       "difficulty": "3.02",
       "description": [
@@ -83,6 +83,7 @@
       "MDNlinks": [
         "Math.pow()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],
@@ -105,7 +106,6 @@
         "pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
-      "type": "bonfire",
       "challengeSeed": [
         "function pairwise(arr, arg) {",
         "  return arg;",
@@ -123,6 +123,7 @@
       "MDNlinks": [
         "Array.reduce()"
       ],
+      "type": "bonfire",
       "challengeType": 5,
       "nameCn": "",
       "descriptionCn": [],

From 8dabd39950ee87dd7fcb3a4edb672a086a4883e8 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 12:14:38 -0700
Subject: [PATCH 31/47] add to seed script: exit on error filter challenge
 blocks that do not have challenges

---
 seed/index.js | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/seed/index.js b/seed/index.js
index 8c46b77..3830542 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -17,23 +17,25 @@ var Nonprofit = app.models.Nonprofit;
 var Job = app.models.Job;
 var counter = 0;
 var challenges = getFilesFor('challenges');
+// plus two accounts for nonprofits and jobs seed.
+var numberToSave = challenges.length + 1;
 
 function completionMonitor() {
   // Increment counter
   counter++;
 
   // Exit if all challenges have been checked
-  if (counter > challenges.length) {
+  if (counter >= numberToSave) {
     process.exit(0);
   }
 
   // Log where in the seed order we're currently at
-  console.log('Call: ' + counter + "/" + challenges.length);
+  console.log('Call: ' + counter + '/' + numberToSave);
 }
 
 Challenge.destroyAll(function(err, info) {
   if (err) {
-    console.error(err);
+    throw err;
   } else {
     console.log('Deleted ', info);
   }
@@ -42,6 +44,13 @@ Challenge.destroyAll(function(err, info) {
     var order = challengeSpec.order;
     var block = challengeSpec.name;
 
+    // challenge file has no challenges...
+    if (challengeSpec.challenges.length === 0) {
+      console.log('file %s has no challenges', file);
+      completionMonitor();
+      return;
+    }
+
     var challenges = challengeSpec.challenges
       .map(function(challenge, index) {
         // NOTE(berks): add title for displaying in views
@@ -64,10 +73,10 @@ Challenge.destroyAll(function(err, info) {
       challenges,
       function(err) {
         if (err) {
-          console.log(err);
+          throw err;
         } else {
           console.log('Successfully parsed %s', file);
-          completionMonitor();
+          completionMonitor(err);
         }
       }
     );
@@ -82,28 +91,28 @@ Nonprofit.destroyAll(function(err, info) {
   }
   Nonprofit.create(nonprofits, function(err, data) {
     if (err) {
-      console.log(err);
+      throw err;
     } else {
       console.log('Saved ', data);
     }
-    completionMonitor();
+    completionMonitor(err);
     console.log('nonprofits');
   });
 });
 
 Job.destroyAll(function(err, info) {
   if (err) {
-    console.error(err);
+    throw err;
   } else {
     console.log('Deleted ', info);
   }
   Job.create(jobs, function(err, data) {
     if (err) {
-      console.log(err);
+      console.log('error: ', err);
     } else {
       console.log('Saved ', data);
     }
     console.log('jobs');
-    completionMonitor();
+    completionMonitor(err);
   });
 });

From 737adf1facb91ad01591eed8893418d1127eb639 Mon Sep 17 00:00:00 2001
From: Martin Kwan <martinkkwan@gmail.com>
Date: Mon, 10 Aug 2015 13:42:33 -0700
Subject: [PATCH 32/47] Update intermediate-bonfires.json

---
 seed/challenges/intermediate-bonfires.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index 965767f..6a87b21 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -187,7 +187,7 @@
       "difficulty": "2.04",
       "description": [
         "Translate the provided string to pig latin.",
-        "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target = "_blank">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
+        "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target="_blank">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
         "If a word begins with a vowel you just add \"way\" to the end.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],

From 81af7a69e64c56475742b543babeca96bcaf75c2 Mon Sep 17 00:00:00 2001
From: Martin Kwan <martinkkwan@gmail.com>
Date: Mon, 10 Aug 2015 14:42:37 -0700
Subject: [PATCH 33/47] Updated DNA Pairing link

Updated link so it would open in a new tab instead of the current tab
---
 seed/challenges/intermediate-bonfires.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index a85f636..2187161 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -229,7 +229,7 @@
       "difficulty": "2.05",
       "description": [
         "The DNA strand is missing the pairing element. Match each character with the missing element and return the results as a 2d array.",
-        "<a href=\"http://en.wikipedia.org/wiki/Base_pair\">Base pairs</a> are a pair of AT and CG. Match the missing element to the provided character.",
+        "<a href=\"http://en.wikipedia.org/wiki/Base_pair\" target="_blank">Base pairs</a> are a pair of AT and CG. Match the missing element to the provided character.",
         "Return the provided character as the first element in each array.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],

From add87ae801e36c6bf38bd46945bf68a55c9fc067 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 15:10:38 -0700
Subject: [PATCH 34/47] start simplifying account page

---
 server/boot/user.js                     |  76 --------------
 server/views/account/account.jade       | 174 ++++++++++----------------------
 server/views/partials/navbar.jade       |   2 +-
 server/views/resources/get-started.jade |  28 ++---
 4 files changed, 71 insertions(+), 209 deletions(-)

diff --git a/server/boot/user.js b/server/boot/user.js
index aa925e6..6afddc9 100644
--- a/server/boot/user.js
+++ b/server/boot/user.js
@@ -44,9 +44,7 @@ module.exports = function(app) {
   router.post('/reset/:token', postReset);
   router.get('/email-signup', getEmailSignup);
   router.get('/email-signin', getEmailSignin);
-
   router.get('/account/api', getAccountAngular);
-  router.post('/account/profile', postUpdateProfile);
   router.post('/account/password', postUpdatePassword);
   router.post('/account/delete', postDeleteAccount);
   router.get('/account/unlink/:provider', getOauthUnlink);
@@ -186,80 +184,6 @@ module.exports = function(app) {
   }
 
   /**
-  * POST /account/profile
-  * Update profile information.
-  */
-
-  function postUpdateProfile(req, res, next) {
-
-    User.findById(req.user.id, function(err) {
-      if (err) { return next(err); }
-      var errors = req.validationErrors();
-      if (errors) {
-        req.flash('errors', errors);
-        return res.redirect('/account');
-      }
-
-      User.findOne({
-        where: { email: req.body.email }
-      }, function(err, existingEmail) {
-        if (err) {
-          return next(err);
-        }
-        var user = req.user;
-        if (existingEmail && existingEmail.email !== user.email) {
-          req.flash('errors', {
-            msg: 'An account with that email address already exists.'
-          });
-          return res.redirect('/account');
-        }
-        User.findOne(
-          { where: { username: req.body.username } },
-          function(err, existingUsername) {
-            if (err) {
-              return next(err);
-            }
-            var user = req.user;
-            if (
-              existingUsername &&
-              existingUsername.username !== user.username
-            ) {
-              req.flash('errors', {
-                msg: 'An account with that username already exists.'
-              });
-              return res.redirect('/account');
-            }
-            var body = req.body || {};
-            user.facebookProfile = body.facebookProfile.trim() || '';
-            user.linkedinProfile = body.linkedinProfile.trim() || '';
-            user.codepenProfile = body.codepenProfile.trim() || '';
-            user.twitterHandle = body.twitterHandle.trim() || '';
-            user.bio = body.bio.trim() || '';
-
-            user.save(function(err) {
-              if (err) {
-                return next(err);
-              }
-              updateUserStoryPictures(
-                user.id.toString(),
-                user.picture,
-                user.username,
-                function(err) {
-                  if (err) { return next(err); }
-                  req.flash('success', {
-                    msg: 'Profile information updated.'
-                  });
-                  res.redirect('/account');
-                }
-              );
-            });
-          }
-        );
-      });
-    });
-  }
-
-  /**
   * POST /account/password
   * Update current password.
   */
diff --git a/server/views/account/account.jade b/server/views/account/account.jade
index 54c423d..526b604 100644
--- a/server/views/account/account.jade
+++ b/server/views/account/account.jade
@@ -8,13 +8,9 @@ block content
             if (!user.isGithubCool)
               .row
                 .col-xs-12
-                  .text-left.btn-info.btn.btn-block.btn-link-social(href='http://www.freecodecamp.com/challenges/waypoint-join-our-chat-room')
-                    span Link your account to GitHub to update your portfolio page. Click here if you don’t have a GitHub account yet.
-              .row
-                .col-xs-12
                   a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
                       i.fa.fa-github
-                      | Link GitHub with my account
+                      | Link GitHub to unlock profile
             else
               .row
                 .col-xs-12
@@ -22,117 +18,59 @@ block content
                       i.fa.fa-github
                       | Update Github Info
 
-            .row
-              .col-xs-12
-                form.form-horizontal(action='/account/profile', method='POST', novalidate='novalidate', name='profileForm' ng-show="asyncComplete")
-                  input(type='hidden', name='_csrf', value=_csrf)
-                  .form-group
-                    label.col-sm-3.col-sm-offset-1.control-label(for='bio') Bio (140 characters)
-                    .col-sm-4
-                      input.form-control(type='text', name='bio', autocomplete="off", ng-model='user.bio', ng-maxlength='140', id='bio')
-                    .col-sm-4.col-sm-offset-5(ng-cloak, ng-show='profileForm.bio.$error.maxlength && !profileForm.bio.$pristine')
-                      alert(type='danger')
-                        span.ion-close-circled
-                        | Your bio must be fewer than 140 characters.
-                  .form-group
-                    label.col-sm-3.col-sm-offset-1.control-label(for='email') Twitter
-                    .col-sm-4
-                      .input-group.twitter-input
-                          span.input-group-addon @
-                          input.form-control(type='text', name='twitterHandle', autocomplete="off", id='twitterHandle', ng-model='user.twitterHandle', ng-maxlength='15', ng-pattern="/^[A-z0-9_]+$/")
-                    .col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.twitterHandle.$error.pattern")
-                      alert(type='danger')
-                          span.ion-close-circled
-                          | Your Twitter handle should only contain letters, numbers and underscores (az10_).
-                    .col-sm-4.col-sm-offset-5(ng-cloak, ng-show='profileForm.twitterHandle.$error.maxlength && !profileForm.twitterHandle.$pristine')
-                      alert(type='danger')
-                          span.ion-close-circled
-                          |  Your name must be fewer than 15 characters.
-
-                  .form-group
-                    label.col-sm-3.col-sm-offset-1.control-label(for='email') CodePen
-                    .col-sm-4
-                      input.form-control(type='url', name='codepenProfile', id='codepenProfile', autocomplete="off", ng-model='user.codepenProfile', placeholder='http://')
-                    .col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.codepenProfile.$error.url && !profileForm.codepenProfile.$pristine")
-                      alert(type='danger')
-                        span.ion-close-circled
-                        | Please enter a valid URL format (http://www.example.com).
-
-                  .form-group
-                    label.col-sm-3.col-sm-offset-1.control-label(for='email') LinkedIn
-                    .col-sm-4
-                      input.form-control(type='url', name='linkedinProfile', id='linkedinProfile', autocomplete="off", ng-model='user.linkedinProfile', placeholder='http://')
-                    .col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.linkedinProfile.$error.url && !profileForm.linkedinProfile.$pristine")
-                      alert(type='danger')
-                        span.ion-close-circled
-                        | Please enter a valid URL format (http://www.example.com).
+                  if (!user.twitter)
+                      .col-xs-12
+                          a.btn.btn-lg.btn-block.btn-twitter.btn-link-social.disabled(href='#')
+                              i.fa.fa-twitter
+                              | Add my Twitter to my profile
+                  if (!user.google)
+                      .col-xs-12
+                          a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social.disabled(href='#')
+                              i.fa.fa-google-plus
+                              | Add my Google+ to my profile
+                  if (!user.facebook)
+                      .col-xs-12
+                          a.btn.btn-lg.btn-block.btn-facebook.btn-link-social.disabled(href='#')
+                              i.fa.fa-facebook
+                              | Add my Facebook to my profile
+                  if (!user.linkedin)
+                      .col-xs-12
+                          a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social.disabled(href='#')
+                              i.fa.fa-linkedin
+                              | Add my LinkedIn to my profile
 
-                  .form-group
-                    label.col-sm-3.col-sm-offset-1.control-label(for='email') Facebook
-                    .col-sm-4
-                      input.form-control(type='url', name='facebookProfile', id='facebookProfile', autocomplete="off", ng-model='user.facebookProfile', placeholder='http://')
-                    .col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.facebookProfile.$error.url && !profileForm.facebookProfile.$pristine")
-                      alert(type='danger')
-                        span.ion-close-circled
-                        | Please enter a valid URL format (http://www.example.com).
-
-                  button.btn.btn-lg.btn-block.btn-primary.btn-link-social(type='submit', ng-disabled='!user.isGithubCool || profileForm.$invalid')
-                      span.ion-edit
-                      | Update my info
-
-    .panel.panel-info
-        .panel-heading.text-center Manage your account here:
-        .panel-body
-            if (!user.google || !user.facebook || !user.linkedin || !user.twitter)
-                if (!user.twitter)
-                    .col-xs-12
-                        a.btn.btn-lg.btn-block.btn-twitter.btn-link-social.disabled(href='#')
-                            i.fa.fa-twitter
-                            | Link Twitter with my account
-                if (!user.google)
-                    .col-xs-12
-                        a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social.disabled(href='#')
-                            i.fa.fa-google-plus
-                            | Link Google with my account
-                if (!user.facebook)
-                    .col-xs-12
-                        a.btn.btn-lg.btn-block.btn-facebook.btn-link-social.disabled(href='#')
-                            i.fa.fa-facebook
-                            | Link Facebook with my account
-                if (!user.linkedin)
-                    .col-xs-12
-                        a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social.disabled(href='#')
-                            i.fa.fa-linkedin
-                            | Link LinkedIn with my account
-            .col-xs-12
-                a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
-                    span.ion-android-exit
-                    | Sign me out of Free Code Camp
-            .col-xs-12
-                a.btn.btn-lg.btn-block.btn-danger.confirm-deletion.btn-link-social
-                    span.ion-trash-b
-                    | Delete my Free Code Camp account
-                script.
-                    $('.confirm-deletion').on("click", function() {
-                      $('#modal-dialog').modal('show');
-                    });
-                #modal-dialog.modal.animated.wobble
-                    .modal-dialog
-                        .modal-content
-                            .modal-header
-                                a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
-                                h3 Are you really leaving us?
-                            .modal-body
-                                p Pro Tip: If you tweet feedback to&thinsp;
-                                    a(href="https://twitter.com/intent/tweet?text=Hey%20@freecodecamp") @FreeCodeCamp
-                                    | ,&thinsp;we'll act quickly on it!
-                            .modal-footer
-                                a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
-                                    span.ion-happy
-                                    | Nevermind, I'll stick around
-                                br
-                                form(action='/account/delete', method='POST')
-                                    input(type='hidden', name='_csrf', value=_csrf)
-                                    button.btn.btn-danger.btn-block(type='submit')
-                                        span.ion-trash-b
-                                        | Yes, Delete my account
+            .spacer
+            .spacer
+            .row
+                .col-xs-6.col-sm-4.col-sm-offset-2
+                    a.btn.btn-warning.btn-block.btn-link-social(href='/logout')
+                        span.ion-android-exit
+                        | Sign me out of Free Code Camp
+                .col-xs-6.col-sm-4
+                    a.btn.btn-danger.btn-block.confirm-deletion.btn-link-social
+                        span.ion-trash-b
+                        | Delete my Free Code Camp account
+                    script.
+                        $('.confirm-deletion').on("click", function() {
+                          $('#modal-dialog').modal('show');
+                        });
+                    #modal-dialog.modal.animated.wobble
+                        .modal-dialog
+                            .modal-content
+                                .modal-header
+                                    a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
+                                    h3 Are you really leaving us?
+                                .modal-body
+                                    p Pro Tip: If you tweet feedback to&thinsp;
+                                        a(href="https://twitter.com/intent/tweet?text=Hey%20@freecodecamp") @FreeCodeCamp
+                                        | ,&thinsp;we'll act quickly on it!
+                                .modal-footer
+                                    a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
+                                        span.ion-happy
+                                        | Nevermind, I'll stick around
+                                    br
+                                    form(action='/account/delete', method='POST')
+                                        input(type='hidden', name='_csrf', value=_csrf)
+                                        button.btn.btn-danger.btn-block(type='submit')
+                                            span.ion-trash-b
+                                            | Yes, Delete my account
diff --git a/server/views/partials/navbar.jade b/server/views/partials/navbar.jade
index 85996b9..d7861a2 100644
--- a/server/views/partials/navbar.jade
+++ b/server/views/partials/navbar.jade
@@ -4,7 +4,7 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height
             .col-xs-12
                 span.hamburger-text Menu
         a.navbar-brand(href='/')
-            img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg.gz', alt='learn to code javascript at Free Code Camp logo')
+            img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
     .collapse.navbar-collapse
         ul.nav.navbar-nav.navbar-right.hamburger-dropdown
             li
diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index 4623f56..5dd112a 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -45,20 +45,20 @@ block content
             li.large-li.gif-caption Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/nHtblsq.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption
                 a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
                 | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/.jpg' alt='a gif showing how to install this')
             li.large-li.gif-caption Now that you have a GitHub account, you can&thinsp;
                 a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by authenticating with GitHub
-                | .
+                | . Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuCW6SliIRINoxEuAxLiTplYPralqtcHLQB/image.png' alt='a gif showing how to install this')
+            li.large-li.gif-caption Our chat rooms are extremely active so you probably want to turn off notifications.
 
             hr
             img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
@@ -69,13 +69,13 @@ block content
             li.large-li.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Ant4DdieE8tAK4kYWBxoNOL33ADbJeMBsjEB/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption
                 a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
                 | .
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnvXOQTSV1lKoJVwGK04sExskCXqLyLmM54B/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
 
             hr
@@ -83,7 +83,7 @@ block content
             li.large-li.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Anv5CKnYXa5HGpBllbf1HRp0QgUc0rv5yTwB/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
 
             hr
@@ -99,7 +99,7 @@ block content
             li.large-li.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnspWLymUEpJBZR6LvSCoBJFkn06NLa-GygB/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
 
             hr
@@ -107,7 +107,7 @@ block content
             li.large-li.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption
                 a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
                 | . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
@@ -115,13 +115,13 @@ block content
                 | .
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption
                 a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
                 | and click "Gitter" to join your city's chat room.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Anv-oGsT2wpH962kQu65XdL00BOP591gia8B/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption You can&thinsp;
                 a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
                 | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
@@ -135,11 +135,11 @@ block content
             li.large-li.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Anse5JAKH0VFKLL6EiCzJHFXvJpTidGLszQB/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
 
             hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AHQRHsEhUsRNwpNHtw-nwYEj5Oj5AKTC678B/image.png' alt='a gif showing how to install this')
             li.large-li.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
                 a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
                 | .

From f8665324ad4afc5db7f47d50f5091f418347a13e Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 15:37:49 -0700
Subject: [PATCH 35/47] simplify user account and profile system for github
 locking

---
 server/boot/user.js               |  10 ++--
 server/views/account/account.jade | 101 ++++++++++++++++++++------------------
 server/views/account/show.jade    |  20 ++++----
 3 files changed, 67 insertions(+), 64 deletions(-)

diff --git a/server/boot/user.js b/server/boot/user.js
index 6afddc9..77cd45d 100644
--- a/server/boot/user.js
+++ b/server/boot/user.js
@@ -165,11 +165,11 @@ module.exports = function(app) {
           isMigrationGrandfathered: user.isMigrationGrandfathered,
           isGithubCool: user.isGithubCool,
           location: user.location,
-          githubProfile: user.githubProfile,
-          linkedinProfile: user.linkedinProfile,
-          codepenProfile: user.codepenProfile,
-          facebookProfile: user.facebookProfile,
-          twitterHandle: user.twitterHandle,
+          githubProfile: user.github,
+          linkedinProfile: user.linkedin,
+          googleProfile: user.google,
+          facebookProfile: user.facebook,
+          twitterHandle: user.twitter,
           bio: user.bio,
           picture: user.picture,
           progressTimestamps: user.progressTimestamps,
diff --git a/server/views/account/account.jade b/server/views/account/account.jade
index 526b604..db839fe 100644
--- a/server/views/account/account.jade
+++ b/server/views/account/account.jade
@@ -3,74 +3,77 @@ block content
     script.
         var challengeName = 'Account View'
     .panel.panel-info(ng-controller="profileValidationController")
-        .panel-heading.text-center Update your portfolio here:
+        .panel-heading.text-center Manage your account here
         .panel-body
             if (!user.isGithubCool)
               .row
                 .col-xs-12
-                  a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
+                  a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
                       i.fa.fa-github
-                      | Link GitHub to unlock profile
+                      | Link my GitHub to unlock this profile
             else
               .row
                 .col-xs-12
-                  a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
+                  a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
                       i.fa.fa-github
-                      | Update Github Info
+                      | Update my profile from Github
 
                   if (!user.twitter)
                       .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-twitter.btn-link-social.disabled(href='#')
+                          a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
                               i.fa.fa-twitter
                               | Add my Twitter to my profile
-                  if (!user.google)
-                      .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social.disabled(href='#')
-                              i.fa.fa-google-plus
-                              | Add my Google+ to my profile
                   if (!user.facebook)
                       .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-facebook.btn-link-social.disabled(href='#')
+                          a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
                               i.fa.fa-facebook
                               | Add my Facebook to my profile
                   if (!user.linkedin)
                       .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social.disabled(href='#')
+                          a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
                               i.fa.fa-linkedin
                               | Add my LinkedIn to my profile
-
-            .spacer
-            .spacer
-            .row
-                .col-xs-6.col-sm-4.col-sm-offset-2
-                    a.btn.btn-warning.btn-block.btn-link-social(href='/logout')
-                        span.ion-android-exit
-                        | Sign me out of Free Code Camp
-                .col-xs-6.col-sm-4
-                    a.btn.btn-danger.btn-block.confirm-deletion.btn-link-social
-                        span.ion-trash-b
-                        | Delete my Free Code Camp account
-                    script.
-                        $('.confirm-deletion').on("click", function() {
-                          $('#modal-dialog').modal('show');
-                        });
-                    #modal-dialog.modal.animated.wobble
-                        .modal-dialog
-                            .modal-content
-                                .modal-header
-                                    a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
-                                    h3 Are you really leaving us?
-                                .modal-body
-                                    p Pro Tip: If you tweet feedback to&thinsp;
-                                        a(href="https://twitter.com/intent/tweet?text=Hey%20@freecodecamp") @FreeCodeCamp
-                                        | ,&thinsp;we'll act quickly on it!
-                                .modal-footer
-                                    a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
-                                        span.ion-happy
-                                        | Nevermind, I'll stick around
-                                    br
-                                    form(action='/account/delete', method='POST')
-                                        input(type='hidden', name='_csrf', value=_csrf)
-                                        button.btn.btn-danger.btn-block(type='submit')
-                                            span.ion-trash-b
-                                            | Yes, Delete my account
+                  if (!user.google)
+                      .col-xs-12
+                          a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
+                              i.fa.fa-google-plus
+                              | Add my Google+ to my profile
+              .spacer
+              hr
+              .spacer
+              .col-xs-12
+                a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
+                    span.ion-android-exit
+                    | Sign me out of Free Code Camp
+              .col-xs-12
+                a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com')
+                    span.ion-email
+                    | Email us at team@freecodecamp.com
+              .col-xs-12
+                a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion
+                    span.ion-trash-b
+                    | Delete my Free Code Camp account
+                script.
+                    $('.confirm-deletion').on("click", function() {
+                      $('#modal-dialog').modal('show');
+                    });
+                #modal-dialog.modal.animated.wobble
+                    .modal-dialog
+                        .modal-content
+                            .modal-header
+                                a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
+                                h3 Are you really leaving us?
+                            .modal-body
+                                p Pro Tip: If you tweet feedback to&thinsp;
+                                    a(href="https://twitter.com/intent/tweet?text=Hey%20@freecodecamp") @FreeCodeCamp
+                                    | ,&thinsp;we'll act quickly on it!
+                            .modal-footer
+                                a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
+                                    span.ion-happy
+                                    | Nevermind, I'll stick around
+                                br
+                                form(action='/account/delete', method='POST')
+                                    input(type='hidden', name='_csrf', value=_csrf)
+                                    button.btn.btn-danger.btn-block(type='submit')
+                                        span.ion-trash-b
+                                        | Yes, Delete my account
diff --git a/server/views/account/show.jade b/server/views/account/show.jade
index bc65c80..87e5d82 100644
--- a/server/views/account/show.jade
+++ b/server/views/account/show.jade
@@ -23,16 +23,16 @@ block content
                         else
                             img.img-center.img-responsive.public-profile-img(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png')
                         h1.text-center.negative-5.profile-social-icons
-                            if (twitterHandle)
-                                a.fa.fa-twitter-square.text-primary(title="@#{username}'s Twitter Profile", href="http://twitter.com/#{twitterHandle}", target='_blank')
-                            if (githubProfile)
-                                a.fa.fa-github-square.text-primary(title="@#{username}'s GitHub Profile", href=githubProfile, target='_blank')
-                            if (codepenProfile)
-                                a.ion-social-codepen.text-primary(title="@#{username}'s CodePen Profile", href=codepenProfile, target='_blank')
-                            if (linkedinProfile)
-                                a.fa.fa-linkedin-square.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedinProfile, target='_blank')
-                            if (facebookProfile)
-                                a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href=facebookProfile, target='_blank')
+                            if (twitter)
+                                a.fa.fa-twitter-square.text-primary(title="@#{username}'s Twitter Profile", href=twitter, target='_blank')
+                            if (github)
+                                a.fa.fa-github-square.text-primary(title="@#{username}'s GitHub Profile", href=github, target='_blank')
+                            if (linkedin)
+                                a.fa.fa-linkedin-square.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedin, target='_blank')
+                            if (facebook)
+                                a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href=facebook, target='_blank')
+                            if (google)
+                                a.fa.fa-google-square.text-primary(title="@#{username}'s Google Profile", href=google, target='_blank')
                     .visible-md.visible-lg
                         .col-xs-12.col-sm-12.col-md-4.text-justify
                             h1.flat-top.wrappable= name

From 234aa0a5eaa7fcc90b6e3d5274b3febafd1a53e0 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 17:35:16 -0700
Subject: [PATCH 36/47] fix missing quote escape

---
 seed/challenges/intermediate-bonfires.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/seed/challenges/intermediate-bonfires.json b/seed/challenges/intermediate-bonfires.json
index 1f2c681..743f4d2 100644
--- a/seed/challenges/intermediate-bonfires.json
+++ b/seed/challenges/intermediate-bonfires.json
@@ -187,7 +187,7 @@
       "difficulty": "2.04",
       "description": [
         "Translate the provided string to pig latin.",
-        "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target="_blank">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
+        "<a href=\"http://en.wikipedia.org/wiki/Pig_Latin\" target=\"_blank\">Pig Latin</a> takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an \"ay\".",
         "If a word begins with a vowel you just add \"way\" to the end.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],
@@ -229,7 +229,7 @@
       "difficulty": "2.05",
       "description": [
         "The DNA strand is missing the pairing element. Match each character with the missing element and return the results as a 2d array.",
-        "<a href=\"http://en.wikipedia.org/wiki/Base_pair\" target="_blank">Base pairs</a> are a pair of AT and CG. Match the missing element to the provided character.",
+        "<a href=\"http://en.wikipedia.org/wiki/Base_pair\" target=\"_blank\">Base pairs</a> are a pair of AT and CG. Match the missing element to the provided character.",
         "Return the provided character as the first element in each array.",
         "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
       ],

From d67c049d5baeccaffeefe1a953da789f7003987e Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 17:40:13 -0700
Subject: [PATCH 37/47] make onboarding page the default homepage for
 authenticated users

---
 public/css/main.less                    |   4 +
 server/boot/home.js                     |  17 +-
 server/views/resources/get-started.jade | 303 +++++++++++++++++---------------
 3 files changed, 173 insertions(+), 151 deletions(-)

diff --git a/public/css/main.less b/public/css/main.less
index d03c73f..f23a5b1 100644
--- a/public/css/main.less
+++ b/public/css/main.less
@@ -1034,6 +1034,10 @@ hr {
   margin: 18px 0;
 }
 
+.big-spacer {
+  padding: 30px 0 30px 0;
+}
+
 #reply-to-main-post, #upvote {
   cursor: pointer;
 }
diff --git a/server/boot/home.js b/server/boot/home.js
index 2a75265..1e40fb0 100644
--- a/server/boot/home.js
+++ b/server/boot/home.js
@@ -10,13 +10,18 @@ module.exports = function(app) {
   app.use(router);
 
   function index(req, res, next) {
-    if (req.user && !req.user.picture) {
-      req.user.picture = defaultProfileImage;
+    if (req.user)
+      if (!req.user.picture) {
+        req.user.picture = defaultProfileImage;
 
-      req.user.save(function(err) {
-        if (err) { return next(err); }
-        res.render('home', { title: message });
-      });
+        req.user.save(function (err) {
+          if (err) {
+            return next(err);
+          }
+          res.render('get-started', {title: message});
+        });
+      } else {
+      res.render('resources/get-started', {title: message});
     } else {
       res.render('home', { title: message });
     }
diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index 5dd112a..5dd1ac3 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -2,151 +2,164 @@ extends ../layout
 block content
     .jumbotron
         h2.text-center Do these steps to get ready for Free Code Camp (this only takes 10 minutes):
-        ol
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/pYsTbjI.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Gtf8aIq.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Free Code Code camp is self-paced, browser-based, and free.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/dLx8nrg.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/yXyxbDd.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/PprMPUx.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EAR7Lvh.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.i.imgur.com/WAxbGZE.gif' alt='a gif showing how to install this')
-            li.large-li.gif-caption
-                a(href='https://github.com/join' target='_blank') Create an account with GitHub
-                | . This will be private, so you should use your real email address.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/nHtblsq.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption
-                a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
-                | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Now that you have a GitHub account, you can&thinsp;
-                a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by authenticating with GitHub
-                | . Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuCW6SliIRINoxEuAxLiTplYPralqtcHLQB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption Our chat rooms are extremely active so you probably want to turn off notifications.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Ant4DdieE8tAK4kYWBxoNOL33ADbJeMBsjEB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption
-                a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
-                | .
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnvXOQTSV1lKoJVwGK04sExskCXqLyLmM54B/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/9NJfPQv.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Anv5CKnYXa5HGpBllbf1HRp0QgUc0rv5yTwB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Let's check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption You can also add a short bio, and links to your social media profiles.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnspWLymUEpJBZR6LvSCoBJFkn06NLa-GygB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Elb3dfj.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption
-                a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
-                | . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
-                a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
-                | .
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption
-                a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
-                | and click "Gitter" to join your city's chat room.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Anv-oGsT2wpH962kQu65XdL00BOP591gia8B/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption You can&thinsp;
-                a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
-                | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/6VtsD1K.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/99BfAcK.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/Anse5JAKH0VFKLL6EiCzJHFXvJpTidGLszQB/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
-
-            hr
-            img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AHQRHsEhUsRNwpNHtw-nwYEj5Oj5AKTC678B/image.png' alt='a gif showing how to install this')
-            li.large-li.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
-                a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
-                | .
-
-            hr
-            img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rWeBOhF.jpg' alt='a gif showing how to install this')
-            li.large-li.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/pYsTbjI.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Gtf8aIq.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Free Code Code camp is self-paced, browser-based, and free.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/dLx8nrg.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/yXyxbDd.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/PprMPUx.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EAR7Lvh.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/sign-up-for-github.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            a(href='https://github.com/join' target='_blank') Create an account with GitHub
+            | . Be sure to use your real email address - GitHub will keep this private.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/github-profile.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/star-repository.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
+            | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/join-gitter.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Now that you have a GitHub account, you can&thinsp;
+            a(href='https://gitter.im/FreeCodeCamp/FreeCodeCamp' target='_blank') join our main chat room by logging in with GitHub
+            | . Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/gitter-notifications.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Our chat rooms are extremely active. You should change your settings so you're only notified if someone mentions you.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/private-messages.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/keep-chat-open.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/download-gitter-app.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
+            | .
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/challenge-map.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/9NJfPQv.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/wiki.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/camper-news.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            | Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Elb3dfj.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/join-facebook-group.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            span.text-info Try this:&thinsp;
+            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
+            | . Click the "Join group" button to join your city's Facebook group. If your city isn't on this list,&thinsp;
+            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/How-to-create-a-Campsite-for-your-city' target='_blank') follow these directions to create a Facebook group for your city
+            | .
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
+        p.large-p.gif-caption
+            a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
+            | and click "Gitter" to join your city's chat room.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/add-linkedin.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption You can&thinsp;
+            a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
+            | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/6VtsD1K.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/99BfAcK.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/google-search.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/ask-for-help.gif' alt='a gif showing how to install this')
+        p.large-p.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
+            a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
+            | .
+
+        .big-spacer
+        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rWeBOhF.jpg' alt='a gif showing how to install this')
+        p.large-p.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
 
         h2.text-center Nicely done. Now you have all the tools you need to succeed. Happy coding!
         a.btn.btn-cta.signup-btn.btn-block(href="/map") Take me to my Challenge Map

From 4b0e95280d8826745ca00735aeca435c570bdfbe Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 17:40:45 -0700
Subject: [PATCH 38/47] fix duplicate id's

---
 seed/challenges/expert-bonfires.json | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
index 06ab698..13bbd96 100644
--- a/seed/challenges/expert-bonfires.json
+++ b/seed/challenges/expert-bonfires.json
@@ -3,7 +3,7 @@
   "order": 0.013,
   "challenges": [
     {
-      "id": "aff0395860f5d3034dc0bfc9",
+      "id": "aff0495970f5d3034dc0bfc9",
       "title": "Validate US Telephone Numbers",
       "difficulty": "4.01",
       "description": [
@@ -64,7 +64,7 @@
       "descriptionPt": []
     },
     {
-      "id": "a3f503de51cf954ede28891d",
+      "id": "a3f512de51cf954ede28891d",
       "title": "Symmetric Difference",
       "difficulty": "4.02",
       "description": [
@@ -103,7 +103,7 @@
       "descriptionPt": []
     },
     {
-      "id": "aa2e6f85cab2ab736c9a9b24",
+      "id": "aa2e6f96cab3ab736c9a9b24",
       "title": "Exact Change",
       "difficulty": "4.03",
       "description": [
@@ -159,7 +159,7 @@
       "descriptionPt": []
     },
     {
-      "id": "a56138aff60341a09ed6c480",
+      "id": "a56244aff60341a09ed6c480",
       "title": "Inventory Update",
       "difficulty": "4.04",
       "description": [
@@ -214,7 +214,7 @@
       "descriptionPt": []
     },
     {
-      "id": "a7bf700cd123b9a54eef01d5",
+      "id": "a8bf800cd123b9a54eef01d5",
       "title": "No repeats please",
       "difficulty": "4.05",
       "description": [
@@ -256,7 +256,7 @@
       "descriptionPt": []
     },
     {
-      "id": "a19f0fbe1872186acd434d5a",
+      "id": "a19f0fbe1872186acd434d54",
       "title": "Friendly Date Ranges",
       "difficulty": "4.06",
       "description": [

From 8a1694203675e872c4eb50cbbda5ac21ab1e8ae5 Mon Sep 17 00:00:00 2001
From: sonorangirl <manahan.erin@gmail.com>
Date: Mon, 10 Aug 2015 18:05:07 -0700
Subject: [PATCH 39/47] Fixed typos in 1st slot machine challenge

---
 seed/challenges/basic-javascript.json | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index c8cd704..04fd44d 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -1071,16 +1071,16 @@
       "title": "Create a JavaScript Slot Machine",
       "difficulty":"9.988",
       "description":[
-        "We are now going to try and combine some of the stuff we've just learnt abd create the logic for a slot machine game",
+        "We are now going to try and combine some of the stuff we've just learned and create the logic for a slot machine game",
         "For this we will need to generate three random numbers between <code>1</code> and <code>5</code> to represent the possible values of each individual slot",
         "Store the three random numbers in <code>slotOne</code>, <code>slotTwo</code> and <code>slotThree</code>",
         "Generate the random numbers by using the system we used earlier in /challenges/random-whole-numbers-in-a-range",
         "<code>Math.floor(Math.random() * (5 - 1 + 1)) + 1; </code>"
       ],
       "tests":[
-        "assert(typeof(runSlots($('.slot'))[0]) == 'number', 'SlotOne should be a random number');",
-        "assert(typeof(runSlots($('.slot'))[1]) == 'number', 'SlotTwo should be a random number');",
-        "assert(typeof(runSlots($('.slot'))[2]) == 'number', 'SlotThree should be a random number');",
+        "assert(typeof(runSlots($('.slot'))[0]) == 'number', 'slotOne should be a random number');",
+        "assert(typeof(runSlots($('.slot'))[1]) == 'number', 'slotTwo should be a random number');",
+        "assert(typeof(runSlots($('.slot'))[2]) == 'number', 'slotThree should be a random number');",
         "assert((function(){if(editor.match(/Math.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi) !== null){return(editor.match(/Math.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi).length >= 3);}else{return(false);}})(), 'You should have used Math.floor(Math.random() * (5 - 1 + 1)) + 1; three times to generate your random numbers');"
       ],
       "challengeSeed":[

From 8efe8ee825b2f22e3aa6a41d595b9ebb63e7b8ca Mon Sep 17 00:00:00 2001
From: sonorangirl <manahan.erin@gmail.com>
Date: Mon, 10 Aug 2015 19:22:18 -0700
Subject: [PATCH 40/47] Fixed RegEx so that 4th test would pass

---
 seed/challenges/basic-javascript.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index 04fd44d..7834110 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -1081,7 +1081,7 @@
         "assert(typeof(runSlots($('.slot'))[0]) == 'number', 'slotOne should be a random number');",
         "assert(typeof(runSlots($('.slot'))[1]) == 'number', 'slotTwo should be a random number');",
         "assert(typeof(runSlots($('.slot'))[2]) == 'number', 'slotThree should be a random number');",
-        "assert((function(){if(editor.match(/Math.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi) !== null){return(editor.match(/Math.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi).length >= 3);}else{return(false);}})(), 'You should have used Math.floor(Math.random() * (5 - 1 + 1)) + 1; three times to generate your random numbers');"
+        "assert((function(){if(editor.match(/Math\\.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi) !== null){return(editor.match(/Math\\.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi).length >= 3);}else{return(false);}})(), 'You should have used Math.floor(Math.random() * (5 - 1 + 1)) + 1; three times to generate your random numbers');"
       ],
       "challengeSeed":[
         "fccss",

From fb44b50941a575781e815223ace36da9a6dd3f04 Mon Sep 17 00:00:00 2001
From: sonorangirl <manahan.erin@gmail.com>
Date: Mon, 10 Aug 2015 19:32:52 -0700
Subject: [PATCH 41/47] Made some spaces optional for 4th test

---
 seed/challenges/basic-javascript.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json
index 7834110..0aa6f4f 100644
--- a/seed/challenges/basic-javascript.json
+++ b/seed/challenges/basic-javascript.json
@@ -1081,7 +1081,7 @@
         "assert(typeof(runSlots($('.slot'))[0]) == 'number', 'slotOne should be a random number');",
         "assert(typeof(runSlots($('.slot'))[1]) == 'number', 'slotTwo should be a random number');",
         "assert(typeof(runSlots($('.slot'))[2]) == 'number', 'slotThree should be a random number');",
-        "assert((function(){if(editor.match(/Math\\.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi) !== null){return(editor.match(/Math\\.floor\\(Math\\.random\\(\\)\\s\\*\\s\\(5\\s\\-\\s1\\s\\+\\s1\\)\\)\\s\\+\\s1;/gi).length >= 3);}else{return(false);}})(), 'You should have used Math.floor(Math.random() * (5 - 1 + 1)) + 1; three times to generate your random numbers');"
+        "assert((function(){if(editor.match(/Math\\.floor\\(\\s?Math\\.random\\(\\)\\s?\\*\\s?\\(\\s?5\\s?\\-\\s?1\\s?\\+\\s?1\\s?\\)\\s?\\)\\s?\\+\\s?1;/gi) !== null){return(editor.match(/Math\\.floor\\(\\s?Math\\.random\\(\\)\\s?\\*\\s?\\(\\s?5\\s?\\-\\s?1\\s?\\+\\s?1\\s?\\)\\s?\\)\\s?\\+\\s?1;/gi).length >= 3);}else{return(false);}})(), 'You should have used Math.floor(Math.random() * (5 - 1 + 1)) + 1; three times to generate your random numbers');"
       ],
       "challengeSeed":[
         "fccss",

From 853c728d9ce0482478740d34dd80d10461354a9c Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 20:13:13 -0700
Subject: [PATCH 42/47] improve get-started view and fix duplicate bonfire
 issue

---
 seed/challenges/expert-bonfires.json    | 304 --------------------------------
 server/views/resources/get-started.jade |  66 +++----
 2 files changed, 34 insertions(+), 336 deletions(-)
 delete mode 100644 seed/challenges/expert-bonfires.json

diff --git a/seed/challenges/expert-bonfires.json b/seed/challenges/expert-bonfires.json
deleted file mode 100644
index d5322b0..0000000
--- a/seed/challenges/expert-bonfires.json
+++ /dev/null
@@ -1,304 +0,0 @@
-{
-  "name": "Expert Algorithm Scripting",
-  "order": 0.013,
-  "challenges": [
-    {
-      "id": "aff0495970f5d3034dc0bfc9",
-      "title": "Validate US Telephone Numbers",
-      "difficulty": "4.01",
-      "description": [
-        "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 is provided, you must confirm that the country code is \"1\". Return true if the string is a valid US phone number; otherwise false.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "tests": [
-        "expect(telephoneCheck(\"555-555-5555\")).to.be.a(\"boolean\");",
-        "assert.deepEqual(telephoneCheck(\"1 555-555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1 (555) 555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"5555555555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"(555)555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1(555)555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1 555 555 5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"555-555-5555\"), true);",
-        "assert.deepEqual(telephoneCheck(\"1 456 789 4444\"), true);",
-        "assert.deepEqual(telephoneCheck(\"123**&!!asdf#\"), false);",
-        "assert.deepEqual(telephoneCheck(\"55555555\"), false);",
-        "assert.deepEqual(telephoneCheck(\"(6505552368)\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"0 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"-1 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2 757 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"10 (757) 622-7382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"27576227382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"(275)76227382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2(757)6227382\"), false);",
-        "assert.deepEqual(telephoneCheck(\"2(757)622-7382\"), false);"
-      ],
-      "challengeSeed": [
-        "function telephoneCheck(str) {",
-        "  // Good luck!",
-        "  return true;",
-        "}",
-        "",
-        "",
-        "",
-        "telephoneCheck(\"555-555-5555\");"
-      ],
-      "MDNlinks": [
-        "RegExp"
-      ],
-      "type": "bonfire",
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a3f512de51cf954ede28891d",
-      "title": "Symmetric Difference",
-      "difficulty": "4.02",
-      "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function sym(args) {",
-        "  return arguments;",
-        "}",
-        "",
-        "sym([1, 2, 3], [5, 2, 1, 4]);"
-      ],
-      "tests": [
-        "assert.deepEqual(sym([1, 2, 3], [5, 2, 1, 4]).sort(), [3, 4, 5], 'should return the symmetric difference of the given arrays');",
-        "assert.deepEqual(sym([1, 2, 5], [2, 3, 5], [3, 4, 5]).sort(), [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]).sort(), [1, 4, 5], 'should return an array of unique values');",
-        "assert.deepEqual(sym([1, 1]), [1], 'should return an array of unique values');"
-      ],
-      "MDNlinks": [
-        "Array.reduce()",
-        "Symmetric Difference"
-      ],
-      "type": "bonfire",
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "aa2e6f96cab3ab736c9a9b24",
-      "title": "Exact Change",
-      "difficulty": "4.03",
-      "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 cash-in-drawer is less than the change due. 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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function drawer(price, cash, cid) {",
-        "  var change;",
-        "  // Here is your change, ma'am.",
-        "  return change;",
-        "}",
-        "",
-        "// Example cash-in-drawer array:",
-        "// [['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]]",
-        "",
-        "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]]);"
-      ],
-      "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');",
-        "expect(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
-        "assert.deepEqual(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]]), [['QUARTER', 0.50]], 'return correct change');",
-        "assert.deepEqual(drawer(3.26, 100.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]]), [['TWENTY', 60.00], ['TEN', 20.00], ['FIVE', 15], ['ONE', 1], ['QUARTER', 0.50], ['DIME', 0.20], ['PENNY', 0.04] ], 'return correct change with multiple coins and bills');",
-        "assert.deepEqual(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]]), 'Insufficient Funds', 'insufficient funds');",
-        "assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), \"Closed\", 'cash-in-drawer equals change');"
-      ],
-      "MDNlinks": [
-        "Global Object"
-      ],
-      "type": "bonfire",
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a56244aff60341a09ed6c480",
-      "title": "Inventory Update",
-      "difficulty": "4.04",
-      "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.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function inventory(arr1, arr2) {",
-        "    // All inventory must be accounted for or you're fired!",
-        "    return arr1;",
-        "}",
-        "",
-        "// Example inventory lists",
-        "var curInv = [",
-        "    [21, 'Bowling Ball'],",
-        "    [2, 'Dirty Sock'],",
-        "    [1, 'Hair Pin'],",
-        "    [5, 'Microphone']",
-        "];",
-        "",
-        "var newInv = [",
-        "    [2, 'Hair Pin'],",
-        "    [3, 'Half-Eaten Apple'],",
-        "    [67, 'Bowling Ball'],",
-        "    [7, 'Toothpaste']",
-        "];",
-        "",
-        "inventory(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);",
-        "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[88, 'Bowling Ball'], [2, 'Dirty Sock'], [3, 'Hair Pin'], [3, 'Half-Eaten Apple'], [5, 'Microphone'], [7, 'Toothpaste']]);",
-        "assert.deepEqual(inventory([[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']], []), [[21, 'Bowling Ball'], [2, 'Dirty Sock'], [1, 'Hair Pin'], [5, 'Microphone']]);",
-        "assert.deepEqual(inventory([], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[67, 'Bowling Ball'], [2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [7, 'Toothpaste']]);",
-        "assert.deepEqual(inventory([[0, 'Bowling Ball'], [0, 'Dirty Sock'], [0, 'Hair Pin'], [0, 'Microphone']], [[1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [1, 'Bowling Ball'], [1, 'Toothpaste']]), [[1, 'Bowling Ball'], [0, 'Dirty Sock'], [1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [0, 'Microphone'], [1, 'Toothpaste']]);"
-      ],
-      "MDNlinks": [
-        "Global Array Object"
-      ],
-      "type": "bonfire",
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a8bf800cd123b9a54eef01d5",
-      "title": "No repeats please",
-      "difficulty": "4.05",
-      "description": [
-        "Return the number of total permutations of the provided string that don't have repeated consecutive letters.",
-        "For example, 'aab' should return 2 because it has 6 total permutations, but only 2 of them don't have the same letter (in this case 'a') repeating.",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function permAlone(str) {",
-        "  return str;",
-        "}",
-        "",
-        "permAlone('aab');"
-      ],
-      "tests": [
-        "expect(permAlone('aab')).to.be.a('number');",
-        "expect(permAlone('aab')).to.equal(2);",
-        "expect(permAlone('aaa')).to.equal(0);",
-        "expect(permAlone('aabb')).to.equal(8);",
-        "expect(permAlone('abcdefa')).to.equal(3600);",
-        "expect(permAlone('abfdefa')).to.equal(2640);",
-        "expect(permAlone('zzzzzzzz')).to.equal(0);"
-      ],
-      "MDNlinks": [
-        "Permutations",
-        "RegExp"
-      ],
-      "type": "bonfire",
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    },
-    {
-      "id": "a19f0fbe1872186acd434d54",
-      "title": "Friendly Date Ranges",
-      "difficulty": "4.06",
-      "description": [
-        "Implement a way of converting two dates into a more friendly date range that could be presented to a user.",
-        "It must not show any redundant information in the date range.",
-        "For example, if the year and month are the same then only the day range should be displayed.",
-        "Secondly, if the starting year is the current year, and the ending year can be inferred by the reader, the year should be omitted.",
-        "Input date is formatted as YYYY-MM-DD",
-        "Remember to use <a href='//github.com/FreeCodeCamp/freecodecamp/wiki/How-to-get-help-when-you-get-stuck' target='_blank'>RSAP</a> if you get stuck. Try to pair program. Write your own code."
-      ],
-      "challengeSeed": [
-        "function friendly(str) {",
-        "  return str;",
-        "}",
-        "",
-        "friendly(['2015-07-01', '2015-07-04']);"
-      ],
-      "tests": [
-        "assert.deepEqual(friendly(['2015-07-01', '2015-07-04']), ['July 1st','4th'], 'ending month should be omitted since it is already mentioned');",
-        "assert.deepEqual(friendly(['2015-12-01', '2016-02-03']), ['December 1st','February 3rd'], 'two months apart can be inferred if it is the next year');",
-        "assert.deepEqual(friendly(['2015-12-01', '2017-02-03']), ['December 1st, 2015','February 3rd, 2017']);",
-        "assert.deepEqual(friendly(['2016-03-01', '2016-05-05']), ['March 1st','May 5th'], 'one month apart can be inferred it is the same year');",
-        "assert.deepEqual(friendly(['2017-01-01', '2017-01-01']), ['January 1st, 2017'], 'since we do not duplicate only return once');",
-        "assert.deepEqual(friendly(['2022-09-05', '2023-09-04']), ['September 5th, 2022','September 4th, 2023']);"
-      ],
-      "MDNlinks": [
-        "String.split()",
-        "String.substr()",
-        "parseInt()"
-      ],
-      "type": "bonfire",
-      "challengeType": 5,
-      "nameCn": "",
-      "descriptionCn": [],
-      "nameFr": "",
-      "descriptionFr": [],
-      "nameRu": "",
-      "descriptionRu": [],
-      "nameEs": "",
-      "descriptionEs": [],
-      "namePt": "",
-      "descriptionPt": []
-    }
-  ]
-}
diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index 5dd1ac3..6f5d353 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -1,60 +1,60 @@
 extends ../layout
 block content
     .jumbotron
-        h2.text-center Do these steps to get ready for Free Code Camp (this only takes 10 minutes):
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        h2.text-center This 10-minute guide will help you get the most out of Free Code Camp.
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Welcome to Free Code Camp. We're an open source community of busy people who learn to code, then practice by building projects for nonprofits.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/pYsTbjI.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/pYsTbjI.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Learning to code is hard. To succeed, you'll need lots practice and support. That's why we've created a rigorous curriculum and supportive community.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Gtf8aIq.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/Gtf8aIq.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Free Code Code camp is self-paced, browser-based, and free.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/D7Y5luw.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption If you can finish Free Code Camp, you will be able to get a coding job. There are thousands of coding jobs currently going unfilled, and the demand for coders grows every year.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/dLx8nrg.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/dLx8nrg.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption During the first 800 hours of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/yXyxbDd.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/yXyxbDd.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption During the last 800 hours, you'll build several real-life projects for nonprofits.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/PprMPUx.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/PprMPUx.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption By the time you finish, you'll have a job-winning portfolio of real apps that people use every day.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/EAR7Lvh.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/EAR7Lvh.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Now let's join Free Code Camp's chat rooms. You can come here any time of day to hang out, ask questions, or find another camper to pair program with.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/sign-up-for-github.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/sign-up-for-github.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             a(href='https://github.com/join' target='_blank') Create an account with GitHub
             | . Be sure to use your real email address - GitHub will keep this private.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/github-profile.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/github-profile.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how people will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/star-repository.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/star-repository.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             a(href='//github.com/freecodecamp/freecodecamp' target='_blank') Go to Free Code Camp's open-source repository
             | &thinsp;and "star" it. "Starring" is the GitHub equivalent of "liking" something.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/join-gitter.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/join-gitter.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Now that you have a GitHub account, you can&thinsp;
@@ -62,64 +62,64 @@ block content
             | . Introduce yourself by saying "Hello world!". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/gitter-notifications.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/gitter-notifications.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Our chat rooms are extremely active. You should change your settings so you're only notified if someone mentions you.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/private-messages.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/private-messages.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption Please note that all of our chat rooms are visible to the public. If you need to share sensitive information, such as an email address or phone number, do it in a private message.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/keep-chat-open.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/keep-chat-open.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption Keep our chat room open while you work through our challenges. That way, you can ask for help if you get stuck. You can also socialize with other campers when you feel like taking a break.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/download-gitter-app.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/download-gitter-app.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             a(href='https://gitter.im/apps' target='_blank') You can also download the chat room app to your computer or phone
             | .
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/challenge-map.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/challenge-map.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Click the "Map" button in your upper right hand corner. Our map shows all our coding challenges. We recommend that you complete these from top to bottom, at a sustainable pace.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/9NJfPQv.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/9NJfPQv.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption After you finish all of our challenges, you'll start building projects for nonprofits.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/wiki.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/wiki.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/camper-news.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/camper-news.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Click the "News" button in your upper right hand corner. You can browse links on Camper News and upvote ones that you enjoy.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/Elb3dfj.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/Elb3dfj.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Our Campsites help you code with campers in your city. You can coordinate study groups or attend local coding events together.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/join-facebook-group.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/join-facebook-group.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Find your city on this list
@@ -128,38 +128,40 @@ block content
             | .
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
         p.large-p.gif-caption
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
             | and click "Gitter" to join your city's chat room.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/add-linkedin.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/add-linkedin.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption You can&thinsp;
             a(href='https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp' target='_blank') add Free Code Camp to your LinkedIn education background
             | . Set your graduation date as next year. For "Degree", type "Full Stack Web Development". For "Field of study", type "Computer Software Engineering". Then click "Save Changes".
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/6VtsD1K.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/6VtsD1K.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Let's cover one last thing before you start working through our challenges: how to get help. Any time you get stuck or don't know what to do next: RSAP (Read, Search, Ask, Post).
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/99BfAcK.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/99BfAcK.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption First, R - Read the documentation or error message. A key skill that good coders have is the ability to interpret and then follow instructions.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/google-search.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/google-search.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption If that didn't help, S - Search Google. Good Google queries take a lot of practice. When you search Google, you usually want to include the language or framework you're using. You also want to limit the results to a recent period.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/ask-for-help.gif' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/ask-for-help.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption If that didn't help, A - Ask your friends. If you have trouble, you can ask your fellow campers in our&thinsp;
             a(href='https://gitter.im/FreeCodeCamp/Help' target='_blank') help chat room
             | .
 
         .big-spacer
-        img.gif-block.img-center.img-responsive(src='http://i.imgur.com/rWeBOhF.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/rWeBOhF.jpg' alt='a gif showing how to install this')
         p.large-p.gif-caption Finally if you still haven't found an answer to your question, P - Post on Stack Overflow. This is a popular question and answer site where you can get help with coding questions.
 
+        .big-spacer
         h2.text-center Nicely done. Now you have all the tools you need to succeed. Happy coding!
+        .spacer
         a.btn.btn-cta.signup-btn.btn-block(href="/map") Take me to my Challenge Map

From 7bfe61731b5055eba4aecd5c97ccddf9f0d76027 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 20:55:01 -0700
Subject: [PATCH 43/47] give a user a brownie point when they start

---
 common/models/user.js                   |  8 +++++
 server/views/account/account.jade       | 64 ++++++++++++++++-----------------
 server/views/resources/get-started.jade |  2 +-
 3 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/common/models/user.js b/common/models/user.js
index 81078d6..8f79fe6 100644
--- a/common/models/user.js
+++ b/common/models/user.js
@@ -51,6 +51,14 @@ module.exports = function(User) {
       user.email = typeof user.email === 'string' ?
         user.email.trim().toLowerCase() :
         user.email;
+
+      if (!user.progressTimestamps) {
+        user.progressTimestamps = [];
+      }
+
+      if (user.progressTimestamps.length === 0) {
+        user.progressTimestamps.push({ timestamp: Date.now() });
+      }
     }
     next();
   });
diff --git a/server/views/account/account.jade b/server/views/account/account.jade
index db839fe..22ad1b9 100644
--- a/server/views/account/account.jade
+++ b/server/views/account/account.jade
@@ -5,42 +5,38 @@ block content
     .panel.panel-info(ng-controller="profileValidationController")
         .panel-heading.text-center Manage your account here
         .panel-body
-            if (!user.isGithubCool)
-              .row
+            .row
                 .col-xs-12
-                  a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
-                      i.fa.fa-github
-                      | Link my GitHub to unlock this profile
-            else
-              .row
-                .col-xs-12
-                  a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
-                      i.fa.fa-github
-                      | Update my profile from Github
+                    if (!user.isGithubCool)
+                      a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/auth/github')
+                          i.fa.fa-github
+                          | Link my GitHub to unlock this profile
+                    else
+                      a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
+                          i.fa.fa-github
+                          | Update my profile from Github
 
-                  if (!user.twitter)
-                      .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
-                              i.fa.fa-twitter
-                              | Add my Twitter to my profile
-                  if (!user.facebook)
-                      .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
-                              i.fa.fa-facebook
-                              | Add my Facebook to my profile
-                  if (!user.linkedin)
-                      .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
-                              i.fa.fa-linkedin
-                              | Add my LinkedIn to my profile
-                  if (!user.google)
-                      .col-xs-12
-                          a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
-                              i.fa.fa-google-plus
-                              | Add my Google+ to my profile
-              .spacer
-              hr
-              .spacer
+                      if (!user.twitter)
+                          .col-xs-12
+                              a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
+                                  i.fa.fa-twitter
+                                  | Add my Twitter to my profile
+                      if (!user.facebook)
+                          .col-xs-12
+                              a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
+                                  i.fa.fa-facebook
+                                  | Add my Facebook to my profile
+                      if (!user.linkedin)
+                          .col-xs-12
+                              a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
+                                  i.fa.fa-linkedin
+                                  | Add my LinkedIn to my profile
+                      if (!user.google)
+                          .col-xs-12
+                              a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
+                                  i.fa.fa-google-plus
+                                  | Add my Google+ to my profile
+              .big-spacer
               .col-xs-12
                 a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
                     span.ion-android-exit
diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index 6f5d353..2ac55a0 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -99,7 +99,7 @@ block content
             | Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://www.evernote.com/l/AlwO6CNq-OJJXJ3qu2nu1E7ePe72hCSW5IcB/image.png' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.

From 341d9318338446b5ecdecf9c07d04275d84a8033 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 21:01:37 -0700
Subject: [PATCH 44/47] fix streak show days

---
 server/views/account/show.jade | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/views/account/show.jade b/server/views/account/show.jade
index 87e5d82..78cf71c 100644
--- a/server/views/account/show.jade
+++ b/server/views/account/show.jade
@@ -77,8 +77,8 @@ block content
                     .row
                         .hidden-xs.col-sm-12.text-center
                             .row.text-primary
-                                h4.col-sm-6.text-right Longest Streak: #{longestStreak + longestStreak === 1 ? ' day' : ' days'}
-                                h4.col-sm-6.text-left Current Streak: #{currentStreak + currentStreak === 1 ? ' day' : ' days'}
+                              h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak + longestStreak === 1 ? ' day' : ' days'}
+                                h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak + currentStreak === 1 ? ' day' : ' days'}
 
 
                     if (challenges.length > 0)

From 43e3dc8914086923760c295fdee3a4ae339d7d17 Mon Sep 17 00:00:00 2001
From: Quincy Larson <michaelqlarson@gmail.com>
Date: Mon, 10 Aug 2015 21:55:13 -0700
Subject: [PATCH 45/47] Finish onboarding page

---
 server/views/account/show.jade          | 2 +-
 server/views/resources/get-started.jade | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/server/views/account/show.jade b/server/views/account/show.jade
index 78cf71c..ce58b8b 100644
--- a/server/views/account/show.jade
+++ b/server/views/account/show.jade
@@ -10,7 +10,7 @@ block content
             if (user && user.username === username)
                 .row.text-center
                     .col-xs-12.col-sm-10.col-sm-offset-1
-                        a.btn.btn-big.btn-primary.btn-block(href="/account") Update my portfolio page or manage my account
+                        a.btn.btn-big.btn-primary.btn-block(href="/account") Manage my account
                         .button-spacer
                     .col-xs-12.col-sm-10.col-sm-offset-1
                         a.btn.btn-big.btn-success.btn-block(href="/signout") Sign out of Free Code Camp
diff --git a/server/views/resources/get-started.jade b/server/views/resources/get-started.jade
index 2ac55a0..2b46920 100644
--- a/server/views/resources/get-started.jade
+++ b/server/views/resources/get-started.jade
@@ -99,13 +99,13 @@ block content
             | Click the "Wiki" button in your upper right hand corner. Our community has contributed lots of useful information to this searchable wiki.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive.thumbnail(src='https://www.evernote.com/l/AlwO6CNq-OJJXJ3qu2nu1E7ePe72hCSW5IcB/image.png' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/add-github-to-profile.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             span.text-info Try this:&thinsp;
             | Check out your portfolio page. Click your picture your upper right hand corner. Before you can see your portfolio page, you'll need to link your GitHub account with Free Code Camp.
 
         .big-spacer
-        img.gif-block.img-center.img-responsive.thumbnail(src='http://i.imgur.com/RlEk2IF.jpg' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/check-public-profile.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption Your portfolio page shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.
 
         .big-spacer
@@ -128,7 +128,7 @@ block content
             | .
 
         .big-spacer
-        img.gif-block.img-center.img-responsive.thumbnail(src='https://www.evernote.com/l/AnuMiYJUMhFOzqKu2bAjL88LIrCiuHr998sB/image.png' alt='a gif showing how to install this')
+        img.gif-block.img-center.img-responsive.thumbnail(src='https://s3.amazonaws.com/freecodecamp/join-campsite-gitter-room.gif' alt='a gif showing how to install this')
         p.large-p.gif-caption
             a(href='https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites' target='_blank') Go back to our list of Campsites&thinsp;
             | and click "Gitter" to join your city's chat room.

From 5f21db457d74ef364e2c0f43fb88be1ef73110af Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 23:29:32 -0700
Subject: [PATCH 46/47] fix challenge ordering Now challenges are ordered on
 map first by top order value of json file second by index of array

---
 common/models/challenge.json | 3 +++
 seed/index.js                | 3 ++-
 server/boot/challenge.js     | 5 ++++-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/common/models/challenge.json b/common/models/challenge.json
index 7433321..08fa487 100644
--- a/common/models/challenge.json
+++ b/common/models/challenge.json
@@ -22,6 +22,9 @@
     "order": {
       "type": "number"
     },
+    "suborder": {
+      "type": "number"
+    },
     "dashedName": {
       "type": "string"
     },
diff --git a/seed/index.js b/seed/index.js
index 3830542..334a11d 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -63,7 +63,8 @@ Challenge.destroyAll(function(err, info) {
           .toLowerCase()
           .replace(/\:/g, '')
           .replace(/\s/g, '-');
-        challenge.order = +('' + order + (index + 1));
+        challenge.order = order;
+        challenge.suborder = index + 1;
         challenge.block = block;
 
         return challenge;
diff --git a/server/boot/challenge.js b/server/boot/challenge.js
index 1fc4342..feea898 100644
--- a/server/boot/challenge.js
+++ b/server/boot/challenge.js
@@ -458,7 +458,10 @@ module.exports = function(app) {
       .map(camperCount => numberWithCommas(camperCount));
 
     const query = {
-      order: 'order ASC'
+      order: [
+        'order ASC',
+        'suborder ASC'
+      ]
     };
 
     // create a stream of all the challenges

From 2256f3ef6e2cfec7dd82b975ca5795ba792d2401 Mon Sep 17 00:00:00 2001
From: Berkeley Martinez <Berkeley@robotie.com>
Date: Mon, 10 Aug 2015 23:38:10 -0700
Subject: [PATCH 47/47] fix add github link to passport

---
 common/models/User-Identity.js |  2 +-
 server/passport-providers.js   | 14 ++++++++++++++
 server/server.js               |  2 +-
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/common/models/User-Identity.js b/common/models/User-Identity.js
index 87a7ffe..779ad2f 100644
--- a/common/models/User-Identity.js
+++ b/common/models/User-Identity.js
@@ -79,7 +79,7 @@ export default function(UserIdent) {
     }
 
     // if user signed in with github refresh their info
-    if (userIdent.provider === 'github-login') {
+    if (/github/.test(userIdent.provider)) {
       debug("user isn't github cool or username from github is different");
       setProfileFromGithub(user, profile, profile._json);
       userChanged = true;
diff --git a/server/passport-providers.js b/server/passport-providers.js
index ddd29f6..5ffcbf1 100644
--- a/server/passport-providers.js
+++ b/server/passport-providers.js
@@ -141,5 +141,19 @@ module.exports = {
     clientSecret: process.env.GITHUB_SECRET,
     scope: ['email'],
     failureFlash: true
+  },
+  'github-link': {
+    provider: 'github',
+    authScheme: 'oauth2',
+    module: 'passport-github',
+    authPath: '/link/github',
+    callbackURL: '/link/github/callback',
+    callbackPath: '/link/github/callback',
+    successRedirect: successRedirect,
+    failureRedirect: failureRedirect,
+    clientID: process.env.GITHUB_ID,
+    clientSecret: process.env.GITHUB_SECRET,
+    scope: ['email'],
+    failureFlash: true
   }
 };
diff --git a/server/server.js b/server/server.js
index 93a0f06..bf0cb8c 100755
--- a/server/server.js
+++ b/server/server.js
@@ -102,7 +102,7 @@ var passportOptions = {
       userObj.email = email;
     }
 
-    if (provider === 'github-login') {
+    if (/github/.test(provider)) {
       setProfileFromGithub(userObj, profile, profile._json);
     }
     return userObj;
