Adapter
call
Given a key and a set of arguments, call them when given a context. Primarily useful in composition.
Use a closure to call a stored key with stored arguments.
const call = (key, ...args) => context => context[key](...args); + }
30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.
Adapter
call
Given a key and a set of arguments, call them when given a context. Primarily useful in composition.
Use a closure to call a stored key with stored arguments.
const call = (key, ...args) => context => context[key](...args);Promise.resolve([1, 2, 3]) .then(call('map', x => 2 * x)) .then(console.log); //[ 2, 4, 6 ] @@ -50,7 +54,7 @@ Promise.reso let p2 = Promise.resolve(2); let p3 = new Promise(resolve => setTimeout(resolve, 2000, 3)); Pall(p1, p2, p3).then(console.log); -flip
Flip takes a function as an argument, then makes the first argument the last
Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest.
const flip = fn => (...args) => fn(args.pop(), ...args); +flip
Flip takes a function as an argument, then makes the first argument the last.
Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest.
const flip = fn => (...args) => fn(args.pop(), ...args);let a = { name: 'John Smith' }; let b = {}; const mergeFrom = flip(Object.assign); @@ -79,7 +83,7 @@ Object.assigchunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]compact
Removes falsey values from an array.
Use
Array.filter()to filter out falsey values (false,null,0,"",undefined, andNaN).const compact = arr => arr.filter(Boolean);compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34]); // [ 1, 2, 3, 'a', 's', 34 ] -countOccurrences
Counts the occurrences of a value in an array.
Use
Array.reduce()to increment a counter each time you encounter the specific value inside the array.const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); +countOccurrences
Counts the occurrences of a value in an array.
Use
Array.reduce()to increment a counter each time you encounter the specific value inside the array.const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a + 0), 0);countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3deepFlatten
Deep flattens an array.
Use recursion. Use
Array.concat()with an empty array ([]) and the spread operator (...) to flatten an array. Recursively flatten each element that is an array.const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5] @@ -105,7 +109,7 @@ Object.assigeveryNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]filterNonUnique
Filters out the non-unique values in an array.
Use
Array.filter()for an array containing only the unique values.const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1,3,5] -flatten
Flattens an array.
Use a new array and concatenate it with the spread input array causing a shallow denesting of any contained arrays.
const flatten = arr => [].concat(...arr); +flatten
Flattens an array.
Use a new array,
Array.concat()and the spread operator (...) to cause a shallow denesting of any contained arrays.const flatten = arr => [].concat(...arr);flatten([1, [2], 3, 4]); // [1,2,3,4]flattenDepth
Flattens an array up to the specified depth.
Use recursion, decrementing
depthby 1 for each level of depth. UseArray.reduce()andArray.concat()to merge elements or arrays. Base case, fordepthequal to1stops recursion. Omit the second element,depthto flatten only to a depth of1(single flatten).const flattenDepth = (arr, depth = 1) => depth != 1 @@ -128,12 +132,12 @@ Object.assig .fill() .map(() => Array(w).fill(val));initialize2DArray(2, 2, 0); // [[0,0], [0,0]] -initializeArrayWithRange
Initializes an array containing the numbers in the specified range where
startandendare inclusive with there common differencestep.Use
Array(Math.ceil((end+1-start)/step)to create an array of the desired length(the amounts of elements is equal to(end-start)/stepor(end+1-start)/stepfor inclusive end),Array.map()to fill with the desired values in a range. You can omitstartto use a default value of0. You can omitstepto use a default value of1.const initializeArrayWithRange = (end, start = 0, step = 1) => +initializeArrayWithRange
Initializes an array containing the numbers in the specified range where
startandendare inclusive with there common differencestep.Use
Array.from(Math.ceil((end+1-start)/step))to create an array of the desired length(the amounts of elements is equal to(end-start)/stepor(end+1-start)/stepfor inclusive end),Array.map()to fill with the desired values in a range. You can omitstartto use a default value of0. You can omitstepto use a default value of1.const initializeArrayWithRange = (end, start = 0, step = 1) => Array.from({ length: Math.ceil((end + 1 - start) / step) }).map((v, i) => i * step + start);initializeArrayWithRange(5); // [0,1,2,3,4,5] initializeArrayWithRange(7, 3); // [3,4,5,6,7] initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8] -initializeArrayWithValues
Initializes and fills an array with the specified values.
Use
Array(n)to create an array of the desired length,fill(v)to fill it with the desired values. You can omitvalueto use a default value of0.const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); +initializeArrayWithValues
Initializes and fills an array with the specified values.
Use
Array(n)to create an array of the desired length,fill(v)to fill it with the desired values. You can omitvalto use a default value of0.const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val);initializeArrayWithValues(5, 2); // [2,2,2,2,2]intersection
Returns a list of elements that exist in both arrays.
Create a
Setfromb, then useArray.filter()onato only keep values contained inb.const intersection = (a, b) => { const s = new Set(b); @@ -209,16 +213,6 @@ Object.assig };let myArray = ['a', 'b', 'c', 'd']; let pulled = pullAtValue(myArray, ['b', 'd']); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ] -quickSort
QuickSort an Array (ascending sort by default).
Use recursion. Use
Array.filterand 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. If the parameterdescis truthy, return array sorts in descending order.const quickSort = ([n, ...nums], desc) => - isNaN(n) - ? [] - : [ - ...quickSort(nums.filter(v => (desc ? v > n : v <= n)), desc), - n, - ...quickSort(nums.filter(v => (!desc ? v > n : v <= n)), desc) - ]; -quickSort([4, 1, 3, 2]); // [1,2,3,4] -quickSort([4, 1, 3, 2], true); // [4,3,2,1]reducedFilter
Filter an array of objects based on a condition while also filtering out unspecified keys.
Use
Array.filter()to filter the array based on the predicatefnso that it returns the objects for which the condition returned a truthy value. On the filtered array, useArray.map()to return the new object usingArray.reduce()to filter out the keys which were not supplied as thekeysargument.const reducedFilter = (data, keys, fn) => data.filter(fn).map(el => keys.reduce((acc, key) => { @@ -260,7 +254,7 @@ Object.assig };sampleSize([1, 2, 3], 2); // [3,1] sampleSize([1, 2, 3], 4); // [2,3,1] -shuffle
Randomizes the order of the values of an array, returning a new array.
Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the Lodash implementation, but as a pure function.
const shuffle = ([...arr]) => { +shuffle
Randomizes the order of the values of an array, returning a new array.
Uses the Fisher-Yates algorithm to reorder the elements of the array.
const shuffle = ([...arr]) => { let m = arr.length; while (m) { const i = Math.floor(Math.random() * m--); @@ -270,7 +264,7 @@ Object.assig };const foo = [1, 2, 3]; shuffle(foo); // [2,3,1], foo = [1,2,3] -similarity
Returns an array of elements that appear in both arrays.
Use
filter()to remove values that are not part ofvalues, determined usingincludes().const similarity = (arr, values) => arr.filter(v => values.includes(v)); +similarity
Returns an array of elements that appear in both arrays.
Use
Array.filter()to remove values that are not part ofvalues, determined usingArray.includes().const similarity = (arr, values) => arr.filter(v => values.includes(v));similarity([1, 2, 3], [1, 2, 4]); // [1,2]sortedIndex
Returns the lowest index at which value should be inserted into array in order to maintain its sort order.
Check if the array is sorted in descending order (loosely). Use
Array.findIndex()to find the appropriate index where the element should be inserted.const sortedIndex = (arr, n) => { const isDescending = arr[0] > arr[arr.length - 1]; @@ -285,7 +279,7 @@ Object.assig return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]; };symmetricDifference([1, 2, 3], [1, 2, 4]); // [3,4] -tail
Returns all elements in an array except for the first one.
Return
arr.slice(1)if the array'slengthis more than1, otherwise, return the whole array.const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); +tail
Returns all elements in an array except for the first one.
Return
Array.slice(1)if the array'slengthis more than1, otherwise, return the whole array.const tail = arr => (arr.length > 1 ? arr.slice(1) : arr);tail([1, 2, 3]); // [2,3] tail([1]); // [1]take
Returns an array with n elements removed from the beginning.
Use
Array.slice()to create a slice of the array withnelements taken from the beginning.const take = (arr, n = 1) => arr.slice(0, n); @@ -317,7 +311,7 @@ Object.assig document.documentElement.clientHeight + window.scrollY >= (document.documentElement.scrollHeight || document.documentElement.clientHeight);bottomVisible(); // true -copyToClipboard
Copy a string to the clipboard. Only works as a result of user action (i.e. inside a
clickevent listener).Create a new
<textarea>element, fill it with the supplied data and add it to the HTML document. UseSelection.getRangeAt()to store the selected range (if any). Usedocument.execCommand('copy')to copy to the clipboard. Remove the<textarea>element from the HTML document. Finally, useSelection().addRange()to recover the original selected range (if any).const copyToClipboard = str => { +copyToClipboardadvanced
Copy a string to the clipboard. Only works as a result of user action (i.e. inside a
clickevent listener).Create a new
<textarea>element, fill it with the supplied data and add it to the HTML document. UseSelection.getRangeAt()to store the selected range (if any). Usedocument.execCommand('copy')to copy to the clipboard. Remove the<textarea>element from the HTML document. Finally, useSelection().addRange()to recover the original selected range (if any).const copyToClipboard = str => { const el = document.createElement('textarea'); el.value = str; el.setAttribute('readonly', ''); @@ -368,7 +362,7 @@ Object.assig if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]); };httpsRedirect(); // If you are on http://mydomain.com, you are redirected to https://mydomain.com -onUserInputChange
Run the callback whenever the user input type changes (
mouseortouch). Useful for enabling/disabling code depending on the input device. This process is dynamic and works with hybrid devices (e.g. touchscreen laptops).Use two event listeners. Assume
mouseinput initially and bind atouchstartevent listener to the document. Ontouchstart, add amousemoveevent listener to listen for two consecutivemousemoveevents firing within 20ms, usingperformance.now(). Run the callback with the input type as an argument in either of these situations.const onUserInputChange = callback => { +onUserInputChangeadvanced
Run the callback whenever the user input type changes (
mouseortouch). Useful for enabling/disabling code depending on the input device. This process is dynamic and works with hybrid devices (e.g. touchscreen laptops).Use two event listeners. Assume
mouseinput initially and bind atouchstartevent listener to the document. Ontouchstart, add amousemoveevent listener to listen for two consecutivemousemoveevents firing within 20ms, usingperformance.now(). Run the callback with the input type as an argument in either of these situations.const onUserInputChange = callback => { let type = 'mouse', lastTime = 0; const mousemoveHandler = () => { @@ -388,7 +382,7 @@ Object.assigredirect
Redirects to a specified URL.
Use
window.location.hreforwindow.location.replace()to redirect tourl. Pass a second argument to simulate a link click (true- default) or an HTTP redirect (false).const redirect = (url, asLink = true) => asLink ? (window.location.href = url) : window.location.replace(url);redirect('https://google.com'); -runAsync
Runs a function in a separate thread by using a Web Worker, allowing long running functions to not block the UI.
Create a new
Workerusing aBlobobject URL, the contents of which should be the stringified version of the supplied function. Immediately post the return value of calling the function back. Return a promise, listening foronmessageandonerrorevents and resolving the data posted back from the worker, or throwing an error.const runAsync = fn => { +runAsyncadvanced
Runs a function in a separate thread by using a Web Worker, allowing long running functions to not block the UI.
Create a new
Workerusing aBlobobject URL, the contents of which should be the stringified version of the supplied function. Immediately post the return value of calling the function back. Return a promise, listening foronmessageandonerrorevents and resolving the data posted back from the worker, or throwing an error.const runAsync = fn => { const blob = `var fn = ${fn.toString()}; postMessage(fn());`; const worker = new Worker( URL.createObjectURL(new Blob([blob]), { @@ -432,16 +426,10 @@ Object.assig } };scrollToTop(); -setStyle
Sets the value of a CSS rule for the specified element.
Use
element.styleto set the value of the CSS rule for the specified element tovalue.const setStyle = (el, ruleName, value) => (el.style[ruleName] = value); +setStyle
Sets the value of a CSS rule for the specified element.
Use
element.styleto set the value of the CSS rule for the specified element toval.const setStyle = (el, ruleName, val) => (el.style[ruleName] = val);setStyle(document.querySelector('p'), 'font-size', '20px'); // The first <p> element on the page will have a font-size of 20pxshow
Shows all the elements specified.
Use the spread operator (
...) andArray.forEach()to clear thedisplayproperty for each element specified.const show = (...el) => [...el].forEach(e => (e.style.display = ''));show(document.querySelectorAll('img')); // Shows all <img> elements on the page -speechSynthesis
Performs speech synthesis (experimental).
Use
SpeechSynthesisUtterance.voiceandwindow.speechSynthesis.getVoices()to convert a message to speech. Usewindow.speechSynthesis.speak()to play the message.Learn more about the SpeechSynthesisUtterance interface of the Web Speech API.
const speechSynthesis = message => { - const msg = new SpeechSynthesisUtterance(message); - msg.voice = window.speechSynthesis.getVoices()[0]; - window.speechSynthesis.speak(msg); -}; -speechSynthesis('Hello, World'); // // plays the messagetoggleClass
Toggle a class for an element.
Use
element.classList.toggle()to toggle the specified class for the element.const toggleClass = (el, className) => el.classList.toggle(className);toggleClass(document.querySelector('p.special'), 'special'); // The paragraph will not have the 'special' class anymoreUUIDGeneratorBrowser
Generates a UUID in a browser.
Use
cryptoAPI to generate a UUID, compliant with RFC4122 version 4.const UUIDGeneratorBrowser = () => @@ -468,11 +456,6 @@ Object.assiggetDaysDiffBetweenDates
Returns the difference (in days) between two dates.
Calculate the difference (in days) between two
Dateobjects.const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24);getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9 -JSONToDate
Converts a JSON object to a date.
Use
Date(), to convert dates in JSON format to readable format (dd/mm/yyyy).const JSONToDate = arr => { - const dt = new Date(parseInt(arr.toString().substr(6))); - return `${dt.getDate()}/${dt.getMonth() + 1}/${dt.getFullYear()}`; -}; -JSONToDate(/Date(1489525200000)/); // "14/3/2017"toEnglishDate
Converts a date from American format to English format.
Use
Date.toISOString(),split('T')andreplace()to convert a date from American format to the English format. Throws an error if the passed time cannot be converted to a date.const toEnglishDate = time => { try { return new Date(time) @@ -482,7 +465,7 @@ Object.assig } catch (e) {} };toEnglishDate('09/21/2010'); // '21/09/2010' -tomorrow
Results in a string representation of tomorrow's date. Use
new Date()to get today's date, adding86400000of seconds to it(24 hours), usingtoISOStringto convert Date object to string.const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; +tomorrow
Results in a string representation of tomorrow's date. Use
new Date()to get today's date, adding86400000of seconds to it(24 hours), usingDate.toISOString()to convert Date object to string.const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0];tomorrow(); // 2017-12-27 (if current date is 2017-12-26)Function
chainAsync
Chains asynchronous functions.
Loop through an array of functions containing asynchronous events, calling
nextwhen each asynchronous event has completed.const chainAsync = fns => { let curr = 0; @@ -551,25 +534,20 @@ document.bodyawait sleep(1000); console.log('I woke up after 1 second.'); } -Logic
negate
Negates a predicate function.
Take a predicate function and apply
notto it with its arguments.const negate = func => (...args) => !func(...args); +Logic
negate
Negates a predicate function.
Take a predicate function and apply the not operator (
!) to it with its arguments.const negate = func => (...args) => !func(...args);filter([1, 2, 3, 4, 5, 6], negate(isEven)); // [1, 3, 5] negate(isOdd)(1); // false -Math
average
Returns the average of an of two or more numbers/arrays.
Use
Array.reduce()to add each value to an accumulator, initialized with a value of0, divide by thelengthof the array.const average = (...arr) => { - const nums = [].concat(...arr); - return nums.reduce((acc, val) => acc + val, 0) / nums.length; -}; -average([1, 2, 3]); // 2 +Math
average
Returns the average of an of two or more numbers.
Use
Array.reduce()to add each value to an accumulator, initialized with a value of0, divide by thelengthof the array.const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length; +average(...[1, 2, 3]); // 2 average(1, 2, 3); // 2clampNumber
Clamps
numwithin the inclusive range specified by the boundary valuesaandb.If
numfalls within the range, returnnum. Otherwise, return the nearest number in the range.const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));clampNumber(2, 3, 5); // 3 clampNumber(1, -1, -5); // -1 -collatz
Applies the Collatz algorithm.
If
nis even, returnn/2. Otherwise, return3n+1.const collatz = n => (n % 2 == 0 ? n / 2 : 3 * n + 1); -collatz(8); // 4 -digitize
Converts a number to an array of digits.
Convert the number to a string, using spread operators in ES6(
[...string]) build an array. UseArray.map()andparseInt()to transform each value to an integer.const digitize = n => [...('' + n)].map(i => parseInt(i)); +digitize
Converts a number to an array of digits.
Convert the number to a string, using the spread operator (
...) to build an array. UseArray.map()andparseInt()to transform each value to an integer.const digitize = n => [...`${n}`].map(i => parseInt(i));digitize(123); // [1, 2, 3]distance
Returns the distance between two points.
Use
Math.hypot()to calculate the Euclidean distance between two points.const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);distance(1, 1, 2, 3); // 2.23606797749979 -elo
Computes the new ratings between two or more opponents using the Elo rating system. It takes an array of pre-ratings and returns an array containing post-ratings. The array should be ordered from best performer to worst performer (winner -> loser).
Use the exponent
**operator and math operators to compute the expected score (chance of winning) of each opponent and compute the new rating for each. Loop through the ratings, using each permutation to compute the post-Elo rating for each player in a pairwise fashion. Omit the second argument to use the default K-factor of 32, or supply a custom K-factor value. For details on the third argument, see the last example.const elo = ([...ratings], kFactor = 32, selfRating) => { +eloadvanced
Computes the new ratings between two or more opponents using the Elo rating system. It takes an array of pre-ratings and returns an array containing post-ratings. The array should be ordered from best performer to worst performer (winner -> loser).
Use the exponent
**operator and math operators to compute the expected score (chance of winning). of each opponent and compute the new rating for each. Loop through the ratings, using each permutation to compute the post-Elo rating for each player in a pairwise fashion. Omit the second argument to use the defaultkFactorof 32.const elo = ([...ratings], kFactor = 32, selfRating) => { const [a, b] = ratings; const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400)); const newRating = (rating, i) => @@ -593,7 +571,7 @@ document.body// 4 player FFA, all same rank elo([1200, 1200, 1200, 1200]).map(Math.round); // [1246, 1215, 1185, 1154] /* -For teams, each rating can adjusted based on own team's average rating vs. +For teams, each rating can adjusted based on own team's average rating vs. average rating of opposing team, with the score being added to their own individual rating by supplying it as the third argument. */ @@ -604,51 +582,18 @@ own individual rating by supplying it as the third argument. })() : n <= 1 ? 1 : n * factorial(n - 1);factorial(6); // 720 -factors
Returns the array of factors of the given
num. If the second argument is set totruereturns only the prime factors ofnum. Ifnumis1or0returns an empty array. Ifnumis less than0returns all the factors of-inttogether with their additive inverses.Use
Array.from(),Array.map()andArray.filter()to find all the factors ofnum. If givennumis negative, useArray.reduce()to add the additive inverses to the array. Return all results ifprimesisfalse, else determine and return only the prime factors usingisPrimeandArray.filter(). Omit the second argument,primes, to return prime and non-prime factors by default.Note:- Negative numbers are not considered prime.
const factors = (num, primes = false) => { - const isPrime = num => { - const boundary = Math.floor(Math.sqrt(num)); - for (var i = 2; i <= boundary; i++) if (num % i === 0) return false; - return num >= 2; - }; - const isNeg = num < 0; - num = isNeg ? -num : num; - let array = Array.from({ length: num - 1 }) - .map((val, i) => (num % (i + 2) === 0 ? i + 2 : false)) - .filter(val => val); - if (isNeg) - array = array.reduce((acc, val) => { - acc.push(val); - acc.push(-val); - return acc; - }, []); - return primes ? array.filter(isPrime) : array; -}; -factors(12); // [2,3,4,6,12] -factors(12, true); // [2,3] -factors(-12); // [2, -2, 3, -3, 4, -4, 6, -6, 12, -12] -factors(-12, true); // [2,3]fibonacci
Generates an array, containing the Fibonacci sequence, up until the nth term.
Create an empty array of the specific length, initializing the first two values (
0and1). UseArray.reduce()to add values into the array, using the sum of the last two values, except for the first two.const fibonacci = n => Array.from({ length: n }).reduce( (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), [] );fibonacci(6); // [0, 1, 1, 2, 3, 5] -fibonacciCountUntilNum
Returns the number of fibonnacci numbers up to
num(0andnuminclusive).Use a mathematical formula to calculate the number of fibonacci numbers until
num.const fibonacciCountUntilNum = num => - Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); -fibonacciCountUntilNum(10); // 7 -fibonacciUntilNum
Generates an array, containing the Fibonacci sequence, up until the nth term.
Create an empty array of the specific length, initializing the first two values (
0and1). UseArray.reduce()to add values into the array, using the sum of the last two values, except for the first two. Uses a mathematical formula to calculate the length of the array required.const fibonacciUntilNum = num => { - let n = Math.ceil(Math.log(num * Math.sqrt(5) + 1 / 2) / Math.log((Math.sqrt(5) + 1) / 2)); - return Array.from({ length: n }).reduce( - (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i), - [] - ); -}; -fibonacciUntilNum(10); // [ 0, 1, 1, 2, 3, 5, 8 ]gcd
Calculates the greatest common divisor between two or more numbers/arrays.
The inner
_gcdfunction uses recursion. Base case is whenyequals0. In this case, returnx. Otherwise, return the GCD ofyand the remainder of the divisionx/y.const gcd = (...arr) => { const _gcd = (x, y) => (!y ? x : gcd(y, x % y)); - return [].concat(...arr).reduce((a, b) => _gcd(a, b)); + return [...arr].reduce((a, b) => _gcd(a, b)); };gcd(8, 36); // 4 +gcd(...[12, 8, 32]); // 4geometricProgression
Initializes an array containing the numbers in the specified range where
startandendare inclusive and the ratio between two terms isstep. Returns an error ifstepequals1.Use
Array.from(),Math.log()andMath.floor()to create an array of the desired length,Array.map()to fill with the desired values in a range. Omit the second argument,start, to use a default value of1. Omit the third argument,step, to use a default value of2.const geometricProgression = (end, start = 1, step = 2) => Array.from({ length: Math.floor(Math.log(end / start) / Math.log(step)) + 1 }).map( (v, i) => start * step ** i @@ -658,20 +603,6 @@ own individual rating by supplying it as the third argument. geometricProgression(256, 1, 4); // [1, 4, 16, 64, 256]hammingDistance
Calculates the Hamming distance between two values.
Use XOR operator (
^) to find the bit difference between the two numbers, convert to a binary string usingtoString(2). Count and return the number of1s in the string, usingmatch(/1/g).const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length;hammingDistance(2, 3); // 1 -howManyTimes
Returns the number of times
numcan be divided bydivisor(integer or fractional) without getting a fractional answer. Works for both negative and positive integers.If
divisoris-1or1returnInfinity. Ifdivisoris-0or0return0. Otherwise, keep dividingnumwithdivisorand incrementingi, while the result is an integer. Return the number of times the loop was executed,i.const howManyTimes = (num, divisor) => { - if (divisor === 1 || divisor === -1) return Infinity; - if (divisor === 0) return 0; - let i = 0; - while (Number.isInteger(num / divisor)) { - i++; - num = num / divisor; - } - return i; -}; -howManyTimes(100, 2); // 2 -howManyTimes(100, 2.5); // 2 -howManyTimes(100, 0); // 0 -howManyTimes(100, -1); // InfinityinRange
Checks if the given number falls within the given range.
Use arithmetic comparison to check if the given number is in the specified range. If the second parameter,
end, is not specified, the range is considered to be from0tostart.const inRange = (n, start, end = null) => { if (end && start > end) end = [start, (start = end)][0]; return end == null ? n >= 0 && n < start : n >= start && n < end; @@ -680,12 +611,6 @@ own individual rating by supplying it as the third argument. inRange(3, 4); // true inRange(2, 3, 5); // false inrange(3, 2); // false -isArmstrongNumber
Checks if the given number is an Armstrong number or not.
Convert 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, returntrueotherwisefalse.const isArmstrongNumber = digits => - (arr => arr.reduce((a, d) => a + parseInt(d) ** arr.length, 0) == digits)( - (digits + '').split('') - ); -isArmstrongNumber(1634); // true -isArmstrongNumber(56); // falseisDivisible
Checks if the first numeric argument is divisible by the second one.
Use the modulo operator (
%) to check if the remainder is equal to0.const isDivisible = (dividend, divisor) => dividend % divisor === 0;isDivisible(6, 3); // trueisEven
Returns
trueif the given number is even,falseotherwise.Checks whether a number is odd or even using the modulo (
%) operator. Returnstrueif the number is even,falseif the number is odd.const isEven = num => num % 2 === 0; @@ -696,13 +621,13 @@ own individual rating by supplying it as the third argument. return num >= 2; };isPrime(11); // true -lcm
Returns the least common multiple of two or more numbers/arrays.
Use the greatest common divisor (GCD) formula and
Math.abs()to determine the least common multiple. The GCD formula uses recursion.const lcm = (...arr) => { +lcm
Returns the least common multiple of two or more numbers.
Use the greatest common divisor (GCD) formula and
Math.abs()to determine the least common multiple. The GCD formula uses recursion.const lcm = (...arr) => { const gcd = (x, y) => (!y ? x : gcd(y, x % y)); const _lcm = (x, y) => x * y / gcd(x, y); - return [].concat(...arr).reduce((a, b) => _lcm(a, b)); + return [...arr].reduce((a, b) => _lcm(a, b)); };lcm(12, 7); // 84 -lcm([1, 3, 4], 5); // 60 +lcm(...[1, 3, 4, 5]); // 60luhnCheck
Implementation of the Luhn Algorithm used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, National Provider Identifier numbers etc.
Use
String.split(''),Array.reverse()andArray.map()in combination withparseInt()to obtain an array of digits. UseArray.splice(0,1)to obtain the last digit. UseArray.reduce()to implement the Luhn Algorithm. Returntrueifsumis divisible by10,falseotherwise.const luhnCheck = num => { let arr = (num + '') .split('') @@ -741,36 +666,15 @@ own individual rating by supplying it as the third argument.randomNumberInRange(2, 10); // 6.0211363285087005round
Rounds a number to a specified amount of digits.
Use
Math.round()and template literals to round the number to the specified number of digits. Omit the second argument,decimalsto round to an integer.const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);round(1.005, 2); // 1.01 -solveRPN
Solves the given mathematical expression in reverse polish notation. Throws 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.Use a dictionary,
OPERATORSto specify each operator's matching mathematical operation. UseString.replace()with a regular expression to replace^with**,String.split()to tokenize the string andArray.filter()to remove empty tokens. UseArray.forEach()to parse eachsymbol, evaluate it as a numeric value or operator and solve the mathematical expression. Numeric values are converted to floating point numbers and pushed to astack, while operators are evaluated using theOPERATORSdictionary and pop elements from thestackto apply operations.const solveRPN = rpn => { - const OPERATORS = { - '*': (a, b) => a * b, - '+': (a, b) => a + b, - '-': (a, b) => a - b, - '/': (a, b) => a / b, - '**': (a, b) => a ** b - }; - const [stack, solve] = [ - [], - rpn - .replace(/\^/g, '**') - .split(/\s+/g) - .filter(el => !/\s+/.test(el) && el !== '') - ]; - solve.forEach(symbol => { - if (!isNaN(parseFloat(symbol)) && isFinite(symbol)) { - stack.push(symbol); - } else if (Object.keys(OPERATORS).includes(symbol)) { - const [a, b] = [stack.pop(), stack.pop()]; - stack.push(OPERATORS[symbol](parseFloat(b), parseFloat(a))); - } else { - throw `${symbol} is not a recognized symbol`; - } - }); - if (stack.length === 1) return stack.pop(); - else throw `${rpn} is not a proper RPN. Please check it and try again`; +sbdm
Hashes the input string into a whole number.
Use
String.split('')andArray.reduce()to create a hash of the input string, utilizing bit shifting.const sdbm = str => { + let arr = str.split(''); + return arr.reduce( + (hashCode, currentVal) => + (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode), + 0 + ); }; -solveRPN('15 7 1 1 + - / 3 * 2 1 1 + + -'); // 5 -solveRPN('2 3 ^'); // 8 +console.log(sdbm('name')); // -3521204949standardDeviation
Returns the standard deviation of an array of numbers.
Use
Array.reduce()to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then determine the standard deviation. You can omit the second argument to get the sample standard deviation or set it totrueto get the population standard deviation.const standardDeviation = (arr, usePopulation = false) => { const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length; return Math.sqrt( @@ -780,8 +684,8 @@ own individual rating by supplying it as the third argument. };standardDeviation([10, 2, 38, 23, 38, 23, 21]); // 13.284434142114991 (sample) standardDeviation([10, 2, 38, 23, 38, 23, 21], true); // 12.29899614287479 (population) -sum
Returns the sum of two or more numbers/arrays.
Use
Array.reduce()to add each value to an accumulator, initialized with a value of0.const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); -sum([1, 2, 3, 4]); // 10 +sum
Returns the sum of two or more numbers/arrays.
Use
Array.reduce()to add each value to an accumulator, initialized with a value of0.const sum = (...arr) => [...arr].reduce((acc, val) => acc + val, 0); +sum(...[1, 2, 3, 4]); // 10sumPower
Returns the sum of the powers of all the numbers from
starttoend(both inclusive).Use
Array.fill()to create an array of all the numbers in the target range,Array.map()and the exponent operator (**) to raise them topowerandArray.reduce()to add them together. Omit the second argument,power, to use a default power of2. Omit the third argument,start, to use a default starting value of1.const sumPower = (end, power = 2, start = 1) => Array(end + 1 - start) .fill(0) @@ -825,7 +729,7 @@ console.log< (c ^ (crypto.randomBytes(1)[0] & (15 >> (c / 4)))).toString(16) );UUIDGeneratorNode(); // '79c7c136-60ee-40a2-beb2-856f1feabefc' -Object
cleanObj
Removes any properties except the ones specified from a JSON object.
Use
Object.keys()method to loop over given JSON object and deleting keys that are notincluded in given array. Also if you give it a special key (childIndicator) it will search deeply inside it to apply function to inner objects too.const cleanObj = (obj, keysToKeep = [], childIndicator) => { +Object
cleanObj
Removes any properties except the ones specified from a JSON object.
Use
Object.keys()method to loop over given JSON object and deleting keys that are not included in given array. If you pass a special key,childIndicator, it will search deeply apply the function to inner objects, too.const cleanObj = (obj, keysToKeep = [], childIndicator) => { Object.keys(obj).forEach(key => { if (key === childIndicator) { cleanObj(obj[key], keysToKeep, childIndicator); @@ -854,7 +758,7 @@ console.log<objectFromPairs([['a', 1], ['b', 2]]); // {a: 1, b: 2}objectToPairs
Creates an array of key-value pair arrays from an object.
Use
Object.keys()andArray.map()to iterate over the object's keys and produce an array with key-value pairs.const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]);objectToPairs({ a: 1, b: 2 }); // [['a',1],['b',2]]) -orderBy
Returns a sorted array of objects ordered by properties and orders.
Uses a custom implementation of sort, that reduces the props array argument with a default value of 0, it uses destructuring to swap the properties position depending on the order passed. If no orders array is passed it sort by 'asc' by default.
const orderBy = (arr, props, orders) => +orderBy
Returns a sorted array of objects ordered by properties and orders.
Uses
Array.sort(),Array.reduce()on thepropsarray with a default value of0, use array destructuring to swap the properties position depending on the order passed. If noordersarray is passed it sort by'asc'by default.const orderBy = (arr, props, orders) => [...arr].sort((a, b) => props.reduce((acc, prop, i) => { if (acc === 0) { @@ -867,19 +771,19 @@ console.log<const users = [{ name: 'fred', age: 48 }, { name: 'barney', age: 36 }, { name: 'fred', age: 40 }]; orderBy(users, ['name', 'age'], ['asc', 'desc']); // [{name: 'barney', age: 36}, {name: 'fred', age: 48}, {name: 'fred', age: 40}] orderBy(users, ['name', 'age']); // [{name: 'barney', age: 36}, {name: 'fred', age: 40}, {name: 'fred', age: 48}] -select
Retrieve a property that indicated by the selector from an object.
If the property does not exists returns
undefined.const select = (from, selector) => +select
Retrieve a property indicated by the selector from an object.
If the property does not exists returns
undefined.const select = (from, selector) => selector.split('.').reduce((prev, cur) => prev && prev[cur], from);const obj = { selector: { to: { val: 'val to select' } } }; select(obj, 'selector.to.val'); // 'val to select'shallowClone
Creates a shallow clone of an object.
Use
Object.assign()and an empty object ({}) to create a shallow clone of the original.const shallowClone = obj => Object.assign({}, obj);const a = { x: true, y: 1 }; const b = shallowClone(a); // a !== b -size
Get size of arrays, objects or strings.
Get type of
value(array,objectorstring). Uselengthproperty for arrays. Uselengthorsizevalue if available or number of keys for objects. Usesizeof aBlobobject created fromvaluefor strings.Split strings into array of characters with
split('')and return its length.const size = value => - Array.isArray(value) - ? value.length - : value && typeof value === 'object' - ? value.size || value.length || Object.keys(value).length - : typeof value === 'string' ? new Blob([value]).size : 0; +size
Get size of arrays, objects or strings.
Get type of
val(array,objectorstring). Uselengthproperty for arrays. Uselengthorsizevalue if available or number of keys for objects. Usesizeof aBlobobject created fromvalfor strings.Split strings into array of characters with
split('')and return its length.const size = val => + Array.isArray(val) + ? val.length + : val && typeof val === 'object' + ? val.size || val.length || Object.keys(val).length + : typeof val === 'string' ? new Blob([val]).size : 0;size([1, 2, 3, 4, 5]); // 5 size('size'); // 4 size({ one: 1, two: 2, three: 3 }); // 3 @@ -896,19 +800,19 @@ console.log< ); };anagrams('abc'); // ['abc','acb','bac','bca','cab','cba'] -byteSize
Returns the length of string.
Convert a given string to a
BlobObject and find itssize.const byteSize = str => new Blob([str]).size; +byteSize
Returns the length of a string in bytes.
Convert a given string to a
BlobObject and find itssize.const byteSize = str => new Blob([str]).size;byteSize('😀'); // 4 byteSize('Hello World'); // 11 -capitalize
Capitalizes the first letter of a string.
Use destructuring and
toUpperCase()to capitalize first letter,...restto get array of characters after first letter and thenArray.join('')to make it a string again. Omit thelowerRestparameter to keep the rest of the string intact, or set it totrueto convert to lowercase.const capitalize = ([first, ...rest], lowerRest = false) => +capitalize
Capitalizes the first letter of a string.
Use array destructuring and
String.toUpperCase()to capitalize first letter,...restto get array of characters after first letter and thenArray.join('')to make it a string again. Omit thelowerRestparameter to keep the rest of the string intact, or set it totrueto convert to lowercase.const capitalize = ([first, ...rest], lowerRest = false) => first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''));capitalize('fooBar'); // 'FooBar' capitalize('fooBar', true); // 'Foobar' -capitalizeEveryWord
Capitalizes the first letter of every word in a string.
Use
replace()to match the first character of each word andtoUpperCase()to capitalize it.const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); +capitalizeEveryWord
Capitalizes the first letter of every word in a string.
Use
String.replace()to match the first character of each word andString.toUpperCase()to capitalize it.const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());capitalizeEveryWord('hello world!'); // 'Hello World!'countVowels
Retuns
numberof vowels in provided string.Use a regular expression to count the number of vowels
(A, E, I, O, U)in astring.const countVowels = str => (str.match(/[aeiou]/gi) || []).length;countVowels('foobar'); // 3 countVowels('gym'); // 0 -escapeHTML
Escapes a string for use in HTML.
Use
String.replace()with a regex that matches the characters that need to be escaped, using a callback function to replace each character instance with its associated escaped character using a dictionary (object).const escapeHTML = str => +escapeHTML
Escapes a string for use in HTML.
Use
String.replace()with a regexp that matches the characters that need to be escaped, using a callback function to replace each character instance with its associated escaped character using a dictionary (object).const escapeHTML = str => str.replace( /[&<>'"]/g, tag => @@ -921,9 +825,9 @@ console.log< }[tag] || tag) );escapeHTML('<a href="#">Me & you</a>'); // '<a href="#">Me & you</a>' -escapeRegExp
Escapes a string to use in a regular expression.
Use
replace()to escape special characters.const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +escapeRegExp
Escapes a string to use in a regular expression.
Use
String.replace()to escape special characters.const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');escapeRegExp('(test)'); // \\(test\\) -fromCamelCase
Converts a string from camelcase.
Use
replace()to remove underscores, hyphens, and spaces and convert words to camelcase. Omit the second argument to use a default separator of_.const fromCamelCase = (str, separator = '_') => +fromCamelCase
Converts a string from camelcase.
Use
String.replace()to remove underscores, hyphens, and spaces and convert words to camelcase. Omit the second argument to use a defaultseparatorof_.const fromCamelCase = (str, separator = '_') => str .replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2') .replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2') @@ -935,12 +839,12 @@ console.log<isAbsoluteURL('https://google.com'); // true isAbsoluteURL('ftp://www.myserver.net'); // true isAbsoluteURL('/foo/bar'); // false -mask
Replaces all but the last
numof characters with the specified mask character.Use
String.slice()to grab the portion of the characters that need to be masked and useString.replace()with a regex to replace every character with the mask character. Concatenate the masked characters with the remaining unmasked portion of the string. Omit the second argument,num, to keep a default of4characters unmasked. Ifnumis negative, the unmasked characters will be at the start of the string. Omit the third argument,mask, to use a default character of'*'for the mask.const mask = (cc, num = 4, mask = '*') => +mask
Replaces all but the last
numof characters with the specified mask character.Use
String.slice()to grab the portion of the characters that need to be masked and useString.replace()with a regexp to replace every character with the mask character. Concatenate the masked characters with the remaining unmasked portion of the string. Omit the second argument,num, to keep a default of4characters unmasked. Ifnumis negative, the unmasked characters will be at the start of the string. Omit the third argument,mask, to use a default character of'*'for the mask.const mask = (cc, num = 4, mask = '*') => ('' + cc).slice(0, -num).replace(/./g, mask) + ('' + cc).slice(-num);mask(1234567890); // '******7890' mask(1234567890, 3); // '*******890' mask(1234567890, -4, '$'); // '1234$$$$$$' -palindrome
Returns
trueif the given string is a palindrome,falseotherwise.Convert string
toLowerCase()and usereplace()to remove non-alphanumeric characters from it. Then,split('')into individual characters,reverse(),join('')and compare to the original, unreversed string, after converting ittolowerCase().const palindrome = str => { +palindrome
Returns
trueif the given string is a palindrome,falseotherwise.Convert string
String.toLowerCase()and useString.replace()to remove non-alphanumeric characters from it. Then,String.split('')into individual characters,Array.reverse(),String.join('')and compare to the original, unreversed string, after converting itString.tolowerCase().const palindrome = str => { const s = str.toLowerCase().replace(/[\W_]/g, ''); return ( s === @@ -968,26 +872,19 @@ console.log< }; const autoPluralize = pluralize(PLURALS); autoPluralize(2, 'person'); // 'people' -repeatString
Repeats a string n times using
String.repeat()If no string is provided the default is
""and the default number of times is 2.const repeatString = (str = '', num = 2) => { - return num >= 0 ? str.repeat(num) : str; -}; -repeatString('abc', 3); // 'abcabcabc' -repeatString('abc'); // 'abcabc' -reverseString
Reverses a string.
Use
split('')andArray.reverse()to reverse the order of the characters in the string. Combine characters to get a string usingjoin('').const reverseString = str => - str - .split('') +reverseString
Reverses a string.
Use the spread operator (
...) andArray.reverse()to reverse the order of the characters in the string. Combine characters to get a string usingString.join('').+ + +const reverseString = str => + [..str] .reverse() .join('');reverseString('foobar'); // 'raboof' -sortCharactersInString
Alphabetically sorts the characters in a string.
Split the string using
split(''),Array.sort()utilizinglocaleCompare(), recombine usingjoin('').const sortCharactersInString = str => - str - .split('') - .sort((a, b) => a.localeCompare(b)) - .join(''); +sortCharactersInString
Alphabetically sorts the characters in a string.
Use the spread operator (
...),Array.sort()andString.localeCompare()to sort the characters instr, recombine usingString.join('').const sortCharactersInString = str => [...str].sort((a, b) => a.localeCompare(b)).join('');sortCharactersInString('cabbage'); // 'aabbceg'splitLines
Splits a multiline string into an array of lines.
Use
String.split()and a regular expression to match line breaks and create an array.const splitLines = str => str.split(/\r?\n/);splitLines('This\nis a\nmultiline\nstring.\n'); // ['This', 'is a', 'multiline', 'string' , ''] -toCamelCase
Converts a string to camelcase.
Break the string into words and combine them capitalizing the first letter of each word. For more detailed explanation of this Regex, visit this Site.
const toCamelCase = str => { +toCamelCase
Converts a string to camelcase.
Break the string into words and combine them capitalizing the first letter of each word, using a regexp.
const toCamelCase = str => { let s = str && str @@ -1000,7 +897,7 @@ console.log< toCamelCase('Some label that needs to be camelized'); // 'someLabelThatNeedsToBeCamelized' toCamelCase('some-javascript-property'); // 'someJavascriptProperty' toCamelCase('some-mixed_string with spaces_underscores-and-hyphens'); // 'someMixedStringWithSpacesUnderscoresAndHyphens' -toKebabCase
Converts a string to kebab case.
Break the string into words and combine them using
-as a separator. For more detailed explanation of this Regex, visit this Site.const toKebabCase = str => +toKebabCase
Converts a string to kebab case.
Break the string into words and combine them adding
-as a separator, using a regexp.const toKebabCase = str => str && str .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) @@ -1011,7 +908,7 @@ console.log< toKebabCase('some-mixed_string With spaces_underscores-and-hyphens'); // 'some-mixed-string-with-spaces-underscores-and-hyphens' toKebabCase('AllThe-small Things'); // "all-the-small-things" toKebabCase('IAmListeningToFMWhileLoadingDifferentURLOnMyBrowserAndAlsoEditingSomeXMLAndHTML'); // "i-am-listening-to-fm-while-loading-different-url-on-my-browser-and-also-editing-xml-and-html" -toSnakeCase
Converts a string to snake case.
Break the string into words and combine them using
_as a separator. For more detailed explanation of this Regex, visit this Site.const toSnakeCase = str => +toSnakeCase
Converts a string to snake case.
Break the string into words and combine them adding
_as a separator, using a regexp.const toSnakeCase = str => str && str .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) @@ -1022,7 +919,7 @@ console.log< toSnakeCase('some-mixed_string With spaces_underscores-and-hyphens'); // 'some_mixed_string_with_spaces_underscores_and_hyphens' toSnakeCase('AllThe-small Things'); // "all_the_smal_things" toSnakeCase('IAmListeningToFMWhileLoadingDifferentURLOnMyBrowserAndAlsoEditingSomeXMLAndHTML'); // "i_am_listening_to_fm_while_loading_different_url_on_my_browser_and_also_editing_some_xml_and_html" -truncateString
Truncates a string up to a specified length.
Determine if the string's
lengthis greater thannum. Return the string truncated to the desired length, with...appended to the end or the original string.const truncateString = (str, num) => +truncateString
Truncates a string up to a specified length.
Determine if the string's
lengthis greater thannum. Return the string truncated to the desired length, with'...'appended to the end or the original string.const truncateString = (str, num) => str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str;truncateString('boomerang', 7); // 'boom...'unescapeHTML
Unescapes escaped HTML characters.
Use
String.replace()with a regex that matches the characters that need to be unescaped, using a callback function to replace each escaped character instance with its associated unescaped character using a dictionary (object).const unescapeHTML = str => @@ -1038,59 +935,14 @@ console.log< }[tag] || tag) );unescapeHTML('<a href="#">Me & you</a>'); // '<a href="#">Me & you</a>' -words
Converts a given string into an array of words.
Use
String.split()with a supplied pattern (defaults to non-alpha as a regex) to convert to an array of strings. UseArray.filter()to remove any empty strings. Omit the second argument to use the default regex.const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); +words
Converts a given string into an array of words.
Use
String.split()with a supplied pattern (defaults to non-alpha as a regexp) to convert to an array of strings. UseArray.filter()to remove any empty strings. Omit the second argument to use the default regexp.const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean);words('I love javaScript!!'); // ["I", "love", "javaScript"] words('python, javaScript & coffee'); // ["python", "javaScript", "coffee"] -Utility
cloneRegExp
Clones a regular expression.
Use
new RegExp(),RegExp.sourceandRegExp.flagsto clone the given regular expression.const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); -const regExp = /lorem ipsum/gi; -const regExp2 = cloneRegExp(regExp); // /lorem ipsum/gi -coalesce
Returns the first non-null/undefined argument.
Use
Array.find()to return the first nonnull/undefinedargument.const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); -coalesce(null, undefined, '', NaN, 'Waldo'); // "" -coalesceFactory
Returns a customized coalesce function that returns the first argument that returns
truefrom the provided argument validation function.Use
Array.find()to return the first argument that returnstruefrom the provided argument validation function.const coalesceFactory = valid => (...args) => args.find(valid); -const customCoalesce = coalesceFactory(_ => ![null, undefined, '', NaN].includes(_)); -customCoalesce(undefined, null, NaN, '', 'Waldo'); // "Waldo" -extendHex
Extends a 3-digit color code to a 6-digit color code.
Use
Array.map(),split()andArray.join()to join the mapped array for converting a 3-digit RGB notated hexadecimal color-code to the 6-digit form.String.slice()is used to remove#from string start since it's added once.const extendHex = shortHex => - '#' + - shortHex - .slice(shortHex.startsWith('#') ? 1 : 0) - .split('') - .map(x => x + x) - .join(''); -extendHex('#03f'); // '#0033ff' -extendHex('05a'); // '#0055aa' -getType
Returns the native type of a value.
Returns lowercased constructor name of value, "undefined" or "null" if value is undefined or null
const getType = v => +Type
getType
Returns the native type of a value.
Returns lowercased constructor name of value,
"undefined"or"null"if value isundefinedornull.const getType = v => v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase();getType(new Set([1, 2, 3])); // 'Set' -getURLParameters
Returns an object containing the parameters of the current URL.
Use
match()with an appropriate regular expression to get all key-value pairs,Array.reduce()to map and combine them into a single object. Passlocation.searchas the argument to apply to the currenturl.const getURLParameters = url => - url - .match(/([^?=&]+)(=([^&]*))/g) - .reduce((a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a), {}); -getURLParameters('http://url.com/page?name=Adam&surname=Smith'); // {name: 'Adam', surname: 'Smith'} -hexToRGB
Converts a color code to a
rgb()orrgba()string if alpha value is provided.Use bitwise right-shift operator and mask bits with
&(and) operator to convert a hexadecimal color code (with or without prefixed with#) to a string with the RGB values. If it's 3-digit color code, first convert to 6-digit version. If an alpha value is provided alongside 6-digit hex, givergba()string in return.const hexToRGB = hex => { - let alpha = false, - h = hex.slice(hex.startsWith('#') ? 1 : 0); - if (h.length === 3) h = [...h].map(x => x + x).join(''); - else if (h.length === 8) alpha = true; - h = parseInt(h, 16); - return ( - 'rgb' + - (alpha ? 'a' : '') + - '(' + - (h >>> (alpha ? 24 : 16)) + - ', ' + - ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + - ', ' + - ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + - (alpha ? `, ${h & 0x000000ff}` : '') + - ')' - ); -}; -hexToRGB('#27ae60ff'); // 'rgba(39, 174, 96, 255)' -hexToRGB('27ae60'); // 'rgb(39, 174, 96)' -hexToRGB('#fff'); // 'rgb(255, 255, 255)' -isArray
Checks if the given argument is an array.
Use
Array.isArray()to check if a value is classified as an array.const isArray = val => !!val && Array.isArray(val); -isArray(null); // false -isArray([1]); // true +isArray
Checks if the given argument is an array.
Use
Array.isArray()to check if a value is classified as an array.const isArray = val => Array.isArray(val); +isArray([1]); // trueisArrayLike
Checks if the provided argument is array-like (i.e. is iterable).
Use the spread operator (
...) to check if the provided argument is iterable inside atry... catchblock and the comma operator (,) to return the appropriate value.const isArrayLike = val => { try { return [...val], true; @@ -1105,8 +957,7 @@ console.log<isBoolean(null); // false isBoolean(false); // trueisFunction
Checks if the given argument is a function.
Use
typeofto check if a value is classified as a function primitive.const isFunction = val => typeof val === 'function'; -isFunction(null); // false -isFunction('x'); // false +isFunction('x'); // false isFunction(x => x); // trueisNull
Returns
trueif the specified value isnull,falseotherwise.Use the strict equality operator to check if the value and of
valare equal tonull.const isNull = val => val === null;isNull(null); // true @@ -1146,6 +997,50 @@ console.log<isValidJSON('{"name":"Adam","age":20}'); // true isValidJSON('{"name":"Adam",age:"20"}'); // false isValidJSON(null); // true +Utility
cloneRegExp
Clones a regular expression.
Use
new RegExp(),RegExp.sourceandRegExp.flagsto clone the given regular expression.const cloneRegExp = regExp => new RegExp(regExp.source, regExp.flags); +const regExp = /lorem ipsum/gi; +const regExp2 = cloneRegExp(regExp); // /lorem ipsum/gi +coalesce
Returns the first non-null/undefined argument.
Use
Array.find()to return the first nonnull/undefinedargument.const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)); +coalesce(null, undefined, '', NaN, 'Waldo'); // "" +coalesceFactory
Returns a customized coalesce function that returns the first argument that returns
truefrom the provided argument validation function.Use
Array.find()to return the first argument that returnstruefrom the provided argument validation function.const coalesceFactory = valid => (...args) => args.find(valid); +const customCoalesce = coalesceFactory(_ => ![null, undefined, '', NaN].includes(_)); +customCoalesce(undefined, null, NaN, '', 'Waldo'); // "Waldo" +extendHex
Extends a 3-digit color code to a 6-digit color code.
Use
Array.map(),String.split()andArray.join()to join the mapped array for converting a 3-digit RGB notated hexadecimal color-code to the 6-digit form.Array.slice()is used to remove#from string start since it's added once.const extendHex = shortHex => + '#' + + shortHex + .slice(shortHex.startsWith('#') ? 1 : 0) + .split('') + .map(x => x + x) + .join(''); +extendHex('#03f'); // '#0033ff' +extendHex('05a'); // '#0055aa' +getURLParameters
Returns an object containing the parameters of the current URL.
Use
String.match()with an appropriate regular expression to get all key-value pairs,Array.reduce()to map and combine them into a single object. Passlocation.searchas the argument to apply to the currenturl.const getURLParameters = url => + url + .match(/([^?=&]+)(=([^&]*))/g) + .reduce((a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a), {}); +getURLParameters('http://url.com/page?name=Adam&surname=Smith'); // {name: 'Adam', surname: 'Smith'} +hexToRGBadvanced
Converts a color code to a
rgb()orrgba()string if alpha value is provided.Use bitwise right-shift operator and mask bits with
&(and) operator to convert a hexadecimal color code (with or without prefixed with#) to a string with the RGB values. If it's 3-digit color code, first convert to 6-digit version. If an alpha value is provided alongside 6-digit hex, givergba()string in return.const hexToRGB = hex => { + let alpha = false, + h = hex.slice(hex.startsWith('#') ? 1 : 0); + if (h.length === 3) h = [...h].map(x => x + x).join(''); + else if (h.length === 8) alpha = true; + h = parseInt(h, 16); + return ( + 'rgb' + + (alpha ? 'a' : '') + + '(' + + (h >>> (alpha ? 24 : 16)) + + ', ' + + ((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) + + ', ' + + ((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) + + (alpha ? `, ${h & 0x000000ff}` : '') + + ')' + ); +}; +hexToRGB('#27ae60ff'); // 'rgba(39, 174, 96, 255)' +hexToRGB('27ae60'); // 'rgb(39, 174, 96)' +hexToRGB('#fff'); // 'rgb(255, 255, 255)'prettyBytes
Converts a number in bytes to a human-readable string.
Use an array dictionary of units to be accessed based on the exponent. Use
Number.toPrecision()to truncate the number to a certain number of digits. Return the prettified string by building it up, taking into account the supplied options and whether it is negative or not. Omit the second argument,precision, to use a default precision of3digits. Omit the third argument,addSpace, to add space between the number and unit by default.const prettyBytes = (num, precision = 3, addSpace = true) => { const UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; if (Math.abs(num) < 1) return num + (addSpace ? ' ' : '') + UNITS[0]; @@ -1161,17 +1056,8 @@ console.log< return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n); };randomHexColorCode(); // "#e34155" -RGBToHex
Converts the values of RGB components to a color code.
Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (
<<) andtoString(16), thenpadStart(6,'0')to get a 6-digit hexadecimal value.const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); +RGBToHex
Converts the values of RGB components to a color code.
Convert given RGB parameters to hexadecimal string using bitwise left-shift operator (
<<) andtoString(16), thenString.padStart(6,'0')to get a 6-digit hexadecimal value.const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');RGBToHex(255, 165, 1); // 'ffa501' -sbdm
This algorithm is a simple hash-algorithm that hashes it input string
sinto a whole number.Use
split('')andArray.reduce()to create a hash of the input string, utilizing bit shifting.const sdbm = str => { - let arr = str.split(''); - return arr.reduce( - (hashCode, currentVal) => - (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode), - 0 - ); -}; -console.log(sdbm('name')); // -3521204949timeTaken
Measures the time taken by a function to execute.
Use
console.time()andconsole.timeEnd()to measure the difference between the start and end times to determine how long the callback took to execute.const timeTaken = callback => { console.time('timeTaken'); const r = callback(); @@ -1192,7 +1078,7 @@ console.log< : int + ordinals[3]; };toOrdinalSuffix('123'); // "123rd" -validateNumber
Returns
trueif the given value is a number,falseotherwise.Use
!isNaNin combination withparseFloat()to check if the argument is a number. UseisFinite()to check if the number is finite. UseNumber()to check if the coercion holds.const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; +validateNumber
Returns
trueif the given value is a number,falseotherwise.Use
!isNaN()in combination withparseFloat()to check if the argument is a number. UseisFinite()to check if the number is finite. UseNumber()to check if the coercion holds.const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n;validateNumber('10'); // trueyesNo
Returns
trueif the string isy/yesorfalseif the string isn/no.Use
RegExp.test()to check if the string evaluates toy/yesorn/no. Omit the second argument,defto set the default answer asno.const yesNo = (val, def = false) => /^(y|yes)$/i.test(val) ? true : /^(n|no)$/i.test(val) ? false : def; diff --git a/docs/mini.css b/docs/mini.css index 2a48b33cd..2a3784bf5 100644 --- a/docs/mini.css +++ b/docs/mini.css @@ -1 +1 @@ -:root{--f-col:#111;--f-col2:#444;--b-col:#f8f8f8;--b-col2:#f0f0f0;--blq-col:#f57c00;--pre-col:#1565c0;--br-col:#aaa;--br-col2:#ddd;--h-ratio:1.19;--u-m:.5rem;--u-p:.5rem;--u-br-r:.125rem;--a-l-col:#0277bd;--a-v-col:#01579b}html{font-size:16px}a,b,del,em,i,ins,q,span,strong,u{font-size:1em}html,*{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif;line-height:1.5;-webkit-text-size-adjust:100%}*{font-size:1rem}body{margin:0;color:var(--f-col);background:var(--b-col)}details{display:block}summary{display:list-item}abbr[title]{border-bottom:none;text-decoration:underline dotted}input{overflow:visible}img{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{line-height:1.2;margin:calc(1.5 * var(--u-m)) var(--u-m);font-weight:500}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:var(--f-col2);display:block;margin-top:-.25rem}h1{font-size:calc(1rem * var(--h-ratio) * var(--h-ratio) * var(--h-ratio) * var(--h-ratio))}h2{font-size:calc(1rem * var(--h-ratio) * var(--h-ratio) * var(--h-ratio))}h3{font-size:calc(1rem * var(--h-ratio) * var(--h-ratio))}h4{font-size:calc(1rem * var(--h-ratio))}h5{font-size:1rem}h6{font-size:calc(1rem / var(--h-ratio))}p{margin:var(--u-m)}ol,ul{margin:var(--u-m);padding-left:calc(2 * var(--u-m))}b,strong{font-weight:700}hr{box-sizing:content-box;border:0;line-height:1.25em;margin:var(--u-m);height:.0625rem;background:linear-gradient(to right, transparent, var(--br-col) 20%, var(--br-col) 80%, transparent)}blockquote{display:block;position:relative;font-style:italic;color:var(--f-col2);margin:var(--u-m);padding:calc(3 * var(--u-p));border:.0625rem solid var(--br-col2);border-left:.375rem solid var(--blq-col);border-radius:0 var(--u-br-r) var(--u-br-r) 0}blockquote:before{position:absolute;top:calc(0rem - var(--u-p));left:0;font-family:sans-serif;font-size:3rem;font-weight:700;content:"\201c";color:var(--blq-col)}blockquote[cite]:after{font-style:normal;font-size:.75em;font-weight:700;content:"\a— " attr(cite);white-space:pre}code,kbd,pre,samp{font-family:Menlo, Consolas, monospace;font-size:.85em}code{background:var(--b-col2);border-radius:var(--u-br-r);padding:calc(var(--u-p) / 4) calc(var(--u-p) / 2)}kbd{background:var(--f-col);color:var(--b-col);border-radius:var(--u-br-r);padding:calc(var(--u-p) / 4) calc(var(--u-p) / 2)}pre{overflow:auto;background:var(--b-col2);padding:calc(1.5 * var(--u-p));margin:var(--u-m);border:.0625rem solid var(--br-col2);border-left:.25rem solid var(--pre-col);border-radius:0 var(--u-br-r) var(--u-br-r) 0}sup,sub,code,kbd{line-height:0;position:relative;vertical-align:baseline}small,sup,sub,figcaption{font-size:.75em}sup{top:-.5em}sub{bottom:-.25em}figure{margin:var(--u-m)}figcaption{color:var(--f-col2)}a{text-decoration:none}a:link{color:var(--a-l-col)}a:visited{color:var(--a-v-col)}a:hover,a:focus{text-decoration:underline}.container{margin:0 auto;padding:0 calc(1.5 * var(--u-p))}.row{box-sizing:border-box;display:flex;flex:0 1 auto;flex-flow:row wrap}.col-sm,[class^='col-sm-'],[class^='col-sm-o-']{flex:0 0 auto;padding:0 calc(var(--u-p) / 2)}.col-sm{max-width:100%;flex-grow:1;flex-basis:0}.col-sm-1{max-width:8.33333%;flex-basis:8.33333%}.col-sm-o-0{margin-left:0}.col-sm-2{max-width:16.66667%;flex-basis:16.66667%}.col-sm-o-1{margin-left:8.33333%}.col-sm-3{max-width:25%;flex-basis:25%}.col-sm-o-2{margin-left:16.66667%}.col-sm-4{max-width:33.33333%;flex-basis:33.33333%}.col-sm-o-3{margin-left:25%}.col-sm-5{max-width:41.66667%;flex-basis:41.66667%}.col-sm-o-4{margin-left:33.33333%}.col-sm-6{max-width:50%;flex-basis:50%}.col-sm-o-5{margin-left:41.66667%}.col-sm-7{max-width:58.33333%;flex-basis:58.33333%}.col-sm-o-6{margin-left:50%}.col-sm-8{max-width:66.66667%;flex-basis:66.66667%}.col-sm-o-7{margin-left:58.33333%}.col-sm-9{max-width:75%;flex-basis:75%}.col-sm-o-8{margin-left:66.66667%}.col-sm-10{max-width:83.33333%;flex-basis:83.33333%}.col-sm-o-9{margin-left:75%}.col-sm-11{max-width:91.66667%;flex-basis:91.66667%}.col-sm-o-10{margin-left:83.33333%}.col-sm-12{max-width:100%;flex-basis:100%}.col-sm-o-11{margin-left:91.66667%}.col-sm-n{order:initial}.col-sm-f{order:-999}.col-sm-l{order:999}@media screen and (min-width: 768px){.col-md,[class^='col-md-'],[class^='col-md-o-']{flex:0 0 auto;padding:0 calc(var(--u-p) / 2)}.col-md{max-width:100%;flex-grow:1;flex-basis:0}.col-md-1{max-width:8.33333%;flex-basis:8.33333%}.col-md-o-0{margin-left:0}.col-md-2{max-width:16.66667%;flex-basis:16.66667%}.col-md-o-1{margin-left:8.33333%}.col-md-3{max-width:25%;flex-basis:25%}.col-md-o-2{margin-left:16.66667%}.col-md-4{max-width:33.33333%;flex-basis:33.33333%}.col-md-o-3{margin-left:25%}.col-md-5{max-width:41.66667%;flex-basis:41.66667%}.col-md-o-4{margin-left:33.33333%}.col-md-6{max-width:50%;flex-basis:50%}.col-md-o-5{margin-left:41.66667%}.col-md-7{max-width:58.33333%;flex-basis:58.33333%}.col-md-o-6{margin-left:50%}.col-md-8{max-width:66.66667%;flex-basis:66.66667%}.col-md-o-7{margin-left:58.33333%}.col-md-9{max-width:75%;flex-basis:75%}.col-md-o-8{margin-left:66.66667%}.col-md-10{max-width:83.33333%;flex-basis:83.33333%}.col-md-o-9{margin-left:75%}.col-md-11{max-width:91.66667%;flex-basis:91.66667%}.col-md-o-10{margin-left:83.33333%}.col-md-12{max-width:100%;flex-basis:100%}.col-md-o-11{margin-left:91.66667%}.col-md-n{order:initial}.col-md-f{order:-999}.col-md-l{order:999}}@media screen and (min-width: 1280px){.col-lg,[class^='col-lg-'],[class^='col-lg-o-']{flex:0 0 auto;padding:0 calc(var(--u-p) / 2)}.col-lg{max-width:100%;flex-grow:1;flex-basis:0}.col-lg-1{max-width:8.33333%;flex-basis:8.33333%}.col-lg-o-0{margin-left:0}.col-lg-2{max-width:16.66667%;flex-basis:16.66667%}.col-lg-o-1{margin-left:8.33333%}.col-lg-3{max-width:25%;flex-basis:25%}.col-lg-o-2{margin-left:16.66667%}.col-lg-4{max-width:33.33333%;flex-basis:33.33333%}.col-lg-o-3{margin-left:25%}.col-lg-5{max-width:41.66667%;flex-basis:41.66667%}.col-lg-o-4{margin-left:33.33333%}.col-lg-6{max-width:50%;flex-basis:50%}.col-lg-o-5{margin-left:41.66667%}.col-lg-7{max-width:58.33333%;flex-basis:58.33333%}.col-lg-o-6{margin-left:50%}.col-lg-8{max-width:66.66667%;flex-basis:66.66667%}.col-lg-o-7{margin-left:58.33333%}.col-lg-9{max-width:75%;flex-basis:75%}.col-lg-o-8{margin-left:66.66667%}.col-lg-10{max-width:83.33333%;flex-basis:83.33333%}.col-lg-o-9{margin-left:75%}.col-lg-11{max-width:91.66667%;flex-basis:91.66667%}.col-lg-o-10{margin-left:83.33333%}.col-lg-12{max-width:100%;flex-basis:100%}.col-lg-o-11{margin-left:91.66667%}.col-lg-n{order:initial}.col-lg-f{order:-999}.col-lg-l{order:999}}:root{--cd-b-col:#f8f8f8;--cd-f-col:#111;--cd-br-col:#ddd}.card{display:flex;flex-direction:column;justify-content:space-between;align-self:center;position:relative;width:100%;background:var(--cd-b-col);color:var(--cd-f-col);border:.0625rem solid var(--cd-br-col);border-radius:var(--u-br-r);margin:var(--u-m);overflow:hidden}@media screen and (min-width: 320px){.card{max-width:320px}}.card>.section{background:var(--cd-b-col);color:var(--cd-f-col);box-sizing:border-box;margin:0;border:0;border-radius:0;border-bottom:.0625rem solid var(--cd-br-col);padding:var(--u-p);width:100%}.card>.section.media{height:200px;padding:0;-o-object-fit:cover;object-fit:cover}.card>.section:last-child{border-bottom:0}.card.fluid{max-width:100%;width:auto}.card>.section.double-padded{padding:calc(1.5 * var(--u-p))}.card{box-shadow:0 1.25rem 2.5rem -0.625rem rgba(0,32,64,0.1)}.card>h3.section.double-padded{padding:calc(3 * var(--u-p))}.card>.section.double-padded>p{margin:var(--u-m) calc(var(--u-m) / 2)}.card+.card{margin-top:calc(5 * var(--u-m))}:root{--frm-b-col:#f0f0f0;--frm-f-col:#111;--frm-br-col:#ddd;--in-b-col:#f8f8f8;--in-f-col:#111;--in-br-col:#ddd;--in-fc-col:#0288d1;--in-inv-col:#d32f2f;--btn-b-col:#e2e2e2;--btn-h-b-col:#dcdcdc;--btn-f-col:#212121;--btn-br-col:transparent;--btn-h-br-col:transparent;--btn-grp-br-col:rgba(124,124,124,0.54)}form{background:var(--frm-b-col);color:var(--frm-f-col);border:.0625rem solid var(--frm-br-col);border-radius:var(--u-br-r);margin:var(--u-m);padding:calc(2 * var(--u-p)) var(--u-p)}fieldset{border:.0625rem solid var(--frm-br-col);border-radius:var(--u-br-r);margin:calc(var(--u-m) / 4);padding:var(--u-p)}legend{box-sizing:border-box;display:table;max-width:100%;white-space:normal;font-weight:700;padding:calc(var(--u-p) / 2)}label{padding:calc(var(--u-p) / 2) var(--u-p)}.input-group{display:inline-block}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input:not([type]),[type="text"],[type="email"],[type="number"],[type="search"],[type="password"],[type="url"],[type="tel"],[type="checkbox"],[type="radio"],textarea,select{box-sizing:border-box;background:var(--in-b-col);color:var(--in-f-col);border:.0625rem solid var(--in-br-col);border-radius:var(--u-br-r);margin:calc(var(--u-m) / 2);padding:var(--u-p) calc(1.5 * var(--u-p))}input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus,textarea:hover,textarea:focus,select:hover,select:focus{border-color:var(--in-fc-col);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid,textarea:invalid,textarea:focus:invalid,select:invalid,select:focus:invalid{border-color:var(--in-inv-col);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly],textarea[readonly],select[readonly]{background:var(--b-col2)}select{max-width:100%}option{overflow:hidden;text-overflow:ellipsis}[type="checkbox"],[type="radio"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;height:calc(1rem + var(--u-p) / 2);width:calc(1rem + var(--u-p) / 2);vertical-align:text-bottom;padding:0;flex-basis:calc(1rem + var(--u-p) / 2) !important;flex-grow:0 !important}[type="checkbox"]:checked:before,[type="radio"]:checked:before{position:absolute}[type="checkbox"]:checked:before{content:'\2713';font-family:sans-serif;font-size:calc(1rem + var(--u-p) / 2);top:calc(0rem - var(--u-p));left:calc(var(--u-p) / 4)}[type="radio"]{border-radius:100%}[type="radio"]:checked:before{border-radius:100%;content:'';top:calc(.0625rem + var(--u-p) / 2);left:calc(.0625rem + var(--u-p) / 2);background:var(--in-f-col);width:0.5rem;height:0.5rem}:placeholder-shown{color:var(--in-f-col)}::-ms-placeholder{color:var(--in-f-col);opacity:0.54}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button{overflow:visible;text-transform:none}button,[type="button"],[type="submit"],[type="reset"],a.button,label.button,.button,a[role="button"],label[role="button"],[role="button"]{display:inline-block;background:var(--btn-b-col);color:var(--btn-f-col);border:.0625rem solid var(--btn-br-col);border-radius:var(--u-br-r);padding:var(--u-p) calc(1.5 * var(--u-p));margin:var(--u-m);text-decoration:none;cursor:pointer;transition:background 0.3s}button:hover,button:focus,[type="button"]:hover,[type="button"]:focus,[type="submit"]:hover,[type="submit"]:focus,[type="reset"]:hover,[type="reset"]:focus,a.button:hover,a.button:focus,label.button:hover,label.button:focus,.button:hover,.button:focus,a[role="button"]:hover,a[role="button"]:focus,label[role="button"]:hover,label[role="button"]:focus,[role="button"]:hover,[role="button"]:focus{background:var(--btn-h-b-col);border-color:var(--btn-h-br-col)}input:disabled,input[disabled],textarea:disabled,textarea[disabled],select:disabled,select[disabled],button:disabled,button[disabled],.button:disabled,.button[disabled],[role="button"]:disabled,[role="button"][disabled]{cursor:not-allowed;opacity:.75}.button-group{display:flex;border:.0625rem solid var(--btn-grp-br-col);border-radius:var(--u-br-r);margin:var(--u-m)}.button-group>button,.button-group [type="button"],.button-group>[type="submit"],.button-group>[type="reset"],.button-group>.button,.button-group>[role="button"]{margin:0;max-width:100%;flex:1 1 auto;text-align:center;border:0;border-radius:0;box-shadow:none}.button-group>:not(:first-child){border-left:.0625rem solid var(--btn-grp-br-col)}@media screen and (max-width: 767px){.button-group{flex-direction:column}.button-group>:not(:first-child){border:0;border-top:.0625rem solid var(--btn-grp-br-col)}}button.primary,[type="button"].primary,[type="submit"].primary,[type="reset"].primary,.button.primary,[role="button"].primary{--btn-b-col:#1976d2;--btn-f-col:#f8f8f8}button.primary:hover,button.primary:focus,[type="button"].primary:hover,[type="button"].primary:focus,[type="submit"].primary:hover,[type="submit"].primary:focus,[type="reset"].primary:hover,[type="reset"].primary:focus,.button.primary:hover,.button.primary:focus,[role="button"].primary:hover,[role="button"].primary:focus{--btn-h-b-col:#1565c0}:root{--hd-b-col:#f8f8f8;--hd-hv-b-col:#f0f0f0;--hd-f-col:#444;--hd-br-col:#ddd;--nv-b-col:#f8f8f8;--nv-hv-b-col:#f0f0f0;--nv-f-col:#444;--nv-br-col:#ddd;--nv-ln-col:#0277bd;--ft-f-col:#444;--ft-b-col:#f8f8f8;--ft-br-col:#ddd;--ft-ln-col:#0277bd;--dr-b-col:#f8f8f8;--dr-hv-b-col:#f0f0f0;--dr-br-col:#ddd;--dr-cl-col:#444}header{height:3.1875rem;background:var(--hd-b-col);color:var(--hd-f-col);border-bottom:.0625rem solid var(--hd-br-col);padding:calc(var(--u-p) / 4) 0;white-space:nowrap;overflow-x:auto;overflow-y:hidden}header.row{box-sizing:content-box}header .logo{color:var(--hd-f-col);font-size:1.75rem;padding:var(--u-p) calc(2 * var(--u-p));text-decoration:none}header button,header [type="button"],header .button,header [role="button"]{box-sizing:border-box;position:relative;top:calc(0rem - var(--u-p) / 4);height:calc(3.1875rem + var(--u-p) / 2);background:var(--hd-b-col);line-height:calc(3.1875rem - var(--u-p) * 1.5);text-align:center;color:var(--hd-f-col);border:0;border-radius:0;margin:0;text-transform:uppercase}header button:hover,header button:focus,header [type="button"]:hover,header [type="button"]:focus,header .button:hover,header .button:focus,header [role="button"]:hover,header [role="button"]:focus{background:var(--hd-hv-b-col)}nav{background:var(--nv-b-col);color:var(--nv-f-col);border:.0625rem solid var(--nv-br-col);border-radius:var(--u-br-r);margin:var(--u-m)}nav *{padding:var(--u-p) calc(1.5 * var(--u-p))}nav a,nav a:visited{display:block;color:var(--nv-ln-col);border-radius:var(--u-br-r);transition:background 0.3s}nav a:hover,nav a:focus,nav a:visited:hover,nav a:visited:focus{text-decoration:none;background:var(--nv-hv-b-col)}nav .sublink-1{position:relative;margin-left:calc(2 * var(--u-p))}nav .sublink-1:before{position:absolute;left:calc(var(--u-p) - 1 * var(--u-p));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nv-br-col);border-left:0}footer{background:var(--ft-b-col);color:var(--ft-f-col);border-top:.0625rem solid var(--ft-br-col);padding:calc(2 * var(--u-p)) var(--u-p);font-size:.875rem}footer a,footer a:visited{color:var(--ft-ln-col)}header.sticky{position:-webkit-sticky;position:sticky;z-index:1101;top:0}footer.sticky{position:-webkit-sticky;position:sticky;z-index:1101;bottom:0}.drawer-toggle:before{display:inline-block;position:relative;vertical-align:bottom;content:'\00a0\2261\00a0';font-family:sans-serif;font-size:1.5em}@media screen and (min-width: 768px){.drawer-toggle:not(.persistent){display:none}}[type="checkbox"].drawer{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].drawer+*{display:block;box-sizing:border-box;position:fixed;top:0;width:320px;height:100vh;overflow-y:auto;background:var(--dr-b-col);border:.0625rem solid var(--dr-br-col);border-radius:0;margin:0;z-index:1110;left:-320px;transition:left 0.3s}[type="checkbox"].drawer+* .drawer-close{position:absolute;top:var(--u-m);right:var(--u-m);z-index:1111;width:2rem;height:2rem;border-radius:var(--u-br-r);padding:var(--u-p);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].drawer+* .drawer-close:before{display:block;content:'\00D7';color:var(--dr-cl-col);position:relative;font-family:sans-serif;font-size:2rem;line-height:1;text-align:center}[type="checkbox"].drawer+* .drawer-close:hover,[type="checkbox"].drawer+* .drawer-close:focus{background:var(--dr-hv-b-col)}@media screen and (max-width: 320px){[type="checkbox"].drawer+*{width:100%}}[type="checkbox"].drawer:checked+*{left:0}@media screen and (min-width: 768px){[type="checkbox"].drawer:not(.persistent)+*{position:static;height:100%;z-index:1100}[type="checkbox"].drawer:not(.persistent)+* .drawer-close{display:none}}:root{--mrk-b-col:#0277bd;--mrk-f-col:#fafafa}mark{background:var(--mrk-b-col);color:var(--mrk-f-col);font-size:.95em;line-height:1em;border-radius:var(--u-br-r);padding:calc(var(--u-p) / 4) calc(var(--u-p) / 2)}mark.inline-block{display:inline-block;font-size:1em;line-height:1.5;padding:calc(var(--u-p) / 2) var(--u-p)}:root{--tst-b-col:#212121;--tst-f-col:#fafafa}.toast{position:fixed;bottom:calc(var(--u-m) * 3);left:50%;transform:translate(-50%, -50%);z-index:1111;color:var(--tst-f-col);background:var(--tst-b-col);border-radius:calc(var(--u-br-r) * 16);padding:var(--u-p) calc(var(--u-p) * 3)}.toast{bottom:calc(var(--u-m) / 2);opacity:1;transition:opacity 0.3s ease-in-out}mark.secondary{--mrk-b-col:#d32f2f}mark.tertiary{--mrk-b-col:#308732}mark.tag{padding:calc(var(--u-p)/2) var(--u-p);border-radius:1em}code,pre,kbd,code *,pre *,kbd *,code[class*="language-"],pre[class*="language-"]{font-family:Menlo, Consolas, monospace !important}pre{border:0.0625rem solid var(--br-col2);border-radius:var(--u-br-r)}.group{position:relative;margin-top:2em;margin-bottom:1em}.search{font-size:0.875rem;margin-top:-0.1em;display:block;width:100%;border:none;border-bottom:.0625rem solid var(--nv-ln-col)}.search:focus{outline:none}label#search-label{color:var(--nv-ln-col);font-size:1.125rem;font-weight:400;position:absolute;left:0.3125rem;top:0.625rem}.search:focus ~ label#search-label,.search:valid ~ label#search-label{top:-1.25rem;font-size:0.875rem;color:var(--nv-ln-col)}label#menu-toggle{width:3.4375rem}header h1.logo{margin-top:-0.8rem;text-align:center}header h1.logo a{text-decoration:none;color:#111}header #title{position:relative;top:-1rem}@media screen and (max-width: 500px){header #title{font-size:1rem;display:block}}header h1 small{display:block;font-size:0.875rem;color:#888;margin-top:-0.8rem}@media screen and (max-width: 768px){header h1 small{font-size:0.75rem}}@media screen and (max-width: 600px){header h1 small{font-size:0.625rem}}@media screen and (max-width: 500px){header h1 small{font-size:0.5rem;margin-top:-1.2rem}}label#menu-toggle{position:absolute;left:0.5rem;top:0.5rem;width:3.4375rem}main{padding:0}:root{--clps-lbl-b-col:#e8e8e8;--clps-lbl-f-col:#212121;--clps-lbl-h-b-col:#f0f0f0;--clps-sel-lbl-b-col:#ececec;--clps-br-col:#ddd;--clps-cnt-b-col:#fafafa;--clps-sel-lbl-br-col:#0277bd}label.collapse{width:100%;display:inline-block;cursor:pointer;box-sizing:border-box;transition:background 0.3s;color:var(--clps-lbl-f-col);background:var(--clps-lbl-b-col);border:.0625rem solid var(--clps-br-col);padding:calc(1.5 * var(--u-p));border-radius:var(--u-br-r)}label.collapse:hover,label.collapse:focus{background:var(--clps-lbl-h-b-col)}label.collapse+pre{box-sizing:border-box;height:0;max-height:1px;overflow:auto;margin:0;border:0;padding:0;transition:max-height 0.3s}label.collapse.toggled{background:var(--clps-sel-lbl-b-col);border-bottom-color:var(--clps-sel-lbl-br-col);border-bottom-left-radius:0;border-bottom-right-radius:0}label.collapse.toggled+pre{border-top-left-radius:0;border-top-right-radius:0;position:relative;width:100%;height:auto;border:.0625rem solid var(--clps-br-col);border-top:0;padding:calc(2 * var(--u-p));max-height:400px}button.primary.clipboard-copy{width:100%;margin-left:0}button.primary.clipboard-copy>img{vertical-align:bottom}code[class*="language-"],pre[class*="language-"]{color:black;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.8;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-hypens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*="language-"]{padding:calc(2 * var(--u-p));overflow:auto;margin:var(--u-m) 0}pre[class*="language-"]::-moz-selection,pre[class*="language-"] ::-moz-selection,code[class*="language-"]::-moz-selection,code[class*="language-"] ::-moz-selection{background:#b3d4fc}pre[class*="language-"]::selection,pre[class*="language-"] ::selection,code[class*="language-"]::selection,code[class*="language-"] ::selection{background:#b3d4fc}:not(pre)>code[class*="language-"]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#7a8490}.token.punctuation{color:#666}.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.constant,.token.symbol,.token.deleted,.token.function{color:#005cc5}.token.number{color:#8132b5}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#007e5d}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string,.token.atrule,.token.attr-value,.token.keyword{color:#d73a49}.token.regex{color:#007972}.token.important,.token.variable{color:#e90}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help} +:root{--f-col:#111;--f-col2:#444;--b-col:#f8f8f8;--b-col2:#f0f0f0;--blq-col:#f57c00;--pre-col:#1565c0;--br-col:#aaa;--br-col2:#ddd;--h-ratio:1.19;--u-m:.5rem;--u-p:.5rem;--u-br-r:.125rem;--a-l-col:#0277bd;--a-v-col:#01579b}html{font-size:16px}a,b,del,em,i,ins,q,span,strong,u{font-size:1em}html,*{font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", Helvetica, sans-serif;line-height:1.5;-webkit-text-size-adjust:100%}*{font-size:1rem}body{margin:0;color:var(--f-col);background:var(--b-col)}details{display:block}summary{display:list-item}abbr[title]{border-bottom:none;text-decoration:underline dotted}input{overflow:visible}img{max-width:100%;height:auto}h1,h2,h3,h4,h5,h6{line-height:1.2;margin:calc(1.5 * var(--u-m)) var(--u-m);font-weight:500}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{color:var(--f-col2);display:block;margin-top:-.25rem}h1{font-size:calc(1rem * var(--h-ratio) * var(--h-ratio) * var(--h-ratio) * var(--h-ratio))}h2{font-size:calc(1rem * var(--h-ratio) * var(--h-ratio) * var(--h-ratio))}h3{font-size:calc(1rem * var(--h-ratio) * var(--h-ratio))}h4{font-size:calc(1rem * var(--h-ratio))}h5{font-size:1rem}h6{font-size:calc(1rem / var(--h-ratio))}p{margin:var(--u-m)}ol,ul{margin:var(--u-m);padding-left:calc(2 * var(--u-m))}b,strong{font-weight:700}hr{box-sizing:content-box;border:0;line-height:1.25em;margin:var(--u-m);height:.0625rem;background:linear-gradient(to right, transparent, var(--br-col) 20%, var(--br-col) 80%, transparent)}blockquote{display:block;position:relative;font-style:italic;color:var(--f-col2);margin:var(--u-m);padding:calc(3 * var(--u-p));border:.0625rem solid var(--br-col2);border-left:.375rem solid var(--blq-col);border-radius:0 var(--u-br-r) var(--u-br-r) 0}blockquote:before{position:absolute;top:calc(0rem - var(--u-p));left:0;font-family:sans-serif;font-size:3rem;font-weight:700;content:"\201c";color:var(--blq-col)}blockquote[cite]:after{font-style:normal;font-size:.75em;font-weight:700;content:"\a— " attr(cite);white-space:pre}code,kbd,pre,samp{font-family:Menlo, Consolas, monospace;font-size:.85em}code{background:var(--b-col2);border-radius:var(--u-br-r);padding:calc(var(--u-p) / 4) calc(var(--u-p) / 2)}kbd{background:var(--f-col);color:var(--b-col);border-radius:var(--u-br-r);padding:calc(var(--u-p) / 4) calc(var(--u-p) / 2)}pre{overflow:auto;background:var(--b-col2);padding:calc(1.5 * var(--u-p));margin:var(--u-m);border:.0625rem solid var(--br-col2);border-left:.25rem solid var(--pre-col);border-radius:0 var(--u-br-r) var(--u-br-r) 0}sup,sub,code,kbd{line-height:0;position:relative;vertical-align:baseline}small,sup,sub,figcaption{font-size:.75em}sup{top:-.5em}sub{bottom:-.25em}figure{margin:var(--u-m)}figcaption{color:var(--f-col2)}a{text-decoration:none}a:link{color:var(--a-l-col)}a:visited{color:var(--a-v-col)}a:hover,a:focus{text-decoration:underline}.container{margin:0 auto;padding:0 calc(1.5 * var(--u-p))}.row{box-sizing:border-box;display:flex;flex:0 1 auto;flex-flow:row wrap}.col-sm,[class^='col-sm-'],[class^='col-sm-o-']{flex:0 0 auto;padding:0 calc(var(--u-p) / 2)}.col-sm{max-width:100%;flex-grow:1;flex-basis:0}.col-sm-1{max-width:8.33333%;flex-basis:8.33333%}.col-sm-o-0{margin-left:0}.col-sm-2{max-width:16.66667%;flex-basis:16.66667%}.col-sm-o-1{margin-left:8.33333%}.col-sm-3{max-width:25%;flex-basis:25%}.col-sm-o-2{margin-left:16.66667%}.col-sm-4{max-width:33.33333%;flex-basis:33.33333%}.col-sm-o-3{margin-left:25%}.col-sm-5{max-width:41.66667%;flex-basis:41.66667%}.col-sm-o-4{margin-left:33.33333%}.col-sm-6{max-width:50%;flex-basis:50%}.col-sm-o-5{margin-left:41.66667%}.col-sm-7{max-width:58.33333%;flex-basis:58.33333%}.col-sm-o-6{margin-left:50%}.col-sm-8{max-width:66.66667%;flex-basis:66.66667%}.col-sm-o-7{margin-left:58.33333%}.col-sm-9{max-width:75%;flex-basis:75%}.col-sm-o-8{margin-left:66.66667%}.col-sm-10{max-width:83.33333%;flex-basis:83.33333%}.col-sm-o-9{margin-left:75%}.col-sm-11{max-width:91.66667%;flex-basis:91.66667%}.col-sm-o-10{margin-left:83.33333%}.col-sm-12{max-width:100%;flex-basis:100%}.col-sm-o-11{margin-left:91.66667%}.col-sm-n{order:initial}.col-sm-f{order:-999}.col-sm-l{order:999}@media screen and (min-width: 768px){.col-md,[class^='col-md-'],[class^='col-md-o-']{flex:0 0 auto;padding:0 calc(var(--u-p) / 2)}.col-md{max-width:100%;flex-grow:1;flex-basis:0}.col-md-1{max-width:8.33333%;flex-basis:8.33333%}.col-md-o-0{margin-left:0}.col-md-2{max-width:16.66667%;flex-basis:16.66667%}.col-md-o-1{margin-left:8.33333%}.col-md-3{max-width:25%;flex-basis:25%}.col-md-o-2{margin-left:16.66667%}.col-md-4{max-width:33.33333%;flex-basis:33.33333%}.col-md-o-3{margin-left:25%}.col-md-5{max-width:41.66667%;flex-basis:41.66667%}.col-md-o-4{margin-left:33.33333%}.col-md-6{max-width:50%;flex-basis:50%}.col-md-o-5{margin-left:41.66667%}.col-md-7{max-width:58.33333%;flex-basis:58.33333%}.col-md-o-6{margin-left:50%}.col-md-8{max-width:66.66667%;flex-basis:66.66667%}.col-md-o-7{margin-left:58.33333%}.col-md-9{max-width:75%;flex-basis:75%}.col-md-o-8{margin-left:66.66667%}.col-md-10{max-width:83.33333%;flex-basis:83.33333%}.col-md-o-9{margin-left:75%}.col-md-11{max-width:91.66667%;flex-basis:91.66667%}.col-md-o-10{margin-left:83.33333%}.col-md-12{max-width:100%;flex-basis:100%}.col-md-o-11{margin-left:91.66667%}.col-md-n{order:initial}.col-md-f{order:-999}.col-md-l{order:999}}@media screen and (min-width: 1280px){.col-lg,[class^='col-lg-'],[class^='col-lg-o-']{flex:0 0 auto;padding:0 calc(var(--u-p) / 2)}.col-lg{max-width:100%;flex-grow:1;flex-basis:0}.col-lg-1{max-width:8.33333%;flex-basis:8.33333%}.col-lg-o-0{margin-left:0}.col-lg-2{max-width:16.66667%;flex-basis:16.66667%}.col-lg-o-1{margin-left:8.33333%}.col-lg-3{max-width:25%;flex-basis:25%}.col-lg-o-2{margin-left:16.66667%}.col-lg-4{max-width:33.33333%;flex-basis:33.33333%}.col-lg-o-3{margin-left:25%}.col-lg-5{max-width:41.66667%;flex-basis:41.66667%}.col-lg-o-4{margin-left:33.33333%}.col-lg-6{max-width:50%;flex-basis:50%}.col-lg-o-5{margin-left:41.66667%}.col-lg-7{max-width:58.33333%;flex-basis:58.33333%}.col-lg-o-6{margin-left:50%}.col-lg-8{max-width:66.66667%;flex-basis:66.66667%}.col-lg-o-7{margin-left:58.33333%}.col-lg-9{max-width:75%;flex-basis:75%}.col-lg-o-8{margin-left:66.66667%}.col-lg-10{max-width:83.33333%;flex-basis:83.33333%}.col-lg-o-9{margin-left:75%}.col-lg-11{max-width:91.66667%;flex-basis:91.66667%}.col-lg-o-10{margin-left:83.33333%}.col-lg-12{max-width:100%;flex-basis:100%}.col-lg-o-11{margin-left:91.66667%}.col-lg-n{order:initial}.col-lg-f{order:-999}.col-lg-l{order:999}}:root{--cd-b-col:#f8f8f8;--cd-f-col:#111;--cd-br-col:#ddd}.card{display:flex;flex-direction:column;justify-content:space-between;align-self:center;position:relative;width:100%;background:var(--cd-b-col);color:var(--cd-f-col);border:.0625rem solid var(--cd-br-col);border-radius:var(--u-br-r);margin:var(--u-m);overflow:hidden}@media screen and (min-width: 320px){.card{max-width:320px}}.card>.section{background:var(--cd-b-col);color:var(--cd-f-col);box-sizing:border-box;margin:0;border:0;border-radius:0;border-bottom:.0625rem solid var(--cd-br-col);padding:var(--u-p);width:100%}.card>.section.media{height:200px;padding:0;-o-object-fit:cover;object-fit:cover}.card>.section:last-child{border-bottom:0}.card.fluid{max-width:100%;width:auto}.card>.section.double-padded{padding:calc(1.5 * var(--u-p))}.card{box-shadow:0 1.25rem 2.5rem -0.625rem rgba(0,32,64,0.1)}.card>h3.section.double-padded{padding:calc(3 * var(--u-p))}.card>.section.double-padded>p{margin:var(--u-m) calc(var(--u-m) / 2)}.card+.card{margin-top:calc(5 * var(--u-m))}:root{--frm-b-col:#f0f0f0;--frm-f-col:#111;--frm-br-col:#ddd;--in-b-col:#f8f8f8;--in-f-col:#111;--in-br-col:#ddd;--in-fc-col:#0288d1;--in-inv-col:#d32f2f;--btn-b-col:#e2e2e2;--btn-h-b-col:#dcdcdc;--btn-f-col:#212121;--btn-br-col:transparent;--btn-h-br-col:transparent;--btn-grp-br-col:rgba(124,124,124,0.54)}form{background:var(--frm-b-col);color:var(--frm-f-col);border:.0625rem solid var(--frm-br-col);border-radius:var(--u-br-r);margin:var(--u-m);padding:calc(2 * var(--u-p)) var(--u-p)}fieldset{border:.0625rem solid var(--frm-br-col);border-radius:var(--u-br-r);margin:calc(var(--u-m) / 4);padding:var(--u-p)}legend{box-sizing:border-box;display:table;max-width:100%;white-space:normal;font-weight:700;padding:calc(var(--u-p) / 2)}label{padding:calc(var(--u-p) / 2) var(--u-p)}.input-group{display:inline-block}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}input:not([type]),[type="text"],[type="email"],[type="number"],[type="search"],[type="password"],[type="url"],[type="tel"],[type="checkbox"],[type="radio"],textarea,select{box-sizing:border-box;background:var(--in-b-col);color:var(--in-f-col);border:.0625rem solid var(--in-br-col);border-radius:var(--u-br-r);margin:calc(var(--u-m) / 2);padding:var(--u-p) calc(1.5 * var(--u-p))}input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus,textarea:hover,textarea:focus,select:hover,select:focus{border-color:var(--in-fc-col);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid,input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid,textarea:invalid,textarea:focus:invalid,select:invalid,select:focus:invalid{border-color:var(--in-inv-col);box-shadow:none}input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly],textarea[readonly],select[readonly]{background:var(--b-col2)}select{max-width:100%}option{overflow:hidden;text-overflow:ellipsis}[type="checkbox"],[type="radio"]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;height:calc(1rem + var(--u-p) / 2);width:calc(1rem + var(--u-p) / 2);vertical-align:text-bottom;padding:0;flex-basis:calc(1rem + var(--u-p) / 2) !important;flex-grow:0 !important}[type="checkbox"]:checked:before,[type="radio"]:checked:before{position:absolute}[type="checkbox"]:checked:before{content:'\2713';font-family:sans-serif;font-size:calc(1rem + var(--u-p) / 2);top:calc(0rem - var(--u-p));left:calc(var(--u-p) / 4)}[type="radio"]{border-radius:100%}[type="radio"]:checked:before{border-radius:100%;content:'';top:calc(.0625rem + var(--u-p) / 2);left:calc(.0625rem + var(--u-p) / 2);background:var(--in-f-col);width:0.5rem;height:0.5rem}:placeholder-shown{color:var(--in-f-col)}::-ms-placeholder{color:var(--in-f-col);opacity:0.54}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button{overflow:visible;text-transform:none}button,[type="button"],[type="submit"],[type="reset"],a.button,label.button,.button,a[role="button"],label[role="button"],[role="button"]{display:inline-block;background:var(--btn-b-col);color:var(--btn-f-col);border:.0625rem solid var(--btn-br-col);border-radius:var(--u-br-r);padding:var(--u-p) calc(1.5 * var(--u-p));margin:var(--u-m);text-decoration:none;cursor:pointer;transition:background 0.3s}button:hover,button:focus,[type="button"]:hover,[type="button"]:focus,[type="submit"]:hover,[type="submit"]:focus,[type="reset"]:hover,[type="reset"]:focus,a.button:hover,a.button:focus,label.button:hover,label.button:focus,.button:hover,.button:focus,a[role="button"]:hover,a[role="button"]:focus,label[role="button"]:hover,label[role="button"]:focus,[role="button"]:hover,[role="button"]:focus{background:var(--btn-h-b-col);border-color:var(--btn-h-br-col)}input:disabled,input[disabled],textarea:disabled,textarea[disabled],select:disabled,select[disabled],button:disabled,button[disabled],.button:disabled,.button[disabled],[role="button"]:disabled,[role="button"][disabled]{cursor:not-allowed;opacity:.75}.button-group{display:flex;border:.0625rem solid var(--btn-grp-br-col);border-radius:var(--u-br-r);margin:var(--u-m)}.button-group>button,.button-group [type="button"],.button-group>[type="submit"],.button-group>[type="reset"],.button-group>.button,.button-group>[role="button"]{margin:0;max-width:100%;flex:1 1 auto;text-align:center;border:0;border-radius:0;box-shadow:none}.button-group>:not(:first-child){border-left:.0625rem solid var(--btn-grp-br-col)}@media screen and (max-width: 767px){.button-group{flex-direction:column}.button-group>:not(:first-child){border:0;border-top:.0625rem solid var(--btn-grp-br-col)}}button.primary,[type="button"].primary,[type="submit"].primary,[type="reset"].primary,.button.primary,[role="button"].primary{--btn-b-col:#1976d2;--btn-f-col:#f8f8f8}button.primary:hover,button.primary:focus,[type="button"].primary:hover,[type="button"].primary:focus,[type="submit"].primary:hover,[type="submit"].primary:focus,[type="reset"].primary:hover,[type="reset"].primary:focus,.button.primary:hover,.button.primary:focus,[role="button"].primary:hover,[role="button"].primary:focus{--btn-h-b-col:#1565c0}:root{--hd-b-col:#f8f8f8;--hd-hv-b-col:#f0f0f0;--hd-f-col:#444;--hd-br-col:#ddd;--nv-b-col:#f8f8f8;--nv-hv-b-col:#f0f0f0;--nv-f-col:#444;--nv-br-col:#ddd;--nv-ln-col:#0277bd;--ft-f-col:#444;--ft-b-col:#f8f8f8;--ft-br-col:#ddd;--ft-ln-col:#0277bd;--dr-b-col:#f8f8f8;--dr-hv-b-col:#f0f0f0;--dr-br-col:#ddd;--dr-cl-col:#444}header{height:3.1875rem;background:var(--hd-b-col);color:var(--hd-f-col);border-bottom:.0625rem solid var(--hd-br-col);padding:calc(var(--u-p) / 4) 0;white-space:nowrap;overflow-x:auto;overflow-y:hidden}header.row{box-sizing:content-box}header .logo{color:var(--hd-f-col);font-size:1.75rem;padding:var(--u-p) calc(2 * var(--u-p));text-decoration:none}header button,header [type="button"],header .button,header [role="button"]{box-sizing:border-box;position:relative;top:calc(0rem - var(--u-p) / 4);height:calc(3.1875rem + var(--u-p) / 2);background:var(--hd-b-col);line-height:calc(3.1875rem - var(--u-p) * 1.5);text-align:center;color:var(--hd-f-col);border:0;border-radius:0;margin:0;text-transform:uppercase}header button:hover,header button:focus,header [type="button"]:hover,header [type="button"]:focus,header .button:hover,header .button:focus,header [role="button"]:hover,header [role="button"]:focus{background:var(--hd-hv-b-col)}nav{background:var(--nv-b-col);color:var(--nv-f-col);border:.0625rem solid var(--nv-br-col);border-radius:var(--u-br-r);margin:var(--u-m)}nav *{padding:var(--u-p) calc(1.5 * var(--u-p))}nav a,nav a:visited{display:block;color:var(--nv-ln-col);border-radius:var(--u-br-r);transition:background 0.3s}nav a:hover,nav a:focus,nav a:visited:hover,nav a:visited:focus{text-decoration:none;background:var(--nv-hv-b-col)}nav .sublink-1{position:relative;margin-left:calc(2 * var(--u-p))}nav .sublink-1:before{position:absolute;left:calc(var(--u-p) - 1 * var(--u-p));top:-.0625rem;content:'';height:100%;border:.0625rem solid var(--nv-br-col);border-left:0}footer{background:var(--ft-b-col);color:var(--ft-f-col);border-top:.0625rem solid var(--ft-br-col);padding:calc(2 * var(--u-p)) var(--u-p);font-size:.875rem}footer a,footer a:visited{color:var(--ft-ln-col)}header.sticky{position:-webkit-sticky;position:sticky;z-index:1101;top:0}footer.sticky{position:-webkit-sticky;position:sticky;z-index:1101;bottom:0}.drawer-toggle:before{display:inline-block;position:relative;vertical-align:bottom;content:'\00a0\2261\00a0';font-family:sans-serif;font-size:1.5em}@media screen and (min-width: 768px){.drawer-toggle:not(.persistent){display:none}}[type="checkbox"].drawer{height:1px;width:1px;margin:-1px;overflow:hidden;position:absolute;clip:rect(0 0 0 0);-webkit-clip-path:inset(100%);clip-path:inset(100%)}[type="checkbox"].drawer+*{display:block;box-sizing:border-box;position:fixed;top:0;width:320px;height:100vh;overflow-y:auto;background:var(--dr-b-col);border:.0625rem solid var(--dr-br-col);border-radius:0;margin:0;z-index:1110;left:-320px;transition:left 0.3s}[type="checkbox"].drawer+* .drawer-close{position:absolute;top:var(--u-m);right:var(--u-m);z-index:1111;width:2rem;height:2rem;border-radius:var(--u-br-r);padding:var(--u-p);margin:0;cursor:pointer;transition:background 0.3s}[type="checkbox"].drawer+* .drawer-close:before{display:block;content:'\00D7';color:var(--dr-cl-col);position:relative;font-family:sans-serif;font-size:2rem;line-height:1;text-align:center}[type="checkbox"].drawer+* .drawer-close:hover,[type="checkbox"].drawer+* .drawer-close:focus{background:var(--dr-hv-b-col)}@media screen and (max-width: 320px){[type="checkbox"].drawer+*{width:100%}}[type="checkbox"].drawer:checked+*{left:0}@media screen and (min-width: 768px){[type="checkbox"].drawer:not(.persistent)+*{position:static;height:100%;z-index:1100}[type="checkbox"].drawer:not(.persistent)+* .drawer-close{display:none}}:root{--mrk-b-col:#424242;--mrk-f-col:#fafafa}mark{background:var(--mrk-b-col);color:var(--mrk-f-col);font-size:.5em;line-height:1em;border-radius:var(--u-br-r);padding:calc(var(--u-p) / 4) calc(var(--u-p) / 2)}mark.inline-block{display:inline-block;font-size:1em;line-height:1.5;padding:calc(var(--u-p) / 2) var(--u-p)}:root{--tst-b-col:#212121;--tst-f-col:#fafafa}.toast{position:fixed;bottom:calc(var(--u-m) * 3);left:50%;transform:translate(-50%, -50%);z-index:1111;color:var(--tst-f-col);background:var(--tst-b-col);border-radius:calc(var(--u-br-r) * 16);padding:var(--u-p) calc(var(--u-p) * 3)}.toast{bottom:calc(var(--u-m) / 2);opacity:1;transition:opacity 0.3s ease-in-out}mark{position:relative;top:-0.25rem;left:0.25rem}mark.secondary{--mrk-b-col:#d32f2f}mark.tertiary{--mrk-b-col:#308732}mark.tag{padding:calc(var(--u-p)/2) var(--u-p);border-radius:1em}code,pre,kbd,code *,pre *,kbd *,code[class*="language-"],pre[class*="language-"]{font-family:Menlo, Consolas, monospace !important}pre{border:0.0625rem solid var(--br-col2);border-radius:var(--u-br-r)}.group{position:relative;margin-top:2em;margin-bottom:1em}.search{font-size:0.875rem;margin-top:-0.1em;display:block;width:100%;border:none;border-bottom:.0625rem solid var(--nv-ln-col)}.search:focus{outline:none}label#search-label{color:var(--nv-ln-col);font-size:1.125rem;font-weight:400;position:absolute;left:0.3125rem;top:0.625rem}.search:focus ~ label#search-label,.search:valid ~ label#search-label{top:-1.25rem;font-size:0.875rem;color:var(--nv-ln-col)}label#menu-toggle{width:3.4375rem}header h1.logo{margin-top:-0.8rem;text-align:center}header h1.logo a{text-decoration:none;color:#111}header #title{position:relative;top:-1rem}@media screen and (max-width: 500px){header #title{font-size:1rem;display:block}}header h1 small{display:block;font-size:0.875rem;color:#888;margin-top:-0.8rem}@media screen and (max-width: 768px){header h1 small{font-size:0.75rem}}@media screen and (max-width: 600px){header h1 small{font-size:0.625rem}}@media screen and (max-width: 500px){header h1 small{font-size:0.5rem;margin-top:-1.2rem}}label#menu-toggle{position:absolute;left:0.5rem;top:0.5rem;width:3.4375rem}main{padding:0}:root{--clps-lbl-b-col:#e8e8e8;--clps-lbl-f-col:#212121;--clps-lbl-h-b-col:#f0f0f0;--clps-sel-lbl-b-col:#ececec;--clps-br-col:#ddd;--clps-cnt-b-col:#fafafa;--clps-sel-lbl-br-col:#0277bd}label.collapse{width:100%;display:inline-block;cursor:pointer;box-sizing:border-box;transition:background 0.3s;color:var(--clps-lbl-f-col);background:var(--clps-lbl-b-col);border:.0625rem solid var(--clps-br-col);padding:calc(1.5 * var(--u-p));border-radius:var(--u-br-r)}label.collapse:hover,label.collapse:focus{background:var(--clps-lbl-h-b-col)}label.collapse+pre{box-sizing:border-box;height:0;max-height:1px;overflow:auto;margin:0;border:0;padding:0;transition:max-height 0.3s}label.collapse.toggled{background:var(--clps-sel-lbl-b-col);border-bottom-color:var(--clps-sel-lbl-br-col);border-bottom-left-radius:0;border-bottom-right-radius:0}label.collapse.toggled+pre{border-top-left-radius:0;border-top-right-radius:0;position:relative;width:100%;height:auto;border:.0625rem solid var(--clps-br-col);border-top:0;padding:calc(2 * var(--u-p));max-height:400px}button.primary.clipboard-copy{width:100%;margin-left:0}button.primary.clipboard-copy>img{vertical-align:bottom}code[class*="language-"],pre[class*="language-"]{color:#222;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.8;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-hypens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*="language-"]{padding:calc(2 * var(--u-p));overflow:auto;margin:var(--u-m) 0}pre[class*="language-"]::-moz-selection,pre[class*="language-"] ::-moz-selection,code[class*="language-"]::-moz-selection,code[class*="language-"] ::-moz-selection{background:#b3d4fc}pre[class*="language-"]::selection,pre[class*="language-"] ::selection,code[class*="language-"]::selection,code[class*="language-"] ::selection{background:#b3d4fc}:not(pre)>code[class*="language-"]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:#7a8490}.token.punctuation{color:#666}.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.constant,.token.symbol,.token.deleted,.token.function{color:#005cc5}.token.number,.token.class-name{color:#832ed2}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#067e36}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string,.token.atrule,.token.attr-value,.token.keyword{color:#d73a49}.token.regex{color:#097cab}.token.important,.token.variable{color:#e90}.token.important,.token.bold{font-weight:bold}.token.italic{font-style:italic}.token.entity{cursor:help} diff --git a/docs/mini/flavor.scss b/docs/mini/flavor.scss index c400fdde5..b3e3f11c0 100644 --- a/docs/mini/flavor.scss +++ b/docs/mini/flavor.scss @@ -131,6 +131,8 @@ $_drawer-right: false; @import 'navigation'; +$mark-back-color: #424242; +$mark-font-size: 0.5em; $toast-back-color: #212121; @@ -163,6 +165,12 @@ $_include-collapse: false; transition: opacity 0.3s ease-in-out; } +mark { + position: relative; + top: -0.25rem; + left: 0.25rem; +} + /* Custom elements for contextual background elements, toasts and tooltips. */ @@ -318,7 +326,7 @@ button.primary.clipboard-copy { code[class*="language-"], pre[class*="language-"] { - color: black; + color: #222; text-align: left; white-space: pre; word-spacing: normal; @@ -385,8 +393,9 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection { } -.token.number{ - color: #8132b5; +.token.number, +.token.class-name { + color: #832ed2; } .token.selector, @@ -395,7 +404,7 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection { .token.char, .token.builtin, .token.inserted { - color: #007e5d; + color: #067e36; } .token.operator, @@ -410,7 +419,7 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection { } .token.regex { - color: #007972; + color: #097cab; } .token.important, .token.variable { diff --git a/scripts/build.js b/scripts/build.js index 1b9a464a6..1354de249 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -73,7 +73,11 @@ try { .readFileSync('tag_database', 'utf8') .split('\n') .slice(0, -1) - .map(v => v.split(':').slice(0, 2)) + .map(v => { + let data = v.split(':').slice(0, 2); + data[1] = data[1].split(',').map(t => t.trim()); + return data; + }) ); } catch (err) { console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`); @@ -85,7 +89,7 @@ try { const tags = [ ...new Set( Object.entries(tagDbData) - .map(t => t[1]) + .map(t => t[1][0]) .filter(v => v) .sort((a, b) => a.localeCompare(b)) ) @@ -101,16 +105,16 @@ try { if (capitalizedTag === 'Uncategorized') { uncategorizedOutput += `### _${capitalizedTag}_\n\n\n\n\n'; } else { output += `### ${ EMOJIS[tag] || '' } ${capitalizedTag}\n\nView contents
\n\n`; - for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { - uncategorizedOutput += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`; + for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) { + uncategorizedOutput += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()}${taggedSnippet[1].includes('advanced')?'-':''})\n`; } uncategorizedOutput += '\n\n\n\n'; } @@ -122,17 +126,23 @@ try { // Loop over tags and snippets to create the list of snippets for (const tag of tags) { const capitalizedTag = capitalize(tag, true); - + //  if (capitalizedTag == 'Uncategorized') { uncategorizedOutput += `---\n ## _${capitalizedTag}_\n`; - for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { + for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) { uncategorizedOutput += `\n${snippets[taggedSnippet[0] + '.md'] + '\nView contents
\n\n`; - for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { - output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()})\n`; + for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) { + output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()}${taggedSnippet[1].includes('advanced')?'-':''})\n`; } output += '\n
[⬆ back to top](#table-of-contents)\n\n'}`; } } else { output += `---\n ## ${EMOJIS[tag] || ''} ${capitalizedTag}\n`; - for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) { + for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) { let data = snippets[taggedSnippet[0] + '.md']; + // Add advanced tag + if(taggedSnippet[1].includes('advanced')){ + data = data.split(/\r?\n/); + data[0] = data[0] +' '; + data = data.join('\n'); + } data = data.slice(0, data.lastIndexOf('```js')) + '\nExamples
\n\n' + diff --git a/scripts/tag.js b/scripts/tag.js index bf57fd7cf..c3dd9aa64 100644 --- a/scripts/tag.js +++ b/scripts/tag.js @@ -50,10 +50,14 @@ try { .readFileSync('tag_database', 'utf8') .split('\n') .slice(0, -1) - .map(v => v.split(':').slice(0, 2)) + .map(v => { + let data = v.split(':').slice(0, 2); + data[1] = data[1].split(',').map(t => t.trim()); + return data; + }) ); tagDbStats = Object.entries(tagDbData) - .sort((a, b) => a[1].localeCompare(b[1])) + .sort((a, b) => a[1][0].localeCompare(b[1][0])) .reduce((acc, val) => { acc.hasOwnProperty(val[1]) ? acc[val[1]]++ : (acc[val[1]] = 1); return acc; @@ -68,9 +72,9 @@ try { for (let snippet of Object.entries(snippets)) if ( tagDbData.hasOwnProperty(snippet[0].slice(0, -3)) && - tagDbData[snippet[0].slice(0, -3)].trim() + tagDbData[snippet[0].slice(0, -3)].join(',').trim() ) - output += `${snippet[0].slice(0, -3)}:${tagDbData[snippet[0].slice(0, -3)].trim()}\n`; + output += `${snippet[0].slice(0, -3)}:${tagDbData[snippet[0].slice(0, -3)].join(',').trim()}\n`; else { output += `${snippet[0].slice(0, -3)}:uncategorized\n`; missingTags++; diff --git a/scripts/web.js b/scripts/web.js index eeb848d9b..6b86c7683 100644 --- a/scripts/web.js +++ b/scripts/web.js @@ -61,7 +61,7 @@ const objectFromPairs = arr => arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {}); const capitalize = (str, lowerRest = false) => str.slice(0, 1).toUpperCase() + (lowerRest ? str.slice(1).toLowerCase() : str.slice(1)); // Start the timer of the script -console.time('Builder'); +console.time('Webber'); // Synchronously read all snippets and sort them as necessary (case-insensitive) try { let snippetFilenames = fs.readdirSync(snippetsPath); @@ -96,7 +96,11 @@ try { .readFileSync('tag_database', 'utf8') .split('\n') .slice(0, -1) - .map(v => v.split(':').slice(0, 2)) + .map(v => { + let data = v.split(':').slice(0, 2); + data[1] = data[1].split(',').map(t => t.trim()); + return data; + }) ); } catch (err) { // Handle errors (hopefully not!) @@ -109,7 +113,7 @@ try { output += `${startPart + '\n'}`; let uncategorizedOutput = ''; // Loop over tags and snippets to create the table of contents - for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))] + for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1][0]))] .filter(v => v) .sort((a, b) => a.localeCompare(b))) { if (capitalize(tag, true) == 'Uncategorized') { @@ -120,12 +124,12 @@ try { .replace(//g, '') .replace(/<\/p>/g, '') + ``; - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) uncategorizedOutput += md .render(`[${taggedSnippet[0]}](#${taggedSnippet[0].toLowerCase()})\n`) .replace(/
/g, '') .replace(/<\/p>/g, '') - .replace(//g, '') .replace(/<\/p>/g, '') + ``; - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) output += md .render(`[${taggedSnippet[0]}](#${taggedSnippet[0].toLowerCase()})\n`) .replace(/
/g, '') .replace(/<\/p>/g, '') - .replace(/ `; uncategorizedOutput = ''; // Loop over tags and snippets to create the list of snippets - for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1]))] + for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1][0]))] .filter(v => v) .sort((a, b) => a.localeCompare(b))) { if (capitalize(tag, true) == 'Uncategorized') { uncategorizedOutput += md .render(`## ${capitalize(tag, true)}\n`) .replace(/
/g, '
'); - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) uncategorizedOutput += '
' + md .render(`\n${snippets[taggedSnippet[0] + '.md']}`) .replace(//g, `${taggedSnippet[1].includes('advanced')?'advanced':''}
`) .replace(/([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}`) .replace(/<\/pre>\s+Copy to clipboard' + @@ -170,12 +175,13 @@ try { output += md .render(`## ${capitalize(tag, true)}\n`) .replace(/
/g, '
'); - for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1] === tag)) + for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) output += '
' + md .render(`\n${snippets[taggedSnippet[0] + '.md']}`) .replace(//g, `${taggedSnippet[1].includes('advanced')?'advanced':''}
`) .replace(/<\/h3>/g, '') .replace(/([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}`) .replace(/<\/pre>\s+((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); diff --git a/snippets/average.md b/snippets/average.md index 6eccc0636..fff5dd5a6 100644 --- a/snippets/average.md +++ b/snippets/average.md @@ -1,17 +1,14 @@ ### average -Returns the average of an of two or more numbers/arrays. +Returns the average of an of two or more numbers. Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`, divide by the `length` of the array. ```js -const average = (...arr) => { - const nums = [].concat(...arr); - return nums.reduce((acc, val) => acc + val, 0) / nums.length; -}; +const average = (...nums) => [...nums].reduce((acc, val) => acc + val, 0) / nums.length; ``` ```js -average([1, 2, 3]); // 2 +average(...[1, 2, 3]); // 2 average(1, 2, 3); // 2 ``` diff --git a/snippets/byteSize.md b/snippets/byteSize.md index 5693da1ab..459ee3796 100644 --- a/snippets/byteSize.md +++ b/snippets/byteSize.md @@ -1,6 +1,6 @@ ### byteSize -Returns the length of string. +Returns the length of a string in bytes. Convert a given string to a [`Blob` Object](https://developer.mozilla.org/en-US/docs/Web/API/Blob) and find its `size`. diff --git a/snippets/capitalize.md b/snippets/capitalize.md index f9a26e7be..c56616e51 100644 --- a/snippets/capitalize.md +++ b/snippets/capitalize.md @@ -2,7 +2,7 @@ Capitalizes the first letter of a string. -Use destructuring and `toUpperCase()` to capitalize first letter, `...rest` to get array of characters after first letter and then `Array.join('')` to make it a string again. +Use array destructuring and `String.toUpperCase()` to capitalize first letter, `...rest` to get array of characters after first letter and then `Array.join('')` to make it a string again. Omit the `lowerRest` parameter to keep the rest of the string intact, or set it to `true` to convert to lowercase. ```js diff --git a/snippets/capitalizeEveryWord.md b/snippets/capitalizeEveryWord.md index d02d2296f..845553aa3 100644 --- a/snippets/capitalizeEveryWord.md +++ b/snippets/capitalizeEveryWord.md @@ -2,7 +2,7 @@ Capitalizes the first letter of every word in a string. -Use `replace()` to match the first character of each word and `toUpperCase()` to capitalize it. +Use `String.replace()` to match the first character of each word and `String.toUpperCase()` to capitalize it. ```js const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); diff --git a/snippets/cleanObj.md b/snippets/cleanObj.md index b53a42806..e068deb10 100644 --- a/snippets/cleanObj.md +++ b/snippets/cleanObj.md @@ -2,8 +2,8 @@ Removes any properties except the ones specified from a JSON object. -Use `Object.keys()` method to loop over given JSON object and deleting keys that are not `include`d in given array. -Also if you give it a special key (`childIndicator`) it will search deeply inside it to apply function to inner objects too. +Use `Object.keys()` method to loop over given JSON object and deleting keys that are not included in given array. +If you pass a special key,`childIndicator`, it will search deeply apply the function to inner objects, too. ```js const cleanObj = (obj, keysToKeep = [], childIndicator) => { diff --git a/snippets/countOccurrences.md b/snippets/countOccurrences.md index 927631f6f..b6e0d2aad 100644 --- a/snippets/countOccurrences.md +++ b/snippets/countOccurrences.md @@ -5,7 +5,7 @@ Counts the occurrences of a value in an array. Use `Array.reduce()` to increment a counter each time you encounter the specific value inside the array. ```js -const countOccurrences = (arr, value) => arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0); +const countOccurrences = (arr, val) => arr.reduce((a, v) => (v === val ? a + 1 : a + 0), 0); ``` ```js diff --git a/snippets/digitize.md b/snippets/digitize.md index 60f636847..9222ce30f 100644 --- a/snippets/digitize.md +++ b/snippets/digitize.md @@ -2,11 +2,11 @@ Converts a number to an array of digits. -Convert the number to a string, using spread operators in ES6(`[...string]`) build an array. +Convert the number to a string, using the spread operator (`...`) to build an array. Use `Array.map()` and `parseInt()` to transform each value to an integer. ```js -const digitize = n => [...('' + n)].map(i => parseInt(i)); +const digitize = n => [...`${n}`].map(i => parseInt(i)); ``` ```js diff --git a/snippets/elo.md b/snippets/elo.md index e08171878..622cdc981 100644 --- a/snippets/elo.md +++ b/snippets/elo.md @@ -4,8 +4,10 @@ Computes the new ratings between two or more opponents using the [Elo rating sys of pre-ratings and returns an array containing post-ratings. The array should be ordered from best performer to worst performer (winner -> loser). -Use the exponent `**` operator and math operators to compute the expected score (chance of winning) -of each opponent and compute the new rating for each. Loop through the ratings, using each permutation to compute the post-Elo rating for each player in a pairwise fashion. Omit the second argument to use the default K-factor of 32, or supply a custom K-factor value. For details on the third argument, see the last example. +Use the exponent `**` operator and math operators to compute the expected score (chance of winning). +of each opponent and compute the new rating for each. +Loop through the ratings, using each permutation to compute the post-Elo rating for each player in a pairwise fashion. +Omit the second argument to use the default `kFactor` of 32. ```js const elo = ([...ratings], kFactor = 32, selfRating) => { @@ -35,7 +37,7 @@ elo([1200, 1200], 64); // [1232, 1168] // 4 player FFA, all same rank elo([1200, 1200, 1200, 1200]).map(Math.round); // [1246, 1215, 1185, 1154] /* -For teams, each rating can adjusted based on own team's average rating vs. +For teams, each rating can adjusted based on own team's average rating vs. average rating of opposing team, with the score being added to their own individual rating by supplying it as the third argument. */ diff --git a/snippets/escapeHTML.md b/snippets/escapeHTML.md index 2db4cf0c0..85c772621 100644 --- a/snippets/escapeHTML.md +++ b/snippets/escapeHTML.md @@ -2,7 +2,7 @@ Escapes a string for use in HTML. -Use `String.replace()` with a regex that matches the characters that need to be escaped, using a callback function to replace each character instance with its associated escaped character using a dictionary (object). +Use `String.replace()` with a regexp that matches the characters that need to be escaped, using a callback function to replace each character instance with its associated escaped character using a dictionary (object). ```js const escapeHTML = str => diff --git a/snippets/escapeRegExp.md b/snippets/escapeRegExp.md index e83e13667..52a6aa3a2 100644 --- a/snippets/escapeRegExp.md +++ b/snippets/escapeRegExp.md @@ -2,7 +2,7 @@ Escapes a string to use in a regular expression. -Use `replace()` to escape special characters. +Use `String.replace()` to escape special characters. ```js const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); diff --git a/snippets/extendHex.md b/snippets/extendHex.md index 39ca049fe..57231ee07 100644 --- a/snippets/extendHex.md +++ b/snippets/extendHex.md @@ -2,8 +2,9 @@ Extends a 3-digit color code to a 6-digit color code. -Use `Array.map()`, `split()` and `Array.join()` to join the mapped array for converting a 3-digit RGB notated hexadecimal color-code to the 6-digit form. -`String.slice()` is used to remove `#` from string start since it's added once. +Use `Array.map()`, `String.split()` and `Array.join()` to join the mapped array for converting a 3-digit RGB notated hexadecimal color-code to the 6-digit form. +`Array.slice()` is used to remove `#` from string start since it's added once. + ```js const extendHex = shortHex => '#' + diff --git a/snippets/flatten.md b/snippets/flatten.md index dd90ca3be..a31bbe2d0 100644 --- a/snippets/flatten.md +++ b/snippets/flatten.md @@ -2,7 +2,7 @@ Flattens an array. -Use a new array and concatenate it with the spread input array causing a shallow denesting of any contained arrays. +Use a new array, `Array.concat()` and the spread operator (`...`) to cause a shallow denesting of any contained arrays. ```js const flatten = arr => [].concat(...arr); diff --git a/snippets/flip.md b/snippets/flip.md index 3ab12dd78..bcc66e500 100644 --- a/snippets/flip.md +++ b/snippets/flip.md @@ -1,6 +1,6 @@ ### flip -Flip takes a function as an argument, then makes the first argument the last +Flip takes a function as an argument, then makes the first argument the last. Return a closure that takes variadic inputs, and splices the last argument to make it the first argument before applying the rest. diff --git a/snippets/fromCamelCase.md b/snippets/fromCamelCase.md index d67b37d4a..503fcdeeb 100644 --- a/snippets/fromCamelCase.md +++ b/snippets/fromCamelCase.md @@ -2,8 +2,8 @@ Converts a string from camelcase. -Use `replace()` to remove underscores, hyphens, and spaces and convert words to camelcase. -Omit the second argument to use a default separator of `_`. +Use `String.replace()` to remove underscores, hyphens, and spaces and convert words to camelcase. +Omit the second argument to use a default `separator` of `_`. ```js const fromCamelCase = (str, separator = '_') => diff --git a/snippets/gcd.md b/snippets/gcd.md index 39ab41b6e..5b3f7a29a 100644 --- a/snippets/gcd.md +++ b/snippets/gcd.md @@ -9,10 +9,11 @@ Otherwise, return the GCD of `y` and the remainder of the division `x/y`. ```js const gcd = (...arr) => { const _gcd = (x, y) => (!y ? x : gcd(y, x % y)); - return [].concat(...arr).reduce((a, b) => _gcd(a, b)); + return [...arr].reduce((a, b) => _gcd(a, b)); }; ``` ```js gcd(8, 36); // 4 +gcd(...[12, 8, 32]); // 4 ``` diff --git a/snippets/getType.md b/snippets/getType.md index 612c248fa..ae3d9268a 100644 --- a/snippets/getType.md +++ b/snippets/getType.md @@ -2,7 +2,7 @@ Returns the native type of a value. -Returns lowercased constructor name of value, "undefined" or "null" if value is undefined or null +Returns lowercased constructor name of value, `"undefined"` or `"null"` if value is `undefined` or `null`. ```js const getType = v => diff --git a/snippets/getURLParameters.md b/snippets/getURLParameters.md index 69138e57f..cf601b0f5 100644 --- a/snippets/getURLParameters.md +++ b/snippets/getURLParameters.md @@ -2,7 +2,7 @@ Returns an object containing the parameters of the current URL. -Use `match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. +Use `String.match()` with an appropriate regular expression to get all key-value pairs, `Array.reduce()` to map and combine them into a single object. Pass `location.search` as the argument to apply to the current `url`. ```js diff --git a/snippets/initializeArrayWithRange.md b/snippets/initializeArrayWithRange.md index 2b7e40348..228c6fcaf 100644 --- a/snippets/initializeArrayWithRange.md +++ b/snippets/initializeArrayWithRange.md @@ -2,7 +2,7 @@ Initializes an array containing the numbers in the specified range where `start` and `end` are inclusive with there common difference `step`. -Use `Array(Math.ceil((end+1-start)/step)` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.map()` to fill with the desired values in a range. +Use `Array.from(Math.ceil((end+1-start)/step))` to create an array of the desired length(the amounts of elements is equal to `(end-start)/step` or `(end+1-start)/step` for inclusive end), `Array.map()` to fill with the desired values in a range. You can omit `start` to use a default value of `0`. You can omit `step` to use a default value of `1`. diff --git a/snippets/initializeArrayWithValues.md b/snippets/initializeArrayWithValues.md index b91496068..46880dd45 100644 --- a/snippets/initializeArrayWithValues.md +++ b/snippets/initializeArrayWithValues.md @@ -3,10 +3,10 @@ Initializes and fills an array with the specified values. Use `Array(n)` to create an array of the desired length, `fill(v)` to fill it with the desired values. -You can omit `value` to use a default value of `0`. +You can omit `val` to use a default value of `0`. ```js -const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); +const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val); ``` ```js diff --git a/snippets/isArray.md b/snippets/isArray.md index ebe1efecc..def452a89 100644 --- a/snippets/isArray.md +++ b/snippets/isArray.md @@ -5,10 +5,9 @@ Checks if the given argument is an array. Use `Array.isArray()` to check if a value is classified as an array. ```js -const isArray = val => !!val && Array.isArray(val); +const isArray = val => Array.isArray(val); ``` ```js -isArray(null); // false isArray([1]); // true ``` diff --git a/snippets/isFunction.md b/snippets/isFunction.md index e507bb9e5..0cf8ee580 100644 --- a/snippets/isFunction.md +++ b/snippets/isFunction.md @@ -9,7 +9,6 @@ const isFunction = val => typeof val === 'function'; ``` ```js -isFunction(null); // false isFunction('x'); // false isFunction(x => x); // true ``` diff --git a/snippets/lcm.md b/snippets/lcm.md index 4b560f29d..cbd86c264 100644 --- a/snippets/lcm.md +++ b/snippets/lcm.md @@ -1,6 +1,6 @@ ### lcm -Returns the least common multiple of two or more numbers/arrays. +Returns the least common multiple of two or more numbers. Use the greatest common divisor (GCD) formula and `Math.abs()` to determine the least common multiple. The GCD formula uses recursion. @@ -9,11 +9,11 @@ The GCD formula uses recursion. const lcm = (...arr) => { const gcd = (x, y) => (!y ? x : gcd(y, x % y)); const _lcm = (x, y) => x * y / gcd(x, y); - return [].concat(...arr).reduce((a, b) => _lcm(a, b)); + return [...arr].reduce((a, b) => _lcm(a, b)); }; ``` ```js lcm(12, 7); // 84 -lcm([1, 3, 4], 5); // 60 +lcm(...[1, 3, 4, 5]); // 60 ``` diff --git a/snippets/mask.md b/snippets/mask.md index 7257e76fc..7cdf3d104 100644 --- a/snippets/mask.md +++ b/snippets/mask.md @@ -2,7 +2,7 @@ Replaces all but the last `num` of characters with the specified mask character. -Use `String.slice()` to grab the portion of the characters that need to be masked and use `String.replace()` with a regex to replace every character with the mask character. +Use `String.slice()` to grab the portion of the characters that need to be masked and use `String.replace()` with a regexp to replace every character with the mask character. Concatenate the masked characters with the remaining unmasked portion of the string. Omit the second argument, `num`, to keep a default of `4` characters unmasked. If `num` is negative, the unmasked characters will be at the start of the string. Omit the third argument, `mask`, to use a default character of `'*'` for the mask. diff --git a/snippets/negate.md b/snippets/negate.md index b8e4b4ab4..9c621990e 100644 --- a/snippets/negate.md +++ b/snippets/negate.md @@ -2,7 +2,7 @@ Negates a predicate function. -Take a predicate function and apply `not` to it with its arguments. +Take a predicate function and apply the not operator (`!`) to it with its arguments. ```js const negate = func => (...args) => !func(...args); diff --git a/snippets/orderBy.md b/snippets/orderBy.md index 5bed5a07e..fb8c99310 100644 --- a/snippets/orderBy.md +++ b/snippets/orderBy.md @@ -2,8 +2,8 @@ Returns a sorted array of objects ordered by properties and orders. -Uses a custom implementation of sort, that reduces the props array argument with a default value of 0, it uses destructuring to swap the properties position depending on the order passed. -If no orders array is passed it sort by 'asc' by default. +Uses `Array.sort()`, `Array.reduce()` on the `props` array with a default value of `0`, use array destructuring to swap the properties position depending on the order passed. +If no `orders` array is passed it sort by `'asc'` by default. ```js const orderBy = (arr, props, orders) => diff --git a/snippets/palindrome.md b/snippets/palindrome.md index e5d4601e4..4db143f65 100644 --- a/snippets/palindrome.md +++ b/snippets/palindrome.md @@ -2,8 +2,8 @@ Returns `true` if the given string is a palindrome, `false` otherwise. -Convert string `toLowerCase()` and use `replace()` to remove non-alphanumeric characters from it. -Then, `split('')` into individual characters, `reverse()`, `join('')` and compare to the original, unreversed string, after converting it `tolowerCase()`. +Convert string `String.toLowerCase()` and use `String.replace()` to remove non-alphanumeric characters from it. +Then, `String.split('')` into individual characters, `Array.reverse()`, `String.join('')` and compare to the original, unreversed string, after converting it `String.tolowerCase()`. ```js const palindrome = str => { diff --git a/snippets/repeatString.md b/snippets/repeatString.md deleted file mode 100644 index 221883ecf..000000000 --- a/snippets/repeatString.md +++ /dev/null @@ -1,16 +0,0 @@ -### repeatString - -Repeats a string n times using `String.repeat()` - -If no string is provided the default is `""` and the default number of times is 2. - -```js -const repeatString = (str = '', num = 2) => { - return num >= 0 ? str.repeat(num) : str; -}; -``` - -```js -repeatString('abc', 3); // 'abcabcabc' -repeatString('abc'); // 'abcabc' -``` diff --git a/snippets/reverseString.md b/snippets/reverseString.md index 95935d47c..befdd8bf5 100644 --- a/snippets/reverseString.md +++ b/snippets/reverseString.md @@ -2,13 +2,15 @@ Reverses a string. -Use `split('')` and `Array.reverse()` to reverse the order of the characters in the string. -Combine characters to get a string using `join('')`. +Use the spread operator (`...`) and `Array.reverse()` to reverse the order of the characters in the string. +Combine characters to get a string using `String.join('')`. ```js + + + const reverseString = str => - str - .split('') + [..str] .reverse() .join(''); ``` diff --git a/snippets/sdbm.md b/snippets/sdbm.md index d64fd2f67..17231a9f2 100644 --- a/snippets/sdbm.md +++ b/snippets/sdbm.md @@ -1,8 +1,8 @@ ### sbdm -This algorithm is a simple hash-algorithm that hashes it input string `s` into a whole number. +Hashes the input string into a whole number. -Use `split('')` and `Array.reduce()` to create a hash of the input string, utilizing bit shifting. +Use `String.split('')` and `Array.reduce()` to create a hash of the input string, utilizing bit shifting. ```js const sdbm = str => { diff --git a/snippets/select.md b/snippets/select.md index 6cb60448b..e000a3cec 100644 --- a/snippets/select.md +++ b/snippets/select.md @@ -1,6 +1,6 @@ ### select -Retrieve a property that indicated by the selector from an object. +Retrieve a property indicated by the selector from an object. If the property does not exists returns `undefined`. diff --git a/snippets/setStyle.md b/snippets/setStyle.md index ef70e78ad..b85c5207c 100644 --- a/snippets/setStyle.md +++ b/snippets/setStyle.md @@ -2,10 +2,10 @@ Sets the value of a CSS rule for the specified element. -Use `element.style` to set the value of the CSS rule for the specified element to `value`. +Use `element.style` to set the value of the CSS rule for the specified element to `val`. ```js -const setStyle = (el, ruleName, value) => (el.style[ruleName] = value); +const setStyle = (el, ruleName, val) => (el.style[ruleName] = val); ``` ```js diff --git a/snippets/shuffle.md b/snippets/shuffle.md index 97b25e8cf..c5ee974d2 100644 --- a/snippets/shuffle.md +++ b/snippets/shuffle.md @@ -2,7 +2,7 @@ Randomizes the order of the values of an array, returning a new array. -Uses the Fisher-Yates algorithm to reorder the elements of the array, based on the [Lodash implementation](https://github.com/lodash/lodash/blob/b2ea6b1cd251796dcb5f9700c4911a7b6223920b/shuffle.js), but as a pure function. +Uses the [Fisher-Yates algorithm](https://github.com/chalarangelo/30-seconds-of-code#shuffle) to reorder the elements of the array. ```js const shuffle = ([...arr]) => { diff --git a/snippets/similarity.md b/snippets/similarity.md index 7aade10ef..1736aebcd 100644 --- a/snippets/similarity.md +++ b/snippets/similarity.md @@ -2,7 +2,7 @@ Returns an array of elements that appear in both arrays. -Use `filter()` to remove values that are not part of `values`, determined using `includes()`. +Use `Array.filter()` to remove values that are not part of `values`, determined using `Array.includes()`. ```js const similarity = (arr, values) => arr.filter(v => values.includes(v)); diff --git a/snippets/size.md b/snippets/size.md index 1c3127929..04a5ff478 100644 --- a/snippets/size.md +++ b/snippets/size.md @@ -2,20 +2,20 @@ Get size of arrays, objects or strings. -Get type of `value` (`array`, `object` or `string`). -Use `length` property for arrays. -Use `length` or `size` value if available or number of keys for objects. -Use `size` of a [`Blob` object](https://developer.mozilla.org/en-US/docs/Web/API/Blob) created from `value` for strings. +Get type of `val` (`array`, `object` or `string`). +Use `length` property for arrays. +Use `length` or `size` value if available or number of keys for objects. +Use `size` of a [`Blob` object](https://developer.mozilla.org/en-US/docs/Web/API/Blob) created from `val` for strings. Split strings into array of characters with `split('')` and return its length. ```js -const size = value => - Array.isArray(value) - ? value.length - : value && typeof value === 'object' - ? value.size || value.length || Object.keys(value).length - : typeof value === 'string' ? new Blob([value]).size : 0; +const size = val => + Array.isArray(val) + ? val.length + : val && typeof val === 'object' + ? val.size || val.length || Object.keys(val).length + : typeof val === 'string' ? new Blob([val]).size : 0; ``` ```js diff --git a/snippets/sortCharactersInString.md b/snippets/sortCharactersInString.md index e9b8c50ae..49c808cd9 100644 --- a/snippets/sortCharactersInString.md +++ b/snippets/sortCharactersInString.md @@ -2,14 +2,10 @@ Alphabetically sorts the characters in a string. -Split the string using `split('')`, `Array.sort()` utilizing `localeCompare()`, recombine using `join('')`. +Use the spread operator (`...`), `Array.sort()` and `String.localeCompare()` to sort the characters in `str`, recombine using `String.join('')`. ```js -const sortCharactersInString = str => - str - .split('') - .sort((a, b) => a.localeCompare(b)) - .join(''); +const sortCharactersInString = str => [...str].sort((a, b) => a.localeCompare(b)).join(''); ``` ```js diff --git a/snippets/sum.md b/snippets/sum.md index a69aa3d4f..0c03ab736 100644 --- a/snippets/sum.md +++ b/snippets/sum.md @@ -5,9 +5,9 @@ Returns the sum of two or more numbers/arrays. Use `Array.reduce()` to add each value to an accumulator, initialized with a value of `0`. ```js -const sum = (...arr) => [].concat(...arr).reduce((acc, val) => acc + val, 0); +const sum = (...arr) => [...arr].reduce((acc, val) => acc + val, 0); ``` ```js -sum([1, 2, 3, 4]); // 10 +sum(...[1, 2, 3, 4]); // 10 ``` diff --git a/snippets/tail.md b/snippets/tail.md index ed2a1458b..49cba196c 100644 --- a/snippets/tail.md +++ b/snippets/tail.md @@ -2,7 +2,7 @@ Returns all elements in an array except for the first one. -Return `arr.slice(1)` if the array's `length` is more than `1`, otherwise, return the whole array. +Return `Array.slice(1)` if the array's `length` is more than `1`, otherwise, return the whole array. ```js const tail = arr => (arr.length > 1 ? arr.slice(1) : arr); diff --git a/snippets/toCamelCase.md b/snippets/toCamelCase.md index 489c045f3..393082f77 100644 --- a/snippets/toCamelCase.md +++ b/snippets/toCamelCase.md @@ -2,8 +2,7 @@ Converts a string to camelcase. -Break the string into words and combine them capitalizing the first letter of each word. -For more detailed explanation of this Regex, [visit this Site](https://regex101.com/r/bMCgAB/1). +Break the string into words and combine them capitalizing the first letter of each word, using a regexp. ```js const toCamelCase = str => { diff --git a/snippets/toKebabCase.md b/snippets/toKebabCase.md index 0c506eb21..4e456982e 100644 --- a/snippets/toKebabCase.md +++ b/snippets/toKebabCase.md @@ -2,8 +2,7 @@ Converts a string to kebab case. -Break the string into words and combine them using `-` as a separator. -For more detailed explanation of this Regex, [visit this Site](https://regex101.com/r/bMCgAB/1). +Break the string into words and combine them adding `-` as a separator, using a regexp. ```js const toKebabCase = str => diff --git a/snippets/toSnakeCase.md b/snippets/toSnakeCase.md index 983095f47..d21d40222 100644 --- a/snippets/toSnakeCase.md +++ b/snippets/toSnakeCase.md @@ -2,8 +2,7 @@ Converts a string to snake case. -Break the string into words and combine them using `_` as a separator. -For more detailed explanation of this Regex, [visit this Site](https://regex101.com/r/bMCgAB/1). +Break the string into words and combine them adding `_` as a separator, using a regexp. ```js const toSnakeCase = str => diff --git a/snippets/tomorrow.md b/snippets/tomorrow.md index 5b4614424..3bd5a6412 100644 --- a/snippets/tomorrow.md +++ b/snippets/tomorrow.md @@ -1,7 +1,7 @@ ### tomorrow Results in a string representation of tomorrow's date. -Use `new Date()` to get today's date, adding `86400000` of seconds to it(24 hours), using `toISOString` to convert Date object to string. +Use `new Date()` to get today's date, adding `86400000` of seconds to it(24 hours), using `Date.toISOString()` to convert Date object to string. ```js const tomorrow = () => new Date(new Date().getTime() + 86400000).toISOString().split('T')[0]; diff --git a/snippets/truncateString.md b/snippets/truncateString.md index faded5500..951343be9 100644 --- a/snippets/truncateString.md +++ b/snippets/truncateString.md @@ -3,7 +3,7 @@ Truncates a string up to a specified length. Determine if the string's `length` is greater than `num`. -Return the string truncated to the desired length, with `...` appended to the end or the original string. +Return the string truncated to the desired length, with `'...'` appended to the end or the original string. ```js const truncateString = (str, num) => diff --git a/snippets/validateNumber.md b/snippets/validateNumber.md index e41370a1e..17a5987d1 100644 --- a/snippets/validateNumber.md +++ b/snippets/validateNumber.md @@ -2,7 +2,7 @@ Returns `true` if the given value is a number, `false` otherwise. -Use `!isNaN` in combination with `parseFloat()` to check if the argument is a number. +Use `!isNaN()` in combination with `parseFloat()` to check if the argument is a number. Use `isFinite()` to check if the number is finite. Use `Number()` to check if the coercion holds. diff --git a/snippets/words.md b/snippets/words.md index bc5f9cee3..425bfbf71 100644 --- a/snippets/words.md +++ b/snippets/words.md @@ -2,8 +2,8 @@ Converts a given string into an array of words. -Use `String.split()` with a supplied pattern (defaults to non-alpha as a regex) to convert to an array of strings. Use `Array.filter()` to remove any empty strings. -Omit the second argument to use the default regex. +Use `String.split()` with a supplied pattern (defaults to non-alpha as a regexp) to convert to an array of strings. Use `Array.filter()` to remove any empty strings. +Omit the second argument to use the default regexp. ```js const words = (str, pattern = /[^a-zA-Z-]+/) => str.split(pattern).filter(Boolean); diff --git a/snippets/JSONToDate.md b/snippets_archive/JSONToDate.md similarity index 100% rename from snippets/JSONToDate.md rename to snippets_archive/JSONToDate.md diff --git a/snippets/collatz.md b/snippets_archive/collatz.md similarity index 100% rename from snippets/collatz.md rename to snippets_archive/collatz.md diff --git a/snippets/factors.md b/snippets_archive/factors.md similarity index 100% rename from snippets/factors.md rename to snippets_archive/factors.md diff --git a/snippets/fibonacciCountUntilNum.md b/snippets_archive/fibonacciCountUntilNum.md similarity index 100% rename from snippets/fibonacciCountUntilNum.md rename to snippets_archive/fibonacciCountUntilNum.md diff --git a/snippets/fibonacciUntilNum.md b/snippets_archive/fibonacciUntilNum.md similarity index 100% rename from snippets/fibonacciUntilNum.md rename to snippets_archive/fibonacciUntilNum.md diff --git a/snippets/howManyTimes.md b/snippets_archive/howManyTimes.md similarity index 100% rename from snippets/howManyTimes.md rename to snippets_archive/howManyTimes.md diff --git a/snippets/isArmstrongNumber.md b/snippets_archive/isArmstrongNumber.md similarity index 100% rename from snippets/isArmstrongNumber.md rename to snippets_archive/isArmstrongNumber.md diff --git a/snippets/quickSort.md b/snippets_archive/quickSort.md similarity index 100% rename from snippets/quickSort.md rename to snippets_archive/quickSort.md diff --git a/snippets/solveRPN.md b/snippets_archive/solveRPN.md similarity index 100% rename from snippets/solveRPN.md rename to snippets_archive/solveRPN.md diff --git a/snippets/speechSynthesis.md b/snippets_archive/speechSynthesis.md similarity index 100% rename from snippets/speechSynthesis.md rename to snippets_archive/speechSynthesis.md diff --git a/static-parts/README-start.md b/static-parts/README-start.md index 105049b76..fc7589866 100644 --- a/static-parts/README-start.md +++ b/static-parts/README-start.md @@ -18,7 +18,7 @@ ⚠️ **WARNING:** Snippets are not production ready. -You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code). +You can find a package with all the snippets on [npm](https://www.npmjs.com/package/30-seconds-of-code). ``` npm install 30-seconds-of-code diff --git a/static-parts/index-start.html b/static-parts/index-start.html index 66e981ad9..00bbe441b 100644 --- a/static-parts/index-start.html +++ b/static-parts/index-start.html @@ -14,13 +14,17 @@