Merge pull request #45 from Bouncey/fix/ui

Fix up the UI and pull in the latest seed files
This commit is contained in:
Stuart Taylor
2018-05-18 14:54:21 +01:00
committed by Mrugesh Mohapatra
parent 04a6a2026c
commit f962d7774a
105 changed files with 7019 additions and 9431 deletions

View File

@ -4,6 +4,14 @@
"react" "react"
], ],
"plugins": [ "plugins": [
"add-module-exports" "add-module-exports",
[
"transform-imports", {
"react-bootstrap": {
"transform": "react-bootstrap/lib/${member}",
"preventFullImport": true
}
}
]
] ]
} }

View File

@ -38,7 +38,7 @@ exports.createPages = ({ graphql, boundActionCreators }) => {
const { createPage } = boundActionCreators; const { createPage } = boundActionCreators;
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Query for all markdown "nodes" and for the slug we previously created. // Query for all markdown 'nodes' and for the slug we previously created.
resolve( resolve(
graphql(` graphql(`
{ {
@ -140,3 +140,22 @@ exports.modifyWebpackConfig = ({ config, stage }) => {
]); ]);
}); });
}; };
/* eslint-disable prefer-object-spread/prefer-object-spread */
exports.modifyBabelrc = ({ babelrc }) =>
Object.assign({}, babelrc, {
plugins: babelrc.plugins.concat([
[
'transform-imports',
{
'react-bootstrap': {
transform: 'react-bootstrap/lib/${member}',
preventFullImport: true
},
lodash: {
transform: 'lodash/${member}',
preventFullImport: true
}
}
]
])
});

View File

@ -8,6 +8,7 @@
"auth0-js": "^9.5.1", "auth0-js": "^9.5.1",
"babel-core": "^6.26.0", "babel-core": "^6.26.0",
"babel-jest": "^22.4.3", "babel-jest": "^22.4.3",
"babel-plugin-transform-imports": "^1.5.0",
"babel-standalone": "^6.26.0", "babel-standalone": "^6.26.0",
"brace": "^0.11.1", "brace": "^0.11.1",
"chai": "^4.1.2", "chai": "^4.1.2",

View File

@ -45,7 +45,7 @@ that delivers challenge files to the plugin
const { source } = pluginOptions; const { source } = pluginOptions;
const createAndProcessNodes = () => const createAndProcessNodes = () =>
source() source()
.filter(node => node.challengeType !== 7) .filter(nodes => nodes.some(node => node.superBlock !== 'Certificates'))
.map(nodes => nodes.map(node => createChallengeNodes(node, reporter))) .map(nodes => nodes.map(node => createChallengeNodes(node, reporter)))
.map(nodes => nodes.map(node => createNode(node))) .map(nodes => nodes.map(node => createNode(node)))
.subscribe(); .subscribe();

View File

@ -29,15 +29,15 @@
"translations": {}, "translations": {},
"guideUrl": "https://guide.freecodecamp.org/certificates/add-alt-text-to-an-image-for-accessibility", "guideUrl": "https://guide.freecodecamp.org/certificates/add-alt-text-to-an-image-for-accessibility",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
"contents": [ "contents": [
"<img src=\"doingKarateWow.jpeg\">" "<img src=\"doingKarateWow.jpeg\">"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -70,7 +70,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -88,8 +88,8 @@
" <p>To Come...</p>", " <p>To Come...</p>",
"</article>" "</article>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -125,7 +125,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -145,8 +145,8 @@
" <h5>How to Simplify your Life</h5>", " <h5>How to Simplify your Life</h5>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -178,7 +178,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -191,8 +191,8 @@
"", "",
"<footer></footer>" "<footer></footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -225,7 +225,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -252,8 +252,8 @@
" </article>", " </article>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -292,7 +292,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -323,8 +323,8 @@
" </main>", " </main>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -362,7 +362,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -399,8 +399,8 @@
" </main>", " </main>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -437,7 +437,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -477,8 +477,8 @@
"", "",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -532,7 +532,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -549,8 +549,8 @@
" </main>", " </main>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -598,7 +598,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -645,8 +645,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -679,7 +679,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -717,8 +717,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -763,7 +763,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -812,8 +812,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -854,7 +854,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -883,8 +883,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -923,7 +923,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -960,8 +960,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1006,7 +1006,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1096,8 +1096,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1127,7 +1127,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1151,8 +1151,8 @@
" </article>", " </article>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1184,7 +1184,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1208,8 +1208,8 @@
" </article>", " </article>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1236,7 +1236,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1258,8 +1258,8 @@
" <button>Delete Internet</button>", " <button>Delete Internet</button>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1289,7 +1289,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1304,8 +1304,8 @@
" </article>", " </article>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1345,7 +1345,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1373,8 +1373,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1406,7 +1406,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1459,8 +1459,8 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1502,7 +1502,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1539,13 +1539,10 @@
" <footer>&copy; 2016 Camper Cat</footer>", " <footer>&copy; 2016 Camper Cat</footer>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/applied-accessibility.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -34,7 +34,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -73,8 +73,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -100,7 +100,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -140,8 +140,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -167,7 +167,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -208,8 +208,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -242,7 +242,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -286,8 +286,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -321,7 +321,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -365,8 +365,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -376,7 +376,7 @@
"description": [ "description": [
"To emphasize text, you can use the <code>em</code> tag. This displays text as italicized, as the browser applies the CSS of <code>font-style: italic;</code> to the element.", "To emphasize text, you can use the <code>em</code> tag. This displays text as italicized, as the browser applies the CSS of <code>font-style: italic;</code> to the element.",
"<hr>", "<hr>",
"Wrap an <code>em</code> tag around the paragraph tag to give it emphasis." "Wrap an <code>em</code> tag around the contents of the paragraph tag to give it emphasis."
], ],
"tests": [ "tests": [
{ {
@ -384,8 +384,8 @@
"testString": "assert($('em').length == 1, 'Your code should add an <code>em</code> tag to the markup.');" "testString": "assert($('em').length == 1, 'Your code should add an <code>em</code> tag to the markup.');"
}, },
{ {
"text": "The <code>em</code> tag should wrap around the <code>p</code> tag and its contents.", "text": "The <code>em</code> tag should wrap around the contents of the <code>p</code> tag but not the <code>p</code> tag itself.",
"testString": "assert($('em').children('p').length == 1, 'The <code>em</code> tag should wrap around the <code>p</code> tag and its contents.');" "testString": "assert($('p').children().length == 1 && $('em').children().length == 2, 'The <code>em</code> tag should wrap around the contents of the <code>p</code> tag but not the <code>p</code> tag itself.');"
} }
], ],
"solutions": [], "solutions": [],
@ -395,7 +395,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -439,8 +439,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -473,7 +473,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -517,8 +517,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -548,7 +548,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -593,8 +593,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -631,7 +631,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -678,8 +678,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -704,7 +704,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -751,8 +751,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -784,7 +784,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -834,8 +834,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -862,7 +862,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -913,8 +913,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -945,7 +945,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -997,8 +997,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1043,7 +1043,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1063,8 +1063,8 @@
"<h5>This is h5 text</h5>", "<h5>This is h5 text</h5>",
"<h6>This is h6 text</h6>" "<h6>This is h6 text</h6>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1110,7 +1110,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1148,8 +1148,8 @@
"<h5>This is h5 text</h5>", "<h5>This is h5 text</h5>",
"<h6>This is h6 text</h6>" "<h6>This is h6 text</h6>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1174,7 +1174,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1188,8 +1188,8 @@
" Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1214,7 +1214,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1229,8 +1229,8 @@
" Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", " Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1261,7 +1261,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1276,8 +1276,8 @@
"</style>", "</style>",
"<a href=\"http://freecatphotoapp.com/\" target=\"_blank\">CatPhotoApp</a>" "<a href=\"http://freecatphotoapp.com/\" target=\"_blank\">CatPhotoApp</a>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1310,7 +1310,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1327,8 +1327,8 @@
" <p>I still think the h2 is where it normally sits.</p>", " <p>I still think the h2 is where it normally sits.</p>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1358,7 +1358,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1378,8 +1378,8 @@
" <p>I still think the h2 is where it normally sits.</p>", " <p>I still think the h2 is where it normally sits.</p>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1390,7 +1390,7 @@
"The next option for the CSS <code>position</code> property is <code>absolute</code>, which locks the element in place relative to its parent container. Unlike the <code>relative</code> position, this removes the element from the normal flow of the document, so surrounding items ignore it. The CSS offset properties (top or bottom and left or right) are used to adjust the position.", "The next option for the CSS <code>position</code> property is <code>absolute</code>, which locks the element in place relative to its parent container. Unlike the <code>relative</code> position, this removes the element from the normal flow of the document, so surrounding items ignore it. The CSS offset properties (top or bottom and left or right) are used to adjust the position.",
"One nuance with absolute positioning is that it will be locked relative to its closest <em>positioned</em> ancestor. If you forget to add a position rule to the parent item, (this is typically done using <code>position: relative;</code>), the browser will keep looking up the chain and ultimately default to the body tag.", "One nuance with absolute positioning is that it will be locked relative to its closest <em>positioned</em> ancestor. If you forget to add a position rule to the parent item, (this is typically done using <code>position: relative;</code>), the browser will keep looking up the chain and ultimately default to the body tag.",
"<hr>", "<hr>",
"Lock the <code>#searchbar</code> element to the top-right of its <code>section</code> parent by declaring its <code>position</code> as <code>absolute</code>. Give it <code>top</code> and <code>right</code> offsets of 0.5 pixels each." "Lock the <code>#searchbar</code> element to the top-right of its <code>section</code> parent by declaring its <code>position</code> as <code>absolute</code>. Give it <code>top</code> and <code>right</code> offsets of 50 pixels each."
], ],
"tests": [ "tests": [
{ {
@ -1398,12 +1398,12 @@
"testString": "assert($('#searchbar').css('position') == 'absolute', 'The <code>#searchbar</code> element should have a <code>position</code> set to <code>absolute</code>.');" "testString": "assert($('#searchbar').css('position') == 'absolute', 'The <code>#searchbar</code> element should have a <code>position</code> set to <code>absolute</code>.');"
}, },
{ {
"text": "Your code should use the <code>top</code> CSS offset of 0.5 pixels on the <code>#searchbar</code> element.", "text": "Your code should use the <code>top</code> CSS offset of 50 pixels on the <code>#searchbar</code> element.",
"testString": "assert($('#searchbar').css('top') == '0.5px', 'Your code should use the <code>top</code> CSS offset of 0.5 pixels on the <code>#searchbar</code> element.');" "testString": "assert($('#searchbar').css('top') == '50px', 'Your code should use the <code>top</code> CSS offset of 50 pixels on the <code>#searchbar</code> element.');"
}, },
{ {
"text": "Your code should use the <code>right</code> CSS offset of 0.5 pixels on the <code>#searchbar</code> element.", "text": "Your code should use the <code>right</code> CSS offset of 50 pixels on the <code>#searchbar</code> element.",
"testString": "assert($('#searchbar').css('right') == '0.5px', 'Your code should use the <code>right</code> CSS offset of 0.5 pixels on the <code>#searchbar</code> element.');" "testString": "assert($('#searchbar').css('right') == '50px', 'Your code should use the <code>right</code> CSS offset of 50 pixels on the <code>#searchbar</code> element.');"
} }
], ],
"solutions": [], "solutions": [],
@ -1413,7 +1413,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1439,8 +1439,8 @@
" </section>", " </section>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1474,7 +1474,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1512,8 +1512,8 @@
" <p>I shift up when the #navbar is fixed to the browser window.</p>", " <p>I shift up when the #navbar is fixed to the browser window.</p>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1542,7 +1542,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1577,8 +1577,8 @@
" </aside>", " </aside>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1603,7 +1603,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1632,8 +1632,8 @@
"<div class=\"first\"></div>", "<div class=\"first\"></div>",
"<div class=\"second\"></div>" "<div class=\"second\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1659,7 +1659,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1674,8 +1674,8 @@
"</style>", "</style>",
"<div></div>" "<div></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1709,7 +1709,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1733,8 +1733,8 @@
"<div class=\"blue\"></div>", "<div class=\"blue\"></div>",
"<div class=\"yellow\"></div>" "<div class=\"yellow\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1771,7 +1771,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1804,8 +1804,8 @@
"<div class=\"cyan\"></div>", "<div class=\"cyan\"></div>",
"<div class=\"raspberry\"></div>" "<div class=\"raspberry\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1842,7 +1842,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1886,8 +1886,8 @@
"<br>", "<br>",
"<footer>&copy;2016 FCC Kitchen</footer>" "<footer>&copy;2016 FCC Kitchen</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1937,7 +1937,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1970,8 +1970,8 @@
"<div class=\"cyan\"></div>", "<div class=\"cyan\"></div>",
"<div class=\"blue\"></div>" "<div class=\"blue\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1996,7 +1996,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2043,8 +2043,8 @@
" </nav>", " </nav>",
"</header>" "</header>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2074,7 +2074,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2093,8 +2093,8 @@
"", "",
"<div></div>" "<div></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2144,7 +2144,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2169,8 +2169,8 @@
"", "",
"<div></div>" "<div></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2197,7 +2197,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2208,8 +2208,8 @@
" }", " }",
"</style>" "</style>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2235,7 +2235,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2267,8 +2267,8 @@
"<div class=\"ball\" id= \"ball1\"></div>", "<div class=\"ball\" id= \"ball1\"></div>",
"<div class=\"ball\" id= \"ball2\"></div>" "<div class=\"ball\" id= \"ball2\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2297,7 +2297,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2320,8 +2320,8 @@
"", "",
"<div></div>" "<div></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2350,7 +2350,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2373,8 +2373,8 @@
"<div id=\"top\"></div>", "<div id=\"top\"></div>",
"<div id=\"bottom\"></div>" "<div id=\"bottom\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2399,7 +2399,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2423,8 +2423,8 @@
"<div id=\"top\"></div>", "<div id=\"top\"></div>",
"<div id=\"bottom\"></div>" "<div id=\"bottom\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2460,7 +2460,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2485,8 +2485,8 @@
"</style>", "</style>",
"<div class=\"center\"></div>" "<div class=\"center\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2528,7 +2528,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2569,8 +2569,8 @@
"</style>", "</style>",
"<div class = \"heart\"></div>" "<div class = \"heart\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2622,7 +2622,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2647,8 +2647,8 @@
"</style>", "</style>",
"<div id=\"rect\"></div>" "<div id=\"rect\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2680,7 +2680,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2703,8 +2703,8 @@
" ", " ",
"<button>Register</button>" "<button>Register</button>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2730,7 +2730,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2757,8 +2757,8 @@
"</style>", "</style>",
"<button>Register</button>" "<button>Register</button>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2793,7 +2793,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2834,8 +2834,8 @@
"", "",
"<div id=\"rect\"></div>" "<div id=\"rect\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2861,7 +2861,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2895,8 +2895,8 @@
"", "",
"<div id=\"ball\"></div>" "<div id=\"ball\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2923,7 +2923,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2962,8 +2962,8 @@
"</style>", "</style>",
"<div id=\"ball\"></div>" "<div id=\"ball\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2993,7 +2993,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3068,8 +3068,8 @@
"<div class=\"back\"></div>", "<div class=\"back\"></div>",
"<div class=\"heart\"></div>" "<div class=\"heart\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3097,7 +3097,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3155,8 +3155,8 @@
"<div class=\"star-1 stars\"></div>", "<div class=\"star-1 stars\"></div>",
"<div class=\"star-2 stars\"></div>" "<div class=\"star-2 stars\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3190,7 +3190,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3249,8 +3249,8 @@
"<div class=\"star-2 stars\"></div>", "<div class=\"star-2 stars\"></div>",
"<div class=\"star-3 stars\"></div>" "<div class=\"star-3 stars\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3280,7 +3280,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3325,8 +3325,8 @@
"<div class=\"balls\" id=\"ball1\"></div>", "<div class=\"balls\" id=\"ball1\"></div>",
"<div class=\"balls\" id=\"ball2\"></div>" "<div class=\"balls\" id=\"ball2\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3359,7 +3359,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3404,8 +3404,8 @@
"<div class=\"balls\" id=\"ball1\"></div>", "<div class=\"balls\" id=\"ball1\"></div>",
"<div class=\"balls\" id=\"ball2\"></div>" "<div class=\"balls\" id=\"ball2\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3441,7 +3441,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3479,8 +3479,8 @@
"<div class=\"balls\" id= \"red\"></div>", "<div class=\"balls\" id= \"red\"></div>",
"<div class=\"balls\" id= \"blue\"></div>" "<div class=\"balls\" id= \"blue\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3509,7 +3509,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3552,13 +3552,10 @@
"<div class=\"balls\" id=\"blue\"></div>", "<div class=\"balls\" id=\"blue\"></div>",
"<div class=\"balls\" id=\"green\"></div>" "<div class=\"balls\" id=\"green\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/applied-visual-design.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -79,7 +79,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -116,8 +116,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -223,7 +223,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -260,8 +260,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -366,7 +366,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -409,8 +409,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -496,7 +496,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -539,8 +539,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -601,7 +601,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -644,8 +644,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -711,7 +711,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -758,8 +758,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -846,7 +846,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -894,8 +894,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -981,7 +981,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1034,8 +1034,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1111,7 +1111,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1164,8 +1164,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1262,7 +1262,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-borders-around-your-elements", "guideUrl": "https://guide.freecodecamp.org/certificates/add-borders-around-your-elements",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1319,8 +1319,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1385,7 +1385,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-rounded-corners-a-border-radius", "guideUrl": "https://guide.freecodecamp.org/certificates/add-rounded-corners-a-border-radius",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1448,8 +1448,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1508,7 +1508,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1572,8 +1572,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1644,7 +1644,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1708,8 +1708,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1784,7 +1784,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1852,8 +1852,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1938,7 +1938,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2006,8 +2006,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2087,7 +2087,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/adjust-the-padding-of-an-element", "guideUrl": "https://guide.freecodecamp.org/certificates/adjust-the-padding-of-an-element",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2129,8 +2129,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2196,7 +2196,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/adjust-the-margin-of-an-element", "guideUrl": "https://guide.freecodecamp.org/certificates/adjust-the-margin-of-an-element",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2240,8 +2240,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2307,7 +2307,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-a-negative-margin-to-an-element", "guideUrl": "https://guide.freecodecamp.org/certificates/add-a-negative-margin-to-an-element",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2350,8 +2350,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2424,7 +2424,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-different-padding-to-each-side-of-an-element", "guideUrl": "https://guide.freecodecamp.org/certificates/add-different-padding-to-each-side-of-an-element",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2468,8 +2468,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2541,7 +2541,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2585,8 +2585,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2667,7 +2667,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2708,8 +2708,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2791,7 +2791,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2832,8 +2832,8 @@
" <h5 class=\"box blue-box\">padding</h5>", " <h5 class=\"box blue-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2869,7 +2869,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2937,8 +2937,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2967,7 +2967,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3008,8 +3008,8 @@
" <h5 class=\"box green-box\">padding</h5>", " <h5 class=\"box green-box\">padding</h5>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3089,7 +3089,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3098,8 +3098,8 @@
"", "",
"</style>" "</style>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3193,7 +3193,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3205,8 +3205,8 @@
"", "",
"</style>" "</style>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3282,7 +3282,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3296,8 +3296,8 @@
"</style>", "</style>",
"<h1>Hello World!</h1>" "<h1>Hello World!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3394,7 +3394,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3411,8 +3411,8 @@
"</style>", "</style>",
"<h1 class=\"pink-text\">Hello World!</h1>" "<h1 class=\"pink-text\">Hello World!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3524,7 +3524,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3544,8 +3544,8 @@
"</style>", "</style>",
"<h1 class=\"pink-text blue-text\">Hello World!</h1>" "<h1 class=\"pink-text blue-text\">Hello World!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3631,7 +3631,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3654,8 +3654,8 @@
"</style>", "</style>",
"<h1 id=\"orange-text\" class=\"pink-text blue-text\">Hello World!</h1>" "<h1 id=\"orange-text\" class=\"pink-text blue-text\">Hello World!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3755,7 +3755,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3778,8 +3778,8 @@
"</style>", "</style>",
"<h1 id=\"orange-text\" class=\"pink-text blue-text\" style=\"color: white\">Hello World!</h1>" "<h1 id=\"orange-text\" class=\"pink-text blue-text\" style=\"color: white\">Hello World!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3849,7 +3849,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3860,8 +3860,8 @@
" }", " }",
"</style>" "</style>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3953,7 +3953,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3981,8 +3981,8 @@
"", "",
"<h1 class=\"orange-text\">I am orange!</h1>" "<h1 class=\"orange-text\">I am orange!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -4076,7 +4076,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -4104,8 +4104,8 @@
"", "",
"<h1 class=\"green-text\">I am green!</h1>" "<h1 class=\"green-text\">I am green!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -4196,7 +4196,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -4207,8 +4207,8 @@
" }", " }",
"</style>" "</style>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -4292,7 +4292,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -4320,8 +4320,8 @@
"", "",
"<h1 class=\"blue-text\">I am blue!</h1>" "<h1 class=\"blue-text\">I am blue!</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -4355,7 +4355,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -4561,8 +4561,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -4590,7 +4590,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -4793,8 +4793,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -4834,7 +4834,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -5050,8 +5050,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -5084,7 +5084,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -5294,8 +5294,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -5303,7 +5303,7 @@
"id": "5a9d7295424fe3d0e10cad14", "id": "5a9d7295424fe3d0e10cad14",
"title": "Cascading CSS variables", "title": "Cascading CSS variables",
"description": [ "description": [
"When you create a variable, it is becomes available for you to use inside the element in which you create it. It also becomes available within any elements nested within it. This effect is known as <dfn>cascading</dfn>.", "When you create a variable, it becomes available for you to use inside the element in which you create it. It also becomes available within any elements nested within it. This effect is known as <dfn>cascading</dfn>.",
"Because of cascading, CSS variables are often defined in the <dfn>:root</dfn> element.", "Because of cascading, CSS variables are often defined in the <dfn>:root</dfn> element.",
"You can think of the <code>:root</code> element as a container for your entire HTML document, in the same way that an <code>html</code> element is a container for the <code>body</code> element.", "You can think of the <code>:root</code> element as a container for your entire HTML document, in the same way that an <code>html</code> element is a container for the <code>body</code> element.",
"By creating your variables in <code>:root</code>, they will be available throughout the whole web page.", "By creating your variables in <code>:root</code>, they will be available throughout the whole web page.",
@ -5323,7 +5323,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -5531,8 +5531,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -5558,7 +5558,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -5768,8 +5768,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -5799,7 +5799,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -6035,13 +6035,10 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/basic-css.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -101,15 +101,15 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
"contents": [ "contents": [
"<h1>Hello</h1>" "<h1>Hello</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -189,15 +189,15 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
"contents": [ "contents": [
"<h1>Hello World</h1>" "<h1>Hello World</h1>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -269,7 +269,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -277,8 +277,8 @@
"<h1>Hello World</h1>", "<h1>Hello World</h1>",
"<h2>CatPhotoApp</h2>" "<h2>CatPhotoApp</h2>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -342,7 +342,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -353,8 +353,8 @@
"", "",
"<p>Hello Paragraph</p>" "<p>Hello Paragraph</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -362,7 +362,7 @@
"id": "bad87fee1348bd9aedf08802", "id": "bad87fee1348bd9aedf08802",
"title": "Uncomment HTML", "title": "Uncomment HTML",
"description": [ "description": [
"Commenting is a way that you can leave comments for other developers within your code without affecting the resulting output that is displayed the the end user.", "Commenting is a way that you can leave comments for other developers within your code without affecting the resulting output that is displayed the end user.",
"Commenting is also a convenient way to make code inactive without having to delete it entirely.", "Commenting is also a convenient way to make code inactive without having to delete it entirely.",
"Comments in HTML starts with <code>&#60;!--</code>, and ends with a <code>--&#62;</code>", "Comments in HTML starts with <code>&#60;!--</code>, and ends with a <code>--&#62;</code>",
"<hr>", "<hr>",
@ -430,7 +430,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -443,8 +443,8 @@
"<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
"-->" "-->"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -519,7 +519,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -532,8 +532,8 @@
"<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>", "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>",
"-->" "-->"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -600,7 +600,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -611,8 +611,8 @@
"", "",
"<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -675,7 +675,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -684,8 +684,8 @@
"", "",
"<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>" "<p>Kitty ipsum dolor sit amet, shed everywhere shed everywhere stretching attack your ankles chase the red dot, hairball run catnip eat the grass sniff.</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -695,13 +695,13 @@
"description": [ "description": [
"You can add images to your website by using the <code>img</code> element, and point to a specific image's URL using the <code>src</code> attribute.", "You can add images to your website by using the <code>img</code> element, and point to a specific image's URL using the <code>src</code> attribute.",
"An example of this would be:", "An example of this would be:",
"<code>&#60img src=\"https://www.your-image-source.com/your-image.jpg\" /&#62</code>", "<code>&#60img src=\"https://www.your-image-source.com/your-image.jpg\"&#62</code>",
"Note that in most cases, <code>img</code> elements are self-closing.", "Note that <code>img</code> elements are self-closing.",
"All <code>img</code> elements <strong>must</strong> have an <code>alt</code> attribute. The text inside an <code>alt</code> attribute is used for screen readers to improve accessibility and is displayed if the image fails to load.", "All <code>img</code> elements <strong>must</strong> have an <code>alt</code> attribute. The text inside an <code>alt</code> attribute is used for screen readers to improve accessibility and is displayed if the image fails to load.",
"Note: If the image is purely decorative, using an empty <code>alt</code> attribute is a best practice.", "Note: If the image is purely decorative, using an empty <code>alt</code> attribute is a best practice.",
"Ideally the <code>alt</code> attribute should not contain special characters unless needed.", "Ideally the <code>alt</code> attribute should not contain special characters unless needed.",
"Let's add an <code>alt</code> attribute to our <code>img</code> example above:", "Let's add an <code>alt</code> attribute to our <code>img</code> example above:",
"<code>&#60img src=\"https://www.your-image-source.com/your-image.jpg\" alt=\"Author standing on a beach with two thumbs up.\" /&#62</code>", "<code>&#60img src=\"https://www.your-image-source.com/your-image.jpg\" alt=\"Author standing on a beach with two thumbs up.\"&#62</code>",
"<hr>", "<hr>",
"Let's try to add an image to our website:", "Let's try to add an image to our website:",
"Insert an <code>img</code> tag, before the <code>h2</code> element.", "Insert an <code>img</code> tag, before the <code>h2</code> element.",
@ -783,7 +783,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-images-to-your-website", "guideUrl": "https://guide.freecodecamp.org/certificates/add-images-to-your-website",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -796,8 +796,8 @@
" <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>", " <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -850,7 +850,7 @@
"He aquí un ejemplo:", "He aquí un ejemplo:",
"<code>&#60;p&#62;Aquí está un &#60;a href=\"https://freecodecamp.org\"&#62; enlace a freeCodeCamp&#60;/a&#62; para que lo sigas.&#60;/p&#62;</code>", "<code>&#60;p&#62;Aquí está un &#60;a href=\"https://freecodecamp.org\"&#62; enlace a freeCodeCamp&#60;/a&#62; para que lo sigas.&#60;/p&#62;</code>",
"<hr>", "<hr>",
"Crea un elemento <code>a</code> que se vincule a <code>http://freecatphotoapp.com</code> y tenga como <code>texto de ancla</code> \"fotos de gatos\"." "Crea un elemento <code>a</code> que se vincule a <code>http://freecatphotoapp.com</code> y tenga como <code>texto de ancla</code> \"cat photos\"."
] ]
}, },
"pt-br": { "pt-br": {
@ -879,7 +879,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -895,8 +895,8 @@
" <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>", " <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -961,7 +961,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -982,8 +982,8 @@
" ", " ",
"<footer>Copyright Cat Photo App</footer>" "<footer>Copyright Cat Photo App</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1089,7 +1089,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1105,8 +1105,8 @@
" <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>", " <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1167,7 +1167,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1182,8 +1182,8 @@
" <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>", " <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1263,7 +1263,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1278,8 +1278,8 @@
" <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>", " <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1366,7 +1366,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1381,8 +1381,8 @@
" <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>", " <p>Purr jump eat the grass rip the couch scratched sunbathe, shed everywhere rip the couch sleep in the sink fluffy fur catnip scratched.</p>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1489,7 +1489,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1510,8 +1510,8 @@
" ", " ",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1522,7 +1522,7 @@
"Now let's create a web form.", "Now let's create a web form.",
"Input elements are a convenient way to get input from your user.", "Input elements are a convenient way to get input from your user.",
"You can create a text input like this:", "You can create a text input like this:",
"<code>&#60;input type=\"text\" /&#62;</code>", "<code>&#60;input type=\"text\"&#62;</code>",
"Note that <code>input</code> elements are self-closing.", "Note that <code>input</code> elements are self-closing.",
"<hr>", "<hr>",
"Create an <code>input</code> element of type <code>text</code> below your lists." "Create an <code>input</code> element of type <code>text</code> below your lists."
@ -1586,7 +1586,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1613,8 +1613,8 @@
" ", " ",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1688,7 +1688,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-placeholder-text-to-a-text-field", "guideUrl": "https://guide.freecodecamp.org/certificates/add-placeholder-text-to-a-text-field",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1714,8 +1714,8 @@
" <input type=\"text\">", " <input type=\"text\">",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1788,7 +1788,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1814,8 +1814,8 @@
" <input type=\"text\" placeholder=\"cat photo URL\">", " <input type=\"text\" placeholder=\"cat photo URL\">",
"<main>" "<main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1893,7 +1893,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/add-a-submit-button-to-a-form", "guideUrl": "https://guide.freecodecamp.org/certificates/add-a-submit-button-to-a-form",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1921,8 +1921,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1991,7 +1991,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2020,8 +2020,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2127,7 +2127,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2156,8 +2156,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2249,7 +2249,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2280,8 +2280,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2350,7 +2350,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2384,8 +2384,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2467,7 +2467,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2502,8 +2502,8 @@
" </form>", " </form>",
"</main>" "</main>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2554,17 +2554,13 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
"contents": [ "contents": [],
"", "head": [],
"", "tail": []
""
],
"head": "",
"tail": ""
} }
} }
}, },
@ -2621,7 +2617,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2635,13 +2631,10 @@
" ", " ",
"</html> " "</html> "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/basic-html-and-html5.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -26,7 +26,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -56,8 +56,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -107,7 +107,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -202,8 +202,8 @@
" </div>", " </div>",
"</footer>" "</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -230,7 +230,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -259,8 +259,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -289,7 +289,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -386,8 +386,8 @@
" </div>", " </div>",
"</footer>" "</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -412,7 +412,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -441,8 +441,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -467,7 +467,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -561,8 +561,8 @@
" </div>", " </div>",
"</footer>" "</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -592,7 +592,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -622,8 +622,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -648,7 +648,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -743,8 +743,8 @@
" </div>", " </div>",
"</footer>" "</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -774,7 +774,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -804,8 +804,8 @@
" <div id=\"box-2\"><p>Goodbye</p></div>", " <div id=\"box-2\"><p>Goodbye</p></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -838,7 +838,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -935,8 +935,8 @@
" </div>", " </div>",
"</footer>" "</footer>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -964,7 +964,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1018,8 +1018,8 @@
" <div id=\"box-6\"></div>", " <div id=\"box-6\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1050,7 +1050,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1080,8 +1080,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1111,7 +1111,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1140,8 +1140,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1179,7 +1179,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1208,8 +1208,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1245,7 +1245,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1273,8 +1273,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1303,7 +1303,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1333,8 +1333,8 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1364,7 +1364,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1394,13 +1394,10 @@
" <div id=\"box-2\"></div>", " <div id=\"box-2\"></div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/css-flexbox.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -26,7 +26,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -57,8 +57,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -86,7 +86,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -118,8 +118,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -144,7 +144,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -177,8 +177,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -209,7 +209,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -243,8 +243,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -271,7 +271,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -306,8 +306,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -332,7 +332,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -367,8 +367,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -393,7 +393,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -427,8 +427,8 @@
" <div class=\"d5\">5</div>", " <div class=\"d5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -438,6 +438,8 @@
"description": [ "description": [
"Up to this point, all the properties that have been discussed are for grid containers. The <code>grid-column</code> property is the first one for use on the grid items themselves.", "Up to this point, all the properties that have been discussed are for grid containers. The <code>grid-column</code> property is the first one for use on the grid items themselves.",
"The hypothetical horizontal and vertical lines that create the grid are referred to as <dfn>lines</dfn>. These lines are numbered starting with 1 at the top left corner of the grid and move right for columns and down for rows, counting upward.", "The hypothetical horizontal and vertical lines that create the grid are referred to as <dfn>lines</dfn>. These lines are numbered starting with 1 at the top left corner of the grid and move right for columns and down for rows, counting upward.",
"This is what the lines look like for a 3x3 grid:",
"<div style=\"position:relative;margin:auto;background:Gainsboro;display:block;margin-top:100px;margin-bottom:50px;width:200px;height:200px;\"><p style=\"left:25%;top:-30%;font-size:130%;position:absolute;color:RoyalBlue;\">column lines</p><p style=\"left:0%;top:-15%;font-size:130%;position:absolute;color:RoyalBlue;\">1</p><p style=\"left:30%;top:-15%;font-size:130%;position:absolute;color:RoyalBlue;\">2</p><p style=\"left:63%;top:-15%;font-size:130%;position:absolute;color:RoyalBlue;\">3</p><p style=\"left:95%;top:-15%;font-size:130%;position:absolute;color:RoyalBlue;\">4</p><p style=\"left:-40%;top:45%;font-size:130%;transform:rotateZ(-90deg);position:absolute;\">row lines</p><p style=\"left:-10%;top:-10%;font-size:130%;position:absolute;\">1</p><p style=\"left:-10%;top:21%;font-size:130%;position:absolute;\">2</p><p style=\"left:-10%;top:53%;font-size:130%;position:absolute;\">3</p><p style=\"left:-10%;top:85%;font-size:130%;position:absolute;\">4</p><div style=\"left:0%;top:0%;width:5%;height:100%;background:RoyalBlue;position:absolute;\"></div><div style=\"left:31%;top:0%;width:5%;height:100%;background:RoyalBlue;position:absolute;\"></div><div style=\"left:63%;top:0%;width:5%;height:100%;background:RoyalBlue;position:absolute;\"></div><div style=\"left:95%;top:0%;width:5%;height:100%;background:RoyalBlue;position:absolute;\"></div><div style=\"left:0%;top:0%;width:100%;height:5%;background:black;position:absolute;\"></div><div style=\"left:0%;top:31%;width:100%;height:5%;background:black;position:absolute;\"></div><div style=\"left:0%;top:63%;width:100%;height:5%;background:black;position:absolute;\"></div><div style=\"left:0%;top:95%;width:100%;height:5%;background:black;position:absolute;\"></div></div>",
"To control the amount of columns an item will consume, you can use the <code>grid-column</code> property in conjunction with the line numbers you want the item to start and stop at.", "To control the amount of columns an item will consume, you can use the <code>grid-column</code> property in conjunction with the line numbers you want the item to start and stop at.",
"Here's an example:", "Here's an example:",
"<blockquote>grid-column: 1 / 3;</blockquote>", "<blockquote>grid-column: 1 / 3;</blockquote>",
@ -458,7 +460,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -497,8 +499,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -523,7 +525,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -563,8 +565,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -572,7 +574,7 @@
"id": "5a90374338fddaf9a66b5d3a", "id": "5a90374338fddaf9a66b5d3a",
"title": "Align an Item Horizontally using justify-self", "title": "Align an Item Horizontally using justify-self",
"description": [ "description": [
"In CSS Grid, the content of each item is located in a box which is referred to as a <dfn>cell</dfn>. You can align the content's position within its cell horizontally using the <code>justify-self</code> property on a grid item. By default, this property has a value of <code>stetch</code>, which will make the content fill the whole width of the cell. This CSS Grid property accepts other values as well:", "In CSS Grid, the content of each item is located in a box which is referred to as a <dfn>cell</dfn>. You can align the content's position within its cell horizontally using the <code>justify-self</code> property on a grid item. By default, this property has a value of <code>stretch</code>, which will make the content fill the whole width of the cell. This CSS Grid property accepts other values as well:",
"<code>start</code>: aligns the content at the left of the cell,", "<code>start</code>: aligns the content at the left of the cell,",
"<code>center</code>: aligns the content in the center of the cell,", "<code>center</code>: aligns the content in the center of the cell,",
"<code>end</code>: aligns the content at the right of the cell.", "<code>end</code>: aligns the content at the right of the cell.",
@ -592,7 +594,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -632,8 +634,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -658,7 +660,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -698,8 +700,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -724,7 +726,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -760,8 +762,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -786,7 +788,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -822,8 +824,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -852,7 +854,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -891,8 +893,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -919,7 +921,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -962,8 +964,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -992,7 +994,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1031,8 +1033,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1065,7 +1067,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1101,8 +1103,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1112,7 +1114,7 @@
"description": [ "description": [
"There's another built-in function to use with <code>grid-template-columns</code> and <code>grid-template-rows</code> called <code>minmax</code>. It's used to limit the size of items when the grid container changes size. To do this you need to specify the acceptable size range for your item. Here is an example:", "There's another built-in function to use with <code>grid-template-columns</code> and <code>grid-template-rows</code> called <code>minmax</code>. It's used to limit the size of items when the grid container changes size. To do this you need to specify the acceptable size range for your item. Here is an example:",
"<blockquote>grid-template-columns: 100px minmax(50px, 200px);</blockquote>", "<blockquote>grid-template-columns: 100px minmax(50px, 200px);</blockquote>",
"In the code above, <code>grid-template-columns</code> is set to create three columns; the first is 100px wide, and the second has the minimum width of 50px and the maximum width of 200px.", "In the code above, <code>grid-template-columns</code> is set to create two columns; the first is 100px wide, and the second has the minimum width of 50px and the maximum width of 200px.",
"<hr>", "<hr>",
"Using the <code>minmax</code> function, replace the <code>1fr</code> in the <code>repeat</code> function with a column size that has the minimum width of <code>90px</code> and the maximum width of <code>1fr</code>, and resize the preview panel to see the effect." "Using the <code>minmax</code> function, replace the <code>1fr</code> in the <code>repeat</code> function with a column size that has the minimum width of <code>90px</code> and the maximum width of <code>1fr</code>, and resize the preview panel to see the effect."
], ],
@ -1129,7 +1131,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1165,8 +1167,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1195,7 +1197,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1248,8 +1250,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1275,7 +1277,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1329,8 +1331,8 @@
" <div class=\"item5\">5</div>", " <div class=\"item5\">5</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1356,7 +1358,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1430,8 +1432,8 @@
" <div class=\"item4\">footer</div>", " <div class=\"item4\">footer</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1461,7 +1463,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1525,13 +1527,10 @@
" <div class=\"item4\">footer</div>", " <div class=\"item4\">footer</div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/css-grid.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -1,5 +1,5 @@
{ {
"name": "Applied Responsive Web Design Projects", "name": "Responsive Web Design Projects",
"order": 7, "order": 7,
"time": "150 hours", "time": "150 hours",
"helpRoom": "Help", "helpRoom": "Help",
@ -8,8 +8,17 @@
"id": "bd7158d8c442eddfaeb5bd18", "id": "bd7158d8c442eddfaeb5bd18",
"title": "Build a Tribute Page", "title": "Build a Tribute Page",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/zNqgVx' target='_blank'>https://codepen.io/freeCodeCamp/full/zNqgVx</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/zNqgVx' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use HTML, JavaScript, and CSS to complete this project. Plain CSS is recommended because that is what the lessons have covered so far and you should get some practice with plain CSS. You can use Bootstrap or SASS if you choose. Additional technologies (just for example jQuery, React, Angular, or Vue) are not recommended for this project, and using them is at your own risk. Other projects will give you a chance to work with different technology stacks like React. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> My tribute page should have an element with a corresponding <code>id=\"main\"</code>, which contains all other elements.",
"<strong>User Story #2:</strong> I should see an element with a corresponding <code>id=\"title\"</code>, which contains a string (i.e. text) that describes the subject of the tribute page (e.g. \"Dr. Norman Borlaug\").",
"<strong>User Story #3:</strong> I should see a <code>div</code> element with a corresponding <code>id=\"img-div\"</code>.",
"<strong>User Story #4:</strong> Within the <code>img-div</code> element, I should see an <code>img</code> element with a corresponding <code>id=\"image\"</code>.",
"<strong>User Story #5:</strong> Within the <code>img-div</code> element, I should see an element with a corresponding <code>id=\"img-caption\"</code> that contains textual content describing the image shown in <code>img-div</code>.",
"<strong>User Story #6:</strong> I should see an element with a corresponding <code>id=\"tribute-info\"</code>, which contains textual content describing the subject of the tribute page.",
"<strong>User Story #7:</strong> I should see an <code>a</code> element with a corresponding <code>id=\"tribute-link\"</code>, which links to an outside site that contains additional information about the subject of the tribute page. HINT: You must give your element an attribute of <code>target</code> and set it to <code>_blank</code> in order for your link to open in a new tab (i.e. <code>target=\"_blank\"</code>).",
"<strong>User Story #8:</strong> The <code>img</code> element should responsively resize, relative to the width of its parent element, without exceeding its original size.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>.", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>.",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -36,8 +45,25 @@
"id": "587d78af367417b2b2512b03", "id": "587d78af367417b2b2512b03",
"title": "Build a Survey Form", "title": "Build a Survey Form",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/VPaoNP' target='_blank'>https://codepen.io/freeCodeCamp/full/VPaoNP</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/VPaoNP' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use HTML, JavaScript, and CSS to complete this project. Plain CSS is recommended because that is what the lessons have covered so far and you should get some practice with plain CSS. You can use Bootstrap or SASS if you choose. Additional technologies (just for example jQuery, React, Angular, or Vue) are not recommended for this project, and using them is at your own risk. Other projects will give you a chance to work with different technology stacks like React. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> I can see a title with <code>id=\"title\"</code> in H1 sized text.",
"<strong>User Story #2:</strong> I can see a short explanation with <code>id=\"description\"</code> in P sized text.",
"<strong>User Story #3:</strong> I can see a <code>form</code> with <code>id=\"survey-form\"</code>.",
"<strong>User Story #4:</strong> Inside the form element, I am required to enter my name in a field with <code>id=\"name\"</code>.",
"<strong>User Story #5:</strong> Inside the form element, I am required to enter an email in a field with <code>id=\"email\"</code>.",
"<strong>User Story #6:</strong> If I enter an email that is not formatted correctly, I will see an HTML5 validation error.",
"<strong>User Story #7:</strong> Inside the form, I can enter a number in a field with <code>id=\"number\"</code>.",
"<strong>User Story #8:</strong> If I enter non-numbers in the number input, I will see an HTML5 validation error.",
"<strong>User Story #9:</strong> If I enter numbers outside the range of the number input, I will see an HTML5 validation error.",
"<strong>User Story #10:</strong> For the name, email, and number input fields inside the form I can see corresponding labels that describe the purpose of each field with the following ids: <code>id=\"name-label\"</code>, <code>id=\"email-label\"</code>, and <code>id=\"number-label\"</code>.",
"<strong>User Story #11:</strong> For the name, email, and number input fields, I can see placeholder text that gives me a description or instructions for each field.",
"<strong>User Story #12:</strong> Inside the form element, I can select an option from a dropdown that has a corresponding <code>id=\"dropdown\"</code>.",
"<strong>User Story #13:</strong> Inside the form element, I can select a field from one or more groups of radio buttons. Each group should be grouped using the <code>name</code> attribute.",
"<strong>User Story #14:</strong> Inside the form element, I can select several fields from a series of checkboxes, each of which must have a <code>value</code> attribute.",
"<strong>User Story #15:</strong> Inside the form element, I am presented with a <code>textarea</code> at the end for additional comments.",
"<strong>User Story #16:</strong> Inside the form element, I am presented with a button with <code>id=\"submit\"</code> to submit all my inputs.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -54,8 +80,24 @@
"id": "587d78af367417b2b2512b04", "id": "587d78af367417b2b2512b04",
"title": "Build a Product Landing Page", "title": "Build a Product Landing Page",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/RKRbwL' target='_blank'>https://codepen.io/freeCodeCamp/full/RKRbwL</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/RKRbwL' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use HTML, JavaScript, and CSS to complete this project. Plain CSS is recommended because that is what the lessons have covered so far and you should get some practice with plain CSS. You can use Bootstrap or SASS if you choose. Additional technologies (just for example jQuery, React, Angular, or Vue) are not recommended for this project, and using them is at your own risk. Other projects will give you a chance to work with different technology stacks like React. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> My product landing page should have a <code>header</code> element with a corresponding <code>id=\"header\"</code>.",
"<strong>User Story #2:</strong> I can see an image within the <code>header</code> element with a corresponding <code>id=\"header-img\"</code>. A company logo would make a good image here.",
"<strong>User Story #3:</strong> Within the <code>#header</code> element I can see a <code>nav</code> element with a corresponding <code>id=\"nav-bar\"</code>.",
"<strong>User Story #4:</strong> I can see at least three clickable elements inside the <code>nav</code> element, each with the class <code>nav-link</code>.",
"<strong>User Story #5:</strong> When I click a <code>.nav-link</code> button in the <code>nav</code> element, I am taken to the corresponding section of the landing page.",
"<strong>User Story #6:</strong> I can watch an embedded product video with <code>id=\"video\"</code>.",
"<strong>User Story #7:</strong> My landing page has a <code>form</code> element with a corresponding <code>id=\"form\"</code>.",
"<strong>User Story #8:</strong> Within the form, there is an <code>input</code> field with <code>id=\"email\"</code> where I can enter an email address.",
"<strong>User Story #9:</strong> The <code>#email</code> input field should have placeholder text to let the user know what the field is for.",
"<strong>User Story #10:</strong> The <code>#email</code> input field uses HTML5 validation to confirm that the entered text is an email address.",
"<strong>User Story #11:</strong> Within the form, there is a submit <code>input</code> with a corresponding <code>id=\"submit\"</code>.",
"<strong>User Story #12:</strong> When I click the <code>#submit</code> element, the email is submitted to a static page (use this mock URL: <a href='https://www.freecodecamp.com/email-submit' target='_blank'>https://www.freecodecamp.com/email-submit</a>) that confirms the email address was entered and that it posted successfully.",
"<strong>User Story #13:</strong> The navbar should always be at the top of the viewport.",
"<strong>User Story #14:</strong> My product landing page should have at least one media query.",
"<strong>User Story #15:</strong> My product landing page should utilize CSS flexbox at least once.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/full/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/full/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -72,8 +114,24 @@
"id": "587d78b0367417b2b2512b05", "id": "587d78b0367417b2b2512b05",
"title": "Build a Technical Documentation Page", "title": "Build a Technical Documentation Page",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/NdrKKL' target='_blank'>https://codepen.io/freeCodeCamp/full/NdrKKL</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/NdrKKL' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use HTML, JavaScript, and CSS to complete this project. Plain CSS is recommended because that is what the lessons have covered so far and you should get some practice with plain CSS. You can use Bootstrap or SASS if you choose. Additional technologies (just for example jQuery, React, Angular, or Vue) are not recommended for this project, and using them is at your own risk. Other projects will give you a chance to work with different technology stacks like React. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> I can see a <code>main</code> element with a corresponding <code>id=\"main-doc\"</code>, which contains the page's main content (technical documentation).",
"<strong>User Story #2:</strong> Within the <code>#main-doc</code> element, I can see several <code>section</code> elements, each with a class of <code>main-section</code>. There should be a minimum of 5.",
"<strong>User Story #3:</strong> The first element within each <code>.main-section</code> should be a <code>header</code> element which contains text that describes the topic of that section.",
"<strong>User Story #4:</strong> Each <code>section</code> element with the class of <code>main-section</code> should also have an id that corresponds with the text of each <code>header</code> contained within it. Any spaces should be replaced with underscores (e.g. The <code>section</code> that contains the header \"Javascript and Java\" should have a corresponding <code>id=\"Javascript_and_Java\"</code>).",
"<strong>User Story #5:</strong> The <code>.main-section</code> elements should contain at least 10 <code>p</code> elements total (not each).",
"<strong>User Story #6:</strong> The <code>.main-section</code> elements should contain at least 5 <code>code</code> elements total (not each).",
"<strong>User Story #7:</strong> The <code>.main-section</code> elements should contain at least 5 <code>li</code> items total (not each).",
"<strong>User Story #8:</strong> I can see a <code>nav</code> element with a corresponding <code>id=\"navbar\"</code>.",
"<strong>User Story #9:</strong> The navbar element should contain one <code>header</code> element which contains text that describes the topic of the technical documentation.",
"<strong>User Story #10:</strong> Additionally, the navbar should contain link (<code>a</code>) elements with the class of <code>nav-link</code>. There should be one for every element with the class <code>main-section</code>.",
"<strong>User Story #11:</strong> The <code>header</code> element in the navbar must come before any link (<code>a</code>) elements in the navbar.",
"<strong>User Story #12:</strong> Each element with the class of <code>nav-link</code> should contain text that corresponds to the <code>header</code> text within each <code>section</code> (e.g. if you have a \"Hello world\" section/header, your navbar should have an element which contains the text \"Hello world\").",
"<strong>User Story #13:</strong> When I click on a navbar element, the page should navigate to the corresponding section of the <code>main-doc</code> element (e.g. If I click on a <code>nav-link</code> element that contains the text \"Hello world\", the page navigates to a <code>section</code> element that has that id and contains the corresponding <code>header</code>.",
"<strong>User Story #14:</strong> On regular sized devices (laptops, desktops), the element with <code>id=\"navbar\"</code> should be shown on the left side of the screen and should always be visible to the user.",
"<strong>User Story #15:</strong> My Technical Documentation page should use at least one media query.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -90,8 +148,20 @@
"id": "bd7158d8c242eddfaeb5bd13", "id": "bd7158d8c242eddfaeb5bd13",
"title": "Build a Personal Portfolio Webpage", "title": "Build a Personal Portfolio Webpage",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/zNBOYG' target='_blank'>https://codepen.io/freeCodeCamp/full/zNBOYG</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/zNBOYG' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use HTML, JavaScript, and CSS to complete this project. Plain CSS is recommended because that is what the lessons have covered so far and you should get some practice with plain CSS. You can use Bootstrap or SASS if you choose. Additional technologies (just for example jQuery, React, Angular, or Vue) are not recommended for this project, and using them is at your own risk. Other projects will give you a chance to work with different technology stacks like React. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> My portfolio should have a welcome section with an id of <code>welcome-section</code>.",
"<strong>User Story #2:</strong> The welcome section should have an <code>h1</code> element that contains text.",
"<strong>User Story #3:</strong> My portfolio should have a projects section with an id of <code>projects</code>.",
"<strong>User Story #4:</strong> The projects section should contain at least one element with a class of <code>project-tile</code> to hold a project.",
"<strong>User Story #5:</strong> The projects section should contain at least one link to a project.",
"<strong>User Story #6:</strong> My portfolio should have a navbar with an id of <code>navbar</code>.",
"<strong>User Story #7:</strong> The navbar should contain at least one link that I can click on to navigate to different sections of the page.",
"<strong>User Story #8:</strong> My portfolio should have a link with an id of <code>profile-link</code>, which opens my GitHub or FCC profile in a new tab.",
"<strong>User Story #9:</strong> My portfolio should have at least one media query.",
"<strong>User Story #10:</strong> The height of the welcome section should be equal to the height of the viewport.",
"<strong>User Story #11:</strong> The navbar should always be at the top of the viewport.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -113,8 +183,5 @@
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/responsive-web-design-projects.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -48,7 +48,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -64,8 +64,8 @@
" ", " ",
"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis tempus massa. Aenean erat nisl, gravida vel vestibulum cursus, interdum sit amet lectus. Sed sit amet quam nibh. Suspendisse quis tincidunt nulla. In hac habitasse platea dictumst. Ut sit amet pretium nisl. Vivamus vel mi sem. Aenean sit amet consectetur sem. Suspendisse pretium, purus et gravida consequat, nunc ligula ultricies diam, at aliquet velit libero a dui.</p>" "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis tempus massa. Aenean erat nisl, gravida vel vestibulum cursus, interdum sit amet lectus. Sed sit amet quam nibh. Suspendisse quis tincidunt nulla. In hac habitasse platea dictumst. Ut sit amet pretium nisl. Vivamus vel mi sem. Aenean sit amet consectetur sem. Suspendisse pretium, purus et gravida consequat, nunc ligula ultricies diam, at aliquet velit libero a dui.</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -115,7 +115,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -126,8 +126,8 @@
"", "",
"<img src=\"https://s3.amazonaws.com/freecodecamp/FCCStickerPack.jpg\" alt=\"freeCodeCamp stickers set\">" "<img src=\"https://s3.amazonaws.com/freecodecamp/FCCStickerPack.jpg\" alt=\"freeCodeCamp stickers set\">"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -169,7 +169,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -180,8 +180,8 @@
"", "",
"<img src=\"https://s3.amazonaws.com/freecodecamp/FCCStickers-CamperBot200x200.jpg\" alt=\"freeCodeCamp sticker that says 'Because CamperBot Cares'\">" "<img src=\"https://s3.amazonaws.com/freecodecamp/FCCStickers-CamperBot200x200.jpg\" alt=\"freeCodeCamp sticker that says 'Because CamperBot Cares'\">"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -223,7 +223,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -235,13 +235,10 @@
"<h2>Importantus Ipsum</h2>", "<h2>Importantus Ipsum</h2>",
"<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis tempus massa. Aenean erat nisl, gravida vel vestibulum cursus, interdum sit amet lectus. Sed sit amet quam nibh. Suspendisse quis tincidunt nulla. In hac habitasse platea dictumst. Ut sit amet pretium nisl. Vivamus vel mi sem. Aenean sit amet consectetur sem. Suspendisse pretium, purus et gravida consequat, nunc ligula ultricies diam, at aliquet velit libero a dui.</p>" "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus quis tempus massa. Aenean erat nisl, gravida vel vestibulum cursus, interdum sit amet lectus. Sed sit amet quam nibh. Suspendisse quis tincidunt nulla. In hac habitasse platea dictumst. Ut sit amet pretium nisl. Vivamus vel mi sem. Aenean sit amet consectetur sem. Suspendisse pretium, purus et gravida consequat, nunc ligula ultricies diam, at aliquet velit libero a dui.</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "01-responsive-web-design/responsive-web-design.json",
"superBlock": "responsive-web-design",
"superOrder": 1
} }

View File

@ -75,8 +75,8 @@
"", "",
"convertToF(30);" "convertToF(30);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -151,8 +151,8 @@
"", "",
"reverseString(\"hello\");" "reverseString(\"hello\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -232,8 +232,8 @@
"", "",
"factorialize(5);" "factorialize(5);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -311,8 +311,8 @@
"", "",
"findLongestWordLength(\"The quick brown fox jumped over the lazy dog\");" "findLongestWordLength(\"The quick brown fox jumped over the lazy dog\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -383,8 +383,8 @@
"", "",
"largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);" "largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -483,8 +483,8 @@
"", "",
"confirmEnding(\"Bastian\", \"n\");" "confirmEnding(\"Bastian\", \"n\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -563,8 +563,8 @@
"", "",
"repeatStringNumTimes(\"abc\", 3);" "repeatStringNumTimes(\"abc\", 3);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -639,8 +639,8 @@
"", "",
"truncateString(\"A-tisket a-tasket A green and yellow basket\", 8);" "truncateString(\"A-tisket a-tasket A green and yellow basket\", 8);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -706,8 +706,8 @@
"", "",
"findElement([1, 2, 3, 4], num => num % 2 === 0);" "findElement([1, 2, 3, 4], num => num % 2 === 0);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -809,8 +809,8 @@
"", "",
"booWho(null);" "booWho(null);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -879,8 +879,8 @@
"", "",
"titleCase(\"I'm a little tea pot\");" "titleCase(\"I'm a little tea pot\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -955,8 +955,11 @@
"", "",
"frankenSplice([1, 2, 3], [4, 5, 6], 1);" "frankenSplice([1, 2, 3], [4, 5, 6], 1);"
], ],
"head": "", "head": [],
"tail": "let testArr1 = [1, 2];\nlet testArr2 = [\"a\", \"b\"];" "tail": [
"let testArr1 = [1, 2];",
"let testArr2 = [\"a\", \"b\"];"
]
} }
} }
}, },
@ -1029,8 +1032,8 @@
"", "",
"bouncer([7, \"ate\", \"\", false, 9]);" "bouncer([7, \"ate\", \"\", false, 9]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1151,8 +1154,8 @@
"", "",
"getIndexToIns([40, 60], 50);" "getIndexToIns([40, 60], 50);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1247,8 +1250,8 @@
"", "",
"mutation([\"hello\", \"hey\"]);" "mutation([\"hello\", \"hey\"]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1328,13 +1331,10 @@
"", "",
"chunkArrayInGroups([\"a\", \"b\", \"c\", \"d\"], 2);" "chunkArrayInGroups([\"a\", \"b\", \"c\", \"d\"], 2);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/basic-algorithm-scripting.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -51,8 +51,8 @@
"contents": [ "contents": [
"let yourArray; // change this line" "let yourArray; // change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -107,8 +107,8 @@
"//change code above this line", "//change code above this line",
"console.log(myArray);" "console.log(myArray);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -158,8 +158,8 @@
"// do not change code below this line", "// do not change code below this line",
"console.log(mixedNumbers(['IV', 5, 'six']));" "console.log(mixedNumbers(['IV', 5, 'six']));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -209,8 +209,8 @@
"// do not change code below this line", "// do not change code below this line",
"console.log(popShift(['challenge', 'is', 'not', 'complete']));" "console.log(popShift(['challenge', 'is', 'not', 'complete']));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -257,8 +257,8 @@
"// do not change code below this line", "// do not change code below this line",
"console.log(sumOfTen([2, 5, 1, 5, 2, 1]));" "console.log(sumOfTen([2, 5, 1, 5, 2, 1]));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -311,8 +311,8 @@
"// do not change code below this line", "// do not change code below this line",
"console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']));" "console.log(htmlColorNames(['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick']));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -356,8 +356,8 @@
"// do not change code below this line", "// do not change code below this line",
"console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']));" "console.log(forecast(['cold', 'rainy', 'warm', 'sunny', 'cool', 'thunderstorms']));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -418,8 +418,8 @@
"// change code here to test different cases:", "// change code here to test different cases:",
"console.log(copyMachine([true, false, true], 2));" "console.log(copyMachine([true, false, true], 2));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -463,8 +463,8 @@
"// do not change code below this line", "// do not change code below this line",
"console.log(spreadOut());" "console.log(spreadOut());"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -520,8 +520,8 @@
"// change code here to test different cases:", "// change code here to test different cases:",
"console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));" "console.log(quickCheck(['squash', 'onions', 'shallots'], 'mushrooms'));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -580,8 +580,8 @@
"// change code here to test different cases:", "// change code here to test different cases:",
"console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));" "console.log(filteredArray([[3, 2, 3], [1, 6, 3], [3, 13, 26], [19, 3, 9]], 3));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -643,8 +643,8 @@
" // change code above this line", " // change code above this line",
"];" "];"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -707,8 +707,8 @@
"", "",
"console.log(foods);" "console.log(foods);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -766,8 +766,8 @@
"", "",
"console.log(userActivity);" "console.log(userActivity);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -832,8 +832,8 @@
"// change code below this line to test different cases:", "// change code below this line to test different cases:",
"console.log(checkInventory(\"apples\"));" "console.log(checkInventory(\"apples\"));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -884,8 +884,8 @@
"", "",
"console.log(foods);" "console.log(foods);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -950,8 +950,8 @@
"", "",
"console.log(isEveryoneHere(users));" "console.log(isEveryoneHere(users));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1014,8 +1014,8 @@
"", "",
"console.log(countOnline(users));" "console.log(countOnline(users));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1075,8 +1075,8 @@
"", "",
"console.log(getArrayOfUsers(users));" "console.log(getArrayOfUsers(users));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1141,13 +1141,10 @@
"", "",
"console.log(addFriend(user, 'Pete'));" "console.log(addFriend(user, 'Pete'));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/basic-data-structures.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -43,8 +43,8 @@
"let sumAB = a + b;", "let sumAB = a + b;",
"console.log(sumAB);" "console.log(sumAB);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -73,7 +73,7 @@
}, },
{ {
"text": "Use <code>console.clear()</code> to modify your output so that <code>outputOne</code> variable only outputs once.", "text": "Use <code>console.clear()</code> to modify your output so that <code>outputOne</code> variable only outputs once.",
"testString": "assert(code.match(/console\\.clear\\(\\)/g), 'Use <code>console.clear()</code> to modify your output so that <code>outputOne</code> variable only outputs once.');" "testString": "assert(code.match(/(?<!\\/\\/ Use )console\\.clear\\(\\)/g), 'Use <code>console.clear()</code> to modify your output so that <code>outputOne</code> variable only outputs once.');"
} }
], ],
"solutions": [], "solutions": [],
@ -101,8 +101,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -149,8 +149,8 @@
"// Add your code below this line", "// Add your code below this line",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -202,8 +202,8 @@
"let netWorkingCapital = recievables - payable;", "let netWorkingCapital = recievables - payable;",
"console.log(`Net working capital is: ${netWorkingCapital}`);" "console.log(`Net working capital is: ${netWorkingCapital}`);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -242,8 +242,8 @@
"let arraySum = myArray.reduce((previous, current => previous + current);", "let arraySum = myArray.reduce((previous, current => previous + current);",
"console.log(`Sum of array values is: ${arraySum}`);" "console.log(`Sum of array values is: ${arraySum}`);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -285,8 +285,8 @@
"let innerHtml = \"<p>Click here to <a href=\"#Home\">return home</a></p>\";", "let innerHtml = \"<p>Click here to <a href=\"#Home\">return home</a></p>\";",
"console.log(innerHtml);" "console.log(innerHtml);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -336,8 +336,8 @@
"", "",
"console.log(result);" "console.log(result);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -382,8 +382,8 @@
"let result = getNine;", "let result = getNine;",
"console.log(result);" "console.log(result);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -426,8 +426,8 @@
"let power = raiseToPower(exp, base);", "let power = raiseToPower(exp, base);",
"console.log(power);" "console.log(power);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -483,8 +483,8 @@
"", "",
"countToFive();" "countToFive();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -543,8 +543,8 @@
"let matrix = zeroArray(3, 2);", "let matrix = zeroArray(3, 2);",
"console.log(matrix);" "console.log(matrix);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -587,13 +587,10 @@
" }", " }",
"}" "}"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/debugging.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -11,7 +11,7 @@
"One of the biggest problems with declaring variables with the <code>var</code> keyword is that you can overwrite variable declarations without an error.", "One of the biggest problems with declaring variables with the <code>var</code> keyword is that you can overwrite variable declarations without an error.",
"<blockquote>var camper = 'James';<br>var camper = 'David';<br>console.log(camper);<br>// logs 'David'</blockquote>", "<blockquote>var camper = 'James';<br>var camper = 'David';<br>console.log(camper);<br>// logs 'David'</blockquote>",
"As you can see in the code above, the <code>camper</code> variable is originally declared as <code>James</code> and then overridden to be <code>David</code>.", "As you can see in the code above, the <code>camper</code> variable is originally declared as <code>James</code> and then overridden to be <code>David</code>.",
"In a small application, you might not run into this type of problem, but when your code becomes larger, you might accidently overwrite a variable that you did not intend to overwrite.", "In a small application, you might not run into this type of problem, but when your code becomes larger, you might accidentally overwrite a variable that you did not intend to overwrite.",
"Because this behavior does not throw an error, searching and fixing bugs becomes more difficult.<br>", "Because this behavior does not throw an error, searching and fixing bugs becomes more difficult.<br>",
"A new keyword called <code>let</code> was introduced in ES6 to solve this potential issue with the <code>var</code> keyword.", "A new keyword called <code>let</code> was introduced in ES6 to solve this potential issue with the <code>var</code> keyword.",
"If you were to replace <code>var</code> with <code>let</code> in the variable declarations of the code above, the result would be an error.", "If you were to replace <code>var</code> with <code>let</code> in the variable declarations of the code above, the result would be an error.",
@ -58,8 +58,8 @@
"}", "}",
"catTalk();" "catTalk();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -71,7 +71,7 @@
"The <code>let</code> keyword behaves similarly, but with some extra features. When you declare a variable with the <code>let</code> keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.", "The <code>let</code> keyword behaves similarly, but with some extra features. When you declare a variable with the <code>let</code> keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.",
"For example:", "For example:",
"<blockquote>var numArray = [];<br>for (var i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>", "<blockquote>var numArray = [];<br>for (var i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>",
"With the <code>var</code> keyword, <code>i</code> is declared globally. So when <code>i++</code> is executed, it updates the global variable. This code is similiar to the following:", "With the <code>var</code> keyword, <code>i</code> is declared globally. So when <code>i++</code> is executed, it updates the global variable. This code is similar to the following:",
"<blockquote>var numArray = [];<br>var i;<br>for (i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>", "<blockquote>var numArray = [];<br>var i;<br>for (i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>",
"This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the <code>i</code> variable. This is because the stored function will always refer to the value of the updated global <code>i</code> variable.", "This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the <code>i</code> variable. This is because the stored function will always refer to the value of the updated global <code>i</code> variable.",
"<blockquote>var printNumTwo;<br>for (var i = 0; i < 3; i++) {<br> if(i === 2){<br> printNumTwo = function() {<br> return i;<br> };<br> }<br>}<br>console.log(printNumTwo());<br>// returns 3</blockquote>", "<blockquote>var printNumTwo;<br>for (var i = 0; i < 3; i++) {<br> if(i === 2){<br> printNumTwo = function() {<br> return i;<br> };<br> }<br>}<br>console.log(printNumTwo());<br>// returns 3</blockquote>",
@ -106,7 +106,6 @@
"ext": "js", "ext": "js",
"name": "index", "name": "index",
"contents": [ "contents": [
"",
"function checkScope() {", "function checkScope() {",
"\"use strict\";", "\"use strict\";",
" var i = \"function scope\";", " var i = \"function scope\";",
@ -118,8 +117,8 @@
" return i;", " return i;",
"}" "}"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -173,8 +172,8 @@
"}", "}",
"printManyTimes(\"freeCodeCamp\");" "printManyTimes(\"freeCodeCamp\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -229,8 +228,8 @@
"}", "}",
"editInPlace();" "editInPlace();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -290,8 +289,8 @@
"}", "}",
"const PI = freezeObj();" "const PI = freezeObj();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -347,8 +346,8 @@
" return new Date();", " return new Date();",
"};" "};"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -401,8 +400,8 @@
"// test your code", "// test your code",
"console.log(myConcat([1, 2], [3, 4, 5]));" "console.log(myConcat([1, 2], [3, 4, 5]));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -472,8 +471,8 @@
"const squaredIntegers = squareList(realNumberArray);", "const squaredIntegers = squareList(realNumberArray);",
"console.log(squaredIntegers);" "console.log(squaredIntegers);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -521,8 +520,8 @@
"console.log(increment(5, 2)); // returns 7", "console.log(increment(5, 2)); // returns 7",
"console.log(increment(5)); // returns NaN" "console.log(increment(5)); // returns NaN"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -535,7 +534,7 @@
"<blockquote>function howMany(...args) {<br> return \"You have passed \" + args.length + \" arguments.\";<br>}<br>console.log(howMany(0, 1, 2)); // You have passed 3 arguments<br>console.log(howMany(\"string\", null, [1, 2, 3], { })); // You have passed 4 arguments.</blockquote>", "<blockquote>function howMany(...args) {<br> return \"You have passed \" + args.length + \" arguments.\";<br>}<br>console.log(howMany(0, 1, 2)); // You have passed 3 arguments<br>console.log(howMany(\"string\", null, [1, 2, 3], { })); // You have passed 4 arguments.</blockquote>",
"The rest operator eliminates the need to check the <code>args</code> array and allows us to apply <code>map()</code>, <code>filter()</code> and <code>reduce()</code> on the parameters array.", "The rest operator eliminates the need to check the <code>args</code> array and allows us to apply <code>map()</code>, <code>filter()</code> and <code>reduce()</code> on the parameters array.",
"<hr>", "<hr>",
"Modify the function <code>sum</code> so that is uses the rest operator and it works in the same way with any number of parameters." "Modify the function <code>sum</code> so that it uses the rest operator and it works in the same way with any number of parameters."
], ],
"tests": [ "tests": [
{ {
@ -578,8 +577,8 @@
"})();", "})();",
"console.log(sum(1, 2, 3)); // 6" "console.log(sum(1, 2, 3)); // 6"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -631,8 +630,8 @@
"})();", "})();",
"console.log(arr2);" "console.log(arr2);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -689,8 +688,8 @@
"", "",
"console.log(getLength('FreeCodeCamp'));" "console.log(getLength('FreeCodeCamp'));"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -740,8 +739,8 @@
"", "",
"console.log(getMaxOfTmrw(LOCAL_FORECAST)); // should be 84.6" "console.log(getMaxOfTmrw(LOCAL_FORECAST)); // should be 84.6"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -793,8 +792,8 @@
"console.log(a); // should be 6", "console.log(a); // should be 6",
"console.log(b); // should be 8" "console.log(b); // should be 8"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -808,7 +807,7 @@
"Variables <code>a</code> and <code>b</code> take the first and second values from the array. After that, because of rest operator's presence, <code>arr</code> gets rest of the values in the form of an array.", "Variables <code>a</code> and <code>b</code> take the first and second values from the array. After that, because of rest operator's presence, <code>arr</code> gets rest of the values in the form of an array.",
"The rest element only works correctly as the last variable in the list. As in, you cannot use the rest operator to catch a subarray that leaves out last element of the original array.", "The rest element only works correctly as the last variable in the list. As in, you cannot use the rest operator to catch a subarray that leaves out last element of the original array.",
"<hr>", "<hr>",
"Use destructuring assignment with the rest operator to perform an effective <code>Array.prototype.slice()</code> so that <code>arr</code> is a sub-array of the original array <code>source</code> with the first two elements ommitted." "Use destructuring assignment with the rest operator to perform an effective <code>Array.prototype.slice()</code> so that <code>arr</code> is a sub-array of the original array <code>source</code> with the first two elements omitted."
], ],
"tests": [ "tests": [
{ {
@ -817,7 +816,7 @@
}, },
{ {
"text": "destructuring was used.", "text": "destructuring was used.",
"testString": "getUserInput => assert(getUserInput('index').match(/\\[\\s*\\w\\s*,\\s*\\w\\s*,\\s*...arr\\s*\\]/g),'destructuring was used.');" "testString": "getUserInput => assert(getUserInput('index').match(/\\[\\s*\\w*\\s*,\\s*\\w*\\s*,\\s*...arr\\s*\\]/g),'destructuring was used.');"
}, },
{ {
"text": "<code>Array.slice()</code> was not used.", "text": "<code>Array.slice()</code> was not used.",
@ -846,8 +845,8 @@
"console.log(arr); // should be [3,4,5,6,7,8,9,10]", "console.log(arr); // should be [3,4,5,6,7,8,9,10]",
"console.log(source); // should be [1,2,3,4,5,6,7,8,9,10];" "console.log(source); // should be [1,2,3,4,5,6,7,8,9,10];"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -911,8 +910,8 @@
"console.log(stats); // should be object", "console.log(stats); // should be object",
"console.log(half(stats)); // should be 28.015" "console.log(half(stats)); // should be 28.015"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -976,8 +975,8 @@
" **/", " **/",
"const resultDisplayArray = makeList(result.failure);" "const resultDisplayArray = makeList(result.failure);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -985,7 +984,7 @@
"id": "587d7b8a367417b2b2512b4f", "id": "587d7b8a367417b2b2512b4f",
"title": "Write Concise Object Literal Declarations Using Simple Fields", "title": "Write Concise Object Literal Declarations Using Simple Fields",
"description": [ "description": [
"ES6 adds some nice support for easily definining object literals.", "ES6 adds some nice support for easily defining object literals.",
"Consider the following code:", "Consider the following code:",
"<blockquote>const getMousePosition = (x, y) => ({<br> x: x,<br> y: y<br>});</blockquote>", "<blockquote>const getMousePosition = (x, y) => ({<br> x: x,<br> y: y<br>});</blockquote>",
"<code>getMousePosition</code> is a simple function that returns an object containing two fields.", "<code>getMousePosition</code> is a simple function that returns an object containing two fields.",
@ -1027,8 +1026,8 @@
"};", "};",
"console.log(createPerson(\"Zodiac Hasbro\", 56, \"male\")); // returns a proper object" "console.log(createPerson(\"Zodiac Hasbro\", 56, \"male\")); // returns a proper object"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1075,8 +1074,8 @@
"bicycle.setGear(3);", "bicycle.setGear(3);",
"console.log(bicycle.gear);" "console.log(bicycle.gear);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1130,8 +1129,8 @@
"const carrot = new Vegetable('carrot');", "const carrot = new Vegetable('carrot');",
"console.log(carrot.name); // => should be 'carrot'" "console.log(carrot.name); // => should be 'carrot'"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1147,7 +1146,7 @@
"Notice the syntax we are using to invoke the getter and setter - as if they are not even functions.", "Notice the syntax we are using to invoke the getter and setter - as if they are not even functions.",
"Getters and setters are important, because they hide internal implementation details.", "Getters and setters are important, because they hide internal implementation details.",
"<hr>", "<hr>",
"Use <code>class</code> keyword to create a Thermostat class. The constructor accepts Farenheit temperature.", "Use <code>class</code> keyword to create a Thermostat class. The constructor accepts Fahrenheit temperature.",
"Now create <code>getter</code> and <code>setter</code> in the class, to obtain the temperature in Celsius scale.", "Now create <code>getter</code> and <code>setter</code> in the class, to obtain the temperature in Celsius scale.",
"Remember that <code>C = 5/9 * (F - 32)</code> and <code>F = C * 9.0 / 5 + 32</code>, where F is the value of temperature in Fahrenheit scale, and C is the value of the same temperature in Celsius scale", "Remember that <code>C = 5/9 * (F - 32)</code> and <code>F = C * 9.0 / 5 + 32</code>, where F is the value of temperature in Fahrenheit scale, and C is the value of the same temperature in Celsius scale",
"Note", "Note",
@ -1187,13 +1186,13 @@
" return Thermostat;", " return Thermostat;",
"}", "}",
"const Thermostat = makeClass();", "const Thermostat = makeClass();",
"const thermos = new Thermostat(76); // setting in Farenheit scale", "const thermos = new Thermostat(76); // setting in Fahrenheit scale",
"let temp = thermos.temperature; // 24.44 in C", "let temp = thermos.temperature; // 24.44 in C",
"thermos.temperature = 26;", "thermos.temperature = 26;",
"temp = thermos.temperature; // 26 in C" "temp = thermos.temperature; // 26 in C"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1210,7 +1209,7 @@
"There are a few ways to write an <code>import</code> statement, but the above is a very common use-case.", "There are a few ways to write an <code>import</code> statement, but the above is a very common use-case.",
"<strong>Note</strong><br>The whitespace surrounding the function inside the curly braces is a best practice - it makes it easier to read the <code>import</code> statement.", "<strong>Note</strong><br>The whitespace surrounding the function inside the curly braces is a best practice - it makes it easier to read the <code>import</code> statement.",
"<strong>Note</strong><br>The lessons in this section handle non-browser features. <code>import</code>, and the statements we introduce in the rest of these lessons, won't work on a browser directly. However, we can use various tools to create code out of this to make it work in browser.", "<strong>Note</strong><br>The lessons in this section handle non-browser features. <code>import</code>, and the statements we introduce in the rest of these lessons, won't work on a browser directly. However, we can use various tools to create code out of this to make it work in browser.",
"<strong>Note</strong><br>In most cases, the file path requires a <code>./</code> before it; otherwise, node will look in the <code>node_modules</code> directory first trying to load it as a dependencie.", "<strong>Note</strong><br>In most cases, the file path requires a <code>./</code> before it; otherwise, node will look in the <code>node_modules</code> directory first trying to load it as a dependency.",
"<hr>", "<hr>",
"Add the appropriate <code>import</code> statement that will allow the current file to use the <code>capitalizeString</code> function. The file where this function lives is called <code>\"string_functions\"</code>, and it is in the same directory as the current file." "Add the appropriate <code>import</code> statement that will allow the current file to use the <code>capitalizeString</code> function. The file where this function lives is called <code>\"string_functions\"</code>, and it is in the same directory as the current file."
], ],
@ -1233,8 +1232,14 @@
"\"use strict\";", "\"use strict\";",
"capitalizeString(\"hello!\");" "capitalizeString(\"hello!\");"
], ],
"head": "window.require = function (str) {\nif (str === 'string_functions') {\nreturn {\ncapitalizeString: str => str.toUpperCase()\n}}};", "head": [
"tail": "" "window.require = function (str) {",
"if (str === 'string_functions') {",
"return {",
"capitalizeString: str => str.toUpperCase()",
"}}};"
],
"tail": []
} }
} }
}, },
@ -1275,8 +1280,10 @@
"const foo = \"bar\";", "const foo = \"bar\";",
"const boo = \"far\";" "const boo = \"far\";"
], ],
"head": "window.exports = function(){};", "head": [
"tail": "" "window.exports = function(){};"
],
"tail": []
} }
} }
}, },
@ -1286,7 +1293,7 @@
"description": [ "description": [
"Suppose you have a file that you wish to import all of its contents into the current file. This can be done with the <dfn>import *</dfn> syntax.", "Suppose you have a file that you wish to import all of its contents into the current file. This can be done with the <dfn>import *</dfn> syntax.",
"Here's an example where the contents of a file named <code>\"math_functions\"</code> are imported into a file in the same directory:", "Here's an example where the contents of a file named <code>\"math_functions\"</code> are imported into a file in the same directory:",
"<blockquote>import * as myMathModule from \"math_functions\"<br>myMathModule.add(2,3);<br>myMathModule.subtract(5,3);</blockquote>", "<blockquote>import * as myMathModule from \"math_functions\";<br>myMathModule.add(2,3);<br>myMathModule.subtract(5,3);</blockquote>",
"And breaking down that code:", "And breaking down that code:",
"<blockquote>import * as object_with_name_of_your_choice from \"file_path_goes_here\"<br>object_with_name_of_your_choice.imported_function</blockquote>", "<blockquote>import * as object_with_name_of_your_choice from \"file_path_goes_here\"<br>object_with_name_of_your_choice.imported_function</blockquote>",
"You may use any name following the <code>import * as </code>portion of the statement. In order to utilize this method, it requires an object that receives the imported values. From here, you will use the dot notation to call your imported values.", "You may use any name following the <code>import * as </code>portion of the statement. In order to utilize this method, it requires an object that receives the imported values. From here, you will use the dot notation to call your imported values.",
@ -1296,7 +1303,7 @@
"tests": [ "tests": [
{ {
"text": "Properly uses <code>import * as</code> syntax.", "text": "Properly uses <code>import * as</code> syntax.",
"testString": "getUserInput => assert(getUserInput('index').match(/import\\s+\\*\\s+as\\s+myStringModule\\s+from\\s+\"capitalize_strings\"/g), 'Properly uses <code>import * as</code> syntax.');" "testString": "assert(code.match(/import\\s+\\*\\s+as\\s+[a-zA-Z0-9_$]+\\s+from\\s*\"\\s*capitalize_strings\\s*\"\\s*;/gi), 'Properly uses <code>import * as</code> syntax.');"
} }
], ],
"type": "waypoint", "type": "waypoint",
@ -1309,12 +1316,17 @@
"ext": "js", "ext": "js",
"name": "index", "name": "index",
"contents": [ "contents": [
"\"use strict\";", "\"use strict\";"
"myStringModule.capitalize(\"foo\");",
"myStringModule.lowercase(\"Foo\");"
], ],
"head": "window.require = function(str) {\nif (str === 'capitalize_strings') {\nreturn {\ncapitalize: str => str.toUpperCase(),\nlowercase: str => str.toLowerCase()\n}}};", "head": [
"tail": "" "window.require = function(str) {",
"if (str === 'capitalize_strings') {",
"return {",
"capitalize: str => str.toUpperCase(),",
"lowercase: str => str.toLowerCase()",
"}}};"
],
"tail": []
} }
} }
}, },
@ -1349,8 +1361,10 @@
"\"use strict\";", "\"use strict\";",
"function subtract(x,y) {return x - y;}" "function subtract(x,y) {return x - y;}"
], ],
"head": "window.exports = function(){};", "head": [
"tail": "" "window.exports = function(){};"
],
"tail": []
} }
} }
}, },
@ -1384,13 +1398,16 @@
"\"use strict\";", "\"use strict\";",
"subtract(7,4);" "subtract(7,4);"
], ],
"head": "window.require = function(str) {\nif (str === 'math_functions') {\nreturn function(a, b) {\nreturn a - b;\n}}};", "head": [
"tail": "" "window.require = function(str) {",
"if (str === 'math_functions') {",
"return function(a, b) {",
"return a - b;",
"}}};"
],
"tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/es6.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -69,8 +69,8 @@
"", "",
"console.log(tea4TeamFCC);" "console.log(tea4TeamFCC);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -159,8 +159,8 @@
" tea4BlackTeamFCC", " tea4BlackTeamFCC",
");" ");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -177,7 +177,7 @@
"A Window object is made up of tabs, and you usually have more than one Window open. The titles of each open site in each Window object is held in an array. After working in the browser (opening new tabs, merging windows, and closing tabs), you want to print the tabs that are still open. Closed tabs are removed from the array and new tabs (for simplicity) get added to the end of it.", "A Window object is made up of tabs, and you usually have more than one Window open. The titles of each open site in each Window object is held in an array. After working in the browser (opening new tabs, merging windows, and closing tabs), you want to print the tabs that are still open. Closed tabs are removed from the array and new tabs (for simplicity) get added to the end of it.",
"The code editor shows an implementation of this functionality with functions for <code>tabOpen()</code>, <code>tabClose()</code>, and <code>join()</code>. The array <code>tabs</code> is part of the Window object that stores the name of the open pages.", "The code editor shows an implementation of this functionality with functions for <code>tabOpen()</code>, <code>tabClose()</code>, and <code>join()</code>. The array <code>tabs</code> is part of the Window object that stores the name of the open pages.",
"<h4>Instructions<h4>", "<h4>Instructions<h4>",
"Run the code in the editor. It's using a method that has side effects in the program, causing incorrect output. The final list of open tabs should be <code>['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium', 'Netflix', 'YouTube', 'Vine', 'GMail', 'Work mail', 'Docs', 'freeCodeCamp', 'new tab']</code> but the output will be slightly different.", "Run the code in the editor. It's using a method that has side effects in the program, causing incorrect output. The final list of open tabs should be <code>['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium', 'new tab', 'Netflix', 'YouTube', 'Vine', 'GMail', 'Work mail', 'Docs', 'freeCodeCamp', 'new tab']</code> but the output will be slightly different.",
"Work through the code and see if you can figure out the problem, then advance to the next challenge to learn more." "Work through the code and see if you can figure out the problem, then advance to the next challenge to learn more."
], ],
"tests": [ "tests": [
@ -236,8 +236,8 @@
"", "",
"alert(finalTabs.tabs);" "alert(finalTabs.tabs);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -288,8 +288,8 @@
"var newValue = incrementer(); // Should equal 5", "var newValue = incrementer(); // Should equal 5",
"console.log(fixedValue); // Should print 4" "console.log(fixedValue); // Should print 4"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -345,8 +345,8 @@
"var newValue = incrementer(fixedValue); // Should equal 5", "var newValue = incrementer(fixedValue); // Should equal 5",
"console.log(fixedValue); // Should print 4" "console.log(fixedValue); // Should print 4"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -427,8 +427,8 @@
"", "",
"console.log(bookList);" "console.log(bookList);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -598,8 +598,8 @@
"", "",
"console.log(rating); " "console.log(rating); "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -651,8 +651,8 @@
" return item * 2;", " return item * 2;",
"});" "});"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -816,8 +816,8 @@
"", "",
"console.log(filteredList); " "console.log(filteredList); "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -867,8 +867,8 @@
" return item % 2 === 1;", " return item % 2 === 1;",
"});" "});"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -924,8 +924,8 @@
"var inputAnim = [\"Cat\", \"Dog\", \"Tiger\", \"Zebra\", \"Ant\"];", "var inputAnim = [\"Cat\", \"Dog\", \"Tiger\", \"Zebra\", \"Ant\"];",
"sliceArray(inputAnim, 1, 3);" "sliceArray(inputAnim, 1, 3);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -978,8 +978,8 @@
"var inputCities = [\"Chicago\", \"Delhi\", \"Islamabad\", \"London\", \"Berlin\"];", "var inputCities = [\"Chicago\", \"Delhi\", \"Islamabad\", \"London\", \"Berlin\"];",
"nonMutatingSplice(inputCities);" "nonMutatingSplice(inputCities);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1031,8 +1031,8 @@
"var second = [4, 5];", "var second = [4, 5];",
"nonMutatingConcat(first, second);" "nonMutatingConcat(first, second);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1090,8 +1090,8 @@
"var second = [4, 5];", "var second = [4, 5];",
"nonMutatingPush(first, second);" "nonMutatingPush(first, second);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1261,8 +1261,8 @@
"", "",
"console.log(averageRating); " "console.log(averageRating); "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1314,8 +1314,8 @@
"}", "}",
"alphabeticalOrder([\"a\", \"d\", \"c\", \"a\", \"z\", \"g\"]);" "alphabeticalOrder([\"a\", \"d\", \"c\", \"a\", \"z\", \"g\"]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1365,8 +1365,8 @@
"}", "}",
"nonMutatingSort(globalArray);" "nonMutatingSort(globalArray);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1420,8 +1420,8 @@
"}", "}",
"splitify(\"Hello World,I-am code\");" "splitify(\"Hello World,I-am code\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1482,8 +1482,8 @@
"}", "}",
"sentensify(\"May-the-force-be-with-you\");" "sentensify(\"May-the-force-be-with-you\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1553,8 +1553,8 @@
"", "",
"var winterComing = urlSlug(globalTitle); // Should be \"winter-is-coming\"" "var winterComing = urlSlug(globalTitle); // Should be \"winter-is-coming\""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1605,8 +1605,8 @@
"}", "}",
"checkPositive([1, 2, 3, -4, 5]);" "checkPositive([1, 2, 3, -4, 5]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1657,8 +1657,8 @@
"}", "}",
"checkPositive([1, 2, 3, -4, 5]);" "checkPositive([1, 2, 3, -4, 5]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1715,13 +1715,10 @@
"}", "}",
"add(10)(20)(30);" "add(10)(20)(30);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/functional-programming.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -80,8 +80,8 @@
"", "",
"sumAll([1, 4]);" "sumAll([1, 4]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -198,8 +198,8 @@
"", "",
"diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);" "diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -277,8 +277,8 @@
"", "",
"destroyer([1, 2, 3, 1, 2, 3], 2, 3);" "destroyer([1, 2, 3, 1, 2, 3], 2, 3);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -363,8 +363,8 @@
"", "",
"whatIsInAName([{ first: \"Romeo\", last: \"Montague\" }, { first: \"Mercutio\", last: null }, { first: \"Tybalt\", last: \"Capulet\" }], { last: \"Capulet\" });" "whatIsInAName([{ first: \"Romeo\", last: \"Montague\" }, { first: \"Mercutio\", last: null }, { first: \"Tybalt\", last: \"Capulet\" }], { last: \"Capulet\" });"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -437,8 +437,8 @@
"", "",
"spinalCase('This Is Spinal Tap');" "spinalCase('This Is Spinal Tap');"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -529,8 +529,8 @@
"", "",
"translatePigLatin(\"consonant\");" "translatePigLatin(\"consonant\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -614,8 +614,8 @@
"", "",
"myReplace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");" "myReplace(\"A quick brown fox jumped over the lazy dog\", \"jumped\", \"leaped\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -690,8 +690,8 @@
"", "",
"pairElement(\"GCG\");" "pairElement(\"GCG\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -765,8 +765,8 @@
"", "",
"fearNotLetter(\"abce\");" "fearNotLetter(\"abce\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -842,8 +842,8 @@
"", "",
"uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);" "uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -924,8 +924,8 @@
"", "",
"convertHTML(\"Dolce & Gabbana\");" "convertHTML(\"Dolce & Gabbana\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1005,8 +1005,8 @@
"", "",
"sumFibs(4);" "sumFibs(4);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1075,8 +1075,8 @@
"", "",
"sumPrimes(10);" "sumPrimes(10);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1157,8 +1157,8 @@
"", "",
"smallestCommons([1,5]);" "smallestCommons([1,5]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1238,8 +1238,8 @@
"", "",
"dropElements([1, 2, 3], function(n) {return n < 3; });" "dropElements([1, 2, 3], function(n) {return n < 3; });"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1306,8 +1306,8 @@
"", "",
"steamrollArray([1, [2], [3, [[4]]]]);" "steamrollArray([1, [2], [3, [[4]]]]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1369,8 +1369,8 @@
"", "",
"binaryAgent(\"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111\");" "binaryAgent(\"01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1463,8 +1463,8 @@
"", "",
"truthCheck([{\"user\": \"Tinky-Winky\", \"sex\": \"male\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], \"sex\");" "truthCheck([{\"user\": \"Tinky-Winky\", \"sex\": \"male\"}, {\"user\": \"Dipsy\", \"sex\": \"male\"}, {\"user\": \"Laa-Laa\", \"sex\": \"female\"}, {\"user\": \"Po\", \"sex\": \"female\"}], \"sex\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1551,8 +1551,8 @@
"", "",
"addTogether(2,3);" "addTogether(2,3);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1678,8 +1678,8 @@
"var bob = new Person('Bob Ross');", "var bob = new Person('Bob Ross');",
"bob.getFullName();" "bob.getFullName();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1761,13 +1761,10 @@
"", "",
"orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]);" "orbitalPeriod([{name : \"sputnik\", avgAlt : 35873.5553}]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -118,8 +118,8 @@
"", "",
"palindrome(\"eye\");" "palindrome(\"eye\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -279,8 +279,8 @@
"", "",
"convertToRoman(36);" "convertToRoman(36);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -359,8 +359,8 @@
"// Change the inputs below to test", "// Change the inputs below to test",
"rot13(\"SERR PBQR PNZC\");" "rot13(\"SERR PBQR PNZC\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -538,8 +538,8 @@
"", "",
"telephoneCheck(\"555-555-5555\");" "telephoneCheck(\"555-555-5555\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -650,13 +650,10 @@
"", "",
"checkCashRegister(19.5, 20, [[\"PENNY\", 1.01], [\"NICKEL\", 2.05], [\"DIME\", 3.1], [\"QUARTER\", 4.25], [\"ONE\", 90], [\"FIVE\", 55], [\"TEN\", 20], [\"TWENTY\", 60], [\"ONE HUNDRED\", 100]]);" "checkCashRegister(19.5, 20, [[\"PENNY\", 1.01], [\"NICKEL\", 2.05], [\"DIME\", 3.1], [\"QUARTER\", 4.25], [\"ONE\", 90], [\"FIVE\", 55], [\"TEN\", 20], [\"TWENTY\", 60], [\"ONE HUNDRED\", 100]]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -49,8 +49,8 @@
" ", " ",
"};" "};"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -96,8 +96,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -145,8 +145,8 @@
"", "",
"dog.sayLegs();" "dog.sayLegs();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -188,7 +188,6 @@
"ext": "js", "ext": "js",
"name": "index", "name": "index",
"contents": [ "contents": [
"",
"let dog = {", "let dog = {",
" name: \"Spot\",", " name: \"Spot\",",
" numLegs: 4,", " numLegs: 4,",
@ -197,8 +196,8 @@
"", "",
"dog.sayLegs();" "dog.sayLegs();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -242,13 +241,9 @@
"key": "indexjs", "key": "indexjs",
"ext": "js", "ext": "js",
"name": "index", "name": "index",
"contents": [ "contents": [],
"", "head": [],
"", "tail": []
""
],
"head": "",
"tail": ""
} }
} }
}, },
@ -299,8 +294,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -360,8 +355,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -411,8 +406,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -465,8 +460,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -522,8 +517,8 @@
"// Add your code above this line", "// Add your code above this line",
"let beagle = new Dog(\"Snoopy\");" "let beagle = new Dog(\"Snoopy\");"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -582,8 +577,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -638,8 +633,8 @@
"}", "}",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -697,8 +692,8 @@
" ", " ",
"};" "};"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -749,8 +744,8 @@
" }", " }",
"};" "};"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -795,8 +790,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -848,8 +843,8 @@
"???.isPrototypeOf(Dog.prototype);", "???.isPrototypeOf(Dog.prototype);",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -924,8 +919,8 @@
" ", " ",
"};" "};"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -995,8 +990,8 @@
"duck.eat(); // Should print \"nom nom nom\"", "duck.eat(); // Should print \"nom nom nom\"",
"beagle.eat(); // Should print \"nom nom nom\" " "beagle.eat(); // Should print \"nom nom nom\" "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1050,8 +1045,8 @@
"let beagle = new Dog();", "let beagle = new Dog();",
"beagle.eat(); // Should print \"nom nom nom\"" "beagle.eat(); // Should print \"nom nom nom\""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1113,8 +1108,8 @@
"let duck = new Bird();", "let duck = new Bird();",
"let beagle = new Dog();" "let beagle = new Dog();"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1187,8 +1182,8 @@
"beagle.eat(); // Should print \"nom nom nom\"", "beagle.eat(); // Should print \"nom nom nom\"",
"beagle.bark(); // Should print \"Woof!\"" "beagle.bark(); // Should print \"Woof!\""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1252,8 +1247,8 @@
"let penguin = new Penguin();", "let penguin = new Penguin();",
"console.log(penguin.fly());" "console.log(penguin.fly());"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1318,8 +1313,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1367,8 +1362,8 @@
"}", "}",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1412,8 +1407,8 @@
"", "",
"makeNest(); " "makeNest(); "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1470,13 +1465,10 @@
" };", " };",
"};" "};"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/object-oriented-programming.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -41,8 +41,8 @@
"let myRegex = /Hello/;", "let myRegex = /Hello/;",
"let result = myRegex; // Change this line" "let result = myRegex; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -88,8 +88,8 @@
"let waldoRegex = /search/; // Change this line", "let waldoRegex = /search/; // Change this line",
"let result = waldoRegex.test(waldoIsHiding);" "let result = waldoRegex.test(waldoIsHiding);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -150,8 +150,8 @@
"let petRegex = /change/; // Change this line", "let petRegex = /change/; // Change this line",
"let result = petRegex.test(petString);" "let result = petRegex.test(petString);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -223,8 +223,8 @@
"let fccRegex = /change/; // Change this line", "let fccRegex = /change/; // Change this line",
"let result = fccRegex.test(myString);" "let result = fccRegex.test(myString);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -268,8 +268,8 @@
"let codingRegex = /change/; // Change this line", "let codingRegex = /change/; // Change this line",
"let result = extractStr; // Change this line" "let result = extractStr; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -319,8 +319,8 @@
"let starRegex = /change/; // Change this line", "let starRegex = /change/; // Change this line",
"let result = twinkleStar; // Change this line" "let result = twinkleStar; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -392,8 +392,8 @@
"let unRegex = /change/; // Change this line", "let unRegex = /change/; // Change this line",
"let result = unRegex.test(exampleStr);" "let result = unRegex.test(exampleStr);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -447,8 +447,8 @@
"let vowelRegex = /change/; // Change this line", "let vowelRegex = /change/; // Change this line",
"let result = vowelRegex; // Change this line" "let result = vowelRegex; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -462,7 +462,7 @@
"<blockquote>let catStr = \"cat\";<br>let batStr = \"bat\";<br>let matStr = \"mat\";<br>let bgRegex = /[a-e]at/;<br>catStr.match(bgRegex); // Returns [\"cat\"]<br>batStr.match(bgRegex); // Returns [\"bat\"]<br>matStr.match(bgRegex); // Returns null</blockquote>", "<blockquote>let catStr = \"cat\";<br>let batStr = \"bat\";<br>let matStr = \"mat\";<br>let bgRegex = /[a-e]at/;<br>catStr.match(bgRegex); // Returns [\"cat\"]<br>batStr.match(bgRegex); // Returns [\"bat\"]<br>matStr.match(bgRegex); // Returns null</blockquote>",
"<hr>", "<hr>",
"Match all the letters in the string <code>quoteSample</code>.", "Match all the letters in the string <code>quoteSample</code>.",
"<strong>Note</strong><br>Be sure to match both upper- and lowercase vowels." "<strong>Note</strong><br>Be sure to match both upper- and lowercase <strong>letters<strong>."
], ],
"tests": [ "tests": [
{ {
@ -494,8 +494,8 @@
"let alphabetRegex = /change/; // Change this line", "let alphabetRegex = /change/; // Change this line",
"let result = alphabetRegex; // Change this line" "let result = alphabetRegex; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -540,8 +540,8 @@
"let myRegex = /change/; // Change this line", "let myRegex = /change/; // Change this line",
"let result = myRegex; // Change this line" "let result = myRegex; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -585,8 +585,8 @@
"let myRegex = /change/; // Change this line", "let myRegex = /change/; // Change this line",
"let result = myRegex; // Change this line" "let result = myRegex; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -631,8 +631,8 @@
"let myRegex = /change/; // Change this line", "let myRegex = /change/; // Change this line",
"let result = difficultSpelling.match(myRegex);" "let result = difficultSpelling.match(myRegex);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -684,8 +684,8 @@
"let chewieRegex = /change/; // Change this line", "let chewieRegex = /change/; // Change this line",
"let result = chewieQuote.match(chewieRegex);" "let result = chewieQuote.match(chewieRegex);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -722,8 +722,8 @@
"let myRegex = /<.*>/; // Change this line", "let myRegex = /<.*>/; // Change this line",
"let result = text.match(myRegex);" "let result = text.match(myRegex);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -790,8 +790,8 @@
"let matchedCriminals = crowd.match(reCriminals);", "let matchedCriminals = crowd.match(reCriminals);",
"console.log(matchedCriminals);" "console.log(matchedCriminals);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -839,8 +839,8 @@
"let calRegex = /change/; // Change this line", "let calRegex = /change/; // Change this line",
"let result = calRegex.test(rickyAndCal);" "let result = calRegex.test(rickyAndCal);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -884,8 +884,8 @@
"let lastRegex = /change/; // Change this line", "let lastRegex = /change/; // Change this line",
"let result = lastRegex.test(caboose);" "let result = lastRegex.test(caboose);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -938,8 +938,8 @@
"let alphabetRegexV2 = /change/; // Change this line", "let alphabetRegexV2 = /change/; // Change this line",
"let result = quoteSample.match(alphabetRegexV2).length;" "let result = quoteSample.match(alphabetRegexV2).length;"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -991,8 +991,8 @@
"let nonAlphabetRegex = /change/; // Change this line", "let nonAlphabetRegex = /change/; // Change this line",
"let result = quoteSample.match(nonAlphabetRegex).length;" "let result = quoteSample.match(nonAlphabetRegex).length;"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1055,8 +1055,8 @@
"let numRegex = /change/; // Change this line", "let numRegex = /change/; // Change this line",
"let result = numString.match(numRegex).length;" "let result = numString.match(numRegex).length;"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1119,8 +1119,8 @@
"let noNumRegex = /change/; // Change this line", "let noNumRegex = /change/; // Change this line",
"let result = numString.match(noNumRegex).length;" "let result = numString.match(noNumRegex).length;"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1178,8 +1178,8 @@
"let userCheck = /change/; // Change this line", "let userCheck = /change/; // Change this line",
"let result = userCheck.test(username);" "let result = userCheck.test(username);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1227,8 +1227,8 @@
"let countWhiteSpace = /change/; // Change this line", "let countWhiteSpace = /change/; // Change this line",
"let result = sample.match(countWhiteSpace);" "let result = sample.match(countWhiteSpace);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1276,8 +1276,8 @@
"let countNonWhiteSpace = /change/; // Change this line", "let countNonWhiteSpace = /change/; // Change this line",
"let result = sample.match(countNonWhiteSpace);" "let result = sample.match(countNonWhiteSpace);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1338,8 +1338,8 @@
"let ohRegex = /change/; // Change this line", "let ohRegex = /change/; // Change this line",
"let result = ohRegex.test(ohStr);" "let result = ohRegex.test(ohStr);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1400,8 +1400,8 @@
"let haRegex = /change/; // Change this line", "let haRegex = /change/; // Change this line",
"let result = haRegex.test(haStr);" "let result = haRegex.test(haStr);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1458,8 +1458,8 @@
"let timRegex = /change/; // Change this line", "let timRegex = /change/; // Change this line",
"let result = timRegex.test(timStr);" "let result = timRegex.test(timStr);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1508,8 +1508,8 @@
"let favRegex = /change/; // Change this line", "let favRegex = /change/; // Change this line",
"let result = favRegex.test(favWord);" "let result = favRegex.test(favWord);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1574,8 +1574,8 @@
"let pwRegex = /change/; // Change this line", "let pwRegex = /change/; // Change this line",
"let result = pwRegex.test(sampleWord);" "let result = pwRegex.test(sampleWord);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1650,8 +1650,8 @@
"let reRegex = /change/; // Change this line", "let reRegex = /change/; // Change this line",
"let result = reRegex.test(repeatNum);" "let result = reRegex.test(repeatNum);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1698,8 +1698,8 @@
"let replaceText = \"\"; // Change this line", "let replaceText = \"\"; // Change this line",
"let result = huhText.replace(fixRegex, replaceText);" "let result = huhText.replace(fixRegex, replaceText);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1744,13 +1744,10 @@
"let wsRegex = /change/; // Change this line", "let wsRegex = /change/; // Change this line",
"let result = hello; // Change this line" "let result = hello; // Change this line"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "02-javascript-algorithms-and-data-structures/regular-expressions.json",
"superBlock": "javascript-algorithms-and-data-structures",
"superOrder": 2
} }

View File

@ -64,7 +64,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -124,8 +124,8 @@
" <button type=\"submit\">Submit</button>", " <button type=\"submit\">Submit</button>",
"</form>" "</form>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -182,7 +182,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -244,8 +244,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -288,7 +288,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -351,8 +351,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -361,16 +361,16 @@
"title": "Create a Bootstrap Button", "title": "Create a Bootstrap Button",
"description": [ "description": [
"Bootstrap has its own styles for <code>button</code> elements, which look much better than the plain HTML ones.", "Bootstrap has its own styles for <code>button</code> elements, which look much better than the plain HTML ones.",
"Create a new <code>button</code> element below your large kitten photo. Give it the class <code>btn</code> and the text of \"Like\"." "Create a new <code>button</code> element below your large kitten photo. Give it the <code>btn</code> and <code>btn-default</code> classes, as well as the text of \"Like\"."
], ],
"tests": [ "tests": [
{ {
"text": "Create a new <code>button</code> element with the text \"Like\".", "text": "Create a new <code>button</code> element with the text \"Like\".",
"testString": "assert(new RegExp(\"like\",\"gi\").test($(\"button\").text()), 'Create a new <code>button</code> element with the text \"Like\".');" "testString": "assert(new RegExp(\"like\",\"gi\").test($(\"button\").text()) && ($(\"img.img-responsive + button.btn\").length > 0), 'Create a new <code>button</code> element with the text \"Like\".');"
}, },
{ {
"text": "Your new button should have the class <code>btn</code>.", "text": "Your new button should have two classes: <code>btn</code> and <code>btn-default</code>.",
"testString": "assert($(\"button\").hasClass(\"btn\"), 'Your new button should have the class <code>btn</code>.');" "testString": "assert($(\"button\").hasClass(\"btn\") && $(\"button\").hasClass(\"btn-default\"), 'Your new button should have two classes: <code>btn</code> and <code>btn-default</code>.');"
}, },
{ {
"text": "Make sure all your <code>button</code> elements have a closing tag.", "text": "Make sure all your <code>button</code> elements have a closing tag.",
@ -396,7 +396,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -460,8 +460,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -469,21 +469,21 @@
"id": "bad87fee1348cd8acef08812", "id": "bad87fee1348cd8acef08812",
"title": "Create a Block Element Bootstrap Button", "title": "Create a Block Element Bootstrap Button",
"description": [ "description": [
"Normally, your <code>button</code> elements with a class of <code>btn</code> are only as wide as the text that they contain. For example:", "Normally, your <code>button</code> elements with the <code>btn</code> and <code>btn-default</code> classes are only as wide as the text that they contain. For example:",
"<code>&lt;button class=\"btn\"&gt;Submit&lt;/button&gt;</code>", "<code>&lt;button class=\"btn btn-default\"&gt;Submit&lt;/button&gt;</code>",
"This button would only be as wide as the word \"Submit\".", "This button would only be as wide as the word \"Submit\".",
"<button class='btn' style='background-color: rgb(0, 100, 0); color: rgb(255, 255, 255);'>Submit</button>", "<button class='btn btn-default'>Submit</button>",
"By making them block elements with the additional class of <code>btn-block</code>, your button will stretch to fill your page's entire horizontal space and any elements following it will flow onto a \"new line\" below the block.", "By making them block elements with the additional class of <code>btn-block</code>, your button will stretch to fill your page's entire horizontal space and any elements following it will flow onto a \"new line\" below the block.",
"<code>&lt;button class=\"btn btn-block\"&gt;Submit&lt;/button&gt;</code>", "<code>&lt;button class=\"btn btn-default btn-block\"&gt;Submit&lt;/button&gt;</code>",
"This button would take up 100% of the available width.", "This button would take up 100% of the available width.",
"<button class='btn btn-block' style='background-color: rgb(0, 100, 0); color: rgb(255, 255, 255);'>Submit</button>", "<button class='btn btn-default btn-block'>Submit</button>",
"Note that these buttons still need the <code>btn</code> class.", "Note that these buttons still need the <code>btn</code> class.",
"Add Bootstrap's <code>btn-block</code> class to your Bootstrap button." "Add Bootstrap's <code>btn-block</code> class to your Bootstrap button."
], ],
"tests": [ "tests": [
{ {
"text": "Your button should still have the class <code>btn</code>.", "text": "Your button should still have the <code>btn</code> and <code>btn-default</code> classes.",
"testString": "assert($(\"button\").hasClass(\"btn\"), 'Your button should still have the class <code>btn</code>.');" "testString": "assert($(\"button\").hasClass(\"btn\") && $(\"button\").hasClass(\"btn-default\"), 'Your button should still have the <code>btn</code> and <code>btn-default</code> classes.');"
}, },
{ {
"text": "Your button should have the class <code>btn-block</code>.", "text": "Your button should have the class <code>btn-block</code>.",
@ -529,7 +529,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -569,7 +569,7 @@
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\" alt=\"A cute orange cat lying on its back.\"></a>", " <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\" alt=\"A cute orange cat lying on its back.\"></a>",
"", "",
" <img src=\"https://bit.ly/fcc-running-cats\" class=\"img-responsive\" alt=\"Three kittens running towards the camera.\">", " <img src=\"https://bit.ly/fcc-running-cats\" class=\"img-responsive\" alt=\"Three kittens running towards the camera.\">",
" <button class=\"btn\">Like</button>", " <button class=\"btn btn-default\">Like</button>",
" <p>Things cats love:</p>", " <p>Things cats love:</p>",
" <ul>", " <ul>",
" <li>cat nip</li>", " <li>cat nip</li>",
@ -593,8 +593,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -603,7 +603,7 @@
"title": "Taste the Bootstrap Button Color Rainbow", "title": "Taste the Bootstrap Button Color Rainbow",
"description": [ "description": [
"The <code>btn-primary</code> class is the main color you'll use in your app. It is useful for highlighting actions you want your user to take.", "The <code>btn-primary</code> class is the main color you'll use in your app. It is useful for highlighting actions you want your user to take.",
"Add Bootstrap's <code>btn-primary</code> class to your button.", "Replace Bootstrap's <code>btn-default</code> class by <code>btn-primary</code> in your button.",
"Note that this button will still need the <code>btn</code> and <code>btn-block</code> classes." "Note that this button will still need the <code>btn</code> and <code>btn-block</code> classes."
], ],
"tests": [ "tests": [
@ -641,7 +641,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -681,7 +681,7 @@
" <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\" alt=\"A cute orange cat lying on its back.\"></a>", " <a href=\"#\"><img class=\"smaller-image thick-green-border\" src=\"https://bit.ly/fcc-relaxing-cat\" alt=\"A cute orange cat lying on its back.\"></a>",
"", "",
" <img src=\"https://bit.ly/fcc-running-cats\" class=\"img-responsive\" alt=\"Three kittens running towards the camera.\">", " <img src=\"https://bit.ly/fcc-running-cats\" class=\"img-responsive\" alt=\"Three kittens running towards the camera.\">",
" <button class=\"btn btn-block\">Like</button>", " <button class=\"btn btn-default btn-block\">Like</button>",
" <p>Things cats love:</p>", " <p>Things cats love:</p>",
" <ul>", " <ul>",
" <li>cat nip</li>", " <li>cat nip</li>",
@ -705,8 +705,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -757,7 +757,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -821,8 +821,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -873,7 +873,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -938,8 +938,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1001,7 +1001,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1067,8 +1067,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1129,7 +1129,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1203,8 +1203,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1268,7 +1268,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1329,8 +1329,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1396,7 +1396,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1456,8 +1456,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1527,7 +1527,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1590,8 +1590,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1642,7 +1642,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1705,8 +1705,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1757,7 +1757,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1820,8 +1820,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1872,7 +1872,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1942,8 +1942,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1998,7 +1998,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2076,8 +2076,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2134,7 +2134,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2212,8 +2212,8 @@
" </form>", " </form>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2271,17 +2271,13 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
"contents": [ "contents": [],
"", "head": [],
"", "tail": []
""
],
"head": "",
"tail": ""
} }
} }
}, },
@ -2325,7 +2321,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2334,8 +2330,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2383,7 +2379,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2394,8 +2390,8 @@
"</div>", "</div>",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2435,7 +2431,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2448,8 +2444,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2493,7 +2489,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2510,8 +2506,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2555,7 +2551,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2580,8 +2576,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2622,7 +2618,7 @@
}, },
"guideUrl": "https://guide.freecodecamp.org/certificates/apply-the-default-bootstrap-button-style", "guideUrl": "https://guide.freecodecamp.org/certificates/apply-the-default-bootstrap-button-style",
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2647,8 +2643,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2684,7 +2680,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2709,8 +2705,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2762,7 +2758,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2787,8 +2783,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2839,7 +2835,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2866,8 +2862,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2926,7 +2922,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2953,8 +2949,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3010,7 +3006,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3037,8 +3033,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -3092,7 +3088,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -3119,13 +3115,10 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "03-front-end-libraries/bootstrap.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -8,8 +8,20 @@
"id": "bd7158d8c442eddfaeb5bd13", "id": "bd7158d8c442eddfaeb5bd13",
"title": "Build a Random Quote Machine", "title": "Build a Random Quote Machine",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/qRZeGZ' target='_blank'>https://codepen.io/freeCodeCamp/full/qRZeGZ</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/qRZeGZ' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use any mix of HTML, JavaScript, CSS, Bootstrap, SASS, React, Redux, and jQuery to complete this project. You should use a frontend framework (like React for example) because this section is about learning frontend frameworks. Additional technologies not listed above are not recommended and using them is at your own risk. We are looking at supporting other frontend frameworks like Angular and Vue, but they are not currently supported. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> I can see a wrapper element with a corresponding <code>id=\"quote-box\"</code>.",
"<strong>User Story #2:</strong> Within <code>#quote-box</code>, I can see an element with a corresponding <code>id=\"text\"</code>.",
"<strong>User Story #3:</strong> Within <code>#quote-box</code>, I can see an element with a corresponding <code>id=\"author\"</code>.",
"<strong>User Story #4:</strong> Within <code>#quote-box</code>, I can see a clickable element with a corresponding <code>id=\"new-quote\"</code>.",
"<strong>User Story #5:</strong> Within <code>#quote-box</code>, I can see a clickable <codea</code> element with a corresponding <code>id=\"tweet-quote\"</code>.",
"<strong>User Story #6:</strong> On first load, my quote machine displays a random quote in the element with <code>id=\"text\"</code>.",
"<strong>User Story #7:</strong> On first load, my quote machine displays the random quote's author in the element with <code>id=\"author\"</code>.",
"<strong>User Story #8:</strong> When the <code>#new-quote</code> button is clicked, my quote machine should fetch a new quote and display it in the <code>#text</code> element.",
"<strong>User Story #9:</strong> My quote machine should fetch the new quote's author when the <code>#new-quote</code> button is clicked and display it in the <code>#author</code> element.",
"<strong>User Story #10:</strong> I can tweet the current quote by clicking on the <code>#tweet-quote</code> <code>a</code> element. This <code>a</code> element should include the <code>\"twitter.com/intent/tweet\"</code> path in it's <code>href</code> attribute to tweet the current quote.",
"<strong>User Story #11:</strong> The <code>#quote-box</code> wrapper element should be horizontally centered. Please run tests with browser's zoom level at 100% and page maximized.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -31,8 +43,17 @@
"id": "bd7157d8c242eddfaeb5bd13", "id": "bd7157d8c242eddfaeb5bd13",
"title": "Build a Markdown Previewer", "title": "Build a Markdown Previewer",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/GrZVVO' target='_blank'>https://codepen.io/freeCodeCamp/full/GrZVVO</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/GrZVVO' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use any mix of HTML, JavaScript, CSS, Bootstrap, SASS, React, Redux, and jQuery to complete this project. You should use a frontend framework (like React for example) because this section is about learning frontend frameworks. Additional technologies not listed above are not recommended and using them is at your own risk. We are looking at supporting other frontend frameworks like Angular and Vue, but they are not currently supported. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> I can see a <code>textarea</code> element with a corresponding <code>id=\"editor\"</code>.",
"<strong>User Story #2:</strong> I can see an element with a corresponding <code>id=\"preview\"</code>.",
"<strong>User Story #3:</strong> When I enter text into the <code>#editor</code> element, the <code>#preview</code> element is updated as I type to display the content of the textarea.",
"<strong>User Story #4:</strong> When I enter GitHub flavored markdown into the <code>#editor</code> element, the text is rendered as HTML in the <code>#preview</code> element as I type (HINT: You don't need to parse Markdown yourself - you can import the Marked library for this: <a href='https://cdnjs.com/libraries/marked' target='_blank'>https://cdnjs.com/libraries/marked</a>).",
"<strong>User Story #5:</strong> When my markdown previewer first loads, the default text in the <code>#editor</code> field should contain valid markdown that represents at least one of each of the following elements: a header (H1 size), a sub header (H2 size), a link, inline code, a code block, a list item, a blockquote, an image, and bolded text.",
"<strong>User Story #6:</strong> When my markdown previewer first loads, the default markdown in the <code>#editor</code> field should be rendered as HTML in the <code>#preview</code> element.",
"<strong>Optional Bonus (you do not need to make this test pass):</strong> When I click a link rendered by my markdown previewer, the link is opened up in a new tab (HINT: read the Marked.js docs for this one!).",
"<strong>Optional Bonus (you do not need to make this test pass):</strong> My markdown previewer interprets carriage returns and renders them as <code>br</code> (line break) elements.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -55,8 +76,16 @@
"id": "587d7dbc367417b2b2512bae", "id": "587d7dbc367417b2b2512bae",
"title": "Build a Drum Machine", "title": "Build a Drum Machine",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/MJyNMd' target='_blank'>https://codepen.io/freeCodeCamp/full/MJyNMd</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/MJyNMd' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use any mix of HTML, JavaScript, CSS, Bootstrap, SASS, React, Redux, and jQuery to complete this project. You should use a frontend framework (like React for example) because this section is about learning frontend frameworks. Additional technologies not listed above are not recommended and using them is at your own risk. We are looking at supporting other frontend frameworks like Angular and Vue, but they are not currently supported. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> I should be able to see an outer container with a corresponding <code>id=\"drum-machine\"</code> that contains all other elements.",
"<strong>User Story #2:</strong> Within <code>#drum-machine</code> I can see an element with a corresponding <code>id=\"display\"</code>.",
"<strong>User Story #3:</strong> Within <code>#drum-machine</code> I can see 9 clickable drum pad elements, each with a class name of <code>drum-pad</code>, a unique id that describes the audio clip the drum pad will be set up to trigger, and an inner text that corresponds to one of the following keys on the keyboard: Q, W, E, A, S, D, Z, X, C. The drum pads MUST be in this order.",
"<strong>User Story #4:</strong> Within each <code>.drum-pad</code>, there should be an HTML5 <code>audio</code> element which has a <code>src</code> attribute pointing to an audio clip, a class name of <code>clip</code>, and an id corresponding to the inner text of its parent <code>.drum-pad</code> (e.g. <code>id=\"Q\"</code>, <code>id=\"W\"</code>, <code>id=\"E\"</code> etc.).",
"<strong>User Story #5:</strong> When I click on a <code>.drum-pad</code> element, the audio clip contained in its child <code>audio</code> element should be triggered.",
"<strong>User Story #6:</strong> When I press the trigger key associated with each <code>.drum-pad</code>, the audio clip contained in its child <code>audio</code> element should be triggered (e.g. pressing the Q key should trigger the drum pad which contains the string \"Q\", pressing the W key should trigger the drum pad which contains the string \"W\", etc.).",
"<strong>User Story #7:</strong> When a <code>.drum-pad</code> is triggered, a string describing the associated audio clip is displayed as the inner text of the <code>#display</code> element (each string must be unique).",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -79,8 +108,24 @@
"id": "bd7158d8c442eddfaeb5bd17", "id": "bd7158d8c442eddfaeb5bd17",
"title": "Build a JavaScript Calculator", "title": "Build a JavaScript Calculator",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/wgGVVX' target='_blank'>https://codepen.io/freeCodeCamp/full/wgGVVX</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/wgGVVX' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use any mix of HTML, JavaScript, CSS, Bootstrap, SASS, React, Redux, and jQuery to complete this project. You should use a frontend framework (like React for example) because this section is about learning frontend frameworks. Additional technologies not listed above are not recommended and using them is at your own risk. We are looking at supporting other frontend frameworks like Angular and Vue, but they are not currently supported. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> My calculator should contain a clickable element containing an <code>=</code> (equal sign) with a corresponding <code>id=\"equals\"</code>.",
"<strong>User Story #2:</strong> My calculator should contain 10 clickable elements containing one number each from 0-9, with the following corresponding IDs: <code>id=\"zero\"</code>, <code>id=\"one\"</code>, <code>id=\"two\"</code>, <code>id=\"three\"</code>, <code>id=\"four\"</code>, <code>id=\"five\"</code>, <code>id=\"six\"</code>, <code>id=\"seven\"</code>, <code>id=\"eight\"</code>, and <code>id=\"nine\"</code>.",
"<strong>User Story #3:</strong> My calculator should contain 4 clickable elements each containing one of the 4 primary mathematical operators with the following corresponding IDs: <code>id=\"add\"</code>, <code>id=\"subtract\"</code>, <code>id=\"multiply\"</code>, <code>id=\"divide\"</code>.",
"<strong>User Story #4:</strong> My calculator should contain a clickable element containing a <code>.</code> (decimal point) symbol with a corresponding <code>id=\"decimal\"</code>.",
"<strong>User Story #5:</strong> My calculator should contain a clickable element with an <code>id=\"clear\"</code>.",
"<strong>User Story #6:</strong> My calculator should contain an element to display values with a corresponding <code>id=\"display\"</code>.",
"<strong>User Story #7:</strong> At any time, pressing the clear button clears the input and output values, and returns the calculator to its initialized state; 0 should be shown in the element with the id of <code>display</code>.",
"<strong>User Story #8:</strong> As I input numbers, I should be able to see my input in the element with the id of <code>display</code>.",
"<strong>User Story #9:</strong> In any order, I should be able to add, subtract, multiply and divide a chain of numbers of any length, and when I hit <code>=</code>, the correct result should be shown in the element with the id of <code>display</code>.",
"<strong>User Story #10:</strong> When inputting numbers, my calculator should not allow a number to begin with multiple zeros.",
"<strong>User Story #11:</strong> When the decimal element is clicked, a <code>.</code> should append to the currently displayed value; two <code>.</code> in one number should not be accepted.",
"<strong>User Story #12:</strong> I should be able to perform any operation (+, -, *, /) on numbers containing decimal points.",
"<strong>User Story #13:</strong> If 2 or more operators are entered consecutively, the operation performed should be the last operator entered.",
"<strong>User Story #14:</strong> Pressing an operator immediately following <code>=</code> should start a new calculation that operates on the result of the previous evaluation.",
"<strong>User Story #15:</strong> My calculator should have several decimal places of precision when it comes to rounding (note that there is no exact standard, but you should be able to handle calculations like <code>2 / 7</code> with reasonable precision to at least 4 decimal places).",
"<strong>Note On Calculator Logic:</strong> It should be noted that there are two main schools of thought on calculator input logic: <dfn>immediate execution logic</dfn> and <dfn>formula logic</dfn>. Our example utilizes formula logic and observes order of operation precedence, immediate execution does not. Either is acceptable, but please note that depending on which you choose, your calculator may yield different results than ours for certain equations (see below example). As long as your math can be verified by another production calculator, please do not consider this a bug.", "<strong>Note On Calculator Logic:</strong> It should be noted that there are two main schools of thought on calculator input logic: <dfn>immediate execution logic</dfn> and <dfn>formula logic</dfn>. Our example utilizes formula logic and observes order of operation precedence, immediate execution does not. Either is acceptable, but please note that depending on which you choose, your calculator may yield different results than ours for certain equations (see below example). As long as your math can be verified by another production calculator, please do not consider this a bug.",
"<strong>EXAMPLE:</strong> <code>3 + 5 x 6 - 2 / 4 =</code><br><ul><li><strong>Immediate Execution Logic:</strong> <code>11.5</code></li><li><strong>Formula/Expression Logic:</strong> <code>32.5</code></li></ul>", "<strong>EXAMPLE:</strong> <code>3 + 5 x 6 - 2 / 4 =</code><br><ul><li><strong>Immediate Execution Logic:</strong> <code>11.5</code></li><li><strong>Formula/Expression Logic:</strong> <code>32.5</code></li></ul>",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
@ -101,8 +146,37 @@
"id": "bd7158d8c442eddfaeb5bd0f", "id": "bd7158d8c442eddfaeb5bd0f",
"title": "Build a Pomodoro Clock", "title": "Build a Pomodoro Clock",
"description": [ "description": [
"Fulfill the user stories by getting all of the tests to pass. Use whichever libraries you need. Give it your own personal style.", "<strong>Objective:</strong> Build a <a href='https://codepen.io' target='_blank'>CodePen.io</a> app that is functionally similar to this: <a href='https://codepen.io/freeCodeCamp/full/XpKrrW' target='_blank'>https://codepen.io/freeCodeCamp/full/XpKrrW</a>.",
"Here's a <a href='http://codepen.io/freeCodeCamp/full/XpKrrW' target='_blank'>working example</a>. Try not to look at its code.", "Fulfill the below <a href='https://en.wikipedia.org/wiki/User_story' target='_blank'>user stories</a> and get all of the tests to pass. Give it your own personal style.",
"You can use any mix of HTML, JavaScript, CSS, Bootstrap, SASS, React, Redux, and jQuery to complete this project. You should use a frontend framework (like React for example) because this section is about learning frontend frameworks. Additional technologies not listed above are not recommended and using them is at your own risk. We are looking at supporting other frontend frameworks like Angular and Vue, but they are not currently supported. We will accept and try to fix all issue reports that use the suggested technology stack for this project. Happy coding!",
"<strong>User Story #1:</strong> I can see an element with <code>id=\"break-label\"</code> that contains a string (e.g. \"Break Length\").",
"<strong>User Story #2:</strong> I can see an element with <code>id=\"session-label\"</code> that contains a string (e.g. \"Session Length\").",
"<strong>User Story #3:</strong> I can see two clickable elements with corresponding IDs: <code>id=\"break-decrement\"</code> and <code>id=\"session-decrement\"</code>.",
"<strong>User Story #4:</strong> I can see two clickable elements with corresponding IDs: <code>id=\"break-increment\"</code> and <code>id=\"session-increment\"</code>.",
"<strong>User Story #5:</strong> I can see an element with a corresponding <code>id=\"break-length\"</code>, which by default (on load) displays a value of 5.",
"<strong>User Story #6:</strong> I can see an element with a corresponding <code>id=\"session-length\"</code>, which by default displays a value of 25.",
"<strong>User Story #7:</strong> I can see an element with a corresponding <code>id=\"timer-label\"</code>, that contains a string indicating a session is initialized (e.g. \"Session\").",
"<strong>User Story #8:</strong> I can see an element with corresponding <code>id=\"time-left\"</code>. NOTE: Paused or running, the value in this field should always be displayed in <code>mm:ss</code> format (i.e. 25:00).",
"<strong>User Story #9:</strong> I can see a clickable element with a corresponding <code>id=\"start_stop\"</code>.",
"<strong>User Story #10:</strong> I can see a clickable element with a corresponding <code>id=\"reset\"</code>.",
"<strong>User Story #11:</strong> When I click the element with the id of <code>reset</code>, any running timer should be stopped, the value within <code>id=\"break-length\"</code> should return to <code>5</code>, the value within <code>id=\"session-length\"</code> should return to 25, and the element with <code>id=\"time-left\"</code> should reset to it's default state.",
"<strong>User Story #12:</strong> When I click the element with the id of <code>break-decrement</code>, the value within <code>id=\"break-length\"</code> decrements by a value of 1, and I can see the updated value.",
"<strong>User Story #13:</strong> When I click the element with the id of <code>break-increment</code>, the value within <code>id=\"break-length\"</code> increments by a value of 1, and I can see the updated value.",
"<strong>User Story #14:</strong> When I click the element with the id of <code>session-decrement</code>, the value within <code>id=\"session-length\"</code> decrements by a value of 1, and I can see the updated value.",
"<strong>User Story #15:</strong> When I click the element with the id of <code>session-increment</code>, the value within <code>id=\"session-length\"</code> increments by a value of 1, and I can see the updated value.",
"<strong>User Story #16:</strong> I should not be able to set a session or break length to <= 0.",
"<strong>User Story #17:</strong> I should not be able to set a session or break length to > 60.",
"<strong>User Story #18:</strong> When I first click the element with <code>id=\"start_stop\"</code>, the timer should begin running from the value currently displayed in <code>id=\"session-length\"</code>, even if the value has been incremented or decremented from the original value of 25.",
"<strong>User Story #19:</strong> If the timer is running, the element with the id of <code>time-left</code> should display the remaining time in <code>mm:ss</code> format (decrementing by a value of 1 and updating the display every 1000ms).",
"<strong>User Story #20:</strong> If the timer is running and I click the element with <code>id=\"start_stop\"</code>, the countdown should pause.",
"<strong>User Story #21:</strong> If the timer is paused and I click the element with <code>id=\"start_stop\"</code>, the countdown should resume running from the point at which it was paused.",
"<strong>User Story #22:</strong> When a session countdown reaches zero (NOTE: timer MUST reach 00:00), and a new countdown begins, the element with the id of <code>timer-label</code> should display a string indicating a break has begun.",
"<strong>User Story #23:</strong> When a session countdown reaches zero (NOTE: timer MUST reach 00:00), a new break countdown should begin, counting down from the value currently displayed in the <code>id=\"break-length\"</code> element.",
"<strong>User Story #24:</strong> When a break countdown reaches zero (NOTE: timer MUST reach 00:00), and a new countdown begins, the element with the id of <code>timer-label</code> should display a string indicating a session has begun.",
"<strong>User Story #25:</strong> When a break countdown reaches zero (NOTE: timer MUST reach 00:00), a new session countdown should begin, counting down from the value currently displayed in the <code>id=\"session-length\"</code> element.",
"<strong>User Story #26:</strong> When a countdown reaches zero (NOTE: timer MUST reach 00:00), a sound indicating that time is up should play. This should utilize an HTML5 <code>audio</code> tag and have a corresponding <code>id=\"beep\"</code>.",
"<strong>User Story #27:</strong> The audio element with <code>id=\"beep\"</code> must be 1 second or longer.",
"<strong>User Story #28:</strong> The audio element with id of <code>beep</code> must stop playing and be rewound to the beginning when the element with the id of <code>reset</code> is clicked.",
"You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>", "You can build your project by forking <a href='http://codepen.io/freeCodeCamp/pen/MJjpwO' target='_blank'>this CodePen pen</a>. Or you can use this CDN link to run the tests in any environment you like: <code>https://gitcdn.link/repo/freeCodeCamp/testable-projects-fcc/master/build/bundle.js</code>",
"Once you're done, submit the URL to your working project with all its tests passing.", "Once you're done, submit the URL to your working project with all its tests passing.",
"Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck." "Remember to use the <a href='https://forum.freecodecamp.org/t/how-to-get-help-when-you-are-stuck/19514' target='_blank'>Read-Search-Ask</a> method if you get stuck."
@ -120,8 +194,5 @@
} }
} }
} }
], ]
"fileName": "03-front-end-libraries/front-end-libraries-projects.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -76,13 +76,11 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
"contents": [ "contents": [
"",
"",
"<!-- Only change code above this line. -->", "<!-- Only change code above this line. -->",
"", "",
"<div class=\"container-fluid\">", "<div class=\"container-fluid\">",
@ -107,8 +105,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -181,7 +179,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -216,8 +214,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -289,7 +287,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -324,8 +322,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -397,7 +395,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -434,8 +432,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -499,7 +497,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -537,8 +535,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -622,7 +620,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -657,8 +655,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -722,7 +720,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -760,8 +758,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -833,7 +831,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -872,8 +870,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -940,7 +938,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -976,8 +974,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1044,7 +1042,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1080,8 +1078,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1124,7 +1122,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1161,8 +1159,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1215,7 +1213,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1253,8 +1251,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1310,7 +1308,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1349,8 +1347,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1410,7 +1408,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1452,8 +1450,8 @@
" </div>", " </div>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1509,7 +1507,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1550,8 +1548,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1616,7 +1614,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1658,8 +1656,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1716,7 +1714,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1760,8 +1758,8 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1808,7 +1806,7 @@
} }
}, },
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1853,13 +1851,10 @@
" </div>", " </div>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "03-front-end-libraries/jquery.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -45,7 +45,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<DisplayMessages />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<DisplayMessages />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -109,7 +112,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<DisplayMessages />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<DisplayMessages />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -164,7 +170,9 @@
"contents": [ "contents": [
"// define ADD, addMessage(), messageReducer(), and store here:", "// define ADD, addMessage(), messageReducer(), and store here:",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -298,7 +306,10 @@
" // change code above this line", " // change code above this line",
"};" "};"
], ],
"tail": "ReactDOM.render(<AppWrapper />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<AppWrapper />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -348,7 +359,9 @@
"", "",
"// change code below this line", "// change code below this line",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -403,7 +416,9 @@
"", "",
"// change code below this line", "// change code below this line",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -499,7 +514,8 @@
" }", " }",
"};", "};",
"ReactDOM.render(<AppWrapper />, document.getElementById('root'))" "ReactDOM.render(<AppWrapper />, document.getElementById('root'))"
] ],
"head": []
} }
}, },
"tests": [ "tests": [
@ -637,7 +653,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<AppWrapper />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<AppWrapper />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -782,7 +801,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<AppWrapper />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<AppWrapper />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -872,7 +894,9 @@
"", "",
"// change code below this line", "// change code below this line",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -889,8 +913,5 @@
"translations": {}, "translations": {},
"reactRedux": true "reactRedux": true
} }
], ]
"fileName": "03-front-end-libraries/react-and-redux.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -35,7 +35,10 @@
"const JSX = <div></div>;", "const JSX = <div></div>;",
"" ""
], ],
"tail": "ReactDOM.render(JSX, document.getElementById('root'))" "tail": [
"ReactDOM.render(JSX, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -84,7 +87,10 @@
"// write your code here", "// write your code here",
"" ""
], ],
"tail": "ReactDOM.render(JSX, document.getElementById('root'))" "tail": [
"ReactDOM.render(JSX, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -140,7 +146,10 @@
" </div>", " </div>",
");" ");"
], ],
"tail": "ReactDOM.render(JSX, document.getElementById('root'))" "tail": [
"ReactDOM.render(JSX, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -194,7 +203,9 @@
");", ");",
"// change code below this line", "// change code below this line",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -247,7 +258,10 @@
" </div>", " </div>",
");" ");"
], ],
"tail": "ReactDOM.render(JSX, document.getElementById('root'))" "tail": [
"ReactDOM.render(JSX, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -298,7 +312,10 @@
");", ");",
"" ""
], ],
"tail": "ReactDOM.render(JSX, document.getElementById('root'))" "tail": [
"ReactDOM.render(JSX, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -351,7 +368,10 @@
" // change code above this line", " // change code above this line",
"}" "}"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -369,7 +389,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst MyComponent = function() {\n // change code below this line\n return (\n <div>\n Demo Solution\n </div>\n );\n // change code above this line\n}" "const MyComponent = function() {\n // change code below this line\n return (\n <div>\n Demo Solution\n </div>\n );\n // change code above this line\n}"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -408,7 +428,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -426,7 +449,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass MyComponent extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n // change code below this line\n return (\n <div>\n <h1>Hello React!</h1>\n </div>\n );\n // change code above this line\n }\n};" "class MyComponent extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n // change code below this line\n return (\n <div>\n <h1>Hello React!</h1>\n </div>\n );\n // change code above this line\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -477,7 +500,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<ParentComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ParentComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -559,7 +585,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<TypesOfFood />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<TypesOfFood />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -596,7 +625,7 @@
"As the challenges continue to use more complex compositions with React components and JSX, there is one important point to note. Rendering ES6 style class components within other components is no different than rendering the simple components you used in the last few challenges. You can render JSX elements, stateless functional components, and ES6 class components within other components.", "As the challenges continue to use more complex compositions with React components and JSX, there is one important point to note. Rendering ES6 style class components within other components is no different than rendering the simple components you used in the last few challenges. You can render JSX elements, stateless functional components, and ES6 class components within other components.",
"<hr>", "<hr>",
"In the code editor, the <code>TypesOfFood</code> component is already rendering a component called <code>Vegetables</code>. Also, there is the <code>Fruits</code> component from the last challenge.", "In the code editor, the <code>TypesOfFood</code> component is already rendering a component called <code>Vegetables</code>. Also, there is the <code>Fruits</code> component from the last challenge.",
"Nest two components inside of <code>Fruits</code> &mdash; first <code>NonCitrus</code>, and then <code>Citrus</code>. Both of these components are provided for you in the background. Next, nest the <code>Fruits</code> class component into the the <code>TypesOfFood</code> component, below the <code>h1</code> header and above <code>Vegetables</code>. The result should be a series of nested components, which uses two different component types." "Nest two components inside of <code>Fruits</code> &mdash; first <code>NonCitrus</code>, and then <code>Citrus</code>. Both of these components are provided for you in the background. Next, nest the <code>Fruits</code> class component into the <code>TypesOfFood</code> component, below the <code>h1</code> header and above <code>Vegetables</code>. The result should be a series of nested components, which uses two different component types."
], ],
"files": { "files": {
"indexjsx": { "indexjsx": {
@ -683,7 +712,9 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<TypesOfFood />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<TypesOfFood />, document.getElementById('root'))"
]
} }
}, },
"tests": [ "tests": [
@ -785,7 +816,8 @@
"", "",
"// change code below this line", "// change code below this line",
"" ""
] ],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -807,7 +839,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass TypesOfFood extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n return (\n <div>\n <h1>Types of Food:</h1>\n {/* change code below this line */}\n <Fruits />\n <Vegetables />\n {/* change code above this line */}\n </div>\n );\n }\n};\n\n// change code below this line\nReactDOM.render(<TypesOfFood />, document.getElementById('challenge-node'));" "class TypesOfFood extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n return (\n <div>\n <h1>Types of Food:</h1>\n {/* change code below this line */}\n <Fruits />\n <Vegetables />\n {/* change code above this line */}\n </div>\n );\n }\n};\n\n// change code below this line\nReactDOM.render(<TypesOfFood />, document.getElementById('challenge-node'));"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -832,7 +864,9 @@
"contents": [ "contents": [
"// change code below this line", "// change code below this line",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -903,7 +937,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<Calendar />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Calendar />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -929,7 +966,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst CurrentDate = (props) => {\n return (\n <div>\n { /* change code below this line */ }\n <p>The current date is: {props.date}</p>\n { /* change code above this line */ }\n </div>\n );\n};\n\nclass Calendar extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n return (\n <div>\n <h3>What date is it?</h3>\n { /* change code below this line */ }\n <CurrentDate date={Date()} />\n { /* change code above this line */ }\n </div>\n );\n }\n};" "const CurrentDate = (props) => {\n return (\n <div>\n { /* change code below this line */ }\n <p>The current date is: {props.date}</p>\n { /* change code above this line */ }\n </div>\n );\n};\n\nclass Calendar extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n return (\n <div>\n <h3>What date is it?</h3>\n { /* change code below this line */ }\n <CurrentDate date={Date()} />\n { /* change code above this line */ }\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -982,7 +1019,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<ToDo />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ToDo />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1048,7 +1088,10 @@
"// change code below this line", "// change code below this line",
"" ""
], ],
"tail": "ReactDOM.render(<ShoppingCart />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ShoppingCart />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1104,7 +1147,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<ShoppingCart />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ShoppingCart />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1176,7 +1222,9 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<ShoppingCart />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ShoppingCart />, document.getElementById('root'))"
]
} }
}, },
"tests": [ "tests": [
@ -1252,7 +1300,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<ResetPassword />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ResetPassword />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1322,7 +1373,9 @@
"// change code below this line", "// change code below this line",
"" ""
], ],
"tail": "ReactDOM.render(<CampSite />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<CampSite />, document.getElementById('root'))"
]
} }
}, },
"tests": [ "tests": [
@ -1389,7 +1442,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<StatefulComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<StatefulComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1402,8 +1458,8 @@
"testString": "assert((function() { const mockedComponent = Enzyme.mount(React.createElement(StatefulComponent)); return mockedComponent.find('div').length === 1 && mockedComponent.find('h1').length === 1; })(), '<code>StatefulComponent</code> should render a <code>div</code> and an <code>h1</code> element.');" "testString": "assert((function() { const mockedComponent = Enzyme.mount(React.createElement(StatefulComponent)); return mockedComponent.find('div').length === 1 && mockedComponent.find('h1').length === 1; })(), '<code>StatefulComponent</code> should render a <code>div</code> and an <code>h1</code> element.');"
}, },
{ {
"text": "The state of <code>StatefulComponent</code> should be initalized with a property <code>name</code> set to a string.", "text": "The state of <code>StatefulComponent</code> should be initialized with a property <code>name</code> set to a string.",
"testString": "assert((function() { const mockedComponent = Enzyme.mount(React.createElement(StatefulComponent)); const initialState = mockedComponent.state(); return ( typeof initialState === 'object' && typeof initialState.name === 'string'); })(), 'The state of <code>StatefulComponent</code> should be initalized with a property <code>name</code> set to a string.');" "testString": "assert((function() { const mockedComponent = Enzyme.mount(React.createElement(StatefulComponent)); const initialState = mockedComponent.state(); return ( typeof initialState === 'object' && typeof initialState.name === 'string'); })(), 'The state of <code>StatefulComponent</code> should be initialized with a property <code>name</code> set to a string.');"
}, },
{ {
"text": "The property <code>name</code> in the state of <code>StatefulComponent</code> should render in the <code>h1</code> element.", "text": "The property <code>name</code> in the state of <code>StatefulComponent</code> should render in the <code>h1</code> element.",
@ -1411,7 +1467,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass StatefulComponent extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n name: 'freeCodeCamp!'\n }\n }\n render() {\n return (\n <div>\n <h1>{this.state.name}</h1>\n </div>\n );\n }\n};" "class StatefulComponent extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n name: 'freeCodeCamp!'\n }\n }\n render() {\n return (\n <div>\n <h1>{this.state.name}</h1>\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -1455,7 +1511,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1517,7 +1576,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1587,7 +1649,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1662,7 +1727,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1736,7 +1804,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1802,17 +1873,20 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<Counter />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Counter />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
{ {
"text": "<code>MyComponent</code> should return a <code>div</code> element which contains three buttons with text content in this order <code>Increment!</code>, <code>Decrement!</code>, <code>Reset</code>.", "text": "<code>Counter</code> should return a <code>div</code> element which contains three buttons with text content in this order <code>Increment!</code>, <code>Decrement!</code>, <code>Reset</code>.",
"testString": "assert((() => { const mockedComponent = Enzyme.mount(React.createElement(Counter)); return (mockedComponent.find('.inc').text() === 'Increment!' && mockedComponent.find('.dec').text() === 'Decrement!' && mockedComponent.find('.reset').text() === 'Reset'); })(), '<code>MyComponent</code> should return a <code>div</code> element which contains three buttons with text content in this order <code>Increment!</code>, <code>Decrement!</code>, <code>Reset</code>.');" "testString": "assert((() => { const mockedComponent = Enzyme.mount(React.createElement(Counter)); return (mockedComponent.find('.inc').text() === 'Increment!' && mockedComponent.find('.dec').text() === 'Decrement!' && mockedComponent.find('.reset').text() === 'Reset'); })(), '<code>Counter</code> should return a <code>div</code> element which contains three buttons with text content in this order <code>Increment!</code>, <code>Decrement!</code>, <code>Reset</code>.');"
}, },
{ {
"text": "The state of <code>MyComponent</code> should initialize with a <code>count</code> property set to <code>0</code>.", "text": "The state of <code>Counter</code> should initialize with a <code>count</code> property set to <code>0</code>.",
"testString": "assert.strictEqual(Enzyme.mount(React.createElement(Counter)).state('count'), 0, 'The state of <code>MyComponent</code> should initialize with a <code>count</code> property set to <code>0</code>.');" "testString": "assert.strictEqual(Enzyme.mount(React.createElement(Counter)).state('count'), 0, 'The state of <code>Counter</code> should initialize with a <code>count</code> property set to <code>0</code>.');"
}, },
{ {
"text": "Clicking the increment button should increment the count by <code>1</code>.", "text": "Clicking the increment button should increment the count by <code>1</code>.",
@ -1880,7 +1954,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<ControlledInput />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<ControlledInput />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -1912,7 +1989,7 @@
"description": [ "description": [
"The last challenge showed that React can control the internal state for certain elements like <code>input</code> and <code>textarea</code>, which makes them controlled components. This applies to other form elements as well, including the regular HTML <code>form</code> element.", "The last challenge showed that React can control the internal state for certain elements like <code>input</code> and <code>textarea</code>, which makes them controlled components. This applies to other form elements as well, including the regular HTML <code>form</code> element.",
"<hr>", "<hr>",
"The <code>MyForm</code> component is set up with an empty <code>form</code> with a submit handler. The submit handler will be called when the formed is submitted.", "The <code>MyForm</code> component is set up with an empty <code>form</code> with a submit handler. The submit handler will be called when the form is submitted.",
"We've added a button which submits the form. You can see it has the <code>type</code> set to <code>submit</code> indicating it is the button controlling the form. Add the <code>input</code> element in the <code>form</code> and set its <code>value</code> and <code>onChange()</code> attributes like the last challenge. You should then complete the <code>handleSubmit</code> method so that it sets the component state property <code>submit</code> to the current input value in the local <code>state</code>.", "We've added a button which submits the form. You can see it has the <code>type</code> set to <code>submit</code> indicating it is the button controlling the form. Add the <code>input</code> element in the <code>form</code> and set its <code>value</code> and <code>onChange()</code> attributes like the last challenge. You should then complete the <code>handleSubmit</code> method so that it sets the component state property <code>submit</code> to the current input value in the local <code>state</code>.",
"<strong>Note:</strong>&nbsp; You also must call <code>event.preventDefault()</code> in the submit handler, to prevent the default form submit behavior which will refresh the web page.", "<strong>Note:</strong>&nbsp; You also must call <code>event.preventDefault()</code> in the submit handler, to prevent the default form submit behavior which will refresh the web page.",
"Finally, create an <code>h1</code> tag after the <code>form</code> which renders the <code>submit</code> value from the component's <code>state</code>. You can then type in the form and click the button (or press enter), and you should see your input rendered to the page." "Finally, create an <code>h1</code> tag after the <code>form</code> which renders the <code>submit</code> value from the component's <code>state</code>. You can then type in the form and click the button (or press enter), and you should see your input rendered to the page."
@ -1960,7 +2037,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyForm />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyForm />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2039,7 +2119,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyApp />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyApp />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2134,7 +2217,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyApp />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyApp />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2204,7 +2290,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2264,7 +2353,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2342,7 +2434,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2427,7 +2522,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<Controller />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Controller />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2516,7 +2614,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<Controller />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Controller />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2550,12 +2651,13 @@
"title": "Introducing Inline Styles", "title": "Introducing Inline Styles",
"releasedOn": "December 25, 2017", "releasedOn": "December 25, 2017",
"description": [ "description": [
"There are other complex concepts that add powerful capabilities to your React code. But you may be wondering about the more simple problem of how to style those JSX elements you create in React. You likely know that it won't be exactly the same as working with HTML because of <a target=\"_blank\" href=\"link to classes challenge\"> the way you apply classes to JSX elements</a>.", "There are other complex concepts that add powerful capabilities to your React code. But you may be wondering about the more simple problem of how to style those JSX elements you create in React. You likely know that it won't be exactly the same as working with HTML because of <a target=\"_blank\" href=\"define-an-html-class-in-jsx\"> the way you apply classes to JSX elements</a>.",
"If you import styles from a stylesheet, it isn't much different at all. You apply a class to your JSX element using the <code>className</code> attribute, and apply styles to the class in your stylesheet. Another option is to apply <strong><em>inline</em></strong> styles, which are very common in ReactJS development.", "If you import styles from a stylesheet, it isn't much different at all. You apply a class to your JSX element using the <code>className</code> attribute, and apply styles to the class in your stylesheet. Another option is to apply <strong><em>inline</em></strong> styles, which are very common in ReactJS development.",
"You apply inline styles to JSX elements similar to how you do it in HTML, but with a few JSX differences. Here's an example of an inline style in HTML:", "You apply inline styles to JSX elements similar to how you do it in HTML, but with a few JSX differences. Here's an example of an inline style in HTML:",
"<code>&lt;div style=\"color: yellow; font-size: 16px\"&gt;Mellow Yellow&lt;/div&gt;</code>", "<code>&lt;div style=\"color: yellow; font-size: 16px\"&gt;Mellow Yellow&lt;/div&gt;</code>",
"JSX elements use the <code>style</code> attribute, but because of the way JSX is transpiled, you can't set the value to a <code>string</code>. Instead, you set it equal to a JavaScript <code>object</code>. Here's an example:", "JSX elements use the <code>style</code> attribute, but because of the way JSX is transpiled, you can't set the value to a <code>string</code>. Instead, you set it equal to a JavaScript <code>object</code>. Here's an example:",
"<code>&lt;div style={{color: \"yellow\", fontSize: 16}}&gt;Mellow Yellow&lt;/div&gt;</code>", "<code>&lt;div style={{color: \"yellow\", fontSize: 16}}&gt;Mellow Yellow&lt;/div&gt;</code>",
"Notice how we camelCase the \"fontSize\" property? This is because React will not accept kebab-case keys in the style object. React will apply the correct property name for us in the HTML.",
"<hr>", "<hr>",
"Add a <code>style</code> attribute to the <code>div</code> in the code editor to give the text a color of red and font size of 72px.", "Add a <code>style</code> attribute to the <code>div</code> in the code editor to give the text a color of red and font size of 72px.",
"Note that you can optionally set the font size to be a number, omitting the units \"px\", or write it as \"72px\"." "Note that you can optionally set the font size to be a number, omitting the units \"px\", or write it as \"72px\"."
@ -2576,7 +2678,10 @@
"};", "};",
"" ""
], ],
"tail": "ReactDOM.render(<Colorful />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Colorful />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2594,7 +2699,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass Colorful extends React.Component {\n render() {\n return (\n <div style={{color: \"red\", fontSize: 72}}>Big Red</div>\n );\n }\n};\n" "class Colorful extends React.Component {\n render() {\n return (\n <div style={{color: \"red\", fontSize: 72}}>Big Red</div>\n );\n }\n};\n"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -2631,7 +2736,10 @@
"};", "};",
"" ""
], ],
"tail": "ReactDOM.render(<Colorful />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Colorful />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2661,7 +2769,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst styles = {\n color: \"purple\",\n fontSize: 40,\n border: \"2px solid purple\"\n};\n// change code above this line\nclass Colorful extends React.Component {\n render() {\n // change code below this line\n return (\n <div style={styles}>Style Me!</div>\n // change code above this line\n );\n }\n};\n" "const styles = {\n color: \"purple\",\n fontSize: 40,\n border: \"2px solid purple\"\n};\n// change code above this line\nclass Colorful extends React.Component {\n render() {\n // change code below this line\n return (\n <div style={styles}>Style Me!</div>\n // change code above this line\n );\n }\n};\n"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -2760,7 +2868,8 @@
"tail": [ "tail": [
"var possibleAnswers = [ 'It is certain', 'It is decidedly so', 'Without a doubt', 'Yes, definitely', 'You may rely on it', 'As I see it, yes', 'Outlook good', 'Yes', 'Signs point to yes', 'Reply hazy try again', 'Ask again later', 'Better not tell you now', 'Cannot predict now', 'Concentrate and ask again', 'Don\\'t count on it', 'My reply is no', 'My sources say no', 'Outlook not so good','Very doubtful', 'Most likely' ];", "var possibleAnswers = [ 'It is certain', 'It is decidedly so', 'Without a doubt', 'Yes, definitely', 'You may rely on it', 'As I see it, yes', 'Outlook good', 'Yes', 'Signs point to yes', 'Reply hazy try again', 'Ask again later', 'Better not tell you now', 'Cannot predict now', 'Concentrate and ask again', 'Don\\'t count on it', 'My reply is no', 'My sources say no', 'Outlook not so good','Very doubtful', 'Most likely' ];",
"ReactDOM.render(<MagicEightBall />, document.getElementById('root'))" "ReactDOM.render(<MagicEightBall />, document.getElementById('root'))"
] ],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2790,7 +2899,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst inputStyle = {\n width: 235,\n margin: 5\n}\n\nclass MagicEightBall extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n userInput: '',\n randomIndex: ''\n }\n this.ask = this.ask.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n ask() {\n if (this.state.userInput) {\n this.setState({\n randomIndex: Math.floor(Math.random() * 20),\n userInput: ''\n });\n }\n }\n handleChange(event) {\n this.setState({\n userInput: event.target.value\n });\n }\n render() {\n const possibleAnswers = [\n \"It is certain\", \"It is decidedly so\", \"Without a doubt\",\n \"Yes, definitely\", \"You may rely on it\", \"As I see it, yes\",\n \"Outlook good\", \"Yes\", \"Signs point to yes\", \"Reply hazy try again\",\n \"Ask again later\", \"Better not tell you now\", \"Cannot predict now\",\n \"Concentrate and ask again\", \"Don't count on it\", \"My reply is no\",\n \"My sources say no\", \"Outlook not so good\",\"Very doubtful\", \"Most likely\"\n ];\n const answer = possibleAnswers[this.state.randomIndex];\n return (\n <div>\n <input\n type=\"text\"\n value={this.state.userInput}\n onChange={this.handleChange}\n style={inputStyle} /><br />\n <button onClick={this.ask}>Ask the Magic Eight Ball!</button><br />\n <h3>Answer:</h3>\n <p>\n {answer}\n </p>\n </div>\n );\n }\n};" "const inputStyle = {\n width: 235,\n margin: 5\n}\n\nclass MagicEightBall extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n userInput: '',\n randomIndex: ''\n }\n this.ask = this.ask.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n ask() {\n if (this.state.userInput) {\n this.setState({\n randomIndex: Math.floor(Math.random() * 20),\n userInput: ''\n });\n }\n }\n handleChange(event) {\n this.setState({\n userInput: event.target.value\n });\n }\n render() {\n const possibleAnswers = [\n \"It is certain\", \"It is decidedly so\", \"Without a doubt\",\n \"Yes, definitely\", \"You may rely on it\", \"As I see it, yes\",\n \"Outlook good\", \"Yes\", \"Signs point to yes\", \"Reply hazy try again\",\n \"Ask again later\", \"Better not tell you now\", \"Cannot predict now\",\n \"Concentrate and ask again\", \"Don't count on it\", \"My reply is no\",\n \"My sources say no\", \"Outlook not so good\",\"Very doubtful\", \"Most likely\"\n ];\n const answer = possibleAnswers[this.state.randomIndex];\n return (\n <div>\n <input\n type=\"text\"\n value={this.state.userInput}\n onChange={this.handleChange}\n style={inputStyle} /><br />\n <button onClick={this.ask}>Ask the Magic Eight Ball!</button><br />\n <h3>Answer:</h3>\n <p>\n {answer}\n </p>\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -2838,7 +2947,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -2908,7 +3020,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3000,7 +3115,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<CheckUserAge />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<CheckUserAge />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3034,7 +3152,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst inputStyle = {\n width: 235,\n margin: 5\n}\n\nclass CheckUserAge extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n userAge: '',\n input: ''\n }\n this.submit = this.submit.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n handleChange(e) {\n this.setState({\n input: e.target.value,\n userAge: ''\n });\n }\n submit() {\n this.setState({\n userAge: this.state.input\n });\n }\n render() {\n const buttonOne = <button onClick={this.submit}>Submit</button>;\n const buttonTwo = <button>You May Enter</button>;\n const buttonThree = <button>You Shall Not Pass</button>;\n return (\n <div>\n <h3>Enter Your Age to Continue</h3>\n <input\n style={inputStyle}\n type=\"number\"\n value={this.state.input}\n onChange={this.handleChange} /><br />\n {\n this.state.userAge === '' ?\n buttonOne :\n this.state.userAge >= 18 ?\n buttonTwo :\n buttonThree\n }\n </div>\n );\n }\n};" "const inputStyle = {\n width: 235,\n margin: 5\n}\n\nclass CheckUserAge extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n userAge: '',\n input: ''\n }\n this.submit = this.submit.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n handleChange(e) {\n this.setState({\n input: e.target.value,\n userAge: ''\n });\n }\n submit() {\n this.setState({\n userAge: this.state.input\n });\n }\n render() {\n const buttonOne = <button onClick={this.submit}>Submit</button>;\n const buttonTwo = <button>You May Enter</button>;\n const buttonThree = <button>You Shall Not Pass</button>;\n return (\n <div>\n <h3>Enter Your Age to Continue</h3>\n <input\n style={inputStyle}\n type=\"number\"\n value={this.state.input}\n onChange={this.handleChange} /><br />\n {\n this.state.userAge === '' ?\n buttonOne :\n this.state.userAge >= 18 ?\n buttonTwo :\n buttonThree\n }\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -3101,7 +3219,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<GameOfChance />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<GameOfChance />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3190,7 +3311,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<GateKeeper />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<GateKeeper />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3216,7 +3340,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass GateKeeper extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n input: ''\n };\n this.handleChange = this.handleChange.bind(this);\n }\n handleChange(event) {\n this.setState({ input: event.target.value })\n }\n render() {\n let inputStyle = {\n border: '1px solid black'\n };\n if (this.state.input.length > 15) {\n inputStyle.border = '3px solid red';\n };\n return (\n <div>\n <h3>Don't Type Too Much:</h3>\n <input\n type=\"text\"\n style={inputStyle}\n value={this.state.input}\n onChange={this.handleChange} />\n </div>\n );\n }\n};" "class GateKeeper extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n input: ''\n };\n this.handleChange = this.handleChange.bind(this);\n }\n handleChange(event) {\n this.setState({ input: event.target.value })\n }\n render() {\n let inputStyle = {\n border: '1px solid black'\n };\n if (this.state.input.length > 15) {\n inputStyle.border = '3px solid red';\n };\n return (\n <div>\n <h3>Don't Type Too Much:</h3>\n <input\n type=\"text\"\n style={inputStyle}\n value={this.state.input}\n onChange={this.handleChange} />\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -3285,7 +3409,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyToDoList />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyToDoList />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3315,7 +3442,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst textAreaStyles = {\n width: 235,\n margin: 5\n};\n\nclass MyToDoList extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n toDoList: [],\n userInput: ''\n }\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n handleSubmit() {\n const itemsArray = this.state.userInput.split(',');\n this.setState({\n toDoList: itemsArray\n });\n }\n handleChange(e) {\n this.setState({\n userInput: e.target.value\n });\n }\n render() {\n const items = this.state.toDoList.map( (item, i) => {\n return <li key={i}>{item}</li>\n });\n return (\n <div>\n <textarea\n onChange={this.handleChange}\n value={this.state.userInput}\n style={textAreaStyles}\n placeholder=\"Separate Items With Commas\" /><br />\n <button onClick={this.handleSubmit}>Create List</button>\n <h1>My \"To Do\" List:</h1>\n <ul>\n {items}\n </ul>\n </div>\n );\n }\n};" "const textAreaStyles = {\n width: 235,\n margin: 5\n};\n\nclass MyToDoList extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n toDoList: [],\n userInput: ''\n }\n this.handleSubmit = this.handleSubmit.bind(this);\n this.handleChange = this.handleChange.bind(this);\n }\n handleSubmit() {\n const itemsArray = this.state.userInput.split(',');\n this.setState({\n toDoList: itemsArray\n });\n }\n handleChange(e) {\n this.setState({\n userInput: e.target.value\n });\n }\n render() {\n const items = this.state.toDoList.map( (item, i) => {\n return <li key={i}>{item}</li>\n });\n return (\n <div>\n <textarea\n onChange={this.handleChange}\n value={this.state.userInput}\n style={textAreaStyles}\n placeholder=\"Separate Items With Commas\" /><br />\n <button onClick={this.handleSubmit}>Create List</button>\n <h1>My \"To Do\" List:</h1>\n <ul>\n {items}\n </ul>\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -3360,7 +3487,10 @@
" );", " );",
"};" "};"
], ],
"tail": "ReactDOM.render(<Frameworks />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<Frameworks />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3386,7 +3516,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nconst frontEndFrameworks = [\n 'React',\n 'Angular',\n 'Ember',\n 'Knockout',\n 'Backbone',\n 'Vue'\n];\n\nfunction Frameworks() {\n const renderFrameworks = frontEndFrameworks.map((fw, i) => {\n return <li key={i}>{fw}</li>\n })\n return (\n <div>\n <h1>Popular Front End JavaScript Frameworks</h1>\n <ul>\n {renderFrameworks}\n </ul>\n </div>\n );\n};" "const frontEndFrameworks = [\n 'React',\n 'Angular',\n 'Ember',\n 'Knockout',\n 'Backbone',\n 'Vue'\n];\n\nfunction Frameworks() {\n const renderFrameworks = frontEndFrameworks.map((fw, i) => {\n return <li key={i}>{fw}</li>\n })\n return (\n <div>\n <h1>Popular Front End JavaScript Frameworks</h1>\n <ul>\n {renderFrameworks}\n </ul>\n </div>\n );\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -3455,7 +3585,10 @@
" }", " }",
"};" "};"
], ],
"tail": "ReactDOM.render(<MyComponent />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<MyComponent />, document.getElementById('root'))"
],
"head": []
} }
}, },
"tests": [ "tests": [
@ -3481,7 +3614,7 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass MyComponent extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n users: [\n {\n username: 'Jeff',\n online: true\n },\n {\n username: 'Alan',\n online: false\n },\n {\n username: 'Mary',\n online: true\n },\n {\n username: 'Jim',\n online: false\n },\n {\n username: 'Sara',\n online: true\n },\n {\n username: 'Laura',\n online: true\n }\n ]\n }\n }\n render() {\n const usersOnline = this.state.users.filter(user => {\n return user.online;\n });\n const renderOnlineUsers = usersOnline.map(user => {\n return (\n <li key={user.username}>{user.username}</li>\n );\n });\n return (\n <div>\n <h1>Current Online Users:</h1>\n <ul>\n {renderOnlineUsers}\n </ul>\n </div>\n );\n }\n};" "class MyComponent extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n users: [\n {\n username: 'Jeff',\n online: true\n },\n {\n username: 'Alan',\n online: false\n },\n {\n username: 'Mary',\n online: true\n },\n {\n username: 'Jim',\n online: false\n },\n {\n username: 'Sara',\n online: true\n },\n {\n username: 'Laura',\n online: true\n }\n ]\n }\n }\n render() {\n const usersOnline = this.state.users.filter(user => {\n return user.online;\n });\n const renderOnlineUsers = usersOnline.map(user => {\n return (\n <li key={user.username}>{user.username}</li>\n );\n });\n return (\n <div>\n <h1>Current Online Users:</h1>\n <ul>\n {renderOnlineUsers}\n </ul>\n </div>\n );\n }\n};"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
@ -3520,7 +3653,9 @@
"// change code below this line", "// change code below this line",
"" ""
], ],
"tail": "ReactDOM.render(<App />, document.getElementById('root'))" "tail": [
"ReactDOM.render(<App />, document.getElementById('root'))"
]
} }
}, },
"tests": [ "tests": [
@ -3530,15 +3665,12 @@
} }
], ],
"solutions": [ "solutions": [
"\nclass App extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n return <div/>\n }\n};\n\n// change code below this line\nReactDOMServer.renderToString(<App/>);" "class App extends React.Component {\n constructor(props) {\n super(props);\n }\n render() {\n return <div/>\n }\n};\n\n// change code below this line\nReactDOMServer.renderToString(<App/>);"
], ],
"challengeType": 6, "challengeType": 6,
"isRequired": false, "isRequired": false,
"translations": {}, "translations": {},
"react": true "react": true
} }
], ]
"fileName": "03-front-end-libraries/react.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -40,7 +40,9 @@
"// Define the store here:", "// Define the store here:",
"", "",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -82,7 +84,9 @@
"", "",
"// change code below this line", "// change code below this line",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -121,7 +125,9 @@
"contents": [ "contents": [
"// Define an action here:", "// Define an action here:",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -162,7 +168,9 @@
"}", "}",
"// Define an action creator here:", "// Define an action creator here:",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -216,7 +224,9 @@
"", "",
"// Dispatch the action here:", "// Dispatch the action here:",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -274,7 +284,9 @@
" type: 'LOGIN'", " type: 'LOGIN'",
" }", " }",
"};" "};"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -342,7 +354,9 @@
" type: 'LOGOUT'", " type: 'LOGOUT'",
" }", " }",
"};" "};"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -437,7 +451,9 @@
" type: 'LOGOUT'", " type: 'LOGOUT'",
" }", " }",
"};" "};"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -526,7 +542,8 @@
"console.log(count);", "console.log(count);",
"store.dispatch({type: ADD});", "store.dispatch({type: ADD});",
"console.log(count);" "console.log(count);"
] ],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -606,7 +623,9 @@
"", "",
"const store = Redux.createStore(rootReducer);", "const store = Redux.createStore(rootReducer);",
"" ""
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -675,7 +694,9 @@
"console.log(store.getState());", "console.log(store.getState());",
"store.dispatch(addNoteText('Hello!'));", "store.dispatch(addNoteText('Hello!'));",
"console.log(store.getState());" "console.log(store.getState());"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -760,7 +781,9 @@
" asyncDataReducer,", " asyncDataReducer,",
" Redux.applyMiddleware(ReduxThunk.default)", " Redux.applyMiddleware(ReduxThunk.default)",
");" ");"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -818,7 +841,9 @@
"const decAction = null; // define an action creator for decrementing", "const decAction = null; // define an action creator for decrementing",
"", "",
"const store = null; // define the Redux store here, passing in your reducers" "const store = null; // define the Redux store here, passing in your reducers"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -901,7 +926,9 @@
"}", "}",
"", "",
"const store = Redux.createStore(immutableReducer);" "const store = Redux.createStore(immutableReducer);"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -961,7 +988,9 @@
"}", "}",
"", "",
"const store = Redux.createStore(immutableReducer);" "const store = Redux.createStore(immutableReducer);"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -1023,7 +1052,9 @@
"}", "}",
"", "",
"const store = Redux.createStore(immutableReducer);" "const store = Redux.createStore(immutableReducer);"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -1089,7 +1120,9 @@
"};", "};",
"", "",
"const store = Redux.createStore(immutableReducer);" "const store = Redux.createStore(immutableReducer);"
] ],
"head": [],
"tail": []
} }
}, },
"tests": [ "tests": [
@ -1118,8 +1151,5 @@
"translations": {}, "translations": {},
"redux": true "redux": true
} }
], ]
"fileName": "03-front-end-libraries/redux.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -47,7 +47,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -77,8 +77,8 @@
" <p>Even more random text within a paragraph</p>", " <p>Even more random text within a paragraph</p>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -113,7 +113,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -136,8 +136,8 @@
" <p>This is a paragraph</p>", " <p>This is a paragraph</p>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -196,7 +196,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -216,8 +216,8 @@
"<div id=\"awesome\"></div>", "<div id=\"awesome\"></div>",
" " " "
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -232,9 +232,9 @@
], ],
"description": [ "description": [
"The <code>@if</code> directive in Sass is useful to test for a specific case - it works just like the <code>if</code> statement in JavaScript</code>.", "The <code>@if</code> directive in Sass is useful to test for a specific case - it works just like the <code>if</code> statement in JavaScript</code>.",
"<blockquote>@mixin make-bold($bool) {<br>&nbsp;&nbsp;@if $bool == bold { font-weight: bold; }<br>}</blockquote>", "<blockquote>@mixin make-bold($bool) {<br>&nbsp;&nbsp;@if $bool == true {<br>&nbsp;&nbsp;&nbsp;&nbsp;font-weight: bold;<br>&nbsp;&nbsp;}<br>}</blockquote>",
"And just like in JavaScript, <code>@else if</code> and <code>@else</code> test for more conditions:", "And just like in JavaScript, <code>@else if</code> and <code>@else</code> test for more conditions:",
"<blockquote>@mixin text-effect($val) {<br>&nbsp;&nbsp;@if $val == danger {color: red;}<br>&nbsp;&nbsp;@else if $val == alert {color: yellow;}<br>&nbsp;&nbsp;@else if $val == success {color: green;}<br>&nbsp;&nbsp;@else {color: black;}<br>}</blockquote>", "<blockquote>@mixin text-effect($val) {<br>&nbsp;&nbsp;@if $val == danger {<br>&nbsp;&nbsp;&nbsp;&nbsp;color: red;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;@else if $val == alert {<br>&nbsp;&nbsp;&nbsp;&nbsp;color: yellow;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;@else if $val == success {<br>&nbsp;&nbsp;&nbsp;&nbsp;color: green;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;@else {<br>&nbsp;&nbsp;&nbsp;&nbsp;color: black;<br>&nbsp;&nbsp;}<br>}</blockquote>",
"<hr>", "<hr>",
"Create a <code>mixin</code> called <code>border-stroke</code> that takes a parameter <code>$val</code>. The <code>mixin</code> should check for the following conditions using <code>@if</code>, <code>@else if</code>, and <code>@else</code>:", "Create a <code>mixin</code> called <code>border-stroke</code> that takes a parameter <code>$val</code>. The <code>mixin</code> should check for the following conditions using <code>@if</code>, <code>@else if</code>, and <code>@else</code>:",
"<blockquote>light - 1px solid black<br>medium - 3px solid black<br>heavy - 6px solid black<br>none - no border</blockquote>" "<blockquote>light - 1px solid black<br>medium - 3px solid black<br>heavy - 6px solid black<br>none - no border</blockquote>"
@ -268,7 +268,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -287,8 +287,8 @@
"", "",
"<div id=\"box\"></div>" "<div id=\"box\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -346,7 +346,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -363,8 +363,8 @@
"<p class=\"text-4\">Hello</p>", "<p class=\"text-4\">Hello</p>",
"<p class=\"text-5\">Hello</p>" "<p class=\"text-5\">Hello</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -397,15 +397,15 @@
}, },
{ {
"text": "Your <code>.blue-bg</code> class should have a <code>background-color</code> of blue.", "text": "Your <code>.blue-bg</code> class should have a <code>background-color</code> of blue.",
"testString": "assert($('blue-bg').css('background-color') == 'rgb(0, 0, 255)', 'Your <code>.blue-bg</code> class should have a <code>background-color</code> of blue.');" "testString": "assert($('.blue-bg').css('background-color') == 'rgb(0, 0, 255)', 'Your <code>.blue-bg</code> class should have a <code>background-color</code> of blue.');"
}, },
{ {
"text": "Your <code>.black-bg</code> class should have a <code>background-color</code> of black.", "text": "Your <code>.black-bg</code> class should have a <code>background-color</code> of black.",
"testString": "assert($('black-bg').css('background-color') == 'rgb(0, 0, 0)', 'Your <code>.black-bg</code> class should have a <code>background-color</code> of black.');" "testString": "assert($('.black-bg').css('background-color') == 'rgb(0, 0, 0)', 'Your <code>.black-bg</code> class should have a <code>background-color</code> of black.');"
}, },
{ {
"text": "Your <code>.red-bg</code> class should have a <code>background-color</code> of red.", "text": "Your <code>.red-bg</code> class should have a <code>background-color</code> of red.",
"testString": "assert($('red-bg').css('background-color') == 'rgb(255, 0, 0)', 'Your <code>.red-bg</code> class should have a <code>background-color</code> of red.');" "testString": "assert($('.red-bg').css('background-color') == 'rgb(255, 0, 0)', 'Your <code>.red-bg</code> class should have a <code>background-color</code> of red.');"
} }
], ],
"solutions": [], "solutions": [],
@ -415,7 +415,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -434,8 +434,8 @@
"<div class=\"black-bg\"></div>", "<div class=\"black-bg\"></div>",
"<div class=\"red-bg\"></div>" "<div class=\"red-bg\"></div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -519,7 +519,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -541,8 +541,8 @@
"<p class=\"text-9\">Hello</p>", "<p class=\"text-9\">Hello</p>",
"<p class=\"text-10\">Hello</p>" "<p class=\"text-10\">Hello</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -577,7 +577,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -588,8 +588,8 @@
"", "",
"" ""
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -616,16 +616,12 @@
], ],
"tests": [ "tests": [
{ {
"text": "Your code should use the <code>@extend</code> directive to extend the <code>info</code> class.", "text": "Your <code>info-important</code> class should have a <code>background-color</code> set to <code>magenta</code>.",
"testString": "assert(code.match(/@extend\\s+?\\.info/g), 'Your code should use the <code>@extend</code> directive to extend the <code>info</code> class.');" "testString": "assert(code.match(/\\.info-important\\s*?{[\\s\\S]*background-color\\s*?:\\s*?magenta\\s*?;[\\s\\S]*}/gi), 'Your <code>info-important</code> class should have a <code>background-color</code> set to <code>magenta</code>.');"
}, },
{ {
"text": "Your <code>info-important</code> class should have a <code>background-color</code> set to magenta.", "text": "Your <code>info-important</code> class should use <code>@extend</code> to inherit the styling from the <code>info</code> class.",
"testString": "assert($('.info-important').css('background-color') == 'rgb(255, 0, 255)', 'Your <code>info-important</code> class should have a <code>background-color</code> set to magenta.');" "testString": "assert(code.match(/\\.info-important\\s*?{[\\s\\S]*@extend\\s*?.info\\s*?;[\\s\\S]*/gi), 'Your <code>info-important</code> class should use <code>@extend</code> to inherit the styling from the <code>info</code> class.');"
},
{
"text": "Your <code>info-important</code> class should inherit the styling from the <code>info</code> class.",
"testString": "assert($('.info-important').css('width') == '200px', 'Your <code>info-important</code> class should inherit the styling from the <code>info</code> class.');"
} }
], ],
"solutions": [], "solutions": [],
@ -635,7 +631,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -663,13 +659,10 @@
" <p>This is a simple post. It has basic styling and can be extended for other uses.</p>", " <p>This is a simple post. It has basic styling and can be extended for other uses.</p>",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "03-front-end-libraries/sass.json",
"superBlock": "front-end-libraries",
"superOrder": 3
} }

View File

@ -183,8 +183,5 @@
"challengeType": 3, "challengeType": 3,
"translations": {} "translations": {}
} }
], ]
"fileName": "04-data-visualization/data-visualization-projects.json",
"superBlock": "data-visualization",
"superOrder": 4
} }

View File

@ -59,7 +59,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -74,8 +74,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -115,7 +115,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -135,8 +135,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -184,7 +184,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -201,8 +201,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -269,7 +269,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -290,8 +290,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -327,7 +327,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -349,8 +349,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -416,7 +416,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -438,8 +438,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -475,7 +475,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -504,8 +504,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -571,7 +571,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -601,8 +601,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -667,7 +667,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -699,8 +699,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -742,7 +742,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -768,8 +768,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -819,7 +819,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -843,8 +843,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -889,7 +889,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -919,8 +919,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -988,7 +988,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1022,8 +1022,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1087,7 +1087,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1121,8 +1121,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1189,7 +1189,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1223,8 +1223,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1255,7 +1255,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1288,8 +1288,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1354,7 +1354,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1393,8 +1393,8 @@
" </script>", " </script>",
"<body>" "<body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1428,7 +1428,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1470,8 +1470,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1502,7 +1502,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1550,8 +1550,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1618,7 +1618,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1667,8 +1667,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1699,7 +1699,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1738,8 +1738,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1814,7 +1814,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1856,8 +1856,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -1929,7 +1929,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -1978,8 +1978,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2023,7 +2023,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2044,8 +2044,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2097,7 +2097,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2117,8 +2117,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2160,7 +2160,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2180,8 +2180,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2225,7 +2225,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2271,8 +2271,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2390,7 +2390,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2451,8 +2451,8 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -2499,7 +2499,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -2567,13 +2567,10 @@
" </script>", " </script>",
"</body>" "</body>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "04-data-visualization/data-visualization-with-d3.json",
"superBlock": "data-visualization",
"superOrder": 4
} }

View File

@ -37,7 +37,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -86,8 +86,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -115,7 +115,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -166,8 +166,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -222,7 +222,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -273,8 +273,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -308,7 +308,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -366,8 +366,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -407,7 +407,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -467,8 +467,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -496,7 +496,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -559,8 +559,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -588,7 +588,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -654,8 +654,8 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -698,7 +698,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -714,8 +714,8 @@
"", "",
"</div>" "</div>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -766,7 +766,7 @@
"challengeType": 0, "challengeType": 0,
"translations": {}, "translations": {},
"files": { "files": {
"indexjs": { "indexhtml": {
"key": "indexhtml", "key": "indexhtml",
"ext": "html", "ext": "html",
"name": "index", "name": "index",
@ -822,13 +822,10 @@
" </button>", " </button>",
"</p>" "</p>"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
} }
], ]
"fileName": "04-data-visualization/json-apis-and-ajax.json",
"superBlock": "data-visualization",
"superOrder": 4
} }

View File

@ -1,5 +1,5 @@
{ {
"name": "API and Microservice Projects", "name": "APIs and Microservices Projects",
"order": 4, "order": 4,
"time": "150 hours", "time": "150 hours",
"helpRoom": "HelpBackend", "helpRoom": "HelpBackend",
@ -9,7 +9,7 @@
"title": "Timestamp Microservice", "title": "Timestamp Microservice",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://curse-arrow.glitch.me/' target='_blank'>https://curse-arrow.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://curse-arrow.glitch.me/' target='_blank'>https://curse-arrow.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-timestamp/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-timestamp/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-timestamp/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-timestamp/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -43,7 +43,7 @@
"title": "Request Header Parser Microservice", "title": "Request Header Parser Microservice",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://dandelion-roar.glitch.me/' target='_blank'>https://dandelion-roar.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://dandelion-roar.glitch.me/' target='_blank'>https://dandelion-roar.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-headerparser/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-headerparser/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-headerparser/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-headerparser/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -69,7 +69,7 @@
"title": "URL Shortener Microservice", "title": "URL Shortener Microservice",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://thread-paper.glitch.me/' target='_blank'>https://thread-paper.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://thread-paper.glitch.me/' target='_blank'>https://thread-paper.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-urlshortener/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-urlshortener/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-urlshortener/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-urlshortener/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -103,7 +103,7 @@
"title": "Exercise Tracker", "title": "Exercise Tracker",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://fuschia-custard.glitch.me/' target='_blank'>https://fuschia-custard.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://fuschia-custard.glitch.me/' target='_blank'>https://fuschia-custard.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-exercisetracker/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-exercisetracker/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-exercisetracker/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -145,7 +145,7 @@
"title": "File Metadata Microservice", "title": "File Metadata Microservice",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://purple-paladin.glitch.me/' target='_blank'>https://purple-paladin.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://purple-paladin.glitch.me/' target='_blank'>https://purple-paladin.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-filemetadata/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-filemetadata/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-filemetadata/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-filemetadata/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -170,8 +170,5 @@
} }
} }
} }
], ]
"fileName": "05-apis-and-microservices/api-and-microservice-projects.json",
"superBlock": "apis-and-microservices",
"superOrder": 5
} }

View File

@ -260,7 +260,7 @@
"Mount a POST handler at the path <code>/name</code>. Its the same path as before. We have prepared a form in the html frontpage. It will submit the same data of exercise 10 (Query string). If the body-parser is configured correctly, you should find the parameters in the object <code>req.body</code>. Have a look at the usual library example:", "Mount a POST handler at the path <code>/name</code>. Its the same path as before. We have prepared a form in the html frontpage. It will submit the same data of exercise 10 (Query string). If the body-parser is configured correctly, you should find the parameters in the object <code>req.body</code>. Have a look at the usual library example:",
"<blockquote>route: POST '/library'<br>urlencoded_body: userId=546&bookId=6754 <br>req.body: {userId: '546', bookId: '6754'}</blockquote>", "<blockquote>route: POST '/library'<br>urlencoded_body: userId=546&bookId=6754 <br>req.body: {userId: '546', bookId: '6754'}</blockquote>",
"Respond with the same JSON object as before: <code>{name: 'firstname lastname'}</code>. Test if your endpoint works using the html form we provided in the app frontpage.", "Respond with the same JSON object as before: <code>{name: 'firstname lastname'}</code>. Test if your endpoint works using the html form we provided in the app frontpage.",
"Tip: There are several other http methods other than GET and POST. And by convention there is a corrispondence between the http verb, and the operation you are going to execute on the server. The conventional mapping is:", "Tip: There are several other http methods other than GET and POST. And by convention there is a correspondence between the http verb, and the operation you are going to execute on the server. The conventional mapping is:",
"POST (sometimes PUT) - Create a new resource using the information sent with the request,", "POST (sometimes PUT) - Create a new resource using the information sent with the request,",
"GET - Read an existing resource without modifying it,", "GET - Read an existing resource without modifying it,",
"PUT or PATCH (sometimes POST) - Update a resource using the data sent,", "PUT or PATCH (sometimes POST) - Update a resource using the data sent,",
@ -283,8 +283,5 @@
"challengeType": 2, "challengeType": 2,
"translations": {} "translations": {}
} }
], ]
"fileName": "05-apis-and-microservices/basic-node-and-express.json",
"superBlock": "apis-and-microservices",
"superOrder": 5
} }

View File

@ -278,8 +278,5 @@
"challengeType": 2, "challengeType": 2,
"translations": {} "translations": {}
} }
], ]
"fileName": "05-apis-and-microservices/managing-packages-with-npm.json",
"superBlock": "apis-and-microservices",
"superOrder": 5
} }

View File

@ -19,6 +19,10 @@
{ {
"text": "\"mongoose\" dependency should be in package.json", "text": "\"mongoose\" dependency should be in package.json",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/file/package.json').then(data => { var packJson = JSON.parse(data); assert.property(packJson.dependencies, 'mongoose'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/file/package.json').then(data => { var packJson = JSON.parse(data); assert.property(packJson.dependencies, 'mongoose'); }, xhr => { throw new Error(xhr.responseText); })"
},
{
"text": "\"mongoose\" should be connected to a database",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/is-mongoose-ok').then(data => {assert.isTrue(data.isMongooseOk, 'mongoose is not connected')}, xhr => { throw new Error(xhr.responseText); })"
} }
], ],
"solutions": [], "solutions": [],
@ -256,8 +260,5 @@
"challengeType": 2, "challengeType": 2,
"translations": {} "translations": {}
} }
], ]
"fileName": "05-apis-and-microservices/mongodb-and-mongoose.json",
"superBlock": "apis-and-microservices",
"superOrder": 5
} }

View File

@ -46,7 +46,7 @@
"Looking at our pug file 'index.pug' included in your project, we used the variables <em>title</em> and <em>message</em>", "Looking at our pug file 'index.pug' included in your project, we used the variables <em>title</em> and <em>message</em>",
"To pass those alone from our server, you will need to add an object as a second argument to your <em>res.render</em> with the variables and their value. For example, pass this object along setting the variables for your index view: <code>{title: 'Hello', message: 'Please login'</code>", "To pass those alone from our server, you will need to add an object as a second argument to your <em>res.render</em> with the variables and their value. For example, pass this object along setting the variables for your index view: <code>{title: 'Hello', message: 'Please login'</code>",
"It should look like: <code>res.render(process.cwd() + '/views/pug/index', {title: 'Hello', message: 'Please login'});</code>", "It should look like: <code>res.render(process.cwd() + '/views/pug/index', {title: 'Hello', message: 'Please login'});</code>",
"Now refresh your page and you should see those values rendered in your view in the correct spot as layed out in your index.pug file! Submit your page when you think you've got it right." "Now refresh your page and you should see those values rendered in your view in the correct spot as laid out in your index.pug file! Submit your page when you think you've got it right."
], ],
"challengeSeed": [], "challengeSeed": [],
"tests": [ "tests": [
@ -471,13 +471,13 @@
}, },
{ {
"id": "589fc830f9fc0f352b528e74", "id": "589fc830f9fc0f352b528e74",
"title": "Set up the Enviroment", "title": "Set up the Environment",
"description": [ "description": [
"As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-socketio/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-socketio/'>GitHub</a>.", "As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-socketio/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-socketio/'>GitHub</a>.",
"Add Socket.IO as a dependency and require/instanciate it in your server defined as 'io' with the http server as an argument. <code>const io = require('socket.io')(http);</code>", "Add Socket.IO as a dependency and require/instantiate it in your server defined as 'io' with the http server as an argument. <code>const io = require('socket.io')(http);</code>",
"The first thing needing to be handled is listening for a new connection from the client. The <dfn>on</dfn> keyword does just that- listen for a specific event. It requires 2 arguments: a string containing the title of the event thats emitted, and a function with which the data is passed though. In the case of our connection listener, we use <em>socket</em> to define the data in the second argument. A socket is an individual client who is connected.", "The first thing needing to be handled is listening for a new connection from the client. The <dfn>on</dfn> keyword does just that- listen for a specific event. It requires 2 arguments: a string containing the title of the event thats emitted, and a function with which the data is passed though. In the case of our connection listener, we use <em>socket</em> to define the data in the second argument. A socket is an individual client who is connected.",
"For listening for connections on our server, add the following between the comments in your project:<pre>io.on('connection', socket => {\n console.log('A user has connected');\n});</pre>", "For listening for connections on our server, add the following between the comments in your project:<pre>io.on('connection', socket => {\n console.log('A user has connected');\n});</pre>",
"Now for the client to connect, you just need to add the following to your client.js which is loaded by the page after you've authenticated: <pre>/*global io*/\nvar socket = io();</pre>The comment supresses the error you would normally see since 'io' is not defined in the file. We've already added a reliable CDN to the Socket.IO library on the page in chat.pug.", "Now for the client to connect, you just need to add the following to your client.js which is loaded by the page after you've authenticated: <pre>/*global io*/\nvar socket = io();</pre>The comment suppresses the error you would normally see since 'io' is not defined in the file. We've already added a reliable CDN to the Socket.IO library on the page in chat.pug.",
"Now try loading up your app and authenticate and you should see in your server console 'A user has connected'!", "Now try loading up your app and authenticate and you should see in your server console 'A user has connected'!",
"<strong>Note</strong><br><code>io()</code> works only when connecting to a socket hosted on the same url/server. For connecting to an external socket hosted elsewhere, you would use <code>io.connect('URL');</code>.", "<strong>Note</strong><br><code>io()</code> works only when connecting to a socket hosted on the same url/server. For connecting to an external socket hosted elsewhere, you would use <code>io.connect('URL');</code>.",
"Submit your page when you think you've got it right." "Submit your page when you think you've got it right."
@ -490,7 +490,7 @@
}, },
{ {
"text": "Socket.IO has been properly required and instanciated", "text": "Socket.IO has been properly required and instanciated",
"testString": "getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /io.*=.*require.*('|\")socket.io('|\").*http/gi, 'You should correctly require and instanciate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })" "testString": "getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /io.*=.*require.*('|\")socket.io('|\").*http/gi, 'You should correctly require and instantiate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })"
}, },
{ {
"text": "Socket.IO should be listening for connections", "text": "Socket.IO should be listening for connections",
@ -511,9 +511,9 @@
"title": "Communicate by Emitting", "title": "Communicate by Emitting",
"description": [ "description": [
"As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-socketio/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-socketio/'>GitHub</a>.", "As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-socketio/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-socketio/'>GitHub</a>.",
"<dfn>Emit</dfn> is the most common way of communicating you will use. When you emit something from the server to 'io', you send an event's name and data to all the connected sockets. A good example of this concept would be emiting the current count of connected users each time a new user connects!", "<dfn>Emit</dfn> is the most common way of communicating you will use. When you emit something from the server to 'io', you send an event's name and data to all the connected sockets. A good example of this concept would be emitting the current count of connected users each time a new user connects!",
"<hr>Start by adding a variable to keep track of the users just before where you are currently listening for connections. <code>var currentUsers = 0;</code>", "<hr>Start by adding a variable to keep track of the users just before where you are currently listening for connections. <code>var currentUsers = 0;</code>",
"Now when someone connects you should increment the count before emiting the count so you will want to add the incrementer within the connection listener. <code>++currentUsers;</code>", "Now when someone connects you should increment the count before emitting the count so you will want to add the incrementer within the connection listener. <code>++currentUsers;</code>",
"Finally after incrementing the count, you should emit the event(still within the connection listener). The event should be named 'user count' and the data should just be the 'currentUsers'. <code>io.emit('user count', currentUsers);</code>", "Finally after incrementing the count, you should emit the event(still within the connection listener). The event should be named 'user count' and the data should just be the 'currentUsers'. <code>io.emit('user count', currentUsers);</code>",
"<hr>Now you can implement a way for your client to listen for this event! Similarly to listening for a connection on the server you will use the <em>on</em> keyword. <pre>socket.on('user count', function(data){\n console.log(data);\n});</pre>", "<hr>Now you can implement a way for your client to listen for this event! Similarly to listening for a connection on the server you will use the <em>on</em> keyword. <pre>socket.on('user count', function(data){\n console.log(data);\n});</pre>",
"Now try loading up your app and authenticate and you should see in your client console '1' representing the current user count! Try loading more clients up and authenticating to see the number go up.", "Now try loading up your app and authenticate and you should see in your client console '1' representing the current user count! Try loading more clients up and authenticating to see the number go up.",
@ -574,7 +574,7 @@
"Currently, you cannot determine who is connected to your web socket. While 'req.user' containers the user object, thats only when your user interacts with the web server and with web sockets you have no req (request) and therefor no user data. One way to solve the problem of knowing who is connected to your web socket is by parsing and decoding the cookie that contains the passport session then deserializing it to obtain the user object. Luckily, there is a package on NPM just for this that turns a once complex task into something simple!", "Currently, you cannot determine who is connected to your web socket. While 'req.user' containers the user object, thats only when your user interacts with the web server and with web sockets you have no req (request) and therefor no user data. One way to solve the problem of knowing who is connected to your web socket is by parsing and decoding the cookie that contains the passport session then deserializing it to obtain the user object. Luckily, there is a package on NPM just for this that turns a once complex task into something simple!",
"<hr>Add 'passport.socketio' as a dependency and require it as 'passportSocketIo'.", "<hr>Add 'passport.socketio' as a dependency and require it as 'passportSocketIo'.",
"Now we just have to tell Socket.IO to use it and set the options. Be sure this is added before the existing socket code and not in the existing connection listener. For your server it should look as follows:<pre>io.use(passportSocketIo.authorize({\n cookieParser: cookieParser,\n key: 'express.sid',\n secret: process.env.SESSION_SECRET,\n store: sessionStore\n}));</pre>You can also optionally pass 'success' and 'fail' with a function that will be called after the authentication process completes when a client trys to connect.", "Now we just have to tell Socket.IO to use it and set the options. Be sure this is added before the existing socket code and not in the existing connection listener. For your server it should look as follows:<pre>io.use(passportSocketIo.authorize({\n cookieParser: cookieParser,\n key: 'express.sid',\n secret: process.env.SESSION_SECRET,\n store: sessionStore\n}));</pre>You can also optionally pass 'success' and 'fail' with a function that will be called after the authentication process completes when a client trys to connect.",
"The user object is now accessable on your socket object as <code>socket.request.user</code>. For example, now you can add the following: <code>console.log('user ' + socket.request.user.name + ' connected');</code> and it will log to the server console who has connected!", "The user object is now accessible on your socket object as <code>socket.request.user</code>. For example, now you can add the following: <code>console.log('user ' + socket.request.user.name + ' connected');</code> and it will log to the server console who has connected!",
"Submit your page when you think you've got it right. If you're running into errors, you can check out the project up to this point <a href='https://gist.github.com/JosephLivengood/a9e69ff91337500d5171e29324e1ff35'>here</a>." "Submit your page when you think you've got it right. If you're running into errors, you can check out the project up to this point <a href='https://gist.github.com/JosephLivengood/a9e69ff91337500d5171e29324e1ff35'>here</a>."
], ],
"challengeSeed": [], "challengeSeed": [],
@ -585,7 +585,7 @@
}, },
{ {
"text": "passportSocketIo is properly required", "text": "passportSocketIo is properly required",
"testString": "getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /passportSockerIo.*=.*require.*('|\")passportSocketIo('|\")/gi, 'You should correctly require and instanciate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })" "testString": "getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /passportSockerIo.*=.*require.*('|\")passportSocketIo('|\")/gi, 'You should correctly require and instantiate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })"
}, },
{ {
"text": "passportSocketIo is properly setup", "text": "passportSocketIo is properly setup",
@ -631,8 +631,8 @@
"As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-socketio/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-socketio/'>GitHub</a>.", "As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-socketio/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-socketio/'>GitHub</a>.",
"It's time you start allowing clients to send a chat message to the server to emit to all the clients! Already in your client.js file you should see there is already a block of code handling when the messgae form is submitted! (<code>$('form').submit(function(){ /*logic*/ });</code>)", "It's time you start allowing clients to send a chat message to the server to emit to all the clients! Already in your client.js file you should see there is already a block of code handling when the messgae form is submitted! (<code>$('form').submit(function(){ /*logic*/ });</code>)",
"<hr>Within the code you're handling the form submit you should emit an event after you define 'messageToSend' but before you clear the text box <code>#m</code>. The event should be named 'chat message' and the data should just be 'messageToSend'. <code>socket.emit('chat message', messageToSend);</code>", "<hr>Within the code you're handling the form submit you should emit an event after you define 'messageToSend' but before you clear the text box <code>#m</code>. The event should be named 'chat message' and the data should just be 'messageToSend'. <code>socket.emit('chat message', messageToSend);</code>",
"Now on your server you should be listening to the socket for the event 'chat message' with the data being named 'message'. Once the event is recieved it should then emit the event 'chat message' to all sockets <code>io.emit</code> with the data being an object containing 'name' and 'message'.", "Now on your server you should be listening to the socket for the event 'chat message' with the data being named 'message'. Once the event is received it should then emit the event 'chat message' to all sockets <code>io.emit</code> with the data being an object containing 'name' and 'message'.",
"On your client now again, you should now listen for event 'chat message' and when recieved, append a list item to <code>#messages</code> with the name a colon and the message!", "On your client now again, you should now listen for event 'chat message' and when received, append a list item to <code>#messages</code> with the name a colon and the message!",
"At this point the chat should be fully functional and sending messages across all clients! Submit your page when you think you've got it right. If you're running into errors, you can check out the project up to this point <a href='https://gist.github.com/JosephLivengood/3e4b7750f6cd42feaa2768458d682136'>here for the server</a> and <a href='https://gist.github.com/JosephLivengood/41ba76348df3013b7870dc64861de744'>here for the client</a>." "At this point the chat should be fully functional and sending messages across all clients! Submit your page when you think you've got it right. If you're running into errors, you can check out the project up to this point <a href='https://gist.github.com/JosephLivengood/3e4b7750f6cd42feaa2768458d682136'>here for the server</a> and <a href='https://gist.github.com/JosephLivengood/41ba76348df3013b7870dc64861de744'>here for the client</a>."
], ],
"challengeSeed": [], "challengeSeed": [],
@ -651,8 +651,5 @@
"challengeType": 2, "challengeType": 2,
"translations": {} "translations": {}
} }
], ]
"fileName": "06-information-security-and-quality-assurance/advanced-express-tools.json",
"superBlock": "information-security-and-quality-assurance",
"superOrder": 6
} }

View File

@ -277,7 +277,7 @@
}, },
{ {
"text": "BCrypt has been properly required", "text": "BCrypt has been properly required",
"testString": "getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /bcrypt.*=.*require.*('|\")bcrypt('|\")/gi, 'You should correctly require and instanciate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })" "testString": "getUserInput => $.get(getUserInput('url')+ '/_api/server.js').then(data => {assert.match(data, /bcrypt.*=.*require.*('|\")bcrypt('|\")/gi, 'You should correctly require and instantiate socket.io as io.');}, xhr => { throw new Error(xhr.statusText); })"
} }
], ],
"solutions": [], "solutions": [],
@ -333,8 +333,5 @@
"releasedOn": "Feb 17, 2017", "releasedOn": "Feb 17, 2017",
"translations": {} "translations": {}
} }
], ]
"fileName": "06-information-security-and-quality-assurance/information-security-with-helmetjs.json",
"superBlock": "information-security-and-quality-assurance",
"superOrder": 6
} }

View File

@ -9,7 +9,7 @@
"title": "Metric-Imperial Converter", "title": "Metric-Imperial Converter",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://hard-twilight.glitch.me/' target='_blank'>https://hard-twilight.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://hard-twilight.glitch.me/' target='_blank'>https://hard-twilight.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-metricimpconverter/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-metricimpconverter/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -79,7 +79,7 @@
"title": "Issue Tracker", "title": "Issue Tracker",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://protective-garage.glitch.me/' target='_blank'>https://protective-garage.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://protective-garage.glitch.me/' target='_blank'>https://protective-garage.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-issuetracker/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-issuetracker/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-issuetracker/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-issuetracker/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -129,7 +129,7 @@
"title": "Personal Library", "title": "Personal Library",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://spark-cathedral.glitch.me/' target='_blank'>https://spark-cathedral.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://spark-cathedral.glitch.me/' target='_blank'>https://spark-cathedral.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-library/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-library/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-library/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-library/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -187,7 +187,7 @@
"title": "Stock Price Checker", "title": "Stock Price Checker",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://giant-chronometer.glitch.me/' target='_blank'>https://giant-chronometer.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://giant-chronometer.glitch.me/' target='_blank'>https://giant-chronometer.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-stockchecker/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-stockchecker/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-stockchecker/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-stockchecker/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -197,7 +197,7 @@
"testString": "" "testString": ""
}, },
{ {
"text": "I can GET /api/stock-prices with form data containing a Nasdaq stock ticker and recieve back an object stockData.", "text": "I can GET /api/stock-prices with form data containing a Nasdaq stock ticker and receive back an object stockData.",
"testString": "" "testString": ""
}, },
{ {
@ -233,7 +233,7 @@
"title": "Anonymous Message Board", "title": "Anonymous Message Board",
"description": [ "description": [
"Build a full stack JavaScript app that is functionally similar to this: <a href='https://horn-celery.glitch.me/' target='_blank'>https://horn-celery.glitch.me/</a>.", "Build a full stack JavaScript app that is functionally similar to this: <a href='https://horn-celery.glitch.me/' target='_blank'>https://horn-celery.glitch.me/</a>.",
"Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicaly visible for our testing.", "Working on this project will involve you writing your code on Glitch on our starter project. After completing this project you can copy your public glitch url (to the homepage of your app) into this screen to test it! Optionally you may choose to write your project on another platform but it must be publicly visible for our testing.",
"Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-messageboard/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-messageboard/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!" "Start this project on Glitch using <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-project-messageboard/'>this link</a> or clone <a href='https://github.com/freeCodeCamp/boilerplate-project-messageboard/'>this repository</a> on GitHub! If you use Glitch, remember to save the link to your project somewhere safe!"
], ],
"challengeSeed": [], "challengeSeed": [],
@ -294,8 +294,5 @@
"releasedOn": "January 15, 2017", "releasedOn": "January 15, 2017",
"translations": {} "translations": {}
} }
], ]
"fileName": "06-information-security-and-quality-assurance/quality-assurance-and-information-security-projects.json",
"superBlock": "information-security-and-quality-assurance",
"superOrder": 6
} }

View File

@ -321,15 +321,15 @@
"tests": [ "tests": [
{ {
"text": "All tests should pass", "text": "All tests should pass",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=10').then(data => {assert.equal(data.state,'passed'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=9').then(data => {assert.equal(data.state,'passed'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
"text": "Use approximately(actual, expected, range) - Chose the correct range", "text": "Use approximately(actual, expected, range) - Chose the correct range",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=10').then(data => { assert.equal(data.assertions[0].method, 'isApproximately', 'weirdNumbers(0.5) is in the range (0.5, 1.5]. It\\'s within 1 +/- 0.5'); assert.equal(data.assertions[0].args[2], 0.5); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=9').then(data => { assert.equal(data.assertions[0].method, 'approximately'); assert.equal(data.assertions[0].args[2], 0.5, 'weirdNumbers(0.5) is in the range (0.5, 1.5]. It\\'s within 1 +/- 0.5'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
"text": "Use approximately(actual, expected, range) - Chose the correct range", "text": "Use approximately(actual, expected, range) - Chose the correct range",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=10').then(data => { assert.equal(data.assertions[1].method, 'isApproximately'); assert.equal(data.assertions[1].args[2], 0.8, 'weirdNumbers(0.2) is in the range (0.2, 1.2] It\\'s within 1 +/- 0.8'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=9').then(data => { assert.equal(data.assertions[1].method, 'approximately'); assert.equal(data.assertions[1].args[2], 0.8, 'weirdNumbers(0.2) is in the range (0.2, 1.2]. It\\'s within 1 +/- 0.8'); }, xhr => { throw new Error(xhr.responseText); })"
} }
], ],
"solutions": [], "solutions": [],
@ -539,7 +539,7 @@
}, },
{ {
"text": "Choose the right assertion - typeOf vs. notTypeOf", "text": "Choose the right assertion - typeOf vs. notTypeOf",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=16').then(data => { assert.equal(data.assertions[1].method, 'notTypeOf', 'Plane.wings is a Number (not a String)'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=unit&n=16').then(data => { assert.equal(data.assertions[2].method, 'notTypeOf', 'Plane.wings is a Number (not a String)'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
"text": "Choose the right assertion - typeOf vs. notTypeOf", "text": "Choose the right assertion - typeOf vs. notTypeOf",
@ -698,7 +698,7 @@
}, },
{ {
"id": "587d824f367417b2b2512c5b", "id": "587d824f367417b2b2512c5b",
"title": "Run Functional Tests on an API Response using Chai-HTTP IV - PUT method redux", "title": "Run Functional Tests on an API Response using Chai-HTTP IV - PUT method",
"description": [ "description": [
"As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-mochachai/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-mochachai/'>GitHub</a>.", "As a reminder, this project is being built upon the following starter project on <a href='https://glitch.com/#!/import/github/freeCodeCamp/boilerplate-mochachai/'>Glitch</a>, or cloned from <a href='https://github.com/freeCodeCamp/boilerplate-mochachai/'>GitHub</a>.",
"This exercise is similar to the preceding. Look at it for the details.", "This exercise is similar to the preceding. Look at it for the details.",
@ -752,7 +752,7 @@
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=4').then(data => { assert.equal(data.state,'passed'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=4').then(data => { assert.equal(data.state,'passed'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
"text": "assert that the headless browser request succeded", "text": "assert that the headless browser request succeeded",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=4').then(data => { assert.equal(data.assertions[0].method, 'browser.success'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=4').then(data => { assert.equal(data.assertions[0].method, 'browser.success'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
@ -789,7 +789,7 @@
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=5').then(data => { assert.equal(data.state,'passed'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=5').then(data => { assert.equal(data.state,'passed'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
"text": " assert that the headless browser request succeded", "text": " assert that the headless browser request succeeded",
"testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=5').then(data => { assert.equal(data.assertions[0].method, 'browser.success'); }, xhr => { throw new Error(xhr.responseText); })" "testString": "getUserInput => $.get(getUserInput('url') + '/_api/get-tests?type=functional&n=5').then(data => { assert.equal(data.assertions[0].method, 'browser.success'); }, xhr => { throw new Error(xhr.responseText); })"
}, },
{ {
@ -811,8 +811,5 @@
"releasedOn": "Feb 17, 2017", "releasedOn": "Feb 17, 2017",
"translations": {} "translations": {}
} }
], ]
"fileName": "06-information-security-and-quality-assurance/quality-assurance-and-testing-with-chai.json",
"superBlock": "information-security-and-quality-assurance",
"superOrder": 6
} }

View File

@ -6,7 +6,7 @@
"challenges": [ "challenges": [
{ {
"id": "a3f503de51cf954ede28891d", "id": "a3f503de51cf954ede28891d",
"title": "Symmetric Difference", "title": "Find the Symmetric Difference",
"description": [ "description": [
"Create a function that takes two or more arrays and returns an array of the <dfn>symmetric difference</dfn> (<code>&xutri;</code> or <code>&oplus;</code>) of the provided arrays.", "Create a function that takes two or more arrays and returns an array of the <dfn>symmetric difference</dfn> (<code>&xutri;</code> or <code>&oplus;</code>) of the provided arrays.",
"Given two sets (for example set <code>A = {1, 2, 3}</code> and set <code>B = {2, 3, 4}</code>), the mathematical term \"symmetric difference\" of two sets is the set of elements which are in either of the two sets, but not in both (<code>A &xutri; B = C = {1, 4}</code>). For every additional symmetric difference you take (say on a set <code>D = {2, 3}</code>), you should get the set with elements which are in either of the two the sets but not both (<code>C &xutri; D = {1, 4} &xutri; {2, 3} = {1, 2, 3, 4}</code>). The resulting array must contain only unique values (<em>no duplicates</em>).", "Given two sets (for example set <code>A = {1, 2, 3}</code> and set <code>B = {2, 3, 4}</code>), the mathematical term \"symmetric difference\" of two sets is the set of elements which are in either of the two sets, but not in both (<code>A &xutri; B = C = {1, 4}</code>). For every additional symmetric difference you take (say on a set <code>D = {2, 3}</code>), you should get the set with elements which are in either of the two the sets but not both (<code>C &xutri; D = {1, 4} &xutri; {2, 3} = {1, 2, 3, 4}</code>). The resulting array must contain only unique values (<em>no duplicates</em>).",
@ -117,8 +117,8 @@
"", "",
"sym([1, 2, 3], [5, 2, 1, 4]);" "sym([1, 2, 3], [5, 2, 1, 4]);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -214,8 +214,8 @@
"", "",
"updateInventory(curInv, newInv);" "updateInventory(curInv, newInv);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -316,8 +316,8 @@
"", "",
"permAlone('aab');" "permAlone('aab');"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -326,7 +326,7 @@
"title": "Pairwise", "title": "Pairwise",
"description": [ "description": [
"Given an array <code>arr</code>, find element pairs whose sum equal the second argument <code>arg</code> and return the sum of their indices.", "Given an array <code>arr</code>, find element pairs whose sum equal the second argument <code>arg</code> and return the sum of their indices.",
"You may use multiple pairs that have the same numeric elements but different indices. Each pair should use the lowest possible available indices. Once an element has been used it cannot be reused to pair with another element.", "You may use multiple pairs that have the same numeric elements but different indices. Each pair should use the lowest possible available indices. Once an element has been used it cannot be reused to pair with another element. For instance, <code>pairwise([1, 1, 2], 3)</code> creates a pair <code>[2, 1]</code> using the 1 at indice 0 rather than the 1 at indice 1, because 0+2 < 1+2.",
"For example <code>pairwise([7, 9, 11, 13, 15], 20)</code> returns <code>6</code>. The pairs that sum to 20 are <code>[7, 13]</code> and <code>[9, 11]</code>. We can then write out the array with their indices and values.", "For example <code>pairwise([7, 9, 11, 13, 15], 20)</code> returns <code>6</code>. The pairs that sum to 20 are <code>[7, 13]</code> and <code>[9, 11]</code>. We can then write out the array with their indices and values.",
"<table class=\"table\"><tr><th><strong>Index</strong></th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th></tr><tr><td>Value</td><td>7</td><td>9</td><td>11</td><td>13</td><td>15</td></tr></table>", "<table class=\"table\"><tr><th><strong>Index</strong></th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th></tr><tr><td>Value</td><td>7</td><td>9</td><td>11</td><td>13</td><td>15</td></tr></table>",
"Below we'll take their corresponding indices and add them.", "Below we'll take their corresponding indices and add them.",
@ -410,8 +410,8 @@
"", "",
"pairwise([1,4,2,3,0,5], 7);" "pairwise([1,4,2,3,0,5], 7);"
], ],
"head": "", "head": [],
"tail": "" "tail": []
} }
} }
}, },
@ -423,7 +423,7 @@
"Here we will see bubble sort. The bubble sort method starts at the beginning of an unsorted array and 'bubbles up' unsorted values towards the end, iterating through the array until it is completely sorted. It does this by comparing adjacent items and swapping them if they are out of order. The method continues looping through the array until no swaps occur at which point the array is sorted.", "Here we will see bubble sort. The bubble sort method starts at the beginning of an unsorted array and 'bubbles up' unsorted values towards the end, iterating through the array until it is completely sorted. It does this by comparing adjacent items and swapping them if they are out of order. The method continues looping through the array until no swaps occur at which point the array is sorted.",
"This method requires multiple iterations through the array and for average and worst cases has quadratic time complexity. While simple, it is usually impractical in most situations.", "This method requires multiple iterations through the array and for average and worst cases has quadratic time complexity. While simple, it is usually impractical in most situations.",
"<strong>Instructions:</strong> Write a function <code>bubbleSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.", "<strong>Instructions:</strong> Write a function <code>bubbleSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.",
"<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting alogrithm in action!" "<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting algorithm in action!"
], ],
"tests": [ "tests": [
{ {
@ -464,8 +464,13 @@
"// test array:", "// test array:",
"// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]" "// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]"
], ],
"head": "", "head": [],
"tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" "tail": [
"function isSorted(arr) {",
" var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);",
" return check(0);",
"};"
]
} }
} }
}, },
@ -474,8 +479,8 @@
"title": "Implement Selection Sort", "title": "Implement Selection Sort",
"description": [ "description": [
"Here we will implement selection sort. Selection sort works by selecting the minimum value in a list and swapping it with the first value in the list. It then starts at the second position, selects the smallest value in the remaining list, and swaps it with the second element. It continues iterating through the list and swapping elements until it reaches the end of the list. Now the list is sorted. Selection sort has quadratic time complexity in all cases.", "Here we will implement selection sort. Selection sort works by selecting the minimum value in a list and swapping it with the first value in the list. It then starts at the second position, selects the smallest value in the remaining list, and swaps it with the second element. It continues iterating through the list and swapping elements until it reaches the end of the list. Now the list is sorted. Selection sort has quadratic time complexity in all cases.",
"<stong>Instructions</stong>: Write a function <code>selectionSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.", "<strong>Instructions</strong>: Write a function <code>selectionSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.",
"<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting alogrithm in action!" "<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting algorithm in action!"
], ],
"tests": [ "tests": [
{ {
@ -516,8 +521,13 @@
"// test array:", "// test array:",
"// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]" "// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]"
], ],
"head": "", "head": [],
"tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" "tail": [
"function isSorted(arr) {",
" var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);",
" return check(0);",
"};"
]
} }
} }
}, },
@ -527,7 +537,7 @@
"description": [ "description": [
"The next sorting method we'll look at is insertion sort. This method works by building up a sorted array at the beginning of the list. It begins the sorted array with the first element. Then it inspects the next element and swaps it backwards into the sorted array until it is in sorted position. It continues iterating through the list and swapping new items backwards into the sorted portion until it reaches the end. This algorithm has quadratic time complexity in the average and worst cases.", "The next sorting method we'll look at is insertion sort. This method works by building up a sorted array at the beginning of the list. It begins the sorted array with the first element. Then it inspects the next element and swaps it backwards into the sorted array until it is in sorted position. It continues iterating through the list and swapping new items backwards into the sorted portion until it reaches the end. This algorithm has quadratic time complexity in the average and worst cases.",
"<strong>Instructions:</strong> Write a function <code>insertionSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.", "<strong>Instructions:</strong> Write a function <code>insertionSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest.",
"<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting alogrithm in action!" "<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting algorithm in action!"
], ],
"tests": [ "tests": [
{ {
@ -568,8 +578,13 @@
"// test array:", "// test array:",
"// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]" "// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]"
], ],
"head": "", "head": [],
"tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" "tail": [
"function isSorted(arr) {",
" var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);",
" return check(0);",
"};"
]
} }
} }
}, },
@ -580,7 +595,7 @@
"Here we will move on to an intermediate sorting algorithm: quick sort. Quick sort is an efficient, recursive divide-and-conquer approach to sorting an array. In this method, a pivot value is chosen in the original array. The array is then partitioned into two subarrays of values less than and greater than the pivot value. We then combine the result of recursively calling the quick sort algorithm on both sub-arrays. This continues until the base case of an empty or single-item array is reached, which we return. The unwinding of the recursive calls return us the sorted array.", "Here we will move on to an intermediate sorting algorithm: quick sort. Quick sort is an efficient, recursive divide-and-conquer approach to sorting an array. In this method, a pivot value is chosen in the original array. The array is then partitioned into two subarrays of values less than and greater than the pivot value. We then combine the result of recursively calling the quick sort algorithm on both sub-arrays. This continues until the base case of an empty or single-item array is reached, which we return. The unwinding of the recursive calls return us the sorted array.",
"Quick sort is a very efficient sorting method, providing <i>O(nlog(n))</i> performance on average. It is also relatively easy to implement. These attributes make it a popular and useful sorting method.", "Quick sort is a very efficient sorting method, providing <i>O(nlog(n))</i> performance on average. It is also relatively easy to implement. These attributes make it a popular and useful sorting method.",
"<strong>Instructions:</strong> Write a function <code>quickSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest. While the choice of the pivot value is important, any pivot will do for our purposes here. For simplicity, the first or last element could be used.", "<strong>Instructions:</strong> Write a function <code>quickSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest. While the choice of the pivot value is important, any pivot will do for our purposes here. For simplicity, the first or last element could be used.",
"<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting alogrithm in action!" "<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting algorithm in action!"
], ],
"tests": [ "tests": [
{ {
@ -621,8 +636,13 @@
"// test array:", "// test array:",
"// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]" "// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]"
], ],
"head": "", "head": [],
"tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" "tail": [
"function isSorted(arr) {",
" var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);",
" return check(0);",
"};"
]
} }
} }
}, },
@ -636,7 +656,7 @@
"Merge sort is an efficient sorting method, with time complexity of <i>O(nlog(n))</i>. This algorithm is popular because it is performant and relatively easy to implement.", "Merge sort is an efficient sorting method, with time complexity of <i>O(nlog(n))</i>. This algorithm is popular because it is performant and relatively easy to implement.",
"As an aside, this will be the last sorting algorithm we cover here. However, later in the section on tree data structures we will describe heap sort, another efficient sorting method that requires a binary heap in its implementation.", "As an aside, this will be the last sorting algorithm we cover here. However, later in the section on tree data structures we will describe heap sort, another efficient sorting method that requires a binary heap in its implementation.",
"<strong>Instructions:</strong> Write a function <code>mergeSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest. A good way to implement this is to write one function, for instance <code>merge</code>, which is responsible for merging two sorted arrays, and another function, for instance <code>mergeSort</code>, which is responsible for the recursion that produces single-item arrays to feed into merge. Good luck!", "<strong>Instructions:</strong> Write a function <code>mergeSort</code> which takes an array of integers as input and returns an array of these integers in sorted order from least to greatest. A good way to implement this is to write one function, for instance <code>merge</code>, which is responsible for merging two sorted arrays, and another function, for instance <code>mergeSort</code>, which is responsible for the recursion that produces single-item arrays to feed into merge. Good luck!",
"<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting alogrithm in action!" "<strong>Note:</strong><br>We are calling this function from behind the scenes; the test array we are using is commented out in the editor. Try logging <code>array</code> to see your sorting algorithm in action!"
], ],
"tests": [ "tests": [
{ {
@ -677,13 +697,15 @@
"// test array:", "// test array:",
"// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]" "// [1, 4, 2, 8, 345, 123, 43, 32, 5643, 63, 123, 43, 2, 55, 1, 234, 92]"
], ],
"head": "", "head": [],
"tail": "function isSorted(arr) {\n var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);\n return check(0);\n};" "tail": [
"function isSorted(arr) {",
" var check = (i) => (i == arr.length - 1) ? true : (arr[i] > arr[i + 1]) ? false : check(i + 1);",
" return check(0);",
"};"
]
} }
} }
} }
], ]
"fileName": "08-coding-interview-questions-and-take-home-assignments/coding-interview-algorithm-questions.json",
"superBlock": "coding-interview-questions-and-take-home-assignments",
"superOrder": 8
} }

View File

@ -0,0 +1,249 @@
# A guide to improve Project Euler's problems
Thank you for contributing to freeCodeCamp, your help is definitely needed here!
freeCodeCamp is having a great breakthrough ahead, one of it is to prepare
campers for interview questions, and Project Euler is one of them.
And to let campers having fun with this challenges during Christmas, we are
going to have a lot of help here to improve the challenges of Project Euler
problems (so people won't cheating by returning the value right away, since
Project Euler's problems only assert one answer.)
**Table of Contents**
* [What is Project Euler](#what-is-project-euler)
* [How to improve the problems](#how-to-improve-the-problems)
## What is Project Euler
[Project Euler](https://projecteuler.net/) is a series of challenging
mathematical/computer programming problems that will require more than just
mathematical insights to solve. Although mathematics will help you arrive at
elegant and efficient methods, the use of a computer and programming skills will
be required to solve most problems.
The motivation for starting Project Euler, and its continuation, is to provide a
platform for the inquiring mind to delve into unfamiliar areas and learn new
concepts in a fun and recreational context.
## How to improve the problems
The Project Euler problems seed can be found at
`seed/challenges/08-coding-interview-questions-and-take-home-assignments/project-euler-problems.json`
Here's what it will look like (this is before the improvements, take problem 23
as the example)
```javascript
{
"_id": "5900f3831000cf542c50fe96",
"challengeType": 5,
"type": "bonfire",
"title": "Problem 23: Non-abundant sums",
"tests": [
"assert.strictEqual(euler23(), 4179871, 'message: <code>euler23()</code> should return 4179871.');"
],
"solutions": [],
"translations": {},
"challengeSeed": [
"function euler23() {",
" // Good luck!",
" return true;",
"}",
"",
"euler23();"
],
"description": [
"A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.",
"A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.",
"",
"As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.",
"Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers."
]
},
```
and here's after some improvements
```javascript
{
"_id": "5900f3831000cf542c50fe96",
"challengeType": 5,
"type": "bonfire",
"title": "Problem 23: Non-abundant sums",
"tests": [
"assert(sumOfNonAbundantNumbers(10000) === 3731004, 'message: <code>sumOfNonAbundantNumbers(10000)</code> should return 3731004.');",
"assert(sumOfNonAbundantNumbers(15000) === 4039939, 'message: <code>sumOfNonAbundantNumbers(15000)</code> should return 4039939.');",
"assert(sumOfNonAbundantNumbers(20000) === 4159710, 'message: <code>sumOfNonAbundantNumbers(20000)</code> should return 4159710.');",
"assert(sumOfNonAbundantNumbers(28123) === 4179871, 'message: <code>sumOfNonAbundantNumbers(28123)</code> should return 4179871.');"
],
"solutions": [],
"translations": {},
"challengeSeed": [
"function sumOfNonAbundantNumbers(n) {",
" // Good luck!",
" return n;",
"}",
"",
"sumOfNonAbundantNumbers(28123);"
],
"description": [
"A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.",
"A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.",
"",
"As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.",
"Find the sum of all positive integers <= n which cannot be written as the sum of two abundant numbers."
]
},
```
Don't be confused now, here's what to do to improve the problems:
(We expect you already have forked freeCodeCamp's repository)
### Step 1: Create new branch at your git origin (e.g: `feature/problem_euler23`)
Always create the branch with the base refer to the newest freeCodeCamp's
staging branch, here's how to do that:
1. Do fetch staging branch from freeCodeCamp's repository `$ git fetch upstream
staging`
2. Checkout to the staging branch `$ git checkout upstream/staging`
3. Create branch from upstream/staging `$ git checkout -b <branch_name>`
### Step 2: Change the name of the function to more readable
For example, from `euler23()` into `sumOfNonAbundantNumbers()` We took the name
from the problem name :D
### Step 3: Solve the problem by yourself
Try to solve the problem by yourself but if you get stucked,
Here's what to do: you can go to [mathblog](http://www.mathblog.dk/) or
[dreamshire](https://blog.dreamshire.com) to find other people's solution
written in other languages (usually C and C#) Learn from their solution and port
it to JavaScript :) ( Always have the perspective of learning, don't just copy
paste other people's code )
So from the example here's my solution (We didn't include it in the JSON because
up till now, we couldn't find a way to fit it in, when we transformed it into
array of strings it spits out error when running `$ npm run test-challenges` it
will be awesome if you can find how to fits that right in)
```javascript
function sumOfNonAbundantNumbers() {
const getFactors = number => {
let factors = [];
let possibleFactor = 1;
let sqrt = Math.sqrt(number);
while (possibleFactor <= sqrt) {
if (number % possibleFactor == 0) {
factors[factors.length] = possibleFactor;
let otherPossibleFactor = number / possibleFactor;
if (otherPossibleFactor > possibleFactor)
factors[factors.length] = otherPossibleFactor;
}
possibleFactor++;
}
return factors;
};
const getAbundantNumbers = upperLimit => {
let abundantNumbers = [];
for (let i = 12; i <= upperLimit; i++) {
let factors = getFactors(i);
let factorSum = 0;
for (let factor, j = 0; (factor = factors[j]); j++)
if (i != factor) factorSum += factor;
if (factorSum > i) {
abundantNumbers.push(i);
}
}
return abundantNumbers;
};
var abundantNumbers = getAbundantNumbers(28123);
var sum = 0;
for (var testNum = 1; testNum <= 28123; testNum++) {
var sumOfAbundant = false;
for (
var i = 0, j = abundantNumbers.length - 1, abundantNumber1;
(abundantNumber1 = abundantNumbers[i]);
i++
) {
if (abundantNumber1 > testNum) {
break;
}
var abundantNumber2 = abundantNumbers[j];
while (j > 0 && abundantNumber1 + abundantNumber2 > testNum) {
abundantNumber2 = abundantNumbers[--j];
}
if (abundantNumber1 + abundantNumber2 == testNum) {
sumOfAbundant = true;
break;
}
}
if (!sumOfAbundant) {
sum += testNum;
}
}
return sum;
}
```
After finished solving the problem, you can improve the task a little bit, for
example compared to asking campers to find the sum of all the positive integers,
you can ask campers to find the sum of all positive integers <= n.
(if you add more assertions to the problem, always assert less than the original
problem, to prevent infinite loop, etc)
One last thing, always make sure that the return value of the function is always
the same data type to which you want the function to return
Like in the example above, we want the user to return integer, so we changed the
return value from true into integer.
### Step 4: Running Test on Arcade Mode
After done with the solution, run the test on
[ FCC's Arcade Mode ](https://github.com/freeCodeCamp/arcade-mode)
### Step 5: Commit changes and push to your origin
1. Do changes and add changed files to stage `$ git add .`
2. Commit those changes using `$ npm run commit` and follow the instruction
there.
3. And run `$ git push origin <branch_name>`
### Step 5: Create Pull Request to freeCodeCamp's staging branch
Create PR to freeCodeCamp's staging branch and wait for your code to be assesed
from the maintainer.
That's all it! if there's something unclear and you still have questions, you
can chat from gitter in
[Arcade-Mode](https://gitter.im/FreeCodeCamp/arcade-mode)
[Contributors](https://gitter.im/FreeCodeCamp/Contributors) or you can text me
right away @alvinkl
# Why do we have to improve Project Euler problems?
Our goal is to prevent user from cheating and just returning the project euler
result rightaway, and by giving more assertions and improving a bit of the task
we are able to make the challenge more challenging as well.
With your help, we can help people to practice their skills and be confident to
face technical interviews like this :)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,37 @@
{
"name": "API's and Microservices Certificate",
"order": 5,
"isPrivate": true,
"challenges": [
{
"id": "561add10cb82ac38a17523bc",
"title": "API's and Microservices Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7158d8c443edefaeb5bdef",
"title": "Timestamp Microservice"
},
{
"id": "bd7158d8c443edefaeb5bdff",
"title": "Request Header Parser Microservice"
},
{
"id": "bd7158d8c443edefaeb5bd0e",
"title": "URL Shortener Microservice"
},
{
"id": "bd7158d8c443edefaeb5bdee",
"title": "Exercise Tracker"
},
{
"id": "bd7158d8c443edefaeb5bd0f",
"title": "File Metadata Microservice"
}
]
}
]
}

View File

@ -0,0 +1,37 @@
{
"name": "Data Visualization Certificate",
"order": 4,
"isPrivate": true,
"challenges": [
{
"id": "5a553ca864b52e1d8bceea14",
"title": "Data Visualization Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7168d8c242eddfaeb5bd13",
"title": "Visualize Data with a Bar Chart"
},
{
"id": "bd7178d8c242eddfaeb5bd13",
"title": "Visualize Data with a Scatterplot Graph"
},
{
"id": "bd7188d8c242eddfaeb5bd13",
"title": "Visualize Data with a Heat Map"
},
{
"id": "587d7fa6367417b2b2512bbf",
"title": "Visualize Data with a Choropleth Map"
},
{
"id": "587d7fa6367417b2b2512bc0",
"title": "Visualize Data with a Treemap Diagram"
}
]
}
]
}

View File

@ -0,0 +1,37 @@
{
"name": "Front End Libraries Certificate",
"order": 3,
"isPrivate": true,
"challenges": [
{
"id": "561acd10cb82ac38a17513bc",
"title": "Front End Libraries Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7158d8c442eddfaeb5bd13",
"title": "Build a Random Quote Machine"
},
{
"id": "bd7157d8c242eddfaeb5bd13",
"title": "Build a Markdown Previewer"
},
{
"id": "587d7dbc367417b2b2512bae",
"title": "Build a Drum Machine"
},
{
"id": "bd7158d8c442eddfaeb5bd17",
"title": "Build a JavaScript Calculator"
},
{
"id": "bd7158d8c442eddfaeb5bd0f",
"title": "Build a Pomodoro Clock"
}
]
}
]
}

View File

@ -0,0 +1,37 @@
{
"name": "Information, Securtiy and Quality Assurance Certificate",
"order": 6,
"isPrivate": true,
"challenges": [
{
"id": "561add10cb82ac38a17213bc",
"title": "Information, Securtiy and Quality Assurance Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "587d8249367417b2b2512c42",
"title": "Issue Tracker"
},
{
"id": "587d8249367417b2b2512c41",
"title": "Metric-Imperial Converter"
},
{
"id": "587d824a367417b2b2512c43",
"title": "Personal Library"
},
{
"id": "587d824a367417b2b2512c44",
"title": "Stock Price Checker"
},
{
"id": "587d824a367417b2b2512c45",
"title": "Anonymous Message Board"
}
]
}
]
}

View File

@ -0,0 +1,37 @@
{
"name": "JavaScript Algorithms and Data Structures Certificate",
"order": 2,
"isPrivate": true,
"challenges": [
{
"id": "561abd10cb81ac38a17513bc",
"title": "JavaScript Algorithms and Data Structures Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "aaa48de84e1ecc7c742e1124",
"title": "Palindrome Checker"
},
{
"id": "a7f4d8f2483413a6ce226cac",
"title": "Roman Numeral Converter"
},
{
"id": "56533eb9ac21ba0edf2244e2",
"title": "Caesars Cipher"
},
{
"id": "aff0395860f5d3034dc0bfc9",
"title": "Telephone Number Validator"
},
{
"id": "aa2e6f85cab2ab736c9a9b24",
"title": "Cash Register"
}
]
}
]
}

View File

@ -0,0 +1,57 @@
{
"name": "Legacy Back End Certificate",
"order": 1,
"isPrivate": true,
"challenges": [
{
"id": "660add10cb82ac38a17513be",
"title": "Legacy Back End Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7158d8c443edefaeb5bdef",
"title": "Timestamp Microservice"
},
{
"id": "bd7158d8c443edefaeb5bdff",
"title": "Request Header Parser Microservice"
},
{
"id": "bd7158d8c443edefaeb5bd0e",
"title": "URL Shortener Microservice"
},
{
"id": "bd7158d8c443edefaeb5bdee",
"title": "Image Search Abstraction Layer"
},
{
"id": "bd7158d8c443edefaeb5bd0f",
"title": "File Metadata Microservice"
},
{
"id": "bd7158d8c443eddfaeb5bdef",
"title": "Build a Voting App"
},
{
"id": "bd7158d8c443eddfaeb5bdff",
"title": "Build a Nightlife Coordination App"
},
{
"id": "bd7158d8c443eddfaeb5bd0e",
"title": "Chart the Stock Market"
},
{
"id": "bd7158d8c443eddfaeb5bd0f",
"title": "Manage a Book Trading Club"
},
{
"id": "bd7158d8c443eddfaeb5bdee",
"title": "Build a Pinterest Clone"
}
]
}
]
}

View File

@ -0,0 +1,57 @@
{
"name": "Legacy Data Visualization Certificate",
"order": 1,
"isPrivate": true,
"challenges": [
{
"id": "561add10cb82ac39a17513bc",
"title": "Legacy Data Visualization Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7157d8c242eddfaeb5bd13",
"title": "Build a Markdown Previewer"
},
{
"id": "bd7156d8c242eddfaeb5bd13",
"title": "Build a Camper Leaderboard"
},
{
"id": "bd7155d8c242eddfaeb5bd13",
"title": "Build a Recipe Box"
},
{
"id": "bd7154d8c242eddfaeb5bd13",
"title": "Build the Game of Life"
},
{
"id": "bd7153d8c242eddfaeb5bd13",
"title": "Build a Roguelike Dungeon Crawler Game"
},
{
"id": "bd7168d8c242eddfaeb5bd13",
"title": "Visualize Data with a Bar Chart"
},
{
"id": "bd7178d8c242eddfaeb5bd13",
"title": "Visualize Data with a Scatterplot Graph"
},
{
"id": "bd7188d8c242eddfaeb5bd13",
"title": "Visualize Data with a Heat Map"
},
{
"id": "bd7198d8c242eddfaeb5bd13",
"title": "Show National Contiguity with a Force Directed Graph"
},
{
"id": "bd7108d8c242eddfaeb5bd13",
"title": "Map Data Across the Globe"
}
]
}
]
}

View File

@ -0,0 +1,57 @@
{
"name": "Legacy Front End Certificate",
"order": 1,
"isPrivate": true,
"challenges": [
{
"id": "561add10cb82ac38a17513be",
"title": "Legacy Front End Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7158d8c242eddfaeb5bd13",
"title": "Build a Personal Portfolio Webpage"
},
{
"id": "bd7158d8c442eddfaeb5bd13",
"title": "Build a Random Quote Machine"
},
{
"id": "bd7158d8c442eddfaeb5bd0f",
"title": "Build a Pomodoro Clock"
},
{
"id": "bd7158d8c442eddfaeb5bd17",
"title": "Build a JavaScript Calculator"
},
{
"id": "bd7158d8c442eddfaeb5bd10",
"title": "Show the Local Weather"
},
{
"id": "bd7158d8c442eddfaeb5bd1f",
"title": "Use the Twitch JSON API"
},
{
"id": "bd7158d8c442eddfaeb5bd18",
"title": "Stylize Stories on Camper News"
},
{
"id": "bd7158d8c442eddfaeb5bd19",
"title": "Build a Wikipedia Viewer"
},
{
"id": "bd7158d8c442eedfaeb5bd1c",
"title": "Build a Tic Tac Toe Game"
},
{
"id": "bd7158d8c442eddfaeb5bd1c",
"title": "Build a Simon Game"
}
]
}
]
}

View File

@ -0,0 +1,37 @@
{
"name": "Responsive Web Design Certificate",
"order": 1,
"isPrivate": true,
"challenges": [
{
"id": "561add10cb82ac38a17513bc",
"title": "Responsive Web Design Certificate",
"challengeType": 7,
"description": [],
"challengeSeed": [],
"isPrivate": true,
"tests": [
{
"id": "bd7158d8c442eddfaeb5bd18",
"title": "Build a Tribute Page"
},
{
"id": "587d78af367417b2b2512b03",
"title": "Build a Survey Form"
},
{
"id": "587d78af367417b2b2512b04",
"title": "Build a Product Landing Page"
},
{
"id": "587d78b0367417b2b2512b05",
"title": "Build a Technical Documentation Page"
},
{
"id": "587d78b0367417b2b2512b06",
"title": "Build a Personal Portfolio Webpage"
}
]
}
]
}

View File

@ -1,3 +1,6 @@
/*
TODO(Bouncey): Placed in ./src/pages when we have auth
*/
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';

View File

@ -1,16 +1,49 @@
header {
top: 0;
position: fixed;
width: 100%;
z-index: 200;
}
#top-nav { #top-nav {
background: #006400; background: #006400;
margin-bottom: 0.45rem; margin-bottom: 0.45rem;
height: 38px;
margin-bottom: 0px;
border-radius: 0;
border: none;
display: flex;
justify-content: space-between;
}
#top-nav .home-link {
display: flex;
align-items: center;
} }
#top-nav img { #top-nav img {
margin-bottom: 0; max-height: 36px;
margin: 0 5px 0 10px;
} }
.top-nav-container { #top-right-nav {
margin: 0 auto;
max-width: 960px;
display: flex; display: flex;
justify-content: space-between; margin: 0;
align-items: center; list-style: none;
}
#top-right-nav li {
display: flex;
align-items: center;
margin: 0px 10px;
}
#top-right-nav li > a {
color:#fff;
font-size: 17px;
}
#top-right-nav li > a:hover, #top-right-nav li > a:focus {
text-decoration: none;
font-weight: 700;
} }

View File

@ -2,27 +2,27 @@ import React from 'react';
import Link from 'gatsby-link'; import Link from 'gatsby-link';
import './header.css'; import './header.css';
import UserState from './components/UserState';
function Header() { function Header() {
return ( return (
<header id='top-nav'> <header>
<div className='top-nav-container'> <nav id='top-nav'>
<Link <Link className='home-link' to='/'>
style={{
color: 'white',
textDecoration: 'none'
}}
to='/'
>
<img <img
alt='Logo - freeCodeCamp | Learn to code' alt='Logo - freeCodeCamp | Learn to code'
src={'https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg'} src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg'
title='freeCodeCamp | Learn to code' title='freeCodeCamp | Learn to code'
/> />
</Link> </Link>
<UserState /> <ul id='top-right-nav'>
</div> <li>
<a href='https://learn.freecodecamp.org'>Learn</a>
</li>
<li>
<a href='https://forum.freecodecamp.org'>Forum</a>
</li>
</ul>
</nav>
</header> </header>
); );
} }

View File

@ -24,10 +24,12 @@ class ShowMap extends PureComponent {
const { nodes } = this.props; const { nodes } = this.props;
const superBlocks = uniq(nodes.map(({ superBlock }) => superBlock)); const superBlocks = uniq(nodes.map(({ superBlock }) => superBlock));
return ( return (
<ul> <div className='map-ui'>
{this.renderSuperBlocks(superBlocks)} <ul>
<Spacer /> {this.renderSuperBlocks(superBlocks)}
</ul> <Spacer />
</ul>
</div>
); );
} }
} }

View File

@ -1,237 +1,241 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Map /> snapshot: Map 1`] = ` exports[`<Map /> snapshot: Map 1`] = `
<ul> <div
<Connect(SuperBlock) className="map-ui"
nodes={ >
Array [ <ul>
Object { <Connect(SuperBlock)
"block": "block-a", nodes={
"dashedName": "challenge-one", Array [
"fields": Object { Object {
"blockName": "Block A", "block": "block-a",
"slug": "/super-block-one/block-a/challenge-one", "dashedName": "challenge-one",
"fields": Object {
"blockName": "Block A",
"slug": "/super-block-one/block-a/challenge-one",
},
"isPrivate": false,
"isRequired": false,
"superBlock": "Super Block One",
"title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-a",
"superBlock": "Super Block One", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-two",
"block": "block-a", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block One",
"slug": "/super-block-one/block-a/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block One", "dashedName": "challenge-one",
"title": "Challenge Two", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-one",
"block": "block-b", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block One",
"slug": "/super-block-one/block-b/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block One", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-two",
"block": "block-b", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block One",
"slug": "/super-block-one/block-b/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-c",
"superBlock": "Super Block One", "dashedName": "challenge-one",
"title": "Challenge Two", "fields": Object {
}, "blockName": "Block C",
Object { "slug": "/super-block-one/block-c/challenge-one",
"block": "block-c", },
"dashedName": "challenge-one", "isPrivate": true,
"fields": Object { "isRequired": false,
"blockName": "Block C", "superBlock": "Super Block One",
"slug": "/super-block-one/block-c/challenge-one", "title": "Challenge One",
}, },
"isPrivate": true, Object {
"isRequired": false, "block": "block-a",
"superBlock": "Super Block One", "dashedName": "challenge-one",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-one",
"block": "block-a", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-a/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-a",
"superBlock": "Super Block Two", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-two",
"block": "block-a", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-a/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block Two", "dashedName": "challenge-one",
"title": "Challenge Two", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-one",
"block": "block-b", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-b/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block Two", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-two",
"block": "block-b", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-b/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, ]
"isRequired": false, }
"superBlock": "Super Block Two", superBlock="Super Block One"
"title": "Challenge Two", />
}, <Connect(SuperBlock)
] nodes={
} Array [
superBlock="Super Block One" Object {
/> "block": "block-a",
<Connect(SuperBlock) "dashedName": "challenge-one",
nodes={ "fields": Object {
Array [ "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-one",
"block": "block-a", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block One",
"slug": "/super-block-one/block-a/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-a",
"superBlock": "Super Block One", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-two",
"block": "block-a", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block One",
"slug": "/super-block-one/block-a/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block One", "dashedName": "challenge-one",
"title": "Challenge Two", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-one",
"block": "block-b", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block One",
"slug": "/super-block-one/block-b/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block One", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-two",
"block": "block-b", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block One",
"slug": "/super-block-one/block-b/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-c",
"superBlock": "Super Block One", "dashedName": "challenge-one",
"title": "Challenge Two", "fields": Object {
}, "blockName": "Block C",
Object { "slug": "/super-block-one/block-c/challenge-one",
"block": "block-c", },
"dashedName": "challenge-one", "isPrivate": true,
"fields": Object { "isRequired": false,
"blockName": "Block C", "superBlock": "Super Block One",
"slug": "/super-block-one/block-c/challenge-one", "title": "Challenge One",
}, },
"isPrivate": true, Object {
"isRequired": false, "block": "block-a",
"superBlock": "Super Block One", "dashedName": "challenge-one",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-one",
"block": "block-a", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-a/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-a",
"superBlock": "Super Block Two", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block A",
Object { "slug": "/super-block-one/block-a/challenge-two",
"block": "block-a", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block A", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-a/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block Two", "dashedName": "challenge-one",
"title": "Challenge Two", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-one",
"block": "block-b", },
"dashedName": "challenge-one", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-b/challenge-one", "title": "Challenge One",
}, },
"isPrivate": false, Object {
"isRequired": false, "block": "block-b",
"superBlock": "Super Block Two", "dashedName": "challenge-two",
"title": "Challenge One", "fields": Object {
}, "blockName": "Block B",
Object { "slug": "/super-block-one/block-b/challenge-two",
"block": "block-b", },
"dashedName": "challenge-two", "isPrivate": false,
"fields": Object { "isRequired": false,
"blockName": "Block B", "superBlock": "Super Block Two",
"slug": "/super-block-one/block-b/challenge-two", "title": "Challenge Two",
}, },
"isPrivate": false, ]
"isRequired": false, }
"superBlock": "Super Block Two", superBlock="Super Block Two"
"title": "Challenge Two", />
}, <Spacer />
] </ul>
} </div>
superBlock="Super Block Two"
/>
<Spacer />
</ul>
`; `;

View File

@ -1,9 +1,9 @@
aside#map { .map-ui {
height: 100%; height: 100%;
max-height: calc(100vh - (45px + 1.45rem)); max-height: calc(100vh - (45px + 1.45rem));
} }
aside#map ul { .map-ui ul {
list-style: none; list-style: none;
color: #006400; color: #006400;
} }
@ -20,6 +20,6 @@ aside#map ul {
flex-shrink: 0 flex-shrink: 0
} }
li.open>.map-title svg { li.open > .map-title svg {
transform: rotate(90deg); transform: rotate(90deg);
} }

View File

@ -0,0 +1,52 @@
import React from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { Modal } from 'react-bootstrap';
import { ChallengeNode } from '../../redux/propTypes';
import Map from '../Map';
import { toggleMapModal, isMapModalOpenSelector } from '../../redux/app';
import Spacer from '../util/Spacer';
const mapStateToProps = createSelector(isMapModalOpenSelector, show => ({
show
}));
const mapDispatchToProps = dispatch =>
bindActionCreators({ toggleMapModal }, dispatch);
const propTypes = {
nodes: PropTypes.arrayOf(ChallengeNode),
show: PropTypes.bool,
toggleMapModal: PropTypes.func.isRequired
};
function MapModal({ nodes, show, toggleMapModal }) {
return (
<Modal
bsSize='lg'
className='map-modal'
onHide={toggleMapModal}
show={show}
>
<Modal.Header className='map-modal-header fcc-modal' closeButton={true}>
<Modal.Title className='text-center'>
A Map to Learn to Code
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Spacer />
<Map nodes={nodes} />
<Spacer />
</Modal.Body>
</Modal>
);
}
MapModal.displayName = 'MapModal';
MapModal.propTypes = propTypes;
export default connect(mapStateToProps, mapDispatchToProps)(MapModal);

View File

@ -0,0 +1,3 @@
.map-modal .map-ui {
overflow-y: scroll;
}

View File

@ -4,7 +4,7 @@ import { Button } from 'react-bootstrap';
function BlockSaveButton(props) { function BlockSaveButton(props) {
return ( return (
<Button block={true} bsSize='lg' bsStyle='primary' {...props} type='submit'> <Button block={true} bsStyle='primary' {...props} type='submit'>
{props.children || 'Save'} {props.children || 'Save'}
</Button> </Button>
); );

View File

@ -44,7 +44,11 @@ export function DynamicForm({
submit submit
}) { }) {
return ( return (
<form id={`dynamic-${id}`} onSubmit={handleSubmit(submit)}> <form
id={`dynamic-${id}`}
onSubmit={handleSubmit(submit)}
style={{ width: '100%' }}
>
<FormFields errors={errors} fields={fields} options={options} /> <FormFields errors={errors} fields={fields} options={options} />
<BlockSaveWrapper> <BlockSaveWrapper>
{hideButton ? null : ( {hideButton ? null : (

View File

@ -1,15 +1,16 @@
import React from 'react'; import React from 'react';
import _ from 'lodash'; import { kebabCase, startCase } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
Alert, Alert,
Col, Col,
ControlLabel, ControlLabel,
FormControl, FormControl,
HelpBlock, HelpBlock
Row
} from 'react-bootstrap'; } from 'react-bootstrap';
import './form-fields.css';
const propTypes = { const propTypes = {
errors: PropTypes.objectOf(PropTypes.string), errors: PropTypes.objectOf(PropTypes.string),
fields: PropTypes.objectOf( fields: PropTypes.objectOf(
@ -44,13 +45,13 @@ function FormFields(props) {
.filter(field => !ignored.includes(field)) .filter(field => !ignored.includes(field))
.map(key => fields[key]) .map(key => fields[key])
.map(({ name, onChange, value, pristine }) => { .map(({ name, onChange, value, pristine }) => {
const key = _.kebabCase(name); const key = kebabCase(name);
const type = name in types ? types[name] : 'text'; const type = name in types ? types[name] : 'text';
return ( return (
<Row className='inline-form-field' key={key}> <div className='inline-form-field' key={key}>
<Col sm={3} xs={12}> <Col sm={3} xs={12}>
{type === 'hidden' ? null : ( {type === 'hidden' ? null : (
<ControlLabel htmlFor={key}>{_.startCase(name)}</ControlLabel> <ControlLabel htmlFor={key}>{startCase(name)}</ControlLabel>
)} )}
</Col> </Col>
<Col sm={9} xs={12}> <Col sm={9} xs={12}>
@ -72,7 +73,7 @@ function FormFields(props) {
</HelpBlock> </HelpBlock>
) : null} ) : null}
</Col> </Col>
</Row> </div>
); );
})} })}
</div> </div>

View File

@ -2,7 +2,7 @@
exports[`<BlockSaveButton /> snapshot 1`] = ` exports[`<BlockSaveButton /> snapshot 1`] = `
<button <button
className="btn btn-lg btn-primary btn-block" className="btn btn-primary btn-block"
disabled={false} disabled={false}
type="submit" type="submit"
> >

View File

@ -4,10 +4,15 @@ exports[`<DynamicForm /> snapshot 1`] = `
<form <form
id="dynamic-my-test-form" id="dynamic-my-test-form"
onSubmit={undefined} onSubmit={undefined}
style={
Object {
"width": "100%",
}
}
> >
<div> <div>
<div <div
className="inline-form-field row" className="inline-form-field"
> >
<div <div
className="col-sm-3 col-xs-12" className="col-sm-3 col-xs-12"
@ -44,7 +49,7 @@ exports[`<DynamicForm /> snapshot 1`] = `
} }
> >
<button <button
className="btn btn-lg btn-primary btn-block" className="btn btn-primary btn-block"
disabled={false} disabled={false}
type="submit" type="submit"
> >

View File

@ -1,6 +1,6 @@
.strange-place-container { .inline-form-field {
display: flex;
height: 100%; height: 100%;
justify-content: center; display: flex;
align-items: center; align-items: center;
margin-bottom: 5px;
} }

View File

@ -0,0 +1,10 @@
---
title: Introduction to the APIs and Microservices Projects
block: APIs and Microservices Projects
superBlock: APIs and Microservices
---
## Introduction to the APIs and Microservices Projects
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -0,0 +1,10 @@
---
title: Introduction to the Data Visualization Projects
block: Data Visualization Projects
superBlock: Data Visualization
---
## Introduction to the Data Visualization Projects
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -0,0 +1,10 @@
---
title: Introduction to the Front End Libraries Projects
block: Front End Libraries Projects
superBlock: Front End Libraries
---
## Introduction to the Front End Libraries Projects
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -0,0 +1,10 @@
---
title: Introduction to the Information Security and Quality Assurance Projects
block: Information Security and Quality Assurance Projects
superBlock: Information Security and Quality Assurance
---
## Introduction to the Information Security and Quality Assurance Projects
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -0,0 +1,10 @@
---
title: Introduction to the JavaScript Algorithms and Data Structures Projects
block: JavaScript Algorithms and Data Structures Projects
superBlock: JavaScript Algorithms and Data Structures
---
## Introduction to the JavaScript Algorithms and Data Structures Projects
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -0,0 +1,10 @@
---
title: Introduction to the Responsive Web Design Projects
block: Responsive Web Design Projects
superBlock: Responsive Web Design
---
## Introduction to the Responsive Web Design Projects
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -5,12 +5,9 @@ html {
} }
body { body {
margin: 0; margin: 0;
font-size: 16px;
} }
html, body, .full-height {
min-height: 100% !important;
height: 100%;
max-height: calc(100vh);
}
article, article,
aside, aside,
details, details,
@ -190,7 +187,6 @@ textarea {
html { html {
font: 112.5%/1.45em georgia, serif; font: 112.5%/1.45em georgia, serif;
box-sizing: border-box; box-sizing: border-box;
overflow-y: scroll;
} }
* { * {
box-sizing: inherit; box-sizing: inherit;
@ -627,3 +623,14 @@ pre tt:after {
font-size: 100%; font-size: 100%;
} }
} }
.fcc-modal {
background-color: #006400;
color: #fff;
}
.fcc-modal .close {
color: #fff;
font-size: 28px;
text-shadow: none;
}

View File

@ -3,12 +3,10 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex';
import { AllChallengeNode } from '../redux/propTypes'; import { AllChallengeNode } from '../redux/propTypes';
import Header from '../components/Header'; import Header from '../components/Header';
import Map from '../components/Map'; import MapModal from '../components/MapModal';
import './global.css'; import './global.css';
import 'react-reflex/styles.css'; import 'react-reflex/styles.css';
@ -24,24 +22,13 @@ const Layout = ({ children, data: { allChallengeNode: { edges } } }) => (
/> />
<Header /> <Header />
<div className='app-wrapper'> <div className='app-wrapper'>
<ReflexContainer orientation='vertical'> <main>{children()}</main>
<ReflexElement flex={0.2} minSize={100}>
<aside id='map'>
<Map
nodes={edges
.map(({ node }) => node)
.filter(({ isPrivate }) => !isPrivate)}
/>
</aside>
</ReflexElement>
<ReflexSplitter />
<ReflexElement>
<main>{children()}</main>
</ReflexElement>
</ReflexContainer>
</div> </div>
<MapModal
nodes={edges
.map(({ node }) => node)
.filter(({ isPrivate }) => !isPrivate)}
/>
</Fragment> </Fragment>
); );

View File

@ -22,5 +22,6 @@ main {
} }
.app-wrapper { .app-wrapper {
height: calc(100vh - (38px + 0.45rem)); margin-top: 38px;
height: calc(100vh - 80px);
} }

View File

@ -1,7 +1,8 @@
.index-page-wrapper { .index-page-wrapper {
display: flex; display: flex;
/* width: calc(100vw - 340px); */
flex-direction: column; flex-direction: column;
justify-content: center;
align-items: center; align-items: center;
max-width: 960px;
margin: 0 auto;
} }

View File

@ -3,30 +3,38 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Link from 'gatsby-link'; import Link from 'gatsby-link';
import Helmet from 'react-helmet'; import Helmet from 'react-helmet';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Button } from 'react-bootstrap';
import { ChallengeNode } from '../redux/propTypes'; import { ChallengeNode } from '../redux/propTypes';
import { toggleMapModal } from '../redux/app';
import './index.css'; import './index.css';
const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch =>
bindActionCreators({ toggleMapModal }, dispatch);
const propTypes = { const propTypes = {
data: PropTypes.shape({ data: PropTypes.shape({
challengeNode: ChallengeNode challengeNode: ChallengeNode
}) }),
toggleMapModal: PropTypes.func.isRequired
}; };
const IndexPage = ({ const IndexPage = ({
data: { challengeNode: { title, fields: { slug, blockName } } } data: { challengeNode: { title, fields: { slug, blockName } } },
toggleMapModal
}) => ( }) => (
<div className='index-page-wrapper'> <div className='index-page-wrapper'>
<Helmet title='Welcome to learn.freeCodeCamp!' /> <Helmet title='Welcome to learn.freeCodeCamp!' />
<h1>Welcome to learn.freeCodeCamp.org</h1> <h1>Welcome to learn.freeCodeCamp.org</h1>
<p>We have thousands of coding lessons to help you improve your skills.</p>
<p> <p>
Check out the lesson map on the left. We have thousands of coding lessons You can earn verified certifications by completing each sections 5
to help you improve your skills. required projects.
</p>
<p>
You can earn verified certificates by completing certificate's 5 required
projects.
</p> </p>
<p> <p>
{'And yes - all of this is 100% free, thanks to the thousands of ' + {'And yes - all of this is 100% free, thanks to the thousands of ' +
@ -41,13 +49,17 @@ const IndexPage = ({
We recommend you start at the beginning{' '} We recommend you start at the beginning{' '}
<Link to={slug}>{`${blockName} -> ${title}`}</Link> <Link to={slug}>{`${blockName} -> ${title}`}</Link>
</p> </p>
<h3>Want to see what we can offer?</h3>
<Button block={true} bsSize='lg' bsStyle='primary' onClick={toggleMapModal}>
Explore the lesson map
</Button>
</div> </div>
); );
IndexPage.displayName = 'IndexPage'; IndexPage.displayName = 'IndexPage';
IndexPage.propTypes = propTypes; IndexPage.propTypes = propTypes;
export default IndexPage; export default connect(mapStateToProps, mapDispatchToProps)(IndexPage);
export const query = graphql` export const query = graphql`
query FirstChallenge { query FirstChallenge {

View File

@ -1,34 +0,0 @@
import React from 'react';
// import PropTypes from 'prop-types';
import Panel from 'react-bootstrap/lib/Panel';
import './strange-place.css';
const propTypes = {};
function StrangePlace(props) {
console.log(props);
return (
<div className='strange-place-container'>
<Panel bsStyle='primary'>
<Panel.Heading>
<Panel.Title componentClass='h3'>Whoops!</Panel.Title>
</Panel.Heading>
<Panel.Body>
<p>Something really weird happend and we are not sure what.</p>
<hr />
<p>
Could you help us fix this by supplying annonymous application data
for us to look over?
</p>
<p>We can show you exactly what we would like to send</p>
</Panel.Body>
</Panel>
</div>
);
}
StrangePlace.displayName = 'StrangePlace';
StrangePlace.propTypes = propTypes;
export default StrangePlace;

View File

@ -4,33 +4,73 @@ import { createTypes } from '../../../utils/stateManagment';
const ns = 'app'; const ns = 'app';
function userIdentReplacer(state) {
return {
...state,
[ns]: {
...state[ns],
user: {
...state[ns].user,
about: '**blank**',
email: '**blank**',
facebook: '**blank**',
githubProfile: '**blank**',
linkedin: '**blank**',
location: '**blank**',
name: '**blank**',
picture: '**blank**',
portfolio: '**blank**',
twitter: '**blank**',
username: '**blank**',
website: '**blank**'
}
}
};
}
export const epics = []; export const epics = [];
export const types = createTypes( export const types = createTypes(
['fetchUser', 'fetchUserComplete', 'fetchUserError', 'updateUserSignedIn'], [
'fetchUser',
'fetchUserComplete',
'fetchUserError',
'updateUserSignedIn',
'toggleMapModal'
],
ns ns
); );
const initialState = { const initialState = {
isSignedIn: false, isSignedIn: false,
user: {} user: {},
showMapModal: false
}; };
export const fetchUser = createAction(types.fetchUser); export const fetchUser = createAction(types.fetchUser);
export const fetchUserComplete = createAction(types.fetchUserComplete); export const fetchUserComplete = createAction(types.fetchUserComplete);
export const fecthUserError = createAction(types.fetchUserError); export const fecthUserError = createAction(types.fetchUserError);
export const toggleMapModal = createAction(types.toggleMapModal);
export const updateUserSignedIn = createAction(types.updateUserSignedIn); export const updateUserSignedIn = createAction(types.updateUserSignedIn);
export const isMapModalOpenSelector = state => state[ns].showMapModal;
export const isSignedInSelector = state => state[ns].isSignedIn; export const isSignedInSelector = state => state[ns].isSignedIn;
export const userSelector = state => state[ns].user; export const userSelector = state => state[ns].user;
export const allAppDataSelector = state => userIdentReplacer(state);
export const reducer = handleActions( export const reducer = handleActions(
{ {
[types.fetchUserComplete]: (state, { payload }) => ({ [types.fetchUserComplete]: (state, { payload }) => ({
...state, ...state,
user: payload user: payload
}), }),
[types.toggleMapModal]: state => ({
...state,
showMapModal: !state.showMapModal
}),
[types.updateUserSignedIn]: (state, { payload }) => ({ [types.updateUserSignedIn]: (state, { payload }) => ({
...state, ...state,
isSignedIn: payload isSignedIn: payload

View File

@ -10,6 +10,7 @@ import ChallengeDescription from '../components/Challenge-Description';
import TestSuite from '../components/Test-Suite'; import TestSuite from '../components/Test-Suite';
import Output from '../components/Output'; import Output from '../components/Output';
import CompletionModal from '../components/CompletionModal'; import CompletionModal from '../components/CompletionModal';
import ProjectToolPanel from '../project/Tool-Panel';
import { import {
executeChallenge, executeChallenge,
challengeTestsSelector, challengeTestsSelector,
@ -25,6 +26,7 @@ import {
makeRequired, makeRequired,
Form Form
} from '../../../components/formHelpers'; } from '../../../components/formHelpers';
import Spacer from '../../../components/util/Spacer';
// provided by redux form // provided by redux form
const reduxFormPropTypes = { const reduxFormPropTypes = {
@ -117,12 +119,14 @@ export class BackEnd extends PureComponent {
const blockNameTitle = `${blockName} - ${title}`; const blockNameTitle = `${blockName} - ${title}`;
return ( return (
<Row> <Row>
<ProjectToolPanel />
<Col xs={6} xsOffset={3}> <Col xs={6} xsOffset={3}>
<Row> <Spacer />
<div>
<ChallengeTitle>{blockNameTitle}</ChallengeTitle> <ChallengeTitle>{blockNameTitle}</ChallengeTitle>
<ChallengeDescription description={description} /> <ChallengeDescription description={description} />
</Row> </div>
<Row> <div>
<Form <Form
buttonText={buttonCopy + '(Ctrl + Enter)'} buttonText={buttonCopy + '(Ctrl + Enter)'}
formFields={formFields} formFields={formFields}
@ -130,19 +134,24 @@ export class BackEnd extends PureComponent {
options={options} options={options}
submit={executeChallenge} submit={executeChallenge}
/> />
</Row> </div>
<Row> <div>
<br /> <br />
<Output <Output
defaultOutput={`/** defaultOutput={`/**
*
* Test output will go here * Test output will go here
*
*
*/`} */`}
height={150}
output={output} output={output}
/> />
</Row> </div>
<Row> <div>
<TestSuite tests={tests} /> <TestSuite tests={tests} />
</Row> </div>
<Spacer />
</Col> </Col>
<CompletionModal /> <CompletionModal />
</Row> </Row>

View File

@ -10,6 +10,8 @@ import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex';
import Editor from './Editor'; import Editor from './Editor';
import Preview from '../components/Preview'; import Preview from '../components/Preview';
import SidePanel from '../components/Side-Panel'; import SidePanel from '../components/Side-Panel';
import TestSuite from '../components/Test-Suite';
import Output from '../components/Output';
import CompletionModal from '../components/CompletionModal'; import CompletionModal from '../components/CompletionModal';
import HelpModal from '../components/HelpModal'; import HelpModal from '../components/HelpModal';
import ResetModal from '../components/ResetModal'; import ResetModal from '../components/ResetModal';
@ -21,17 +23,28 @@ import { ChallengeNode } from '../../../redux/propTypes';
import { import {
createFiles, createFiles,
challengeFilesSelector, challengeFilesSelector,
challengeTestsSelector,
initTests, initTests,
updateChallengeMeta, updateChallengeMeta,
challengeMounted, challengeMounted,
updateSuccessMessage updateSuccessMessage,
consoleOutputSelector
} from '../redux'; } from '../redux';
import './classic.css'; import './classic.css';
import ToolPanel from '../components/Tool-Panel';
import Spacer from '../../../components/util/Spacer';
const mapStateToProps = createSelector(challengeFilesSelector, files => ({ const mapStateToProps = createSelector(
files challengeFilesSelector,
})); challengeTestsSelector,
consoleOutputSelector,
(files, tests, output) => ({
files,
tests,
output
})
);
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators( bindActionCreators(
@ -55,11 +68,18 @@ const propTypes = {
key: PropTypes.string key: PropTypes.string
}), }),
initTests: PropTypes.func.isRequired, initTests: PropTypes.func.isRequired,
output: PropTypes.string,
pathContext: PropTypes.shape({ pathContext: PropTypes.shape({
challengeMeta: PropTypes.shape({ challengeMeta: PropTypes.shape({
nextchallengePath: PropTypes.string nextchallengePath: PropTypes.string
}) })
}), }),
tests: PropTypes.arrayOf(
PropTypes.shape({
text: PropTypes.string,
testString: PropTypes.string
})
),
updateChallengeMeta: PropTypes.func.isRequired, updateChallengeMeta: PropTypes.func.isRequired,
updateSuccessMessage: PropTypes.func.isRequired updateSuccessMessage: PropTypes.func.isRequired
}; };
@ -115,7 +135,9 @@ class ShowClassic extends PureComponent {
guideUrl guideUrl
} }
}, },
files files,
tests,
output
} = this.props; } = this.props;
const editors = Object.keys(files) const editors = Object.keys(files)
.map(key => files[key]) .map(key => files[key])
@ -125,6 +147,21 @@ class ShowClassic extends PureComponent {
<ReflexElement flex={1}> <ReflexElement flex={1}>
<Editor {...file} fileKey={file.key} /> <Editor {...file} fileKey={file.key} />
</ReflexElement> </ReflexElement>
{index + 1 === Object.keys(files).length && <ReflexSplitter />}
{index + 1 === Object.keys(files).length ? (
<ReflexElement flex={0.25}>
<Output
defaultOutput={`
/**
* Your output will go here.
* Any console.log() statements
* will appear in here as well.
*/
`}
output={output}
/>
</ReflexElement>
) : null}
</Fragment> </Fragment>
)); ));
@ -134,7 +171,8 @@ class ShowClassic extends PureComponent {
const blockNameTitle = `${blockName} - ${title}`; const blockNameTitle = `${blockName} - ${title}`;
return ( return (
<Fragment> <Fragment>
<Helmet title={`${blockNameTitle} | Learn freeCodeCamp}`} /> <Helmet title={`${blockNameTitle} | Learn freeCodeCamp`} />
<ToolPanel />
<ReflexContainer orientation='vertical'> <ReflexContainer orientation='vertical'>
<ReflexElement flex={1}> <ReflexElement flex={1}>
<SidePanel <SidePanel
@ -150,13 +188,14 @@ class ShowClassic extends PureComponent {
{editors} {editors}
</ReflexContainer> </ReflexContainer>
</ReflexElement> </ReflexElement>
{showPreview && <ReflexSplitter />} <ReflexSplitter />
{showPreview && ( <ReflexElement flex={0.5}>
<ReflexElement flex={0.3} maxSize={325}> {showPreview ? <Preview className='full-height' /> : null}
<Preview className='full-height' /> <Spacer />
</ReflexElement> <TestSuite tests={tests} />
)} </ReflexElement>
</ReflexContainer> </ReflexContainer>
<CompletionModal /> <CompletionModal />
<HelpModal /> <HelpModal />
<ResetModal /> <ResetModal />

View File

@ -1,9 +1,15 @@
.editor, .editor{
.react-codemirror2,
.react-codemirror2 > .CodeMirror-wrap {
height: 100%; height: 100%;
margin-bottom: 1.45rem;
} }
.instructions-panel { .instructions-panel {
padding: 0 10px; padding: 0 10px;
} }
.react-monaco-editor-container {
width: 100%;
height: 100%;
display: flex;
align-items: end;
}

View File

@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
import { Col, Row } from 'react-bootstrap'; import { Col, Row } from 'react-bootstrap';
import { descriptionRegex } from '../../../../utils'; import { descriptionRegex } from '../../../../utils';
import './challenge-description.css';
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string) description: PropTypes.arrayOf(PropTypes.string)
}; };

View File

@ -7,6 +7,8 @@ import { Button, Modal } from 'react-bootstrap';
import GreenPass from './icons/GreenPass'; import GreenPass from './icons/GreenPass';
import './completion-modal.css';
import { import {
closeModal, closeModal,
submitChallenge, submitChallenge,
@ -58,22 +60,22 @@ export class CompletionModal extends PureComponent {
return ( return (
<Modal <Modal
animation={false} animation={false}
dialogClassName={'challenge-success-modal'} bsSize='lg'
dialogClassName='challenge-success-modal'
keyboard={true} keyboard={true}
onHide={close} onHide={close}
onKeyDown={isOpen ? handleKeypress : noop} onKeyDown={isOpen ? handleKeypress : noop}
show={isOpen} show={isOpen}
> >
<Modal.Header className={'challenge-list-header'} closeButton={true}> <Modal.Header
<Modal.Title>{message}</Modal.Title> className='challenge-list-header fcc-modal'
closeButton={true}
>
<Modal.Title className='text-center'>{message}</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body className='completion-modal-body'>
<div className='text-center'> <div className='success-icon-wrapper'>
<div className='row'> <GreenPass />
<div>
<GreenPass />
</div>
</div>
</div> </div>
</Modal.Body> </Modal.Body>
<Modal.Footer> <Modal.Footer>

View File

@ -27,12 +27,12 @@ export class HelpModal extends PureComponent {
render() { render() {
const { isOpen, closeHelpModal, createQuestion } = this.props; const { isOpen, closeHelpModal, createQuestion } = this.props;
return ( return (
<Modal show={isOpen}> <Modal onHide={closeHelpModal} show={isOpen}>
<Modal.Header> <Modal.Header
Ask for help? className='help-modal-header fcc-modal'
<span className='close closing-x' onClick={closeHelpModal}> closeButton={true}
× >
</span> <Modal.Title className='text-center'>Ask for help?</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body className='text-center'> <Modal.Body className='text-center'>
<h3> <h3>

View File

@ -4,6 +4,7 @@ import MonacoEditor from 'react-monaco-editor';
const propTypes = { const propTypes = {
defaultOutput: PropTypes.string, defaultOutput: PropTypes.string,
height: PropTypes.number,
output: PropTypes.string output: PropTypes.string
}; };
@ -20,13 +21,13 @@ const options = {
wordWrap: 'on' wordWrap: 'on'
}; };
function Output({ output, defaultOutput }) { function Output({ output, defaultOutput, height }) {
return ( return (
<Fragment> <Fragment>
<base href='/' /> <base href='/' />
<MonacoEditor <MonacoEditor
className='challenge-output' className='challenge-output'
height={150} height={height}
options={options} options={options}
value={output ? output : defaultOutput} value={output ? output : defaultOutput}
/> />

View File

@ -7,6 +7,8 @@ import { Button, Modal } from 'react-bootstrap';
import { isResetModalOpenSelector, closeModal, resetChallenge } from '../redux'; import { isResetModalOpenSelector, closeModal, resetChallenge } from '../redux';
import './reset-modal.css';
const propTypes = { const propTypes = {
close: PropTypes.func.isRequired, close: PropTypes.func.isRequired,
isOpen: PropTypes.bool.isRequired, isOpen: PropTypes.bool.isRequired,
@ -31,15 +33,15 @@ function ResetModal({ reset, close, isOpen }) {
return ( return (
<Modal <Modal
animation={false} animation={false}
dialogClassName={'reset-modal'} dialogClassName='reset-modal'
keyboard={true} keyboard={true}
onHide={close} onHide={close}
show={isOpen} show={isOpen}
> >
<Modal.Header className={'challenge-list-header'} closeButton={true}> <Modal.Header className='reset-modal-header' closeButton={true}>
<Modal.Title>Reset this lesson?</Modal.Title> <Modal.Title className='text-center'>Reset this lesson?</Modal.Title>
</Modal.Header> </Modal.Header>
<Modal.Body> <Modal.Body className='reset-modal-body'>
<div className='text-center'> <div className='text-center'>
<p> <p>
Are you sure you wish to reset this lesson? The editors and tests Are you sure you wish to reset this lesson? The editors and tests

View File

@ -1,57 +1,32 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ReactDom from 'react-dom'; import ReactDom from 'react-dom';
import { createSelector } from 'reselect';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { Button } from 'react-bootstrap';
// import HelpModal from './Help-Modal.jsx';
import ToolPanel from './Tool-Panel';
import ChallengeTitle from './Challenge-Title'; import ChallengeTitle from './Challenge-Title';
import ChallengeDescription from './Challenge-Description'; import ChallengeDescription from './Challenge-Description';
import TestSuite from './Test-Suite';
import Output from './Output';
import Spacer from '../../../components/util/Spacer'; import Spacer from '../../../components/util/Spacer';
import { import { initConsole, openModal } from '../redux';
consoleOutputSelector,
challengeTestsSelector,
executeChallenge,
initConsole,
openModal
} from '../redux';
const mapStateToProps = createSelector( const mapStateToProps = () => ({});
consoleOutputSelector,
challengeTestsSelector,
(output, tests) => ({ output, tests })
);
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
bindActionCreators( bindActionCreators(
{ {
executeChallenge,
initConsole, initConsole,
openHelpModal: () => openModal('help'), openHelpModal: () => openModal('help')
openResetModal: () => openModal('reset')
}, },
dispatch dispatch
); );
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.arrayOf(PropTypes.string),
executeChallenge: PropTypes.func.isRequired,
guideUrl: PropTypes.string, guideUrl: PropTypes.string,
initConsole: PropTypes.func.isRequired, initConsole: PropTypes.func.isRequired,
openHelpModal: PropTypes.func.isRequired, openHelpModal: PropTypes.func.isRequired,
openResetModal: PropTypes.func.isRequired,
output: PropTypes.string,
tests: PropTypes.arrayOf(
PropTypes.shape({
text: PropTypes.string,
testString: PropTypes.string
})
),
title: PropTypes.string title: PropTypes.string
}; };
@ -81,40 +56,38 @@ export class SidePanel extends PureComponent {
} }
render() { render() {
const { const { title, description, guideUrl, openHelpModal } = this.props;
title,
description,
tests = [],
output = '',
guideUrl,
executeChallenge,
openResetModal,
openHelpModal
} = this.props;
return ( return (
<div className={'instructions-panel'} ref='panel' role='complementary'> <div className='instructions-panel' role='complementary'>
<div ref={this.bindTopDiv} /> <div ref={this.bindTopDiv} />
<Spacer />
<div> <div>
<ChallengeTitle>{title}</ChallengeTitle> <ChallengeTitle>{title}</ChallengeTitle>
<ChallengeDescription description={description} /> <ChallengeDescription description={description} />
</div> </div>
<ToolPanel
executeChallenge={executeChallenge}
guideUrl={guideUrl}
openHelpModal={openHelpModal}
openResetModal={openResetModal}
/>
<Spacer /> <Spacer />
<Output {guideUrl ? (
defaultOutput={`/** <div>
* Your output will go here. <Button
* Any console.log() statements block={true}
* will appear in here as well. bsStyle='primary'
*/`} className='btn-big'
output={output} href={guideUrl}
/> target='_blank'
<br /> >
<TestSuite tests={tests} /> Get a hint
</Button>
<div className='button-spacer' />
</div>
) : null}
<Button
block={true}
bsStyle='primary'
className='btn-big'
onClick={openHelpModal}
>
Ask for help on the forum
</Button>
</div> </div>
); );
} }

View File

@ -1,26 +1,61 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Button } from 'react-bootstrap'; import { Button } from 'react-bootstrap';
import './tool-panel.css';
import { openModal, executeChallenge } from '../redux';
import { toggleMapModal } from '../../../redux/app';
const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
executeChallenge,
openResetModal: () => openModal('reset'),
toggleMapModal
},
dispatch
);
const propTypes = { const propTypes = {
executeChallenge: PropTypes.func.isRequired, executeChallenge: PropTypes.func.isRequired,
guideUrl: PropTypes.string, openResetModal: PropTypes.func.isRequired,
openHelpModal: PropTypes.func.isRequired, toggleMapModal: PropTypes.func.isRequired
openResetModal: PropTypes.func.isRequired
}; };
function ToolPanel({ function ToolPanel({ executeChallenge, openResetModal, toggleMapModal }) {
executeChallenge,
guideUrl,
openResetModal,
openHelpModal
}) {
return ( return (
<div> <div className='tool-panel'>
<Button <div id='left-tool-panel sub-panel'>
<Button bsStyle='default' onClick={toggleMapModal}>
View the Curriculum
</Button>
</div>
<div id='centre-tool-panel sub-panel'>
<Button bsStyle='primary' onClick={executeChallenge}>
Run the Tests
</Button>
<Button bsStyle='default' onClick={openResetModal}>
Reset All Code
</Button>
</div>
<div id='right-tool-panel sub-panel' />
</div>
);
}
ToolPanel.displayName = 'ToolPanel';
ToolPanel.propTypes = propTypes;
export default connect(mapStateToProps, mapDispatchToProps)(ToolPanel);
/*
<Button
block={true} block={true}
bsStyle='primary' bsStyle='default'
className='btn-big' className='btn-big'
onClick={executeChallenge} onClick={executeChallenge}
> >
@ -29,7 +64,7 @@ function ToolPanel({
<div className='button-spacer' /> <div className='button-spacer' />
<Button <Button
block={true} block={true}
bsStyle='primary' bsStyle='default'
className='btn-big' className='btn-big'
onClick={openResetModal} onClick={openResetModal}
> >
@ -40,7 +75,7 @@ function ToolPanel({
<div> <div>
<Button <Button
block={true} block={true}
bsStyle='primary' bsStyle='default'
className='btn-big' className='btn-big'
href={guideUrl} href={guideUrl}
target='_blank' target='_blank'
@ -52,18 +87,11 @@ function ToolPanel({
)} )}
<Button <Button
block={true} block={true}
bsStyle='primary' bsStyle='default'
className='btn-big' className='btn-big'
onClick={openHelpModal} onClick={openHelpModal}
> >
Ask for help on the forum Ask for help on the forum
</Button> </Button>
<div className='button-spacer' /> <div className='button-spacer' />
</div> */
);
}
ToolPanel.displayName = 'ToolPanel';
ToolPanel.propTypes = propTypes;
export default ToolPanel;

View File

@ -0,0 +1,14 @@
.challenge-instructions {
font-size: 16px;
}
.challenge-instructions blockquote {
background-color: #eee;
color: #c7254e;
padding: 10px;
width: 100%;
margin: 0;
margin-bottom: 1.45rem;
font-family: monospace;
font-size: 16px;
}

View File

@ -0,0 +1,12 @@
.completion-modal-body {
height: 45vh;
display: flex;
justify-content: center;
align-items: center;
}
.success-icon-wrapper > svg {
height: 30vh;
width: 30vh;
}

View File

@ -6,7 +6,7 @@
} }
.challenge-preview, .challenge-preview-frame { .challenge-preview, .challenge-preview-frame {
height: calc(100vh - (45px + 1.45rem)); height: calc(60vh);
width: 100%; width: 100%;
padding: 0; padding: 0;
margin: 0; margin: 0;

View File

@ -0,0 +1,11 @@
.reset-modal-header {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
.reset-modal-header .close {
color: #fff;
font-size: 28px;
text-shadow: none;
}

View File

@ -0,0 +1,12 @@
.tool-panel {
height: 40px;
display: flex;
justify-content: space-around;
align-items: center;
background-color: #99C199;
}
.centre-tool-panel {
width: 300px;
}

View File

@ -8,6 +8,7 @@ import Helmet from 'react-helmet';
import { randomCompliment } from '../utils/get-words'; import { randomCompliment } from '../utils/get-words';
import { ChallengeNode } from '../../../redux/propTypes'; import { ChallengeNode } from '../../../redux/propTypes';
import ProjectForm from './ProjectForm';
import SidePanel from './Side-Panel'; import SidePanel from './Side-Panel';
import ToolPanel from './Tool-Panel'; import ToolPanel from './Tool-Panel';
import CompletionModal from '../components/CompletionModal'; import CompletionModal from '../components/CompletionModal';
@ -16,8 +17,12 @@ import { bindActionCreators } from 'redux';
import { import {
updateChallengeMeta, updateChallengeMeta,
createFiles, createFiles,
updateSuccessMessage updateSuccessMessage,
openModal
} from '../redux'; } from '../redux';
import { frontEndProject } from '../../../../utils/challengeTypes';
import './project.css';
const mapStateToProps = () => ({}); const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch => const mapDispatchToProps = dispatch =>
@ -25,7 +30,8 @@ const mapDispatchToProps = dispatch =>
{ {
updateChallengeMeta, updateChallengeMeta,
createFiles, createFiles,
updateSuccessMessage updateSuccessMessage,
openCompletionModal: () => openModal('completion')
}, },
dispatch dispatch
); );
@ -35,6 +41,7 @@ const propTypes = {
data: PropTypes.shape({ data: PropTypes.shape({
challengeNode: ChallengeNode challengeNode: ChallengeNode
}), }),
openCompletionModal: PropTypes.func.isRequired,
pathContext: PropTypes.shape({ pathContext: PropTypes.shape({
challengeMeta: PropTypes.object challengeMeta: PropTypes.object
}), }),
@ -82,19 +89,27 @@ export class Project extends PureComponent {
description, description,
guideUrl guideUrl
} }
} },
openCompletionModal
} = this.props; } = this.props;
const isFrontEnd = challengeType === frontEndProject;
const blockNameTitle = `${blockName} - ${title}`; const blockNameTitle = `${blockName} - ${title}`;
return ( return (
<Fragment> <Fragment>
<Helmet title={`${blockNameTitle} | Learn freeCodeCamp}`} /> <Helmet title={`${blockNameTitle} | Learn freeCodeCamp}`} />
<SidePanel <ToolPanel />
className='full-height' <div className='project-show-wrapper'>
description={description} <SidePanel
guideUrl={guideUrl} className='full-height'
title={blockNameTitle} description={description}
/> guideUrl={guideUrl}
<ToolPanel challengeType={challengeType} /> title={blockNameTitle}
/>
<ProjectForm
isFrontEnd={isFrontEnd}
openModal={openCompletionModal}
/>
</div>
<CompletionModal /> <CompletionModal />
<HelpModal /> <HelpModal />
</Fragment> </Fragment>

View File

@ -1,6 +1,7 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import ChallengeTitle from '../components/Challenge-Title'; import ChallengeTitle from '../components/Challenge-Title';
import Spacer from '../../../components/util/Spacer';
const propTypes = { const propTypes = {
description: PropTypes.arrayOf(PropTypes.string), description: PropTypes.arrayOf(PropTypes.string),
@ -24,6 +25,7 @@ export default class SidePanel extends PureComponent {
const { title, description, isCompleted } = this.props; const { title, description, isCompleted } = this.props;
return ( return (
<div> <div>
<Spacer />
<ChallengeTitle isCompleted={isCompleted}>{title}</ChallengeTitle> <ChallengeTitle isCompleted={isCompleted}>{title}</ChallengeTitle>
<ul>{this.renderDescription(title, description)}</ul> <ul>{this.renderDescription(title, description)}</ul>
</div> </div>

View File

@ -1,15 +1,12 @@
import React, { PureComponent, Fragment } from 'react'; import React, { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Button } from 'react-bootstrap'; import { Button } from 'react-bootstrap';
// import { submittingSelector } from './redux'; // import { submittingSelector } from './redux';
import { toggleMapModal } from '../../../redux/app';
import { openModal } from '../redux'; import { openModal } from '../redux';
import { frontEndProject } from '../../../../utils/challengeTypes';
import ButtonSpacer from '../../../components/util/ButtonSpacer';
import ProjectForm from './ProjectForm';
const mapStateToProps = () => ({}); const mapStateToProps = () => ({});
@ -17,30 +14,62 @@ const mapDispatchToProps = dispatch =>
bindActionCreators( bindActionCreators(
{ {
openHelpModal: () => openModal('help'), openHelpModal: () => openModal('help'),
openCompletionModal: () => openModal('completion') toggleMapModal
}, },
dispatch dispatch
); );
const propTypes = { const propTypes = {
challengeType: PropTypes.number,
guideUrl: PropTypes.string, guideUrl: PropTypes.string,
openCompletionModal: PropTypes.func.isRequired, openHelpModal: PropTypes.func.isRequired,
openHelpModal: PropTypes.func.isRequired toggleMapModal: PropTypes.func.isRequired
}; };
export class ToolPanel extends PureComponent { export class ToolPanel extends PureComponent {
render() { render() {
const { const { guideUrl, openHelpModal, toggleMapModal } = this.props;
guideUrl,
challengeType,
openHelpModal,
openCompletionModal
} = this.props;
const isFrontEnd = challengeType === frontEndProject;
return ( return (
<Fragment> <div className='tool-panel'>
<div id='left-tool-panel sub-panel'>
<Button bsStyle='default' onClick={toggleMapModal}>
View the Curriculum
</Button>
</div>
<div id='centre-tool-panel sub-panel' />
<div id='right-tool-panel sub-panel'>
{guideUrl && (
<Button
block={true}
bsStyle='primary'
className='btn-primary-ghost btn-big'
href={guideUrl}
target='_blank'
>
Get a hint
</Button>
)}
<Button
block={true}
bsStyle='primary'
className='btn-primary-ghost btn-big'
onClick={openHelpModal}
>
Ask for help on the forum
</Button>
</div>
</div>
);
}
}
ToolPanel.displayName = 'ProjectToolPanel';
ToolPanel.propTypes = propTypes;
export default connect(mapStateToProps, mapDispatchToProps)(ToolPanel);
/**
*
* <Fragment>
<ProjectForm isFrontEnd={isFrontEnd} openModal={openCompletionModal} /> <ProjectForm isFrontEnd={isFrontEnd} openModal={openCompletionModal} />
<ButtonSpacer /> <ButtonSpacer />
{guideUrl && ( {guideUrl && (
@ -67,11 +96,4 @@ export class ToolPanel extends PureComponent {
</Button> </Button>
<ButtonSpacer /> <ButtonSpacer />
</Fragment> </Fragment>
); */
}
}
ToolPanel.displayName = 'ProjectToolPanel';
ToolPanel.propTypes = propTypes;
export default connect(mapStateToProps, mapDispatchToProps)(ToolPanel);

View File

@ -0,0 +1,8 @@
.project-show-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
max-width: 960px;
margin: 0 auto;
}

Some files were not shown because too many files have changed in this diff Show More