diff --git a/config.js b/config.js index f431fcdda..38c8cacf1 100644 --- a/config.js +++ b/config.js @@ -7,6 +7,7 @@ module.exports = { // Path information snippetPath: `snippets`, snippetArchivePath: `snippets_archive`, + glossaryPath: `glossary`, snippetDataPath: `snippet_data`, assetPath: `assets`, pagePath: `src/docs/pages`, diff --git a/scripts/extract.js b/scripts/extract.js index 741d470d6..3cc0b43c1 100644 --- a/scripts/extract.js +++ b/scripts/extract.js @@ -7,88 +7,151 @@ const fs = require('fs-extra'); const path = require('path'); const { green } = require('kleur'); const util = require('./util'); +const config = require('../config'); + // Paths -const SNIPPETS_PATH = './snippets'; -const SNIPPETS_ARCHIVE_PATH = './snippets_archive'; -const OUTPUT_PATH = './snippet_data'; -// Check if running on Travis - only build for cron jobs and custom builds +const SNIPPETS_PATH = `./${config.snippetPath}`; +const SNIPPETS_ARCHIVE_PATH = `./${config.snippetArchivePath}`; +const GLOSSARY_PATH = `./${config.glossaryPath}`; +const OUTPUT_PATH = `./${config.snippetDataPath}`; + +// Check if running on Travis, only build for cron jobs and custom builds if ( util.isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api' ) { - console.log(`${green('NOBUILD')} snippet extraction terminated, not a cron or api build!`); + console.log( + `${green( + 'NOBUILD', + )} snippet extraction terminated, not a cron or api build!`, + ); process.exit(0); } -// Read data -let snippets = {}, - archivedSnippets = {}, - tagDbData = {}; -console.time('Extractor'); -snippets = util.readSnippets(SNIPPETS_PATH); -archivedSnippets = util.readSnippets(SNIPPETS_ARCHIVE_PATH); -tagDbData = util.readTags(); -// Extract snippet data -let snippetData = Object.keys(snippets).map(key => { - return { - id: key.slice(0, -3), - type: 'snippet', - attributes: { - fileName: key, - text: util.getTextualContent(snippets[key]).trim(), - codeBlocks: util.getCodeBlocks(snippets[key]), - tags: tagDbData[key.slice(0, -3)] - }, - meta: { - archived: false, - hash: util.hashData(snippets[key]) - } - }; -}); -// Extract archived snippet data -let snippetArchiveData = Object.keys(archivedSnippets).map(key => { - return { - id: key.slice(0, -3), - type: 'snippet', - attributes: { - fileName: key, - text: util.getTextualContent(archivedSnippets[key]).trim(), - codeBlocks: util.getCodeBlocks(archivedSnippets[key]), - tags: [] - }, - meta: { - archived: true, - hash: util.hashData(archivedSnippets[key]) - } - }; -}); -const completeData = { - data: [...snippetData, ...snippetArchiveData], - meta: { - specification: 'http://jsonapi.org/format/' - } -}; -let listingData = { - data: - completeData.data.map(v => ({ - id: v.id, - type: 'snippetListing', - attributes: { - tags: v.attributes.tags, - archived: v.meta.archived - }, - meta: { - hash: v.meta.hash - } - })), +// Setup everything +let snippets = {}, + snippetsArray = [], + archivedSnippets = {}, + archivedSnippetsArray = [], + glossarySnippets = {}, + glossarySnippetsArray = []; +console.time('Extractor'); + +// Synchronously read all snippets from snippets, snippets_archive and glossary folders and sort them as necessary (case-insensitive) +snippets = util.readSnippets(SNIPPETS_PATH); +snippetsArray = Object.keys(snippets).reduce((acc, key) => { + acc.push(snippets[key]); + return acc; +}, []); + +archivedSnippets = util.readSnippets(SNIPPETS_ARCHIVE_PATH); +archivedSnippetsArray = Object.keys(archivedSnippets).reduce((acc, key) => { + acc.push(archivedSnippets[key]); + return acc; +}, []); + +glossarySnippets = util.readSnippets(GLOSSARY_PATH); +glossarySnippetsArray = Object.keys(glossarySnippets).reduce((acc, key) => { + acc.push(glossarySnippets[key]); + return acc; +}, []); + +const completeData = { + data: [...snippetsArray], meta: { - specification: 'http://jsonapi.org/format/' + specification: 'http://jsonapi.org/format/', + type: 'snippetArray', + }, +}; +const listingData = { + data: completeData.data.map(v => ({ + id: v.id, + type: 'snippetListing', + title: v.title, + attributes: { + text: v.attributes.text, + tags: v.attributes.tags, + }, + meta: { + hash: v.meta.hash, + }, + })), + meta: { + specification: 'http://jsonapi.org/format/', + type: 'snippetListingArray', + }, +}; + +const archiveCompleteData = { + data: [...archivedSnippetsArray], + meta: { + specification: 'http://jsonapi.org/format/', + type: 'snippetArray', } }; +const archiveListingData = { + data: archiveCompleteData.data.map(v => ({ + id: v.id, + type: 'snippetListing', + title: v.title, + attributes: { + text: v.attributes.text, + tags: v.attributes.tags, + }, + meta: { + hash: v.meta.hash, + }, + })), + meta: { + specification: 'http://jsonapi.org/format/', + type: 'snippetListingArray', + }, +}; + +const glossaryData = { + data: glossarySnippetsArray.map(v => ({ + id: v.id, + type: 'glossaryTerm', + title: v.title, + attributes: { + text: v.attributes.text, + tags: v.attributes.tags, + }, + meta: { + hash: v.meta.hash, + }, + })), + meta: { + specification: 'http://jsonapi.org/format/', + type: 'glossaryTermArray', + }, +}; + // Write files -fs.writeFileSync(path.join(OUTPUT_PATH, 'snippets.json'), JSON.stringify(completeData, null, 2)); -fs.writeFileSync(path.join(OUTPUT_PATH, 'snippetList.json'), JSON.stringify(listingData, null, 2)); +fs.writeFileSync( + path.join(OUTPUT_PATH, 'snippets.json'), + JSON.stringify(completeData, null, 2), +); +fs.writeFileSync( + path.join(OUTPUT_PATH, 'snippetList.json'), + JSON.stringify(listingData, null, 2), +); + +fs.writeFileSync( + path.join(OUTPUT_PATH, 'archivedSnippets.json'), + JSON.stringify(archiveCompleteData, null, 2), +); +fs.writeFileSync( + path.join(OUTPUT_PATH, 'archivedSnippetList.json'), + JSON.stringify(archiveListingData, null, 2), +); + +fs.writeFileSync( + path.join(OUTPUT_PATH, 'glossaryTerms.json'), + JSON.stringify(glossaryData, null, 2), +); + // Display messages and time -console.log(`${green('SUCCESS!')} snippets.json and snippetList.json files generated!`); +console.log(`${green('SUCCESS!')} JSON data files generated!`); console.timeEnd('Extractor'); diff --git a/scripts/util/environmentCheck.js b/scripts/util/environmentCheck.js new file mode 100644 index 000000000..05c441bb9 --- /dev/null +++ b/scripts/util/environmentCheck.js @@ -0,0 +1,12 @@ +// Checks if current environment is Travis CI, Cron builds, API builds +const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env; +const isTravisCronOrAPI = () => + process.env['TRAVIS_EVENT_TYPE'] === 'cron' || + process.env['TRAVIS_EVENT_TYPE'] === 'api'; +const isNotTravisCronOrAPI = () => !isTravisCronOrAPI(); + +module.exports = { + isTravisCI, + isTravisCronOrAPI, + isNotTravisCronOrAPI, +}; diff --git a/scripts/util/helpers.js b/scripts/util/helpers.js new file mode 100644 index 000000000..de1386935 --- /dev/null +++ b/scripts/util/helpers.js @@ -0,0 +1,60 @@ +const config = require('../../config'); + +const getMarkDownAnchor = paragraphTitle => + paragraphTitle + .trim() + .toLowerCase() + .replace(/[^\w\- ]+/g, '') + .replace(/\s/g, '-') + .replace(/\-+$/, ''); +// Creates an object from pairs +const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {}); +// Optimizes nodes in an HTML document +const optimizeNodes = (data, regexp, replacer) => { + let count = 0; + let output = data; + do { + output = output.replace(regexp, replacer); + count = 0; + while (regexp.exec(output) !== null) ++count; + } while (count > 0); + return output; +}; +// Capitalizes the first letter of a string +const capitalize = (str, lowerRest = false) => + str.slice(0, 1).toUpperCase() + + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); +const prepTaggedData = tagDbData => + [...new Set(Object.entries(tagDbData).map(t => t[1][0]))] + .filter(v => v) + .sort((a, b) => + capitalize(a, true) === 'Uncategorized' + ? 1 + : capitalize(b, true) === 'Uncategorized' + ? -1 + : a.localeCompare(b), + ); +const makeExamples = data => { + data = + data.slice(0, data.lastIndexOf(`\`\`\`${config.language}`)).trim() + + misc.collapsible( + 'Examples', + data.slice( + data.lastIndexOf(`\`\`\`${config.language}`), + data.lastIndexOf('```'), + ) + data.slice(data.lastIndexOf('```')), + ); + return `${data}\n
${misc.link( + '⬆ Back to top', + misc.anchor('Contents'), + )}\n\n`; +}; + +module.exports = { + getMarkDownAnchor, + objectFromPairs, + optimizeNodes, + capitalize, + prepTaggedData, + makeExamples, +}; diff --git a/scripts/util/index.js b/scripts/util/index.js new file mode 100644 index 000000000..27edbfec9 --- /dev/null +++ b/scripts/util/index.js @@ -0,0 +1,37 @@ +const { + isTravisCI, + isTravisCronOrAPI, + isNotTravisCronOrAPI, +} = require('./environmentCheck'); +const { + getMarkDownAnchor, + objectFromPairs, + optimizeNodes, + capitalize, + prepTaggedData, + makeExamples, +} = require('./helpers'); +const { + getFilesInDir, + hashData, + getCodeBlocks, + getTextualContent, + readSnippets, +} = require('./snippetParser'); + +module.exports = { + isTravisCI, + isTravisCronOrAPI, + isNotTravisCronOrAPI, + getMarkDownAnchor, + objectFromPairs, + optimizeNodes, + capitalize, + prepTaggedData, + makeExamples, + getFilesInDir, + hashData, + getCodeBlocks, + getTextualContent, + readSnippets, +}; diff --git a/scripts/util/snippetParser.js b/scripts/util/snippetParser.js new file mode 100644 index 000000000..1bb71a4ca --- /dev/null +++ b/scripts/util/snippetParser.js @@ -0,0 +1,121 @@ +const fs = require('fs-extra'), + path = require('path'), + { red } = require('kleur'), + crypto = require('crypto'), + frontmatter = require('front-matter'), + babel = require('@babel/core'); +const config = require('../../config'); + +// Reade all files in a directory +const getFilesInDir = (directoryPath, withPath, exclude = null) => { + try { + let directoryFilenames = fs.readdirSync(directoryPath); + directoryFilenames.sort((a, b) => { + a = a.toLowerCase(); + b = b.toLowerCase(); + if (a < b) return -1; + if (a > b) return 1; + return 0; + }); + + if (withPath) { + // a hacky way to do conditional array.map + return directoryFilenames.reduce((fileNames, fileName) => { + if ( + exclude == null || + !exclude.some(toExclude => fileName === toExclude) + ) + fileNames.push(`${directoryPath}/${fileName}`); + return fileNames; + }, []); + } + return directoryFilenames.filter(v => v !== 'README.md'); + } catch (err) { + console.log(`${red('ERROR!')} During snippet loading: ${err}`); + process.exit(1); + } +}; +// Creates a hash for a value using the SHA-256 algorithm. +const hashData = val => + crypto + .createHash('sha256') + .update(val) + .digest('hex'); +// Gets the code blocks for a snippet file. +const getCodeBlocks = str => { + const regex = /```[.\S\s]*?```/g; + let results = []; + let m = null; + while ((m = regex.exec(str)) !== null) { + if (m.index === regex.lastIndex) regex.lastIndex += 1; + + m.forEach((match, groupIndex) => { + results.push(match); + }); + } + const replacer = new RegExp( + `\`\`\`${config.language}([\\s\\S]*?)\`\`\``, + 'g', + ); + results = results.map(v => v.replace(replacer, '$1').trim()); + return { + es6: results[0], + es5: babel.transformSync(results[0], { presets: ['@babel/preset-env'] }).code.replace('"use strict";\n\n', ''), + example: results[1], + }; +}; +// Gets the textual content for a snippet file. +const getTextualContent = str => { + const regex = /([\s\S]*?)```/g; + const results = []; + let m = null; + while ((m = regex.exec(str)) !== null) { + if (m.index === regex.lastIndex) regex.lastIndex += 1; + + m.forEach((match, groupIndex) => { + results.push(match); + }); + } + if (!results.length) return str.replace(/\r\n/g, '\n'); + return results[1].replace(/\r\n/g, '\n'); +}; + +// Synchronously read all snippets and sort them as necessary (case-insensitive) +const readSnippets = snippetsPath => { + const snippetFilenames = getFilesInDir(snippetsPath, false); + + let snippets = {}; + try { + for (let snippet of snippetFilenames) { + let data = frontmatter( + fs.readFileSync(path.join(snippetsPath, snippet), 'utf8'), + ); + snippets[snippet] = { + id: snippet.slice(0, -3), + title: data.attributes.title, + type: 'snippet', + attributes: { + fileName: snippet, + text: getTextualContent(data.body), + codeBlocks: getCodeBlocks(data.body), + tags: data.attributes.tags.split(',').map(t => t.trim()), + }, + meta: { + hash: hashData(data.body), + }, + }; + } + } catch (err) { + console.log(`${red('ERROR!')} During snippet loading: ${err}`); + process.exit(1); + } + return snippets; +}; + +module.exports = { + getFilesInDir, + hashData, + getCodeBlocks, + getTextualContent, + readSnippets, +}; diff --git a/snippet_data/archivedSnippetList.json b/snippet_data/archivedSnippetList.json new file mode 100644 index 000000000..1ff27b823 --- /dev/null +++ b/snippet_data/archivedSnippetList.json @@ -0,0 +1,385 @@ +{ + "data": [ + { + "id": "binarySearch", + "type": "snippetListing", + "title": "binarySearch", + "attributes": { + "text": "Use recursion. Similar to `Array.prototype.indexOf()` that finds the index of a value within an array.\nThe difference being this operation only works with sorted arrays which offers a major performance boost due to it's logarithmic nature when compared to a linear search or `Array.prototype.indexOf()`.\n\nSearch a sorted array by repeatedly dividing the search interval in half.\nBegin with an interval covering the whole array.\nIf the value of the search is less than the item in the middle of the interval, recurse into the lower half. Otherwise recurse into the upper half.\nRepeatedly recurse until the value is found which is the mid or you've recursed to a point that is greater than the length which means the value doesn't exist and return `-1`.\n\n", + "tags": [ + "algorithm", + "beginner" + ] + }, + "meta": { + "hash": "48d538bccbc7be7e78b8f6a69004055c4b21324d2c8d7cbc4cba0cd42e4f67fb" + } + }, + { + "id": "celsiusToFahrenheit", + "type": "snippetListing", + "title": "celsiusToFahrenheit", + "attributes": { + "text": "Celsius to Fahrenheit temperature conversion.\n\nFollows the conversion formula `F = 1.8C + 32`.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "d59410c4fa0ea5173af553068c1e1d4ef931695e084c50cdd8166b0cd0278722" + } + }, + { + "id": "cleanObj", + "type": "snippetListing", + "title": "cleanObj", + "attributes": { + "text": "Removes any properties except the ones specified from a JSON object.\n\nUse `Object.keys()` method to loop over given JSON object and deleting keys that are not included in given array.\nIf you pass a special key,`childIndicator`, it will search deeply apply the function to inner objects, too.\n\n", + "tags": [ + "object", + "beginner" + ] + }, + "meta": { + "hash": "aaefc9bd6e9170001fe4754b1bc7bb9808ab97a5bec7fc6ceb1193be2f8009b1" + } + }, + { + "id": "collatz", + "type": "snippetListing", + "title": "collatz", + "attributes": { + "text": "Applies the Collatz algorithm.\n\nIf `n` is even, return `n/2`. Otherwise, return `3n+1`.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "0280a47e49f505d5f10e0e0bd2c3ab28a6ea2b931fc83f63155f8395f64a1840" + } + }, + { + "id": "countVowels", + "type": "snippetListing", + "title": "countVowels", + "attributes": { + "text": "Retuns `number` of vowels in provided string.\n\nUse a regular expression to count the number of vowels `(A, E, I, O, U)` in a `string`.\n\n", + "tags": [ + "string", + "beginner" + ] + }, + "meta": { + "hash": "961b406dfe98746e3a267532b0703ee7c5c1b1c01a0e04c1f9e13e0fd0aeced1" + } + }, + { + "id": "factors", + "type": "snippetListing", + "title": "factors", + "attributes": { + "text": "Returns the array of factors of the given `num`.\nIf the second argument is set to `true` returns only the prime factors of `num`.\nIf `num` is `1` or `0` returns an empty array.\nIf `num` is less than `0` returns all the factors of `-int` together with their additive inverses.\n\nUse `Array.from()`, `Array.prototype.map()` and `Array.prototype.filter()` to find all the factors of `num`.\nIf given `num` is negative, use `Array.prototype.reduce()` to add the additive inverses to the array.\nReturn all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.prototype.filter()`.\nOmit the second argument, `primes`, to return prime and non-prime factors by default.\n\n**Note**:- _Negative numbers are not considered prime._\n\n", + "tags": [ + "math", + "intermediate" + ] + }, + "meta": { + "hash": "8eed39b1040d6472e2fd619abf744848d30f12eebffda2711966c616d474524f" + } + }, + { + "id": "fahrenheitToCelsius", + "type": "snippetListing", + "title": "fahrenheitToCelsius", + "attributes": { + "text": "Fahrenheit to Celsius temperature conversion.\n\nFollows the conversion formula `C = (F - 32) * 5/9`.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "a39ade2ae05ad86443446b335dbc019e3ac734fe0c1a542d50b929c554040fc0" + } + }, + { + "id": "fibonacciCountUntilNum", + "type": "snippetListing", + "title": "fibonacciCountUntilNum", + "attributes": { + "text": "Returns the number of fibonnacci numbers up to `num`(`0` and `num` inclusive).\n\nUse a mathematical formula to calculate the number of fibonacci numbers until `num`.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "35488eb0f56b59035b56cc67fa0a5e1a970162ede4aafd97ebb2b4009c321c01" + } + }, + { + "id": "fibonacciUntilNum", + "type": "snippetListing", + "title": "fibonacciUntilNum", + "attributes": { + "text": "Generates an array, containing the Fibonacci sequence, up until the nth term.\n\nCreate an empty array of the specific length, initializing the first two values (`0` and `1`).\nUse `Array.prototype.reduce()` to add values into the array, using the sum of the last two values, except for the first two.\nUses a mathematical formula to calculate the length of the array required.\n\n", + "tags": [ + "math", + "intermediate" + ] + }, + "meta": { + "hash": "6ff845c13444a06569be548ce9e69900b7001516c44c315795f34b31e9baa833" + } + }, + { + "id": "heronArea", + "type": "snippetListing", + "title": "heronArea", + "attributes": { + "text": "Returns the area of a triangle using only the 3 side lengths, Heron's formula. Assumes that the sides define a valid triangle. Does NOT assume it is a right triangle.\n\nMore information on what Heron's formula is and why it works available here: https://en.wikipedia.org/wiki/Heron%27s_formula.\n\nUses `Math.sqrt()` to find the square root of a value.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "d0be594ab377cbeb2910308610af5890b3468c06e7567cd0995a84d11aaccf47" + } + }, + { + "id": "howManyTimes", + "type": "snippetListing", + "title": "howManyTimes", + "attributes": { + "text": "Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer.\nWorks for both negative and positive integers.\n\nIf `divisor` is `-1` or `1` return `Infinity`.\nIf `divisor` is `-0` or `0` return `0`.\nOtherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer.\nReturn the number of times the loop was executed, `i`.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "52ffa251dfc4e2bec7160a9066ef24a8c3047706e1ad2837f9d987cdf4d5f73e" + } + }, + { + "id": "httpDelete", + "type": "snippetListing", + "title": "httpDelete", + "attributes": { + "text": "Makes a `DELETE` request to the passed URL.\n\nUse `XMLHttpRequest` web api to make a `delete` request to the given `url`.\nHandle the `onload` event, by running the provided `callback` function.\nHandle the `onerror` event, by running the provided `err` function.\nOmit the third argument, `err` to log the request to the console's error stream by default.\n\n", + "tags": [ + "browser", + "intermediate" + ] + }, + "meta": { + "hash": "4fccb2abe966313a742d13965ee46cfd1094763a2697591eddb19c1c5af1db7e" + } + }, + { + "id": "httpPut", + "type": "snippetListing", + "title": "httpPut", + "attributes": { + "text": "Makes a `PUT` request to the passed URL.\n\nUse `XMLHttpRequest` web api to make a `put` request to the given `url`.\nSet the value of an `HTTP` request header with `setRequestHeader` method.\nHandle the `onload` event, by running the provided `callback` function.\nHandle the `onerror` event, by running the provided `err` function.\nOmit the last argument, `err` to log the request to the console's error stream by default.\n\n", + "tags": [ + "browser", + "intermediate" + ] + }, + "meta": { + "hash": "7eb4b1ffc1cbe28c10190bb82b7731ade2d79e78a5569bdee62af33a1020f2f5" + } + }, + { + "id": "isArmstrongNumber", + "type": "snippetListing", + "title": "isArmstrongNumber", + "attributes": { + "text": "Checks if the given number is an Armstrong number or not.\n\nConvert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "71ebcdb61794d8222fcf447509d206ffb10dc8068072a88c6b587e21e76fc7f2" + } + }, + { + "id": "isSimilar", + "type": "snippetListing", + "title": "isSimilar", + "attributes": { + "text": "Determines if the `pattern` matches with `str`.\n\nUse `String.toLowerCase()` to convert both strings to lowercase, then loop through `str` and determine if it contains all characters of `pattern` and in the correct order.\nAdapted from [here](https://github.com/forrestthewoods/lib_fts/blob/80f3f8c52db53428247e741b9efe2cde9667050c/code/fts_fuzzy_match.js#L18).\n\n", + "tags": [ + "string", + "intermediate" + ] + }, + "meta": { + "hash": "250615cfc281e99014b97d054c722d3ba6aa4190ccf66dd719e530ec80aec3bd" + } + }, + { + "id": "JSONToDate", + "type": "snippetListing", + "title": "JSONToDate", + "attributes": { + "text": "Converts a JSON object to a date.\n\nUse `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`).\n\n", + "tags": [ + "object", + "date", + "beginner" + ] + }, + "meta": { + "hash": "33e1e304fead4088971a60d4da974d0e9380370560f383ddb1ddc14e628df18b" + } + }, + { + "id": "kmphToMph", + "type": "snippetListing", + "title": "kmphToMph", + "attributes": { + "text": "Convert kilometers/hour to miles/hour.\n\nMultiply the constant of proportionality with the argument.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "f885a599e1185f8480445e1eb0c4a5cb8bf33948d7893f013dd4e8085478fe7a" + } + }, + { + "id": "levenshteinDistance", + "type": "snippetListing", + "title": "levenshteinDistance", + "attributes": { + "text": "Calculates the [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) between two strings.\n\nCalculates the number of changes (substitutions, deletions or additions) required to convert `string1` to `string2`. \nCan also be used to compare two strings as shown in the second example.\n\n", + "tags": [ + "algorithm", + "advanced" + ] + }, + "meta": { + "hash": "9f71509c5937cb68b65ef31893b1ad723ce6690e8ecd161707cb222ab67a475b" + } + }, + { + "id": "mphToKmph", + "type": "snippetListing", + "title": "mphToKmph", + "attributes": { + "text": "Convert miles/hour to kilometers/hour.\n\nMultiply the constant of proportionality with the argument.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "d1ec7968c8f8c48642a3f91878db84330231bdf84bf74633dc0754456e951338" + } + }, + { + "id": "pipeLog", + "type": "snippetListing", + "title": "pipeLog", + "attributes": { + "text": "Logs a value and returns it.\n\nUse `console.log` to log the supplied value, combined with the `||` operator to return it.\n\n", + "tags": [ + "utility", + "beginner" + ] + }, + "meta": { + "hash": "dba6fa36424c23d601c4e463463a5f23d32b51d8b058a6c5020d3b4098a65e51" + } + }, + { + "id": "quickSort", + "type": "snippetListing", + "title": "quickSort", + "attributes": { + "text": "QuickSort an Array (ascending sort by default).\n\nUse recursion.\nUse `Array.prototype.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it.\nIf the parameter `desc` is truthy, return array sorts in descending order.\n\n", + "tags": [ + "algorithm", + "recursion", + "beginner" + ] + }, + "meta": { + "hash": "5c26069a02342eadd2c5ba2656a1b211da8f1a94da03c2cc31a5090be556d7b7" + } + }, + { + "id": "removeVowels", + "type": "snippetListing", + "title": "removeVowels", + "attributes": { + "text": "Returns all the vowels in a `str` replaced by `repl`.\n\nUse `String.prototype.replace()` with a regexp to replace all vowels in `str`.\nOmot `repl` to use a default value of `''`.\n\n", + "tags": [ + "string", + "beginner" + ] + }, + "meta": { + "hash": "5c6f8e292db8506568de362aa63890047f9d5a65d35143cfca1e27562642c414" + } + }, + { + "id": "solveRPN", + "type": "snippetListing", + "title": "solveRPN", + "attributes": { + "text": "Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation).\nThrows appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators.\n\nUse a dictionary, `OPERATORS` to specify each operator's matching mathematical operation.\nUse `String.prototype.replace()` with a regular expression to replace `^` with `**`, `String.prototype.split()` to tokenize the string and `Array.prototype.filter()` to remove empty tokens.\nUse `Array.prototype.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression.\nNumeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations.\n\n", + "tags": [ + "algorithm", + "advanced" + ] + }, + "meta": { + "hash": "0c37cf46586652fd20dfa9ca682d3635f01fe61c46864f9773f6b258e8f3b6f6" + } + }, + { + "id": "speechSynthesis", + "type": "snippetListing", + "title": "speechSynthesis", + "attributes": { + "text": "Performs speech synthesis (experimental).\n\nUse `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech.\nUse `window.speechSynthesis.speak()` to play the message.\n\nLearn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance).\n\n", + "tags": [ + "browser", + "intermediate" + ] + }, + "meta": { + "hash": "9859dbef05dc0398e825150b50fccfea370583cf6b807c00c9e83b769d2b51c0" + } + }, + { + "id": "squareSum", + "type": "snippetListing", + "title": "squareSum", + "attributes": { + "text": "Squares each number in an array and then sums the results together.\n\nUse `Array.prototype.reduce()` in combination with `Math.pow()` to iterate over numbers and sum their squares into an accumulator.\n\n", + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "19837ac6714833e9c5fe698811e171cc2598f7b9405a4847b33b8d3b35debf8a" + } + } + ], + "meta": { + "specification": "http://jsonapi.org/format/", + "type": "snippetListingArray" + } +} \ No newline at end of file diff --git a/snippet_data/archivedSnippets.json b/snippet_data/archivedSnippets.json new file mode 100644 index 000000000..3682eddb4 --- /dev/null +++ b/snippet_data/archivedSnippets.json @@ -0,0 +1,535 @@ +{ + "data": [ + { + "id": "binarySearch", + "title": "binarySearch", + "type": "snippet", + "attributes": { + "fileName": "binarySearch.md", + "text": "Use recursion. Similar to `Array.prototype.indexOf()` that finds the index of a value within an array.\nThe difference being this operation only works with sorted arrays which offers a major performance boost due to it's logarithmic nature when compared to a linear search or `Array.prototype.indexOf()`.\n\nSearch a sorted array by repeatedly dividing the search interval in half.\nBegin with an interval covering the whole array.\nIf the value of the search is less than the item in the middle of the interval, recurse into the lower half. Otherwise recurse into the upper half.\nRepeatedly recurse until the value is found which is the mid or you've recursed to a point that is greater than the length which means the value doesn't exist and return `-1`.\n\n", + "codeBlocks": { + "es6": "const binarySearch = (arr, val, start = 0, end = arr.length - 1) => {\n if (start > end) return -1;\n const mid = Math.floor((start + end) / 2);\n if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1);\n if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end);\n return mid;\n};", + "es5": "var binarySearch = function binarySearch(arr, val) {\n var start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;\n var end = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : arr.length - 1;\n if (start > end) return -1;\n var mid = Math.floor((start + end) / 2);\n if (arr[mid] > val) return binarySearch(arr, val, start, mid - 1);\n if (arr[mid] < val) return binarySearch(arr, val, mid + 1, end);\n return mid;\n};", + "example": "binarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 6); // 2\nbinarySearch([1, 4, 6, 7, 12, 13, 15, 18, 19, 20, 22, 24], 21); // -1" + }, + "tags": [ + "algorithm", + "beginner" + ] + }, + "meta": { + "hash": "48d538bccbc7be7e78b8f6a69004055c4b21324d2c8d7cbc4cba0cd42e4f67fb" + } + }, + { + "id": "celsiusToFahrenheit", + "title": "celsiusToFahrenheit", + "type": "snippet", + "attributes": { + "fileName": "celsiusToFahrenheit.md", + "text": "Celsius to Fahrenheit temperature conversion.\n\nFollows the conversion formula `F = 1.8C + 32`.\n\n", + "codeBlocks": { + "es6": "const celsiusToFahrenheit = degrees => 1.8 * degrees + 32;", + "es5": "var celsiusToFahrenheit = function celsiusToFahrenheit(degrees) {\n return 1.8 * degrees + 32;\n};", + "example": "celsiusToFahrenheit(33) // 91.4" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "d59410c4fa0ea5173af553068c1e1d4ef931695e084c50cdd8166b0cd0278722" + } + }, + { + "id": "cleanObj", + "title": "cleanObj", + "type": "snippet", + "attributes": { + "fileName": "cleanObj.md", + "text": "Removes any properties except the ones specified from a JSON object.\n\nUse `Object.keys()` method to loop over given JSON object and deleting keys that are not included in given array.\nIf you pass a special key,`childIndicator`, it will search deeply apply the function to inner objects, too.\n\n", + "codeBlocks": { + "es6": "const cleanObj = (obj, keysToKeep = [], childIndicator) => {\n Object.keys(obj).forEach(key => {\n if (key === childIndicator) {\n cleanObj(obj[key], keysToKeep, childIndicator);\n } else if (!keysToKeep.includes(key)) {\n delete obj[key];\n }\n });\n return obj;\n};", + "es5": "var cleanObj = function cleanObj(obj) {\n var keysToKeep = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n var childIndicator = arguments.length > 2 ? arguments[2] : undefined;\n Object.keys(obj).forEach(function (key) {\n if (key === childIndicator) {\n cleanObj(obj[key], keysToKeep, childIndicator);\n } else if (!keysToKeep.includes(key)) {\n delete obj[key];\n }\n });\n return obj;\n};", + "example": "const testObj = { a: 1, b: 2, children: { a: 1, b: 2 } };\ncleanObj(testObj, ['a'], 'children'); // { a: 1, children : { a: 1}}" + }, + "tags": [ + "object", + "beginner" + ] + }, + "meta": { + "hash": "aaefc9bd6e9170001fe4754b1bc7bb9808ab97a5bec7fc6ceb1193be2f8009b1" + } + }, + { + "id": "collatz", + "title": "collatz", + "type": "snippet", + "attributes": { + "fileName": "collatz.md", + "text": "Applies the Collatz algorithm.\n\nIf `n` is even, return `n/2`. Otherwise, return `3n+1`.\n\n", + "codeBlocks": { + "es6": "const collatz = n => (n % 2 === 0 ? n / 2 : 3 * n + 1);", + "es5": "var collatz = function collatz(n) {\n return n % 2 === 0 ? n / 2 : 3 * n + 1;\n};", + "example": "collatz(8); // 4" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "0280a47e49f505d5f10e0e0bd2c3ab28a6ea2b931fc83f63155f8395f64a1840" + } + }, + { + "id": "countVowels", + "title": "countVowels", + "type": "snippet", + "attributes": { + "fileName": "countVowels.md", + "text": "Retuns `number` of vowels in provided string.\n\nUse a regular expression to count the number of vowels `(A, E, I, O, U)` in a `string`.\n\n", + "codeBlocks": { + "es6": "const countVowels = str => (str.match(/[aeiou]/gi) || []).length;", + "es5": "var countVowels = function countVowels(str) {\n return (str.match(/[aeiou]/gi) || []).length;\n};", + "example": "countVowels('foobar'); // 3\ncountVowels('gym'); // 0" + }, + "tags": [ + "string", + "beginner" + ] + }, + "meta": { + "hash": "961b406dfe98746e3a267532b0703ee7c5c1b1c01a0e04c1f9e13e0fd0aeced1" + } + }, + { + "id": "factors", + "title": "factors", + "type": "snippet", + "attributes": { + "fileName": "factors.md", + "text": "Returns the array of factors of the given `num`.\nIf the second argument is set to `true` returns only the prime factors of `num`.\nIf `num` is `1` or `0` returns an empty array.\nIf `num` is less than `0` returns all the factors of `-int` together with their additive inverses.\n\nUse `Array.from()`, `Array.prototype.map()` and `Array.prototype.filter()` to find all the factors of `num`.\nIf given `num` is negative, use `Array.prototype.reduce()` to add the additive inverses to the array.\nReturn all results if `primes` is `false`, else determine and return only the prime factors using `isPrime` and `Array.prototype.filter()`.\nOmit the second argument, `primes`, to return prime and non-prime factors by default.\n\n**Note**:- _Negative numbers are not considered prime._\n\n", + "codeBlocks": { + "es6": "const factors = (num, primes = false) => {\n const isPrime = num => {\n const boundary = Math.floor(Math.sqrt(num));\n for (var i = 2; i <= boundary; i++) if (num % i === 0) return false;\n return num >= 2;\n };\n const isNeg = num < 0;\n num = isNeg ? -num : num;\n let array = Array.from({ length: num - 1 })\n .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false))\n .filter(val => val);\n if (isNeg)\n array = array.reduce((acc, val) => {\n acc.push(val);\n acc.push(-val);\n return acc;\n }, []);\n return primes ? array.filter(isPrime) : array;\n};", + "es5": "var factors = function factors(num) {\n var primes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var isPrime = function isPrime(num) {\n var boundary = Math.floor(Math.sqrt(num));\n\n for (var i = 2; i <= boundary; i++) {\n if (num % i === 0) return false;\n }\n\n return num >= 2;\n };\n\n var isNeg = num < 0;\n num = isNeg ? -num : num;\n var array = Array.from({\n length: num - 1\n }).map(function (val, i) {\n return num % (i + 2) === 0 ? i + 2 : false;\n }).filter(function (val) {\n return val;\n });\n if (isNeg) array = array.reduce(function (acc, val) {\n acc.push(val);\n acc.push(-val);\n return acc;\n }, []);\n return primes ? array.filter(isPrime) : array;\n};", + "example": "factors(12); // [2,3,4,6,12]\nfactors(12, true); // [2,3]\nfactors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12]\nfactors(-12, true); // [2,3]" + }, + "tags": [ + "math", + "intermediate" + ] + }, + "meta": { + "hash": "8eed39b1040d6472e2fd619abf744848d30f12eebffda2711966c616d474524f" + } + }, + { + "id": "fahrenheitToCelsius", + "title": "fahrenheitToCelsius", + "type": "snippet", + "attributes": { + "fileName": "fahrenheitToCelsius.md", + "text": "Fahrenheit to Celsius temperature conversion.\n\nFollows the conversion formula `C = (F - 32) * 5/9`.\n\n", + "codeBlocks": { + "es6": "const fahrenheitToCelsius = degrees => (degrees - 32) * 5/9;", + "es5": "var fahrenheitToCelsius = function fahrenheitToCelsius(degrees) {\n return (degrees - 32) * 5 / 9;\n};", + "example": "fahrenheitToCelsius(32); // 0" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "a39ade2ae05ad86443446b335dbc019e3ac734fe0c1a542d50b929c554040fc0" + } + }, + { + "id": "fibonacciCountUntilNum", + "title": "fibonacciCountUntilNum", + "type": "snippet", + "attributes": { + "fileName": "fibonacciCountUntilNum.md", + "text": "Returns the number of fibonnacci numbers up to `num`(`0` and `num` inclusive).\n\nUse a mathematical formula to calculate the number of fibonacci numbers until `num`.\n\n", + "codeBlocks": { + "es6": "const fibonacciCountUntilNum = num =>\n Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2));", + "es5": "var fibonacciCountUntilNum = function fibonacciCountUntilNum(num) {\n return Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2));\n};", + "example": "fibonacciCountUntilNum(10); // 7" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "35488eb0f56b59035b56cc67fa0a5e1a970162ede4aafd97ebb2b4009c321c01" + } + }, + { + "id": "fibonacciUntilNum", + "title": "fibonacciUntilNum", + "type": "snippet", + "attributes": { + "fileName": "fibonacciUntilNum.md", + "text": "Generates an array, containing the Fibonacci sequence, up until the nth term.\n\nCreate an empty array of the specific length, initializing the first two values (`0` and `1`).\nUse `Array.prototype.reduce()` to add values into the array, using the sum of the last two values, except for the first two.\nUses a mathematical formula to calculate the length of the array required.\n\n", + "codeBlocks": { + "es6": "const fibonacciUntilNum = num => {\n let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2));\n return Array.from({ length: n }).reduce(\n (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),\n []\n );\n};", + "es5": "var fibonacciUntilNum = function fibonacciUntilNum(num) {\n var n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2));\n return Array.from({\n length: n\n }).reduce(function (acc, val, i) {\n return acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i);\n }, []);\n};", + "example": "fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ]" + }, + "tags": [ + "math", + "intermediate" + ] + }, + "meta": { + "hash": "6ff845c13444a06569be548ce9e69900b7001516c44c315795f34b31e9baa833" + } + }, + { + "id": "heronArea", + "title": "heronArea", + "type": "snippet", + "attributes": { + "fileName": "heronArea.md", + "text": "Returns the area of a triangle using only the 3 side lengths, Heron's formula. Assumes that the sides define a valid triangle. Does NOT assume it is a right triangle.\n\nMore information on what Heron's formula is and why it works available here: https://en.wikipedia.org/wiki/Heron%27s_formula.\n\nUses `Math.sqrt()` to find the square root of a value.\n\n", + "codeBlocks": { + "es6": "const heronArea = (side_a, side_b, side_c) => {\n const p = (side_a + side_b + side_c) / 2\n return Math.sqrt(p * (p-side_a) * (p-side_b) * (p-side_c))\n };", + "es5": "var heronArea = function heronArea(side_a, side_b, side_c) {\n var p = (side_a + side_b + side_c) / 2;\n return Math.sqrt(p * (p - side_a) * (p - side_b) * (p - side_c));\n};", + "example": "heronArea(3, 4, 5); // 6" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "d0be594ab377cbeb2910308610af5890b3468c06e7567cd0995a84d11aaccf47" + } + }, + { + "id": "howManyTimes", + "title": "howManyTimes", + "type": "snippet", + "attributes": { + "fileName": "howManyTimes.md", + "text": "Returns the number of times `num` can be divided by `divisor` (integer or fractional) without getting a fractional answer.\nWorks for both negative and positive integers.\n\nIf `divisor` is `-1` or `1` return `Infinity`.\nIf `divisor` is `-0` or `0` return `0`.\nOtherwise, keep dividing `num` with `divisor` and incrementing `i`, while the result is an integer.\nReturn the number of times the loop was executed, `i`.\n\n", + "codeBlocks": { + "es6": "const howManyTimes = (num, divisor) => {\n if (divisor === 1 || divisor === -1) return Infinity;\n if (divisor === 0) return 0;\n let i = 0;\n while (Number.isInteger(num / divisor)) {\n i++;\n num = num / divisor;\n }\n return i;\n};", + "es5": "var howManyTimes = function howManyTimes(num, divisor) {\n if (divisor === 1 || divisor === -1) return Infinity;\n if (divisor === 0) return 0;\n var i = 0;\n\n while (Number.isInteger(num / divisor)) {\n i++;\n num = num / divisor;\n }\n\n return i;\n};", + "example": "howManyTimes(100, 2); // 2\nhowManyTimes(100, 2.5); // 2\nhowManyTimes(100, 0); // 0\nhowManyTimes(100, -1); // Infinity" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "52ffa251dfc4e2bec7160a9066ef24a8c3047706e1ad2837f9d987cdf4d5f73e" + } + }, + { + "id": "httpDelete", + "title": "httpDelete", + "type": "snippet", + "attributes": { + "fileName": "httpDelete.md", + "text": "Makes a `DELETE` request to the passed URL.\n\nUse `XMLHttpRequest` web api to make a `delete` request to the given `url`.\nHandle the `onload` event, by running the provided `callback` function.\nHandle the `onerror` event, by running the provided `err` function.\nOmit the third argument, `err` to log the request to the console's error stream by default.\n\n", + "codeBlocks": { + "es6": "const httpDelete = (url, callback, err = console.error) => {\n const request = new XMLHttpRequest();\n request.open('DELETE', url, true);\n request.onload = () => callback(request);\n request.onerror = () => err(request);\n request.send();\n};", + "es5": "var httpDelete = function httpDelete(url, callback) {\n var err = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : console.error;\n var request = new XMLHttpRequest();\n request.open('DELETE', url, true);\n\n request.onload = function () {\n return callback(request);\n };\n\n request.onerror = function () {\n return err(request);\n };\n\n request.send();\n};", + "example": "httpDelete('https://website.com/users/123', request => {\n console.log(request.responseText);\n}); // 'Deletes a user from the database'" + }, + "tags": [ + "browser", + "intermediate" + ] + }, + "meta": { + "hash": "4fccb2abe966313a742d13965ee46cfd1094763a2697591eddb19c1c5af1db7e" + } + }, + { + "id": "httpPut", + "title": "httpPut", + "type": "snippet", + "attributes": { + "fileName": "httpPut.md", + "text": "Makes a `PUT` request to the passed URL.\n\nUse `XMLHttpRequest` web api to make a `put` request to the given `url`.\nSet the value of an `HTTP` request header with `setRequestHeader` method.\nHandle the `onload` event, by running the provided `callback` function.\nHandle the `onerror` event, by running the provided `err` function.\nOmit the last argument, `err` to log the request to the console's error stream by default.\n\n", + "codeBlocks": { + "es6": "const httpPut = (url, data, callback, err = console.error) => {\n const request = new XMLHttpRequest();\n request.open(\"PUT\", url, true);\n request.setRequestHeader('Content-type','application/json; charset=utf-8');\n request.onload = () => callback(request);\n request.onerror = () => err(request);\n request.send(data);\n};", + "es5": "var httpPut = function httpPut(url, data, callback) {\n var err = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : console.error;\n var request = new XMLHttpRequest();\n request.open(\"PUT\", url, true);\n request.setRequestHeader('Content-type', 'application/json; charset=utf-8');\n\n request.onload = function () {\n return callback(request);\n };\n\n request.onerror = function () {\n return err(request);\n };\n\n request.send(data);\n};", + "example": "const password = \"fooBaz\";\nconst data = JSON.stringify(password);\nhttpPut('https://website.com/users/123', data, request => {\n console.log(request.responseText);\n}); // 'Updates a user's password in database'" + }, + "tags": [ + "browser", + "intermediate" + ] + }, + "meta": { + "hash": "7eb4b1ffc1cbe28c10190bb82b7731ade2d79e78a5569bdee62af33a1020f2f5" + } + }, + { + "id": "isArmstrongNumber", + "title": "isArmstrongNumber", + "type": "snippet", + "attributes": { + "fileName": "isArmstrongNumber.md", + "text": "Checks if the given number is an Armstrong number or not.\n\nConvert the given number into an array of digits. Use the exponent operator (`**`) to get the appropriate power for each digit and sum them up. If the sum is equal to the number itself, return `true` otherwise `false`.\n\n", + "codeBlocks": { + "es6": "const isArmstrongNumber = digits =>\n (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)(\n (digits + '').split('')\n );", + "es5": "var isArmstrongNumber = function isArmstrongNumber(digits) {\n return function (arr) {\n return arr.reduce(function (a, d) {\n return a + Math.pow(parseInt(d), arr.length);\n }, 0) == digits;\n }((digits + '').split(''));\n};", + "example": "isArmstrongNumber(1634); // true\nisArmstrongNumber(56); // false" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "71ebcdb61794d8222fcf447509d206ffb10dc8068072a88c6b587e21e76fc7f2" + } + }, + { + "id": "isSimilar", + "title": "isSimilar", + "type": "snippet", + "attributes": { + "fileName": "isSimilar.md", + "text": "Determines if the `pattern` matches with `str`.\n\nUse `String.toLowerCase()` to convert both strings to lowercase, then loop through `str` and determine if it contains all characters of `pattern` and in the correct order.\nAdapted from [here](https://github.com/forrestthewoods/lib_fts/blob/80f3f8c52db53428247e741b9efe2cde9667050c/code/fts_fuzzy_match.js#L18).\n\n", + "codeBlocks": { + "es6": "const isSimilar = (pattern, str) =>\n [...str].reduce(\n (matchIndex, char) =>\n char.toLowerCase() === (pattern[matchIndex] || '').toLowerCase()\n ? matchIndex + 1\n : matchIndex,\n 0\n ) === pattern.length;", + "es5": "function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nvar isSimilar = function isSimilar(pattern, str) {\n return _toConsumableArray(str).reduce(function (matchIndex, _char) {\n return _char.toLowerCase() === (pattern[matchIndex] || '').toLowerCase() ? matchIndex + 1 : matchIndex;\n }, 0) === pattern.length;\n};", + "example": "isSimilar('rt','Rohit'); // true\nisSimilar('tr','Rohit'); // false" + }, + "tags": [ + "string", + "intermediate" + ] + }, + "meta": { + "hash": "250615cfc281e99014b97d054c722d3ba6aa4190ccf66dd719e530ec80aec3bd" + } + }, + { + "id": "JSONToDate", + "title": "JSONToDate", + "type": "snippet", + "attributes": { + "fileName": "JSONToDate.md", + "text": "Converts a JSON object to a date.\n\nUse `Date()`, to convert dates in JSON format to readable format (`dd/mm/yyyy`).\n\n", + "codeBlocks": { + "es6": "const JSONToDate = arr => {\n const dt = new Date(parseInt(arr.toString().substr(6)));\n return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`;\n};", + "es5": "var JSONToDate = function JSONToDate(arr) {\n var dt = new Date(parseInt(arr.toString().substr(6)));\n return \"\".concat(dt.getDate(), \"/\").concat(dt.getMonth() + 1, \"/\").concat(dt.getFullYear());\n};", + "example": "JSONToDate(/Date(1489525200000)/); // \"14/3/2017\"" + }, + "tags": [ + "object", + "date", + "beginner" + ] + }, + "meta": { + "hash": "33e1e304fead4088971a60d4da974d0e9380370560f383ddb1ddc14e628df18b" + } + }, + { + "id": "kmphToMph", + "title": "kmphToMph", + "type": "snippet", + "attributes": { + "fileName": "kmphToMph.md", + "text": "Convert kilometers/hour to miles/hour.\n\nMultiply the constant of proportionality with the argument.\n\n", + "codeBlocks": { + "es6": "const kmphToMph = (kmph) => 0.621371192 * kmph;", + "es5": "var kmphToMph = function kmphToMph(kmph) {\n return 0.621371192 * kmph;\n};", + "example": "kmphToMph(10); // 16.09344000614692\nkmphToMph(345.4); // 138.24264965280207" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "f885a599e1185f8480445e1eb0c4a5cb8bf33948d7893f013dd4e8085478fe7a" + } + }, + { + "id": "levenshteinDistance", + "title": "levenshteinDistance", + "type": "snippet", + "attributes": { + "fileName": "levenshteinDistance.md", + "text": "Calculates the [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance) between two strings.\n\nCalculates the number of changes (substitutions, deletions or additions) required to convert `string1` to `string2`. \nCan also be used to compare two strings as shown in the second example.\n\n", + "codeBlocks": { + "es6": "const levenshteinDistance = (string1, string2) => {\n if (string1.length === 0) return string2.length;\n if (string2.length === 0) return string1.length;\n let matrix = Array(string2.length + 1)\n .fill(0)\n .map((x, i) => [i]);\n matrix[0] = Array(string1.length + 1)\n .fill(0)\n .map((x, i) => i);\n for (let i = 1; i <= string2.length; i++) {\n for (let j = 1; j <= string1.length; j++) {\n if (string2[i - 1] === string1[j - 1]) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(\n matrix[i - 1][j - 1] + 1,\n matrix[i][j - 1] + 1,\n matrix[i - 1][j] + 1\n );\n }\n }\n }\n return matrix[string2.length][string1.length];\n};", + "es5": "var levenshteinDistance = function levenshteinDistance(string1, string2) {\n if (string1.length === 0) return string2.length;\n if (string2.length === 0) return string1.length;\n var matrix = Array(string2.length + 1).fill(0).map(function (x, i) {\n return [i];\n });\n matrix[0] = Array(string1.length + 1).fill(0).map(function (x, i) {\n return i;\n });\n\n for (var i = 1; i <= string2.length; i++) {\n for (var j = 1; j <= string1.length; j++) {\n if (string2[i - 1] === string1[j - 1]) {\n matrix[i][j] = matrix[i - 1][j - 1];\n } else {\n matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);\n }\n }\n }\n\n return matrix[string2.length][string1.length];\n};", + "example": "levenshteinDistance('30-seconds-of-code','30-seconds-of-python-code'); // 7\nconst compareStrings = (string1,string2) => (100 - levenshteinDistance(string1,string2) / Math.max(string1.length,string2.length));\ncompareStrings('30-seconds-of-code', '30-seconds-of-python-code'); // 99.72 (%)" + }, + "tags": [ + "algorithm", + "advanced" + ] + }, + "meta": { + "hash": "9f71509c5937cb68b65ef31893b1ad723ce6690e8ecd161707cb222ab67a475b" + } + }, + { + "id": "mphToKmph", + "title": "mphToKmph", + "type": "snippet", + "attributes": { + "fileName": "mphToKmph.md", + "text": "Convert miles/hour to kilometers/hour.\n\nMultiply the constant of proportionality with the argument.\n\n", + "codeBlocks": { + "es6": "const mphToKmph = (mph) => 1.6093440006146922 * mph;", + "es5": "var mphToKmph = function mphToKmph(mph) {\n return 1.6093440006146922 * mph;\n};", + "example": "mphToKmph(10); // 16.09344000614692\nmphToKmph(85.9); // 138.24264965280207" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "d1ec7968c8f8c48642a3f91878db84330231bdf84bf74633dc0754456e951338" + } + }, + { + "id": "pipeLog", + "title": "pipeLog", + "type": "snippet", + "attributes": { + "fileName": "pipeLog.md", + "text": "Logs a value and returns it.\n\nUse `console.log` to log the supplied value, combined with the `||` operator to return it.\n\n", + "codeBlocks": { + "es6": "const pipeLog = data => console.log(data) || data;", + "es5": "var pipeLog = function pipeLog(data) {\n return console.log(data) || data;\n};", + "example": "pipeLog(1); // logs `1` and returns `1`" + }, + "tags": [ + "utility", + "beginner" + ] + }, + "meta": { + "hash": "dba6fa36424c23d601c4e463463a5f23d32b51d8b058a6c5020d3b4098a65e51" + } + }, + { + "id": "quickSort", + "title": "quickSort", + "type": "snippet", + "attributes": { + "fileName": "quickSort.md", + "text": "QuickSort an Array (ascending sort by default).\n\nUse recursion.\nUse `Array.prototype.filter` and spread operator (`...`) to create an array that all elements with values less than the pivot come before the pivot, and all elements with values greater than the pivot come after it.\nIf the parameter `desc` is truthy, return array sorts in descending order.\n\n", + "codeBlocks": { + "es6": "const quickSort = ([n, ...nums], desc) =>\n isNaN(n)\n ? []\n : [\n ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc),\n n,\n ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc)\n ];", + "es5": "function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar quickSort = function quickSort(_ref, desc) {\n var _ref2 = _toArray(_ref),\n n = _ref2[0],\n nums = _ref2.slice(1);\n\n return isNaN(n) ? [] : [].concat(_toConsumableArray(quickSort(nums.filter(function (v) {\n return desc ? v > n : v <= n;\n }), desc)), [n], _toConsumableArray(quickSort(nums.filter(function (v) {\n return !desc ? v > n : v <= n;\n }), desc)));\n};", + "example": "quickSort([4, 1, 3, 2]); // [1,2,3,4]\nquickSort([4, 1, 3, 2], true); // [4,3,2,1]" + }, + "tags": [ + "algorithm", + "recursion", + "beginner" + ] + }, + "meta": { + "hash": "5c26069a02342eadd2c5ba2656a1b211da8f1a94da03c2cc31a5090be556d7b7" + } + }, + { + "id": "removeVowels", + "title": "removeVowels", + "type": "snippet", + "attributes": { + "fileName": "removeVowels.md", + "text": "Returns all the vowels in a `str` replaced by `repl`.\n\nUse `String.prototype.replace()` with a regexp to replace all vowels in `str`.\nOmot `repl` to use a default value of `''`.\n\n", + "codeBlocks": { + "es6": "const removeVowels = (str, repl = '') => str.replace(/[aeiou]/gi, repl);", + "es5": "var removeVowels = function removeVowels(str) {\n var repl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';\n return str.replace(/[aeiou]/gi, repl);\n};", + "example": "removeVowels(\"foobAr\"); // \"fbr\"\nremoveVowels(\"foobAr\",\"*\"); // \"f**b*r\"" + }, + "tags": [ + "string", + "beginner" + ] + }, + "meta": { + "hash": "5c6f8e292db8506568de362aa63890047f9d5a65d35143cfca1e27562642c414" + } + }, + { + "id": "solveRPN", + "title": "solveRPN", + "type": "snippet", + "attributes": { + "fileName": "solveRPN.md", + "text": "Solves the given mathematical expression in [reverse polish notation](https://en.wikipedia.org/wiki/Reverse_Polish_notation).\nThrows appropriate errors if there are unrecognized symbols or the expression is wrong. The valid operators are :- `+`,`-`,`*`,`/`,`^`,`**` (`^`&`**` are the exponential symbols and are same). This snippet does not supports any unary operators.\n\nUse a dictionary, `OPERATORS` to specify each operator's matching mathematical operation.\nUse `String.prototype.replace()` with a regular expression to replace `^` with `**`, `String.prototype.split()` to tokenize the string and `Array.prototype.filter()` to remove empty tokens.\nUse `Array.prototype.forEach()` to parse each `symbol`, evaluate it as a numeric value or operator and solve the mathematical expression.\nNumeric values are converted to floating point numbers and pushed to a `stack`, while operators are evaluated using the `OPERATORS` dictionary and pop elements from the `stack` to apply operations.\n\n", + "codeBlocks": { + "es6": "const solveRPN = rpn => {\n const OPERATORS = {\n '*': (a, b) => a * b,\n '+': (a, b) => a + b,\n '-': (a, b) => a - b,\n '/': (a, b) => a / b,\n '**': (a, b) => a ** b\n };\n const [stack, solve] = [\n [],\n rpn\n .replace(/\\^/g, '**')\n .split(/\\s+/g)\n .filter(el => !/\\s+/.test(el) && el !== '')\n ];\n solve.forEach(symbol => {\n if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) {\n stack.push(symbol);\n } else if (Object.keys(OPERATORS).includes(symbol)) {\n const [a, b] = [stack.pop(), stack.pop()];\n stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a)));\n } else {\n throw `${symbol} is not a recognized symbol`;\n }\n });\n if (stack.length === 1) return stack.pop();\n else throw `${rpn} is not a proper RPN. Please check it and try again`;\n};", + "es5": "var solveRPN = function solveRPN(rpn) {\n var OPERATORS = {\n '*': function _(a, b) {\n return a * b;\n },\n '+': function _(a, b) {\n return a + b;\n },\n '-': function _(a, b) {\n return a - b;\n },\n '/': function _(a, b) {\n return a / b;\n },\n '**': function _(a, b) {\n return Math.pow(a, b);\n }\n };\n var _ref = [[], rpn.replace(/\\^/g, '**').split(/\\s+/g).filter(function (el) {\n return !/\\s+/.test(el) && el !== '';\n })],\n stack = _ref[0],\n solve = _ref[1];\n solve.forEach(function (symbol) {\n if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) {\n stack.push(symbol);\n } else if (Object.keys(OPERATORS).includes(symbol)) {\n var _ref2 = [stack.pop(), stack.pop()],\n a = _ref2[0],\n b = _ref2[1];\n stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a)));\n } else {\n throw \"\".concat(symbol, \" is not a recognized symbol\");\n }\n });\n if (stack.length === 1) return stack.pop();else throw \"\".concat(rpn, \" is not a proper RPN. Please check it and try again\");\n};", + "example": "solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5\nsolveRPN('2 3 ^'); // 8" + }, + "tags": [ + "algorithm", + "advanced" + ] + }, + "meta": { + "hash": "0c37cf46586652fd20dfa9ca682d3635f01fe61c46864f9773f6b258e8f3b6f6" + } + }, + { + "id": "speechSynthesis", + "title": "speechSynthesis", + "type": "snippet", + "attributes": { + "fileName": "speechSynthesis.md", + "text": "Performs speech synthesis (experimental).\n\nUse `SpeechSynthesisUtterance.voice` and `window.speechSynthesis.getVoices()` to convert a message to speech.\nUse `window.speechSynthesis.speak()` to play the message.\n\nLearn more about the [SpeechSynthesisUtterance interface of the Web Speech API](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance).\n\n", + "codeBlocks": { + "es6": "const speechSynthesis = message => {\n const msg = new SpeechSynthesisUtterance(message);\n msg.voice = window.speechSynthesis.getVoices()[0];\n window.speechSynthesis.speak(msg);\n};", + "es5": "var speechSynthesis = function speechSynthesis(message) {\n var msg = new SpeechSynthesisUtterance(message);\n msg.voice = window.speechSynthesis.getVoices()[0];\n window.speechSynthesis.speak(msg);\n};", + "example": "speechSynthesis('Hello, World'); // // plays the message" + }, + "tags": [ + "browser", + "intermediate" + ] + }, + "meta": { + "hash": "9859dbef05dc0398e825150b50fccfea370583cf6b807c00c9e83b769d2b51c0" + } + }, + { + "id": "squareSum", + "title": "squareSum", + "type": "snippet", + "attributes": { + "fileName": "squareSum.md", + "text": "Squares each number in an array and then sums the results together.\n\nUse `Array.prototype.reduce()` in combination with `Math.pow()` to iterate over numbers and sum their squares into an accumulator.\n\n", + "codeBlocks": { + "es6": "const squareSum = (...args) => args.reduce((squareSum, number) => squareSum + Math.pow(number, 2), 0);", + "es5": "var squareSum = function squareSum() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n\n return args.reduce(function (squareSum, number) {\n return squareSum + Math.pow(number, 2);\n }, 0);\n};", + "example": "squareSum(1, 2, 2); // 9" + }, + "tags": [ + "math", + "beginner" + ] + }, + "meta": { + "hash": "19837ac6714833e9c5fe698811e171cc2598f7b9405a4847b33b8d3b35debf8a" + } + } + ], + "meta": { + "specification": "http://jsonapi.org/format/", + "type": "snippetArray" + } +} \ No newline at end of file diff --git a/snippet_data/glossaryTerms.json b/snippet_data/glossaryTerms.json new file mode 100644 index 000000000..641422af1 --- /dev/null +++ b/snippet_data/glossaryTerms.json @@ -0,0 +1,1394 @@ +{ + "data": [ + { + "id": "AJAX", + "type": "glossaryTerm", + "title": "AJAX", + "attributes": { + "text": "Asynchronous JavaScript and XML (known as AJAX) is a term that describes a new approach to using multiple technologies together in order to enable web applications to make quick updates to the user interface without reloading the entire browser page.\n", + "tags": [ + "AJAX" + ] + }, + "meta": { + "hash": "69b3cf5153fa3348e5863392fb2d0ee3c0c7caaf4f1006bbdb65fb8ea3b365af" + } + }, + { + "id": "API", + "type": "glossaryTerm", + "title": "API", + "attributes": { + "text": "API stands for Application Programming Interface and is a set of features and rules provided by a provided by a software to enable third-party software to interact with it.\nThe code features of a web API usually include methods, properties, events or URLs.\n", + "tags": [ + "API" + ] + }, + "meta": { + "hash": "4a38caef0e8879fbe91f96c5d1f61c1628276502f4bb02da38ec79c75bd0e27a" + } + }, + { + "id": "Argument", + "type": "glossaryTerm", + "title": "Argument", + "attributes": { + "text": "An argument is a value passed as an input to a function and can be either a primitive or an object.\nIn JavaScript, functions can also be passed as arguments to other functions.\n", + "tags": [ + "Argument" + ] + }, + "meta": { + "hash": "bb18f4bf7ba352a918752f5fae6c1838acba0c1a355d270e649b008e3e5be183" + } + }, + { + "id": "Array", + "type": "glossaryTerm", + "title": "Array", + "attributes": { + "text": "Arrays are used to store multiple values in a single variable.\nArrays are ordered and each item in an array has a numeric index associated with it.\nJavaScript arrays are zero-indexed, meaning the first element's index is 0.\n", + "tags": [ + "Array" + ] + }, + "meta": { + "hash": "5a8b7e5f9ac56f1008cc87c308371c282d3122746f8908ff80dbc1cdae613ef3" + } + }, + { + "id": "Asynchronous-programming", + "type": "glossaryTerm", + "title": "Asynchronous programming", + "attributes": { + "text": "Asynchronous programming is a way to allow multiple events to trigger code without waiting for each other.\nThe main benefits of asynchronous programming are improved application performance and responsiveness.\n", + "tags": [ + "Asynchronous programming" + ] + }, + "meta": { + "hash": "1a44acdc588be78c7c331704b9b4ab95b461eba5b55d70ebaae484b4cf625d6f" + } + }, + { + "id": "Automatic-semicolon-insertion", + "type": "glossaryTerm", + "title": "Automatic semicolon insertion", + "attributes": { + "text": "Automatic semicolon insertion (ASI) is a JavaScript feature that allows developers to omit semicolons in their code.\n", + "tags": [ + "Automatic semicolon insertion" + ] + }, + "meta": { + "hash": "510b08853e3816e62aba98e3f824bec05b124e6d1b5919bfc09319b7e9486570" + } + }, + { + "id": "Boolean", + "type": "glossaryTerm", + "title": "Boolean", + "attributes": { + "text": "Booleans are one of the primitive data types in JavaScript. \nThey represent logical data values and can only be `true` or `false`.\n", + "tags": [ + "Boolean" + ] + }, + "meta": { + "hash": "3f01c94cb306caf19a88b310c59fe7e488db661729afe6c100fba3c38be6e8a7" + } + }, + { + "id": "Callback", + "type": "glossaryTerm", + "title": "Callback", + "attributes": { + "text": "A callback function, also known as a high-order function, is a function that is passed into another function as an argument, which is then executed inside the outer function.\nCallbacks can be synchronous or asynchronous.\n", + "tags": [ + "Callback" + ] + }, + "meta": { + "hash": "62b781aea272e769d6c92bd8daf99d99141af52462218727576ff207d341d65f" + } + }, + { + "id": "Character-encoding", + "type": "glossaryTerm", + "title": "Character encoding", + "attributes": { + "text": "A character encoding defines a mapping between bytes and text, specifying how the sequenece of bytes should be interpreted.\nTwo commonly used character encodings are ASCII and UTF-8.\n", + "tags": [ + "Character encoding" + ] + }, + "meta": { + "hash": "9c638e81443d53eb1c59a3145716414105aed86ae4046772c63ff81bd4f605a1" + } + }, + { + "id": "Class", + "type": "glossaryTerm", + "title": "Class", + "attributes": { + "text": "In object-oriented programming, a class is a template definition of an object's properties and methods.\n", + "tags": [ + "Class" + ] + }, + "meta": { + "hash": "e0c3dd77f0e3d05ed361dc491ab5fc81cb7d1be88e31e787e4bc45bd32171d2c" + } + }, + { + "id": "Closure", + "type": "glossaryTerm", + "title": "Closure", + "attributes": { + "text": "A closure is the combination of a function and the lexical environment within which that function was declared.\nThe closure allows a function to access the contents of that environment.\n", + "tags": [ + "Closure" + ] + }, + "meta": { + "hash": "9c01b59507a6c71428df711d9089f92d8cb0b030356b061de8a4a6192bf39c93" + } + }, + { + "id": "CoffeeScript", + "type": "glossaryTerm", + "title": "CoffeeScript", + "attributes": { + "text": "CoffeeScript is a programming language inspired by Ruby, Python and Haskell that transpiles to JavaScript.\n", + "tags": [ + "CoffeeScript" + ] + }, + "meta": { + "hash": "f1d55fd4b7da687507a0560f8878828a52a3b442d4462a344cea3324392ff66b" + } + }, + { + "id": "Constant", + "type": "glossaryTerm", + "title": "Constant", + "attributes": { + "text": "A constant is a value, associated with an identifier.\nThe value of a constant can be accessed using the identifier and cannot be altered during execution.\n", + "tags": [ + "Constant" + ] + }, + "meta": { + "hash": "7c461f2980b6f1794518fd6b4b68166167fe912f8406144607c8da04d21908d7" + } + }, + { + "id": "Constructor", + "type": "glossaryTerm", + "title": "Constructor", + "attributes": { + "text": "In class-based object-oriented programming, a constructor is a special type of function called to instantiate an object.\nConstructors often accept arguments that are commonly used to set member properties.\n", + "tags": [ + "Constructor" + ] + }, + "meta": { + "hash": "878d6b1ad8b17eebb1ac24969c4a4c269a65822a21c609221c3d96c7b989b108" + } + }, + { + "id": "Continuous-Deployment", + "type": "glossaryTerm", + "title": "Continuous Deployment", + "attributes": { + "text": "Continuous Deployment follows the testing that happens during Continuous Integration and pushes changes to a staging or production system. \nContinuous Deployment ensures that a version of the codebase is accessible at all times.", + "tags": [ + "Continuous Deployment" + ] + }, + "meta": { + "hash": "2389500f32d8eead9e56735e78d7cc84a735b79f21ce87f902771e95290618f7" + } + }, + { + "id": "Continuous-Integration", + "type": "glossaryTerm", + "title": "Continuous Integration", + "attributes": { + "text": "Continuous Integration (CI) is the practice of testing each change done to a codebase automatically and as early as possible.\nTwo popular CI systems that integrate with GitHub are Travis CI and Circle CI.", + "tags": [ + "Continuous Integration" + ] + }, + "meta": { + "hash": "5e494f687daab24e15c3853d0fccb90da6054f515f7cccd26801c6e0f38aaddc" + } + }, + { + "id": "CORS", + "type": "glossaryTerm", + "title": "CORS", + "attributes": { + "text": "Cross-Origin Resource Sharing (known as CORS) is a mechanism that uses extra HTTP headers to tell a browser to let a web application running at one domain have permission to access resources from a server at a different domain.\n", + "tags": [ + "CORS" + ] + }, + "meta": { + "hash": "75d004b6c01c85c4ca20a4ffac0d859ba438f19319513e9f664ce3ce53abe699" + } + }, + { + "id": "Cross-site-scripting-xss", + "type": "glossaryTerm", + "title": "Cross-site scripting (XSS)", + "attributes": { + "text": "XSS refers to client-side code injection where the attacker injects malicious scripts into a legitimate website or web application. \nThis is often achieved when the application does not validate user input and freely injects dynamic HTML content.\n", + "tags": [ + "Cross-site scripting (XSS)" + ] + }, + "meta": { + "hash": "ad0bd1bd6faba643e1ed7e5b1937a75209dffe5b995a4c19d57367c4311f836a" + } + }, + { + "id": "CSS", + "type": "glossaryTerm", + "title": "CSS", + "attributes": { + "text": "CSS stands for Cascading Style Sheets and is a language used to style web pages.\nCSS documents are plaintext documents structured with rules, which consist of element selectors and property-value pairs that apply the styles to the specified selectors.\n", + "tags": [ + "CSS" + ] + }, + "meta": { + "hash": "fdbdbb8739e718f6be81222bda6e69e9f64f31ac786daa7d0a3118a145aee7f2" + } + }, + { + "id": "CSV", + "type": "glossaryTerm", + "title": "CSV", + "attributes": { + "text": "CSV stands for Comma-Separated Values and is a storage format for tabular data.\nCSV documents are plaintext documents where each line represents a table row, with table columns separated by commas or some other delimiter (e.g. semicolons).\nThe first line of a CSV document sometimes consists of the table column headings for the data to follow.\n", + "tags": [ + "CSV" + ] + }, + "meta": { + "hash": "feee663243f2a5a800908ae230338d6b3c23f8b35b1c041be4e71c65123244bd" + } + }, + { + "id": "Currying", + "type": "glossaryTerm", + "title": "Currying", + "attributes": { + "text": "Currying is a way of constructing functions that allows partial application of a function's arguments.\nPractically, this means that a function is broken down into a series of functions, each one accepting part of the arguments.\n", + "tags": [ + "Currying" + ] + }, + "meta": { + "hash": "964b862cd385b8c17273b7dc3a4621050cceb412a4e7840c3e279c55b983734b" + } + }, + { + "id": "Deserialization", + "type": "glossaryTerm", + "title": "Deserialization", + "attributes": { + "text": "Deserialization is the process of converting a format that has been transferred over a network and/or used for storage to an object or data structure.\nA common type of deserialization in JavaScript is the conversion of JSON string into an object.\n", + "tags": [ + "Deserialization" + ] + }, + "meta": { + "hash": "9d60a691f67322c528e67a5d25fa97210117e7189e2a295bb400a91c1c5f7976" + } + }, + { + "id": "DNS", + "type": "glossaryTerm", + "title": "DNS", + "attributes": { + "text": "A DNS (Domain Name System) translates domain names to the IP addresses needed to find a particular computer service on a network.\n", + "tags": [ + "DNS" + ] + }, + "meta": { + "hash": "8d465038cf1b0d10b1e13e87f1c62ca2b641f83dfcf52d6e15fc65c23017dc9e" + } + }, + { + "id": "DOM", + "type": "glossaryTerm", + "title": "DOM", + "attributes": { + "text": "The DOM (Document Object Model) is a cross-platform API that treats HTML and XML documents as a tree structure consisting of nodes. \nThese nodes (such as elements and text nodes) are objects that can be programmatically manipulated and any visible changes made to them are reflected live in the document. \nIn a browser, this API is available to JavaScript where DOM nodes can be manipulated to change their styles, contents, placement in the document, or interacted with through event listeners.\n", + "tags": [ + "DOM" + ] + }, + "meta": { + "hash": "3fd8b63824d879f4b990a9fb67a60d733becda3ee74c2819f46515e563d19299" + } + }, + { + "id": "Domain-name-registrar", + "type": "glossaryTerm", + "title": "Domain name registrar", + "attributes": { + "text": "A domain name registrar is a company that manages the reservation of internet domain names.\nA domain name registrar must be approved by a general top-level domain (gTLD) registry or a country code top-level domain (ccTLD) registry.\n", + "tags": [ + "Domain name registrar" + ] + }, + "meta": { + "hash": "ce222cb66f1299ffa59c08699cff464b5fb0daa8db3002007e8b8697f5ca5057" + } + }, + { + "id": "Domain-name", + "type": "glossaryTerm", + "title": "Domain name", + "attributes": { + "text": "A domain name is a website's address on the Internet, used primarily in URLs to identify the server for each webpage.\nA domain name consists of a hierarchical sequence of names, separated by dots and ending with an extension.\n", + "tags": [ + "Domain name" + ] + }, + "meta": { + "hash": "0b478a7a88b2b463db686720064db6265b8b3161566815889ec6b00eb6e3ed20" + } + }, + { + "id": "Element", + "type": "glossaryTerm", + "title": "Element", + "attributes": { + "text": "A JavaScript representation of a DOM element commonly returned by `document.querySelector()` and `document.createElement()`. \nThey are used when creating content with JavaScript for display in the DOM that needs to be programatically generated.\n", + "tags": [ + "Element" + ] + }, + "meta": { + "hash": "9ce0565b0108631bea1187d52c5423320eb4833e1de33b223083be9b877eede8" + } + }, + { + "id": "ES6", + "type": "glossaryTerm", + "title": "ES6", + "attributes": { + "text": "ES6 stands for ECMAScript 6 (also known as ECMAScript 2015), a version of the ECMAScript specification that standardizes JavaScript.\nES6 adds a wide variety of new features to the specification, such as classes, promises, generators and arrow functions.\n", + "tags": [ + "ES6" + ] + }, + "meta": { + "hash": "0e3ebc232de61abfd21f7017ed3be1bc877437f26ae4a5df2284c9d1c0e6acf9" + } + }, + { + "id": "Event-driven-programming", + "type": "glossaryTerm", + "title": "Event-driven programming", + "attributes": { + "text": "Event-driven programming is a programming paradigm in which the flow of the program is determined by events (e.g. user actions, thread messages, sensor outputs).\nIn event-driven applications, there is usually a main loop that listens for events and trigger callback functions accordingly when one of these events is detected.\n", + "tags": [ + "Event-driven programming" + ] + }, + "meta": { + "hash": "9c65cdbdb985a10049eb1de1402c316d257c5b667f625f0fc04a87cd4fdd32ac" + } + }, + { + "id": "Event-loop", + "type": "glossaryTerm", + "title": "Event loop", + "attributes": { + "text": "The event loop handles all asynchronous callbacks. \nCallbacks are queued in a loop, while other code runs, and will run one by one when the response for each one has been received.\nThe event loop allows JavaScript to perform non-blocking I/O operations, despite the fact that JavaScript is single-threaded.\n", + "tags": [ + "Event loop" + ] + }, + "meta": { + "hash": "e3f7c2a5f8b2dab4bb5bc1cf04658e8b506825c9624fa260d82f797fc02e7c78" + } + }, + { + "id": "Express", + "type": "glossaryTerm", + "title": "Express", + "attributes": { + "text": "Express is a backend framework, that provides a layer of fundamental web application features for Node.js.\nSome of its key features are routing, middleware, template engines and error handling.\n", + "tags": [ + "Express" + ] + }, + "meta": { + "hash": "29cee59e219e12f9e91bb3e6b9e80b019fed963913cd070ac7e1f7cfab842ef1" + } + }, + { + "id": "Factory-functions", + "type": "glossaryTerm", + "title": "Factory functions", + "attributes": { + "text": "In JavaScript, a factory function is any function, which is not a class or constructor, that returns a new object.\nFactory functions don't require the use of the `new` keyword.\n", + "tags": [ + "Factory functions" + ] + }, + "meta": { + "hash": "a0c1c7de7ccb443a0430390da1004789762a4f9e6979cb9071f950897fa8e9d4" + } + }, + { + "id": "First-class-function", + "type": "glossaryTerm", + "title": "First-class function", + "attributes": { + "text": "A programming language is said to have first-class functions if it treats them as first-class citizens, meaning they can be passed as arguments, be returned as values from other functions, be assigned to variables and stored in data structures.", + "tags": [ + "First-class function" + ] + }, + "meta": { + "hash": "499e7946c147d07e0a7dfa72334f89a36964f328929ec3b173f830b0bdc9a4da" + } + }, + { + "id": "Flexbox", + "type": "glossaryTerm", + "title": "Flexbox", + "attributes": { + "text": "Flexbox is a one-dimensional layout model used to style websites as a property that could advance space distribution between items and provide powerful alignment capabilities.\n", + "tags": [ + "Flexbox" + ] + }, + "meta": { + "hash": "be1cc6d8fee2ab876af349d5d99bb1fc1a4cb7884fecbb9191d3d9e60d90a703" + } + }, + { + "id": "Function", + "type": "glossaryTerm", + "title": "Function", + "attributes": { + "text": "Functions are self-contained blocks of code with their own scope, that can be called by other code and are usually associated with a unique identifier.\nFunctions accept input in the form of arguments and can optionally return an output (if no `return` statement is present, the default value of `undefined` will be returned instead). \nJavaScript functions are also objects.\n", + "tags": [ + "Function" + ] + }, + "meta": { + "hash": "12712370bee0ffd535998408f9977b94ac762fa6ff6b12e9b86359e14150c7af" + } + }, + { + "id": "Functional-programming", + "type": "glossaryTerm", + "title": "Functional programming", + "attributes": { + "text": "Functional programming is a paradigm in which programs are built in a declarative manner using pure functions that avoid shared state and mutable data. \nFunctions that always return the same value for the same input and don't produce side effects are the pillar of functional programming.\n", + "tags": [ + "Functional programming" + ] + }, + "meta": { + "hash": "d774609fa3ba6788d4bacd501f6e658a7afca91526e04dd5a619cf3d30badee4" + } + }, + { + "id": "Functor", + "type": "glossaryTerm", + "title": "Functor", + "attributes": { + "text": "A Functor is a data type common in functional programming that implements a `map` method. \nThe `map` method takes a function and applies it to the data in the Functor, returning a new instance of the Functor with the result.\nJavaScript `Array`s are an example of the Functor data type.\n", + "tags": [ + "Functor" + ] + }, + "meta": { + "hash": "389aaf215eaa534d4625d1aa6aba1e047ca4e7ef1241b4129867fa4e13438cbc" + } + }, + { + "id": "Garbage-collection", + "type": "glossaryTerm", + "title": "Garbage collection", + "attributes": { + "text": "Garbage collection is a form of automatic memory management.\nIt attempts to reclaim memory occupied by objects that are no longer used by the program.\n", + "tags": [ + "Garbage collection" + ] + }, + "meta": { + "hash": "3c3a3376420cf16156ce79e62ea70363fd37710ea62490264bd851fed227cb6c" + } + }, + { + "id": "Git", + "type": "glossaryTerm", + "title": "Git", + "attributes": { + "text": "Git is an open-source version control system, used for source code management.\nGit allows users to copy (clone) and edit code on their local machines, before merging it into the main code base (master repository).\n", + "tags": [ + "Git" + ] + }, + "meta": { + "hash": "25d2b0e1f222f102acdcfdedabfeec8f04b40ff808b61ce047de16f184484fa2" + } + }, + { + "id": "Higher-order-function", + "type": "glossaryTerm", + "title": "Higher-order function", + "attributes": { + "text": "Higher-order functions are functions that either take other functions as arguments, return a function as a result, or both.\n", + "tags": [ + "Higher-order function" + ] + }, + "meta": { + "hash": "f7948fa3ad3524b004127eaf27cd023ce12a87b1d465e3f6e37af034d1239002" + } + }, + { + "id": "Hoisting", + "type": "glossaryTerm", + "title": "Hoisting", + "attributes": { + "text": "Hoisting is JavaScript's default behavior of adding declarations to memory during the compile phase.\nHoisting allows for JavaScript variables to be used before the line they were declared on.\n", + "tags": [ + "Hoisting" + ] + }, + "meta": { + "hash": "7f45960c62541e01c3f7c28e75eb6e131272f81ff25d354031b2f0be1fb16ca4" + } + }, + { + "id": "HTML", + "type": "glossaryTerm", + "title": "HTML", + "attributes": { + "text": "HTML stands for HyperText Markup Language and is a language used to structure web pages.\nHTML documents are plaintext documents structured with elements, which are surrounded by `<>` tags and optionally extended with attributes.\n", + "tags": [ + "HTML" + ] + }, + "meta": { + "hash": "e5e1a1dffda6d69ca6247f3a5e78e629d95a4ad80ef2bd23605556068d86f419" + } + }, + { + "id": "HTTP-and-HTTPS", + "type": "glossaryTerm", + "title": "HTTP and HTTPS", + "attributes": { + "text": "The HyperText Transfer Protocol (HTTP) is the underlying network protocol that enables transfer of hypermedia documents on the Web, usually between a client and a server.\nThe HyperText Transfer Protocol Secure (HTTPS) is an encrypted version of the HTTP protocol, that uses SSL to encrypt all data transferred between a client and a server.\n", + "tags": [ + "HTTP and HTTPS" + ] + }, + "meta": { + "hash": "2c681c09ff405bc1c980151e4f1a3cfd54b415305bb6f3bcaf2b0cbcf9d05332" + } + }, + { + "id": "Integer", + "type": "glossaryTerm", + "title": "Integer", + "attributes": { + "text": "Integers are one of the primitive data types in Javascript.\nThey represent a numerical value that has no fractional component.\n", + "tags": [ + "Integer" + ] + }, + "meta": { + "hash": "ca87340c4addebe9e1a4249fce62c0ef3e9d37505b2a834b95368c2d7250d2a8" + } + }, + { + "id": "Integration-testing", + "type": "glossaryTerm", + "title": "Integration testing", + "attributes": { + "text": "Integration testing is a type of software testing, used to test groups of units/components of a software.\nThe purpose of integration tests are to validate that the units/components interact with each other as expected.\n", + "tags": [ + "Integration testing" + ] + }, + "meta": { + "hash": "f0cc0f86211a8f1ae66ea9be353f3c9adc0e56dec19579709ff6da3ebf388ace" + } + }, + { + "id": "IP", + "type": "glossaryTerm", + "title": "IP", + "attributes": { + "text": "An IP address is a number assigned to a device connected to a network that uses the Internet protocol.\nTwo IP versions are currently in use - IPv4, the older version of the communication protocol (e.g. 192.168.1.100) and IPv6, the newest version of the communication protocol which allows for many different IP addresses (e.g. 0:0:0:0:ffff:c0a8:164).\n", + "tags": [ + "IP" + ] + }, + "meta": { + "hash": "e2812fdbe97a001ef10d72b95ffd9e4b4bdbe67e37ff7d1914eaea8583ae286c" + } + }, + { + "id": "jQuery", + "type": "glossaryTerm", + "title": "jQuery", + "attributes": { + "text": "jQuery is a frontend JavaScript library, that simplifies DOM manipulation, AJAX calls and Event handling.\njQuery uses its globally defined function, `$()`, to select and manipulate DOM elements.\n", + "tags": [ + "jQuery" + ] + }, + "meta": { + "hash": "3b9ca98ed6c2c184e2e7bd30615fe3752c20d7c016afbf6673b005ee76d7aec4" + } + }, + { + "id": "JSON", + "type": "glossaryTerm", + "title": "JSON", + "attributes": { + "text": "JSON (JavaScript Object Notation) is a format for storing and exchanging data.\nIt closely resembles the JavaScript object syntax, however some data types, such as dates and functions, cannot be natively represented and need to be serialized first.\n", + "tags": [ + "JSON" + ] + }, + "meta": { + "hash": "3e028e49f3eceb813e54013fb9bf05ef253efa4fa3034353c220cf28899952be" + } + }, + { + "id": "MDN", + "type": "glossaryTerm", + "title": "MDN", + "attributes": { + "text": "MDN Web Docs, formerly known as Mozilla Developer Network, is the official Mozilla website for development documentation of web standards and Mozilla projects.\n", + "tags": [ + "MDN" + ] + }, + "meta": { + "hash": "61ae68cf3a3b1bbf43ffce76bdaa244fa0f5bc5dbdadcd4a06d5260f8dd3247a" + } + }, + { + "id": "Module", + "type": "glossaryTerm", + "title": "Module", + "attributes": { + "text": "Modules are independent, self-contained pieces of code that can be incorporated into other pieces of code.\nModules improve maintainability and reusability of the code.\n", + "tags": [ + "Module" + ] + }, + "meta": { + "hash": "4e458b6078a1a91ed7da324aa1ac20cdbf290768aa395d3ab530d95238b7a05e" + } + }, + { + "id": "MongoDB", + "type": "glossaryTerm", + "title": "MongoDB", + "attributes": { + "text": "MongoDB is a NoSQL database model that stores data in flexible, JSON-like documents, meaning fields can vary from document to document and data structure can be changed over time\n", + "tags": [ + "MongoDB" + ] + }, + "meta": { + "hash": "c7ca87020640f844151f9422b6c473afd99620b7483f90142040cc46ffb9a7a7" + } + }, + { + "id": "Mutabe-value", + "type": "glossaryTerm", + "title": "Mutable value", + "attributes": { + "text": "Mutable value is a type of variable that can be changed once created.\nObjects are mutable as their state can be modified after they are created.\nPrimitive values are not mutable as we perform reassignment once we change them.\n", + "tags": [ + "Mutable value" + ] + }, + "meta": { + "hash": "64da7def1e95f7220ef3bbf14568350c8cbf6abe187a6f539a64f9fb2067aa5d" + } + }, + { + "id": "MVC", + "type": "glossaryTerm", + "title": "MVC", + "attributes": { + "text": "MVC stands for Model-View-Controller and is a software design pattern, emphasizing separation of concerns (logic and display).\nThe Model part of the MVC pattern refers to the data and business logic, the View handles the layout and display, while the Controller routes commands to the model and view parts. \n", + "tags": [ + "MVC" + ] + }, + "meta": { + "hash": "9956f9ca2dab4c5d7370f3a6ed38abbf871b6f5c11ffef6449e3791aa5229420" + } + }, + { + "id": "Node-js", + "type": "glossaryTerm", + "title": "Node.js", + "attributes": { + "text": "Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine.\nNode.js can execute JavaScript code outside of the browser and can be used to develop web backends or standalone applications.\n", + "tags": [ + "Node.js" + ] + }, + "meta": { + "hash": "e03cbfde15c9f4b7c74ee034ed37f3d78809bd1ec64e2fdb62d2bf9da4c3c3ab" + } + }, + { + "id": "NoSQL", + "type": "glossaryTerm", + "title": "NoSQL", + "attributes": { + "text": "NoSQL databases provide a mechanism to create, update, retrieve and calculate data that is stored in models that are non-tabular.", + "tags": [ + "NoSQL" + ] + }, + "meta": { + "hash": "1f948ede88ba138f4ae41bcb694b2837e59e2427bfadf2a5b62773453db4664a" + } + }, + { + "id": "Npm", + "type": "glossaryTerm", + "title": "Npm", + "attributes": { + "text": "Npm is a package manager for the JavaScript programming language and the default package manager for Node.js.\nIt consists of a command-line client and the npm registry, an online database of packages.\n", + "tags": [ + "Npm" + ] + }, + "meta": { + "hash": "49873aab20ab7019d8253e102d9623f086558d464241f821ed6d3de67aa0a15c" + } + }, + { + "id": "Object-oriented-programming", + "type": "glossaryTerm", + "title": "Object-oriented programming", + "attributes": { + "text": "Object-oriented programming (OOP) is a programming paradigm based on the concept of objects, which may contain both data and procedures which can be use to operate on them.\nJavaScript supports Object-oriented programming both via prototypes and classes.\n", + "tags": [ + "Object-oriented programming" + ] + }, + "meta": { + "hash": "501ba8d90343d16c419320e6896196c38e7b9b14e893ef96617f8bb108931b19" + } + }, + { + "id": "Object", + "type": "glossaryTerm", + "title": "Object", + "attributes": { + "text": "Objects are data structures that contain data and instructions for working with the data.\nObjects consist of key-value pairs, where the keys are alphanumeric identifiers and the values can either be primitives or objects.\nJavaScript functions are also objects.\n", + "tags": [ + "Object" + ] + }, + "meta": { + "hash": "18066e6dbd116c3c589457fb5cef16b9a5728a87a4a096d91aa436c8e3aafdf4" + } + }, + { + "id": "Prepared-statements", + "type": "glossaryTerm", + "title": "Prepared statements", + "attributes": { + "text": "In databases management systems, prepared statements are templates that can be used to execute queries with the provided values substituting the template's parameters.\nPrepared statements offer many benefits, such as reusability, maintainability and higher security.\n", + "tags": [ + "Prepared statements" + ] + }, + "meta": { + "hash": "5720bf41b264de168f79f6a5a4bd2bfb3e34e0bf14668e41d3473047fe606309" + } + }, + { + "id": "Promise", + "type": "glossaryTerm", + "title": "Promise", + "attributes": { + "text": "The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.\nA Promise can be in one of these states: pending(initial state, neither fulfilled nor rejected), fulfilled(operation completed successfully), rejected(operation failed).\n", + "tags": [ + "Promise" + ] + }, + "meta": { + "hash": "ae5316c9f0178c362ae59e5c48d8e2bfca4bb4651e25696c16e7550851220251" + } + }, + { + "id": "Prototype-based-programming", + "type": "glossaryTerm", + "title": "Prototype-based programming", + "attributes": { + "text": "Prototype-based programming is a style of object-oriented programming, where inheritance is based on object delegation, reusing objects that serve as prototypes.\nPrototype-based programming allows the creation of objects before defining their classes.\n", + "tags": [ + "Prototype-based programming" + ] + }, + "meta": { + "hash": "6a8d442044c67422c03c6e2d996380632d589c932b7d8bda1481196de230e83f" + } + }, + { + "id": "Pseudo-class", + "type": "glossaryTerm", + "title": "Pseudo-class", + "attributes": { + "text": "In CSS, a pseudo-class is used to define a special state of an element and can be used as a selector in combination with an id, element or class selector.\n", + "tags": [ + "Pseudo-class" + ] + }, + "meta": { + "hash": "eb4de09ddad1a858923ec46b6b7fb4fd2ec04631ce53054fe3320e25b70650f4" + } + }, + { + "id": "Pseudo-element", + "type": "glossaryTerm", + "title": "Pseudo-element", + "attributes": { + "text": "In CSS, a pseudo-element is used to style specific parts of an element and can be used as a selector in combination with an id, element or class selector.\n", + "tags": [ + "Pseudo-element" + ] + }, + "meta": { + "hash": "101704381209b0f0949dfe98c63a412dfc22736fb9b68adba02aaac76f97f606" + } + }, + { + "id": "PWA", + "type": "glossaryTerm", + "title": "PWA", + "attributes": { + "text": "Progressive Web App (known as PWA) is a term used to describe web applications that load like regular websites but can offer the user functionality such as working offline, push notifications, and device hardware access that were traditionally available only to native mobile applications.\n", + "tags": [ + "PWA" + ] + }, + "meta": { + "hash": "ccf2722f73b32d2693b0cb050ab611f86539ce1ec620af3b277e00042e7e4402" + } + }, + { + "id": "React", + "type": "glossaryTerm", + "title": "React", + "attributes": { + "text": "React is a frontend framework, that allows developers to create dynamic, component-based user interfaces.\nReact separates view and state, utilizing a virtual DOM to update the user interface.\n", + "tags": [ + "React" + ] + }, + "meta": { + "hash": "4a988d97fc5256e61d4c50677b4a78ffb17a34538b34e4bbba96a8ef1638c117" + } + }, + { + "id": "Recursion", + "type": "glossaryTerm", + "title": "Recursion", + "attributes": { + "text": "Recursion is the repeated application of a process. \nIn JavaScript, recursion involves functions that call themselves repeatedly until they reach a base condition. \nThe base condition breaks out of the recursion loop because otherwise the function would call itself indefinitely. \nRecursion is very useful when working with nested data, especially when the nesting depth is dynamically defined or unkown.\n", + "tags": [ + "Recursion" + ] + }, + "meta": { + "hash": "8ccde135a72db896bd889ea27843eb9368d2a0874726aa7a2af67b30c1c57185" + } + }, + { + "id": "Regular-expressions", + "type": "glossaryTerm", + "title": "Regular expressions", + "attributes": { + "text": "Regular expressions (known as regex or regexp) are patterns used to match character combinations in strings.\nJavaScript provides a regular expression implementation through the `RegExp` object.\n", + "tags": [ + "Regular expressions" + ] + }, + "meta": { + "hash": "657233cddce674de187be8e93e1c8b6e38c405505b1266ca1f3fb35b965e1df2" + } + }, + { + "id": "Repository", + "type": "glossaryTerm", + "title": "Repository", + "attributes": { + "text": "In a version control system, a repository (or repo for short) is a data structure that stores metadata for a set of files (i.e. a project).\n", + "tags": [ + "Repository" + ] + }, + "meta": { + "hash": "b70059738193173e8ef6003dbd1b751d1c77921ac1b09f372fb0140c9356aab1" + } + }, + { + "id": "Responsive-web-design", + "type": "glossaryTerm", + "title": "Responsive web design", + "attributes": { + "text": "Responsive web design is a web development concept aiming to provide optimal behavior and performance of websites on all web-enabled devices.\nResponsive web design is usually coupled with a mobile-first approach.\n", + "tags": [ + "Responsive web design" + ] + }, + "meta": { + "hash": "489ab55187ce67a6138db4c0e2606dbe808624effb398ac3a18edde27c16a868" + } + }, + { + "id": "Scope", + "type": "glossaryTerm", + "title": "Scope", + "attributes": { + "text": "Each function has its own scope, and any variable declared within that function is only accessible from that function and any nested functions.\n", + "tags": [ + "Scope" + ] + }, + "meta": { + "hash": "e44cc3eaa39955a9044b5970b515287a4df2cf07599c9e55ad1ae4defbcc2229" + } + }, + { + "id": "Selector", + "type": "glossaryTerm", + "title": "Selector", + "attributes": { + "text": "A CSS selector is a pattern that is used to select and/or style one or more elements in a document, based on certain rules.\nThe order in which CSS selectors apply styles to elements is based on the rules of CSS specificity.\n", + "tags": [ + "Selector" + ] + }, + "meta": { + "hash": "f17eb23b5bda4e18a346a107b8dfcb8fe2ae1b0ce325657ed6b505f3c756be3b" + } + }, + { + "id": "SEO", + "type": "glossaryTerm", + "title": "SEO", + "attributes": { + "text": "SEO stands for Search Engine Optimization and refers to the process of improving a website's search rankings and visibility.\n", + "tags": [ + "SEO" + ] + }, + "meta": { + "hash": "1927b7df02d9e99369401756b6af641c68aa79e71f0e42afe5ccf812dae41709" + } + }, + { + "id": "Serialization", + "type": "glossaryTerm", + "title": "Serialization", + "attributes": { + "text": "Serialization is the process of converting an object or data structure into a format suitable for transfer over a network and/or storage.\nA common type of serialization in JavaScript is the conversion of an object into a JSON string.\n", + "tags": [ + "Serialization" + ] + }, + "meta": { + "hash": "a91560cd1d2f68017e8ce5566b2a01e73201eaad0e79568e3b83d028ec29a45f" + } + }, + { + "id": "ShadowDOM", + "type": "glossaryTerm", + "title": "Shadow DOM", + "attributes": { + "text": "Shadow DOM allows you to attach hidden DOM trees to elements in the normal DOM tree, which are included in the document rendering, but excluded from the main document DOM tree. \nA shadow DOM tree will start with a shadow root, to which you can attach any elements you want, just like in a regular DOM.\nExamples of shadow DOM uses are the `