├── how-2-js.js ├── index.html ├── circular.js ├── biggie-smalls.js ├── concat-str.js ├── primitives.js ├── its-a-match.js ├── returns.js ├── min-max.js ├── for-each.js ├── letter-space-number.js ├── repeat.js ├── vowel-dots.js ├── series.js ├── triangle.js ├── chunky.js ├── currify.js ├── all.js ├── get.js ├── flow.js ├── invert.js ├── last-first-kiss.js ├── mutability.js ├── more-or-less.js ├── pyramid.js ├── has-city.js ├── abs.js ├── same-amount.js ├── count-leap-years.js ├── long-words.js ├── ion-out.js ├── day-of-the-year.js ├── change.js ├── flat.js ├── mapper.js ├── valid-ip.js ├── group-price.js ├── quantifiers.js ├── physics.js ├── method-man.js ├── dog-years.js ├── reverser.js ├── sweet-curry.js ├── is.js ├── block-chain.js ├── declarations.js ├── bloody-sunday.js ├── molecules-cells.js ├── keep-cut.js ├── index-of.js ├── nasa.js ├── find-expression.js ├── interpolation.js ├── filter.js ├── rebecca-black.js ├── pimp-my-style.js ├── manipulate-values.js ├── slicer.js ├── sums.js ├── harder-bigger-bolder-stronger.js ├── dr-strange.js ├── reduce.js ├── get-json.js ├── replica.js ├── deep-copy.js ├── get-them-all.js ├── gougle-search.js ├── using-reduce.js ├── using-filter.js ├── flagger.js ├── date-is.js ├── debounce.js ├── unbreakable.js ├── pick-omit.js ├── greedy-url.js ├── keep-trying-or-giveup.js ├── match-cron.js ├── throttle.js ├── manipulate-keys.js ├── keycodes-symphony.js ├── elementary.js ├── fifty-shades-of-cold.js ├── is-winner.js ├── using-map.js ├── fusion.js ├── get-some-time.js ├── race.js ├── manipulate-entries.js ├── curry-entries.js ├── collections.js ├── cut-corners.js ├── neuron.js ├── unicode-technical-report-35.js ├── pick-and-click.js ├── gossip-grid.js ├── pronoun.js ├── mouse-trap.js └── where-do-we-go.js /how-2-js.js: -------------------------------------------------------------------------------- 1 | console.log('Hello World') 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /circular.js: -------------------------------------------------------------------------------- 1 | const circular = {}; 2 | 3 | circular.circular = circular; 4 | -------------------------------------------------------------------------------- /biggie-smalls.js: -------------------------------------------------------------------------------- 1 | const smalls = Number.NEGATIVE_INFINITY; 2 | const biggie = Number.POSITIVE_INFINITY; 3 | -------------------------------------------------------------------------------- /concat-str.js: -------------------------------------------------------------------------------- 1 | function concatStr(str1, str2) { 2 | return str1.toString() + str2.toString(); 3 | } 4 | -------------------------------------------------------------------------------- /primitives.js: -------------------------------------------------------------------------------- 1 | const str = "string"; 2 | const num = 1; 3 | const bool = true; 4 | const undef = undefined; 5 | -------------------------------------------------------------------------------- /its-a-match.js: -------------------------------------------------------------------------------- 1 | const normal = /hi/; 2 | const begin = /^hi/; 3 | const end = /hi$/; 4 | const beginEnd = /^hi$/; 5 | -------------------------------------------------------------------------------- /returns.js: -------------------------------------------------------------------------------- 1 | function id(x) { 2 | return x; 3 | } 4 | 5 | function getLength(x) { 6 | return x.length; 7 | } 8 | -------------------------------------------------------------------------------- /min-max.js: -------------------------------------------------------------------------------- 1 | function max(a, b) { 2 | return a > b ? a : b; 3 | } 4 | 5 | function min(a, b) { 6 | return a < b ? a : b; 7 | } 8 | -------------------------------------------------------------------------------- /for-each.js: -------------------------------------------------------------------------------- 1 | function forEach(array, action) { 2 | for (let i = 0; i < array.length; i++) { 3 | action(array[i], i, array); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /letter-space-number.js: -------------------------------------------------------------------------------- 1 | function letterSpaceNumber(str) { 2 | let arr = str.match(/[a-z] [0-9](?![a-z0-9])/gi); 3 | return arr !== null ? arr : []; 4 | } 5 | -------------------------------------------------------------------------------- /repeat.js: -------------------------------------------------------------------------------- 1 | function repeat(str, num) { 2 | var result = ""; 3 | for (var i = 0; i < num; i++) { 4 | result += str; 5 | } 6 | return result; 7 | } 8 | -------------------------------------------------------------------------------- /vowel-dots.js: -------------------------------------------------------------------------------- 1 | const vowels = /[aeiou]/gi; 2 | function vowelDots(str) { 3 | return str.replace(/[aeiou]/gi, function (v) { 4 | return v + "."; 5 | }); 6 | } 7 | -------------------------------------------------------------------------------- /series.js: -------------------------------------------------------------------------------- 1 | async function series(arr) { 2 | var result = []; 3 | for (const item of arr) { 4 | result.push(await item()); 5 | } 6 | return result; 7 | } 8 | -------------------------------------------------------------------------------- /triangle.js: -------------------------------------------------------------------------------- 1 | function triangle(char, n) { 2 | let str = ""; 3 | for (var i = 1; i <= n; i++) { 4 | str = str + char.repeat(i) + "\n"; 5 | } 6 | return str.slice(0, -1); 7 | } 8 | -------------------------------------------------------------------------------- /chunky.js: -------------------------------------------------------------------------------- 1 | function chunk(arr, size) { 2 | var result = []; 3 | for (var i = 0; i < arr.length; i += size) { 4 | result.push(arr.slice(i, i + size)); 5 | } 6 | return result; 7 | } 8 | -------------------------------------------------------------------------------- /currify.js: -------------------------------------------------------------------------------- 1 | function currify(fn) { 2 | return function currified(...args) { 3 | return args.length >= fn.length 4 | ? fn(...args) 5 | : currified.bind(null, ...args); 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /all.js: -------------------------------------------------------------------------------- 1 | async function all(objs = {}) { 2 | var res = {}; 3 | if (Object.keys(objs).length === 0) return {}; 4 | for (let key in objs) { 5 | res[key] = await objs[key]; 6 | } 7 | return res; 8 | } 9 | -------------------------------------------------------------------------------- /get.js: -------------------------------------------------------------------------------- 1 | function get(src, path) { 2 | return path.split(".").reduce(function (obj, key) { 3 | if (obj === undefined) { 4 | return undefined; 5 | } 6 | return obj[key]; 7 | }, src); 8 | } 9 | -------------------------------------------------------------------------------- /flow.js: -------------------------------------------------------------------------------- 1 | function flow(arr) { 2 | return function (...args) { 3 | if (args.length > 1) { 4 | args = [arr[0](...args)]; 5 | } 6 | return arr.reduce((acc, fn) => fn(acc), args[0]); 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /invert.js: -------------------------------------------------------------------------------- 1 | function invert(obj) { 2 | const inverted = {}; 3 | for (let key in obj) { 4 | if (obj.hasOwnProperty(key)) { 5 | inverted[obj[key]] = key; 6 | } 7 | } 8 | return inverted; 9 | } 10 | -------------------------------------------------------------------------------- /last-first-kiss.js: -------------------------------------------------------------------------------- 1 | function first(input) { 2 | return input[0]; 3 | } 4 | 5 | function last(input) { 6 | return input[input.length - 1]; 7 | } 8 | 9 | function kiss(input) { 10 | return [last(input), first(input)]; 11 | } 12 | -------------------------------------------------------------------------------- /mutability.js: -------------------------------------------------------------------------------- 1 | let clone1 = { ...person }; 2 | let clone2 = Object.assign({}, person); 3 | 4 | let samePerson = person; 5 | 6 | person.age += 1; 7 | person.country = "FR"; 8 | 9 | if (person !== clone1) { 10 | samePerson = person; 11 | } 12 | -------------------------------------------------------------------------------- /more-or-less.js: -------------------------------------------------------------------------------- 1 | function more(x) { 2 | return (x += 1); 3 | } 4 | 5 | function less(x) { 6 | return (x -= 1); 7 | } 8 | 9 | function add(x, y) { 10 | return (x += y); 11 | } 12 | 13 | function sub(x, y) { 14 | return (x -= y); 15 | } 16 | -------------------------------------------------------------------------------- /pyramid.js: -------------------------------------------------------------------------------- 1 | function pyramid(char, n) { 2 | let str = ""; 3 | let spaces = " ".repeat(char.length); 4 | for (var i = 1; i <= n; i++) { 5 | str = str + spaces.repeat(n - i) + char.repeat(2 * i - 1) + "\n"; 6 | } 7 | return str.slice(0, -1); 8 | } 9 | -------------------------------------------------------------------------------- /has-city.js: -------------------------------------------------------------------------------- 1 | function hasCity(country, cities) { 2 | return function (city) { 3 | if (cities.indexOf(city) === -1) { 4 | return city + " is not a city from " + country; 5 | } 6 | return city + " is a city from " + country; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /abs.js: -------------------------------------------------------------------------------- 1 | function isPositive(a) { 2 | if (a > 0) { 3 | return true; 4 | } else { 5 | return false; 6 | } 7 | } 8 | 9 | function abs(a) { 10 | if (isPositive(a) || a == 0) { 11 | return a; 12 | } else { 13 | return -a; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /same-amount.js: -------------------------------------------------------------------------------- 1 | function sameAmount(str, rexp1, rexp2) { 2 | rexp1 = new RegExp(rexp1, "g"); 3 | rexp2 = new RegExp(rexp2, "g"); 4 | let test1 = str.match(rexp1); 5 | let test2 = str.match(rexp2); 6 | return test1 !== null && test2 !== null && test1.length === test2.length; 7 | } 8 | -------------------------------------------------------------------------------- /count-leap-years.js: -------------------------------------------------------------------------------- 1 | function countLeapYears(date) { 2 | let years = 0; 3 | for (let year = 1; year < date.getFullYear(); year++) { 4 | if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) { 5 | years++; 6 | } 7 | } 8 | return years; 9 | } 10 | -------------------------------------------------------------------------------- /long-words.js: -------------------------------------------------------------------------------- 1 | function longWords(arr) { 2 | return arr.every((item) => item.length >= 5); 3 | } 4 | 5 | function oneLongWord(arr) { 6 | return arr.some((item) => item.length >= 10); 7 | } 8 | 9 | function noLongWords(arr) { 10 | return arr.every((item) => item.length < 7); 11 | } 12 | -------------------------------------------------------------------------------- /ion-out.js: -------------------------------------------------------------------------------- 1 | function ionOut(str) { 2 | let arr = str.split(" "); 3 | let rexp = /tion/g; 4 | let res = []; 5 | arr.forEach((word) => { 6 | word.match(rexp) 7 | ? res.push(word.replace(/[.,?!]/g, "").slice(0, -3)) 8 | : null; 9 | }); 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /day-of-the-year.js: -------------------------------------------------------------------------------- 1 | function dayOfTheYear(date) { 2 | let days = 1; 3 | while (!isFirstofFirst(date)) { 4 | date.setDate(date.getDate() - 1); 5 | days++; 6 | } 7 | return days; 8 | } 9 | 10 | function isFirstofFirst(date) { 11 | return date.getDate() === 1 && date.getMonth() === 0; 12 | } 13 | -------------------------------------------------------------------------------- /change.js: -------------------------------------------------------------------------------- 1 | function get(key) { 2 | return eval("sourceObject." + key); 3 | } 4 | 5 | function set(key, value) { 6 | if (typeof value === "string") { 7 | eval("sourceObject." + key + "='" + value + "'"); 8 | } else { 9 | eval("sourceObject." + key + "=" + value); 10 | } 11 | return value; 12 | } 13 | -------------------------------------------------------------------------------- /flat.js: -------------------------------------------------------------------------------- 1 | function flat(arr, depth) { 2 | if (!Array.isArray(arr)) { 3 | return arr; 4 | } 5 | if (depth === 0) { 6 | return arr; 7 | } 8 | if (depth === undefined) { 9 | depth = 1; 10 | } 11 | return arr.reduce((acc, cur) => { 12 | return acc.concat(flat(cur, depth - 1)); 13 | }, []); 14 | } 15 | -------------------------------------------------------------------------------- /mapper.js: -------------------------------------------------------------------------------- 1 | function map(arr, action) { 2 | let res = []; 3 | for (let i = 0; i < arr.length; i++) { 4 | res.push(action(arr[i], i, arr)); 5 | } 6 | return res; 7 | } 8 | 9 | function flatMap(arr, action) { 10 | return arr.reduce( 11 | (acc, val, i, arr) => acc.concat(action(val, i, arr)), 12 | [] 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /valid-ip.js: -------------------------------------------------------------------------------- 1 | function findIP(str) { 2 | return str.match( 3 | /(?!(((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}):(?!(?![7-9]\d\d\d\d)(?!6[6-9]\d\d\d)(?!65[6-9]\d\d)(?!655[4-9]\d)(?!6553[6-9])(?!0+)(\d{1,5})))((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4})(?::(?![7-9]\d\d\d\d)(?!6[6-9]\d\d\d)(?!65[6-9]\d\d)(?!655[4-9]\d)(?!6553[6-9])(?!0+)(\d{1,5}))?)/g 4 | ); 5 | } 6 | -------------------------------------------------------------------------------- /group-price.js: -------------------------------------------------------------------------------- 1 | function groupPrice(str) { 2 | let prices = str.match(/(([A-Z]{3})|\$)([0-9]+\.[0-9]+)/g); 3 | let res = []; 4 | if (prices === null) return res; 5 | prices.forEach((price, i) => { 6 | res.push([price]); 7 | res[i].push(price.match(/[0-9]+/g)[0]); 8 | res[i].push(price.match(/[0-9]+/g)[1]); 9 | }); 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /quantifiers.js: -------------------------------------------------------------------------------- 1 | function every(array, test) { 2 | for (var i = 0; i < array.length; i++) { 3 | if (!test(array[i])) return false; 4 | } 5 | return true; 6 | } 7 | 8 | function some(array, test) { 9 | for (var i = 0; i < array.length; i++) { 10 | if (test(array[i])) return true; 11 | } 12 | return false; 13 | } 14 | 15 | function none(array, test) { 16 | return !some(array, test); 17 | } 18 | -------------------------------------------------------------------------------- /physics.js: -------------------------------------------------------------------------------- 1 | function getAcceleration(obj) { 2 | if (obj.hasOwnProperty("f") && obj.hasOwnProperty("m")) { 3 | return obj.f / obj.m; 4 | } else if (obj.hasOwnProperty("Δv") && obj.hasOwnProperty("Δt")) { 5 | return obj.Δv / obj.Δt; 6 | } else if (obj.hasOwnProperty("d") && obj.hasOwnProperty("t")) { 7 | return (obj.d * 2) / (obj.t * obj.t); 8 | } else { 9 | return "impossible"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /method-man.js: -------------------------------------------------------------------------------- 1 | function words(string) { 2 | return string.split(" "); 3 | } 4 | 5 | function sentence(arr) { 6 | return arr.join(" "); 7 | } 8 | 9 | function yell(string) { 10 | return string.toUpperCase(); 11 | } 12 | 13 | function whisper(string) { 14 | return "*" + string.toLowerCase() + "*"; 15 | } 16 | 17 | function capitalize(string) { 18 | return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); 19 | } 20 | -------------------------------------------------------------------------------- /dog-years.js: -------------------------------------------------------------------------------- 1 | function dogYears(planet, age) { 2 | const planets = { 3 | earth: 1, 4 | mercury: 0.2408467, 5 | venus: 0.61519726, 6 | mars: 1.8808158, 7 | jupiter: 11.862615, 8 | saturn: 29.447498, 9 | uranus: 84.016846, 10 | neptune: 164.79132, 11 | }; 12 | let earthAge = (age / 31557600) * 7; 13 | 14 | return Number(Number(earthAge / planets[planet]).toFixed(2)); 15 | } 16 | -------------------------------------------------------------------------------- /reverser.js: -------------------------------------------------------------------------------- 1 | function reverse(input) { 2 | if (typeof input === "string") { 3 | let res = ""; 4 | for (let i = input.length - 1; i >= 0; i--) { 5 | res += input[i]; 6 | } 7 | return res; 8 | } else if (Array.isArray(input)) { 9 | let res = []; 10 | for (let i = input.length - 1; i >= 0; i--) { 11 | res.push(input[i]); 12 | } 13 | return res; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sweet-curry.js: -------------------------------------------------------------------------------- 1 | function mult2(x) { 2 | return (y) => x * y; 3 | } 4 | 5 | function add3(x) { 6 | return function (y) { 7 | return function (z) { 8 | return x + y + z; 9 | }; 10 | }; 11 | } 12 | 13 | function sub4(x) { 14 | return function (y) { 15 | return function (z) { 16 | return function (w) { 17 | return x - y - z - w; 18 | }; 19 | }; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /is.js: -------------------------------------------------------------------------------- 1 | is.num = (n) => typeof n === "number"; 2 | is.nan = (n) => Number.isNaN(n); 3 | is.str = (n) => typeof n === "string"; 4 | is.bool = (n) => typeof n === "boolean"; 5 | is.undef = (n) => n === undefined; 6 | is.def = (n) => !is.undef(n); 7 | is.arr = (n) => Array.isArray(n); 8 | is.obj = (n) => typeof n === "object" && !is.fun(n) && !is.arr(n) && n !== null; 9 | is.fun = (n) => typeof n === "function"; 10 | is.truthy = (n) => !!n; 11 | is.falsy = (n) => !n; 12 | -------------------------------------------------------------------------------- /block-chain.js: -------------------------------------------------------------------------------- 1 | function blockChain(data, prev) { 2 | if (prev == null) { 3 | prev = { index: 0, hash: "0" }; 4 | } 5 | return { 6 | index: prev.index + 1, 7 | hash: hashCode( 8 | (prev.index + 1).toString() + prev.hash + JSON.stringify(data) 9 | ), 10 | data: data, 11 | prev: prev, 12 | chain: function (data) { 13 | return blockChain(data, this); 14 | }, 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /declarations.js: -------------------------------------------------------------------------------- 1 | const escapeStr = "`\\/\"'"; 2 | const arr = [4, "2"]; 3 | const obj = { 4 | str: "string", 5 | num: 1, 6 | bool: true, 7 | undef: undefined, 8 | }; 9 | const nested = { 10 | arr: [4, undefined, "2"], 11 | obj: { 12 | str: "string", 13 | num: 1, 14 | bool: true, 15 | }, 16 | }; 17 | Object.freeze(nested); 18 | Object.freeze(nested.obj); 19 | Object.freeze(nested.arr); 20 | Object.freeze(arr); 21 | Object.freeze(obj); 22 | -------------------------------------------------------------------------------- /bloody-sunday.js: -------------------------------------------------------------------------------- 1 | function bloodySunday(date) { 2 | let counter = -1; 3 | const week = [ 4 | "Monday", 5 | "Tuesday", 6 | "Wednesday", 7 | "Thursday", 8 | "Friday", 9 | "Saturday", 10 | ]; 11 | let start = new Date("0001-01-01T00:00:00"); 12 | while (start <= date) { 13 | start.setDate(start.getDate() + 1); 14 | counter++; 15 | } 16 | console.log(week[counter % 6]); 17 | return week[counter % 6]; 18 | } 19 | -------------------------------------------------------------------------------- /molecules-cells.js: -------------------------------------------------------------------------------- 1 | const DNAtoRNA = { 2 | G: "C", 3 | C: "G", 4 | T: "A", 5 | A: "U", 6 | }; 7 | const RNAtoDNA = { 8 | C: "G", 9 | G: "C", 10 | A: "T", 11 | U: "A", 12 | }; 13 | 14 | function RNA(dna) { 15 | return dna 16 | .split("") 17 | .map((nucleotide) => DNAtoRNA[nucleotide]) 18 | .join(""); 19 | } 20 | 21 | function DNA(rna) { 22 | return rna 23 | .split("") 24 | .map((nucleotide) => RNAtoDNA[nucleotide]) 25 | .join(""); 26 | } 27 | -------------------------------------------------------------------------------- /keep-cut.js: -------------------------------------------------------------------------------- 1 | function cutFirst(str) { 2 | return str.slice(2); 3 | } 4 | 5 | function cutLast(str) { 6 | return str.slice(0, -2); 7 | } 8 | 9 | function cutFirstLast(str) { 10 | return str.slice(2, -2); 11 | } 12 | 13 | function keepFirst(str) { 14 | return str.slice(0, 2); 15 | } 16 | 17 | function keepLast(str) { 18 | return str.slice(-2); 19 | } 20 | 21 | function keepFirstLast(str) { 22 | if (str.length <= 3) { 23 | return str; 24 | } 25 | return str.slice(0, 2) + str.slice(-2); 26 | } 27 | -------------------------------------------------------------------------------- /index-of.js: -------------------------------------------------------------------------------- 1 | function indexOf(arr, item, index) { 2 | for (var i = index || 0; i < arr.length; i++) { 3 | if (arr[i] === item) { 4 | return i; 5 | } 6 | } 7 | return -1; 8 | } 9 | 10 | function lastIndexOf(arr, item, index) { 11 | for (var i = index || arr.length - 1; i >= 0; i--) { 12 | if (arr[i] === item) { 13 | return i; 14 | } 15 | } 16 | return -1; 17 | } 18 | 19 | function includes(arr, item, index) { 20 | return indexOf(arr, item, index) !== -1; 21 | } 22 | -------------------------------------------------------------------------------- /nasa.js: -------------------------------------------------------------------------------- 1 | function nasa(int) { 2 | var result = ""; 3 | for (var i = 1; i <= int; i++) { 4 | if (i % 3 === 0 && i % 5 === 0) { 5 | result = result + "NASA"; 6 | } else if (i % 3 === 0) { 7 | result = result + "NA"; 8 | } else if (i % 5 === 0) { 9 | result = result + "SA"; 10 | } else { 11 | result = result + i.toString(); 12 | } 13 | if (i !== int) { 14 | result = result + " "; 15 | } 16 | } 17 | return result; 18 | } 19 | -------------------------------------------------------------------------------- /find-expression.js: -------------------------------------------------------------------------------- 1 | function findExpression(num) { 2 | for (let i = 0; i < 100000; i++) { 3 | let cpy = 1; 4 | let seq = "1"; 5 | while (cpy <= num) { 6 | if (cpy === num) { 7 | return seq; 8 | } 9 | if (Math.random() < 0.4 + 0.1) { 10 | cpy += 4; 11 | seq += " " + add4; 12 | } else { 13 | cpy *= 2; 14 | seq += " " + mul2; 15 | } 16 | } 17 | } 18 | return undefined; 19 | } 20 | -------------------------------------------------------------------------------- /interpolation.js: -------------------------------------------------------------------------------- 1 | function interpolation({ 2 | step = 0, 3 | start = 0, 4 | end = 0, 5 | callback = () => {}, 6 | duration = 0, 7 | } = {}) { 8 | const delta = (end - start) / step; 9 | let current = start; 10 | let i = 0; 11 | const timer = setInterval(() => { 12 | if (i < step) { 13 | callback([current, (duration / step) * (i + 1)]); 14 | current += delta; 15 | i++; 16 | } else { 17 | clearInterval(timer); 18 | } 19 | }, duration / step); 20 | } 21 | -------------------------------------------------------------------------------- /filter.js: -------------------------------------------------------------------------------- 1 | function filter(arr, fn) { 2 | var result = []; 3 | for (var i = 0; i < arr.length; i++) { 4 | if (fn(arr[i], i, arr)) { 5 | result.push(arr[i]); 6 | } 7 | } 8 | return result; 9 | } 10 | 11 | function reject(arr, fn) { 12 | var result = []; 13 | for (var i = 0; i < arr.length; i++) { 14 | if (!fn(arr[i], i, arr)) { 15 | result.push(arr[i]); 16 | } 17 | } 18 | return result; 19 | } 20 | 21 | function partition(arr, fn) { 22 | return [filter(arr, fn), reject(arr, fn)]; 23 | } 24 | -------------------------------------------------------------------------------- /rebecca-black.js: -------------------------------------------------------------------------------- 1 | function isFriday(date) { 2 | return new Date(date).getDay() === 5; 3 | } 4 | 5 | function isWeekend(date) { 6 | var day = new Date(date).getDay(); 7 | return day === 0 || day === 6; 8 | } 9 | 10 | function isLeapYear(date) { 11 | var year = new Date(date).getFullYear(); 12 | return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; 13 | } 14 | 15 | function isLastDayOfMonth(date) { 16 | var d = new Date(date); 17 | return ( 18 | new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate() === d.getDate() 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /pimp-my-style.js: -------------------------------------------------------------------------------- 1 | import { styles } from "./pimp-my-style.data.js"; 2 | var counter = 0; 3 | 4 | function pimp() { 5 | var button = document.querySelector("button.button"); 6 | if (!button.classList.contains("unpimp")) { 7 | button.classList.add(styles[counter]); 8 | counter++; 9 | } else { 10 | counter--; 11 | button.classList.remove(styles[counter]); 12 | if (counter === 0) { 13 | button.classList.toggle("unpimp"); 14 | } 15 | } 16 | if (counter === styles.length) { 17 | button.classList.toggle("unpimp"); 18 | } 19 | } 20 | 21 | export { pimp }; 22 | -------------------------------------------------------------------------------- /manipulate-values.js: -------------------------------------------------------------------------------- 1 | function filterValues(obj, callback) { 2 | let res = {}; 3 | for (let key in obj) { 4 | if (callback(obj[key])) { 5 | res[key] = obj[key]; 6 | } 7 | } 8 | return res; 9 | } 10 | 11 | function mapValues(obj, callback) { 12 | let res = {}; 13 | for (let key in obj) { 14 | res[key] = callback(obj[key]); 15 | } 16 | return res; 17 | } 18 | 19 | function reduceValues(obj, callback, acc) { 20 | if (acc === undefined) { 21 | acc = 0; 22 | } 23 | for (let key in obj) { 24 | acc = callback(acc, obj[key]); 25 | } 26 | return acc; 27 | } 28 | -------------------------------------------------------------------------------- /slicer.js: -------------------------------------------------------------------------------- 1 | function slice(input, start, end) { 2 | if (end === undefined) { 3 | end = input.length; 4 | } 5 | let res; 6 | if (start < 0) { 7 | start = input.length + start; 8 | } 9 | if (end < 0) { 10 | end = input.length + end; 11 | } 12 | if (typeof input === "string") { 13 | res = ""; 14 | for (let i = start; i < end; i++) { 15 | res += input[i]; 16 | } 17 | } 18 | if (Array.isArray(input)) { 19 | res = []; 20 | for (let i = start; i < end; i++) { 21 | res.push(input[i]); 22 | } 23 | } 24 | return res; 25 | } 26 | -------------------------------------------------------------------------------- /sums.js: -------------------------------------------------------------------------------- 1 | function sums(n) { 2 | if (n < 2) return []; 3 | var partitions = [], 4 | current = []; 5 | 6 | function addPartition() { 7 | partitions.push(current.slice()); 8 | } 9 | 10 | function findPartitions(start, remaining) { 11 | if (remaining === 0) { 12 | addPartition(); 13 | } else { 14 | for (var i = start; i <= remaining; i++) { 15 | current.push(i); 16 | findPartitions(i, remaining - i); 17 | current.pop(); 18 | } 19 | } 20 | } 21 | 22 | findPartitions(1, n); 23 | 24 | return partitions.slice(0, -1); 25 | } 26 | -------------------------------------------------------------------------------- /harder-bigger-bolder-stronger.js: -------------------------------------------------------------------------------- 1 | function generateLetters() { 2 | for (let i = 0; i < 120; i++) { 3 | let letter = document.createElement("div"); 4 | letter.style.fontSize = `${11 + i}px`; 5 | letter.textContent = String.fromCharCode( 6 | 65 + Math.floor(Math.random() * 26) 7 | ); 8 | if (i < 40) { 9 | letter.style.fontWeight = "300"; 10 | } else if (i < 80) { 11 | letter.style.fontWeight = "400"; 12 | } else { 13 | letter.style.fontWeight = "600"; 14 | } 15 | document.getElementsByTagName("body")[0].appendChild(letter); 16 | } 17 | } 18 | 19 | export { generateLetters }; 20 | -------------------------------------------------------------------------------- /dr-strange.js: -------------------------------------------------------------------------------- 1 | function addWeek(date) { 2 | const secondWeek = { 3 | 0: "Monday", 4 | 1: "Tuesday", 5 | 2: "Wednesday", 6 | 3: "Thursday", 7 | 4: "Friday", 8 | 5: "Saturday", 9 | 6: "Sunday", 10 | 7: "secondMonday", 11 | 8: "secondTuesday", 12 | 9: "secondWednesday", 13 | 10: "secondThursday", 14 | 11: "secondFriday", 15 | 12: "secondSaturday", 16 | 13: "secondSunday", 17 | }; 18 | let zTime = date.getTime() + 62135596800000; 19 | return secondWeek[(zTime / 86400000) % 14]; 20 | } 21 | 22 | function timeTravel(date) { 23 | return new Date(date.date.setHours(date.hour, date.minute, date.second)); 24 | } 25 | -------------------------------------------------------------------------------- /reduce.js: -------------------------------------------------------------------------------- 1 | function fold(arr, f, acc) { 2 | for (var i = 0; i < arr.length; i++) { 3 | acc = f(acc, arr[i], i, arr); 4 | } 5 | return acc; 6 | } 7 | 8 | function foldRight(arr, f, acc) { 9 | for (var i = arr.length - 1; i >= 0; i--) { 10 | acc = f(acc, arr[i], i, arr); 11 | } 12 | return acc; 13 | } 14 | 15 | function reduce(arr, f) { 16 | let acc = arr[0]; 17 | for (var i = 1; i < arr.length; i++) { 18 | acc = f(acc, arr[i], i, arr); 19 | } 20 | return acc; 21 | } 22 | 23 | function reduceRight(arr, f) { 24 | let acc = arr[arr.length - 1]; 25 | for (var i = arr.length - 2; i >= 0; i--) { 26 | acc = f(acc, arr[i], i, arr); 27 | } 28 | return acc; 29 | } 30 | -------------------------------------------------------------------------------- /get-json.js: -------------------------------------------------------------------------------- 1 | async function getJSON(path = '', params = {}) { 2 | const url = 3 | path + 4 | '?' + 5 | Object.keys(params) 6 | .map((key) => { 7 | return ( 8 | key.replace(' ', '+') + 9 | '=' + 10 | params[key].toString().replace(' ', '+') 11 | ); 12 | }) 13 | .join('&'); 14 | const res = await fetch(url).then((response) => { 15 | if (response.ok) { 16 | return response.json(); 17 | } else { 18 | throw new Error(response.statusText); 19 | } 20 | }); 21 | if (res.error) { 22 | throw new Error(res.error); 23 | } 24 | return res.data; 25 | } 26 | -------------------------------------------------------------------------------- /replica.js: -------------------------------------------------------------------------------- 1 | var is = {}; 2 | is.arr = (n) => Array.isArray(n); 3 | is.obj = (n) => 4 | typeof n === 'object' && 5 | !is.fun(n) && 6 | !is.arr(n) && 7 | n !== null && 8 | !(n instanceof RegExp); 9 | is.fun = (n) => typeof n === 'function'; 10 | 11 | function replica(target, ...sources) { 12 | sources.forEach((source) => { 13 | Object.keys(source).forEach((key) => { 14 | if (is.obj(source[key])) { 15 | if (!target.hasOwnProperty(key) || !is.obj(target[key])) { 16 | target[key] = {}; 17 | } 18 | replica(target[key], source[key]); 19 | } else { 20 | target[key] = source[key]; 21 | } 22 | }); 23 | }); 24 | return target; 25 | } 26 | -------------------------------------------------------------------------------- /deep-copy.js: -------------------------------------------------------------------------------- 1 | function deepCopy(input) { 2 | if (Array.isArray(input)) { 3 | var output = []; 4 | for (var i = 0; i < input.length; i++) { 5 | output[i] = deepCopy(input[i]); 6 | } 7 | return output; 8 | } else if (isDefenitelyAnObject(input)) { 9 | var output = {}; 10 | for (var key in input) { 11 | output[key] = deepCopy(input[key]); 12 | } 13 | return output; 14 | } else { 15 | return input; 16 | } 17 | } 18 | 19 | function isDefenitelyAnObject(input) { 20 | return ( 21 | typeof input === "object" && 22 | !(typeof input === "function") && 23 | !Array.isArray(input) && 24 | input !== null && 25 | !(input instanceof RegExp) 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /get-them-all.js: -------------------------------------------------------------------------------- 1 | function getArchitects() { 2 | return [ 3 | document.querySelectorAll("body a"), 4 | document.querySelectorAll("body span"), 5 | ]; 6 | } 7 | 8 | function getClassical() { 9 | return [ 10 | document.querySelectorAll("a.classical"), 11 | document.querySelectorAll("a:not(.classical)"), 12 | ]; 13 | } 14 | 15 | function getActive() { 16 | return [ 17 | document.querySelectorAll("a.classical.active"), 18 | document.querySelectorAll("a.classical:not(.active)"), 19 | ]; 20 | } 21 | 22 | function getBonannoPisano() { 23 | return [ 24 | document.getElementById("BonannoPisano"), 25 | document.querySelectorAll("a.classical.active"), 26 | ]; 27 | } 28 | 29 | export { getArchitects, getClassical, getActive, getBonannoPisano }; 30 | -------------------------------------------------------------------------------- /gougle-search.js: -------------------------------------------------------------------------------- 1 | async function queryServers(serverName, q) { 2 | var url = '/' + serverName + '?q=' + q; 3 | var backupUrl = '/' + serverName + '_backup?q=' + q; 4 | const req1 = getJSON(url); 5 | const req2 = getJSON(backupUrl); 6 | const res = await Promise.race([req1, req2]); 7 | return res; 8 | } 9 | 10 | async function gougleSearch(q) { 11 | var timeout = new Promise((resolve) => 12 | setTimeout(resolve, 80, Error('timeout')) 13 | ); 14 | var web = queryServers('web', q), 15 | image = queryServers('image', q), 16 | video = queryServers('video', q); 17 | 18 | const res = await Promise.race([timeout, Promise.all([web, image, video])]); 19 | if (res instanceof Error) { 20 | throw res; 21 | } 22 | return { image: res[1], video: res[2], web: res[0] }; 23 | } 24 | -------------------------------------------------------------------------------- /using-reduce.js: -------------------------------------------------------------------------------- 1 | function adder(arr, value) { 2 | return arr.reduce( 3 | (acc, item) => acc + item, 4 | value === undefined ? 0 : value 5 | ); 6 | } 7 | 8 | function sumOrMul(arr, value) { 9 | return arr.reduce( 10 | (acc, item) => { 11 | if (item % 2 === 0) { 12 | return acc * item; 13 | } else { 14 | return acc + item; 15 | } 16 | }, 17 | value === undefined ? 0 : value 18 | ); 19 | } 20 | 21 | function funcExec(arr, value) { 22 | return arr.reduce( 23 | (acc, item) => { 24 | if (typeof item === "function") { 25 | return item(acc, value); 26 | } else { 27 | return acc; 28 | } 29 | }, 30 | value === undefined ? 0 : value 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /using-filter.js: -------------------------------------------------------------------------------- 1 | function filterShortStateName(arr) { 2 | return arr.filter((item) => item.length < 7); 3 | } 4 | 5 | function filterStartVowel(arr) { 6 | return arr.filter((item) => /^[aeiou]/i.test(item)); 7 | } 8 | 9 | function filter5Vowels(arr) { 10 | return arr.filter((item) => item.match(/[aeiou]/gi).length >= 5); 11 | } 12 | 13 | function filter1DistinctVowel(arr) { 14 | return arr.filter( 15 | (item) => new Set(item.toLowerCase().match(/[aeiou]/gi)).size === 1 16 | ); 17 | } 18 | 19 | function multiFilter(arr) { 20 | arr = arr.filter((item) => { 21 | let capital = item.capital.length >= 8; 22 | let name = !/^[aeiou]/i.test(item.name); 23 | let tag = /[aeiou]/i.test(item.tag); 24 | let region = item.region !== "South"; 25 | return capital && name && tag && region; 26 | }); 27 | return arr; 28 | } 29 | -------------------------------------------------------------------------------- /flagger.js: -------------------------------------------------------------------------------- 1 | function flags(obj) { 2 | var res = { alias: { h: 'help' } }; 3 | if (obj.length === 0) return res; 4 | let help = obj.help; 5 | delete obj.help; 6 | for (let key in obj) { 7 | res.alias[key[0]] = key; 8 | } 9 | if (help) { 10 | res.description = help.map((key) => { 11 | let desc = obj[key]; 12 | return `-${key[0]}, --${key}: ${desc}`; 13 | }); 14 | } else { 15 | res.description = Object.keys(obj).map((key) => { 16 | let desc = obj[key]; 17 | return `-${key[0]}, --${key}: ${desc}`; 18 | }); 19 | } 20 | res.description.length === 0 21 | ? (res.description = '') 22 | : res.description.length === 1 23 | ? (res.description = res.description[0]) 24 | : (res.description = res.description.join('\n')); 25 | return res; 26 | } 27 | -------------------------------------------------------------------------------- /date-is.js: -------------------------------------------------------------------------------- 1 | function isValid(date) { 2 | if (new Date(date).toString() === "Invalid Date") { 3 | return false; 4 | } 5 | if (!(date instanceof Date) && typeof date !== "number") { 6 | return false; 7 | } 8 | return true; 9 | } 10 | 11 | function isAfter(d1, d2) { 12 | if (d1 > d2) { 13 | return true; 14 | } 15 | return false; 16 | } 17 | 18 | function isBefore(d1, d2) { 19 | if (d1 < d2) { 20 | return true; 21 | } 22 | return false; 23 | } 24 | 25 | function isFuture(date) { 26 | if (!isValid(date)) { 27 | return false; 28 | } 29 | if (new Date(date).getTime() > Date.now()) { 30 | return true; 31 | } 32 | return false; 33 | } 34 | 35 | function isPast(date) { 36 | if (!isValid(date)) { 37 | return false; 38 | } 39 | if (new Date(date).getTime() < Date.now()) { 40 | return true; 41 | } 42 | return false; 43 | } 44 | -------------------------------------------------------------------------------- /debounce.js: -------------------------------------------------------------------------------- 1 | function debounce(fn, delay) { 2 | let timer = null; 3 | return function () { 4 | let context = this; 5 | let args = arguments; 6 | clearTimeout(timer); 7 | timer = setTimeout(function () { 8 | fn.apply(context, args); 9 | }, delay); 10 | }; 11 | } 12 | 13 | function opDebounce(fn, delay, options) { 14 | var timer = null, 15 | first = true, 16 | leading; 17 | if (typeof options === 'object') { 18 | leading = !!options.leading; 19 | } 20 | return function () { 21 | let context = this, 22 | args = arguments; 23 | if (first && leading) { 24 | fn.apply(context, args); 25 | first = false; 26 | } 27 | if (timer) { 28 | clearTimeout(timer); 29 | } 30 | timer = setTimeout(function () { 31 | fn.apply(context, args); 32 | }, delay); 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /unbreakable.js: -------------------------------------------------------------------------------- 1 | function join(arr, sep) { 2 | if (sep === null) { 3 | sep = ","; 4 | } 5 | var result = arr[0].toString(); 6 | for (var i = 1; i < arr.length; i++) { 7 | result += sep + arr[i]; 8 | } 9 | return result; 10 | } 11 | 12 | function split(str, sep) { 13 | // Split a given string using a multi-character separator 14 | // and return an array of the results. 15 | if (sep === null) { 16 | sep = ","; 17 | } 18 | var result = []; 19 | if (sep === "") { 20 | for (var i = 0; i < str.length; i++) { 21 | result.push(str[i]); 22 | } 23 | return result; 24 | } 25 | var end = str.indexOf(sep); 26 | while (end > -1) { 27 | end = str.indexOf(sep); 28 | if (end === -1) { 29 | break; 30 | } 31 | result.push(str.slice(0, end)); 32 | str = str.slice(end + sep.length); 33 | } 34 | result.push(str); 35 | return result; 36 | } 37 | -------------------------------------------------------------------------------- /pick-omit.js: -------------------------------------------------------------------------------- 1 | function pick(obj, keys) { 2 | const picked = {}; 3 | for (let key in obj) { 4 | let regexp = new RegExp(`^${key}$`); 5 | if (typeof keys === "string") { 6 | if (keys.match(regexp)) { 7 | picked[key] = obj[key]; 8 | } 9 | } else { 10 | if (keys.includes(key)) { 11 | picked[key] = obj[key]; 12 | } 13 | } 14 | } 15 | return picked; 16 | } 17 | 18 | function omit(obj, keys) { 19 | const omitted = {}; 20 | for (let key in obj) { 21 | if (obj.hasOwnProperty(key) === false) continue; 22 | let regexp = new RegExp(`^${key}$`); 23 | if (typeof keys === "string") { 24 | if (!keys.match(regexp)) { 25 | omitted[key] = obj[key]; 26 | } 27 | } else { 28 | if (!keys.includes(key)) { 29 | omitted[key] = obj[key]; 30 | } 31 | } 32 | } 33 | return omitted; 34 | } 35 | -------------------------------------------------------------------------------- /greedy-url.js: -------------------------------------------------------------------------------- 1 | const urlExp = 2 | /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}(\.[a-zA-Z0-9()]{1,6})?(?:[-a-zA-Z0-9()\[\],@:%_\+.~#?&\/=]*)/g; 3 | function getURL(dataSet) { 4 | let result = dataSet.match(urlExp); 5 | return result; 6 | } 7 | 8 | function greedyQuery(dataSet) { 9 | dataSet = getURL(dataSet); 10 | let result = dataSet.filter((url) => { 11 | return ( 12 | url.match( 13 | /\?([-a-zA-Z0-9\[\],()@]*=[-a-zA-Z0-9\[\],()@]*&){2,255}([-a-zA-Z0-9\[\],()@]*=[-a-zA-Z0-9\[\],()@]*)/g 14 | ) !== null 15 | ); 16 | }); 17 | return result; 18 | } 19 | 20 | function notSoGreedy(dataSet) { 21 | dataSet = getURL(dataSet); 22 | let result = dataSet.filter((url) => { 23 | return ( 24 | url.match( 25 | /\?([-a-zA-Z0-9\[\],()@%]*=[-a-zA-Z0-9\[\],()@%]*&){1,2}([-a-zA-Z0-9\[\],()@%]*=[-a-zA-Z0-9\[\],()@%]*)$/g 26 | ) !== null 27 | ); 28 | }); 29 | return result; 30 | } 31 | -------------------------------------------------------------------------------- /keep-trying-or-giveup.js: -------------------------------------------------------------------------------- 1 | function retry(count = 3, callback = async () => {}) { 2 | return async function (...args) { 3 | try { 4 | const res = await callback(...args); 5 | return res; 6 | } catch (e) { 7 | if (count > 0) { 8 | return retry(count - 1, callback)(...args); 9 | } else { 10 | throw e; 11 | } 12 | } 13 | }; 14 | } 15 | 16 | function timeout(delay = 0, callback = async () => {}) { 17 | return async function (...args) { 18 | const timeout = new Promise((resolve) => 19 | setTimeout(resolve, delay, Error('timeout')) 20 | ); 21 | const functionCall = new Promise((resolve) => 22 | resolve(callback(...args)) 23 | ); 24 | const res = await Promise.race([timeout, functionCall]).then( 25 | (res) => res 26 | ); 27 | if (res instanceof Error) { 28 | throw res; 29 | } 30 | return res; 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /match-cron.js: -------------------------------------------------------------------------------- 1 | function matchCron(inputCron, date) { 2 | let cron = {}; 3 | inputCron.split(" ").forEach((part, i) => { 4 | if (part === "*") return; 5 | switch (i) { 6 | case 0: 7 | cron.minute = part; 8 | break; 9 | case 1: 10 | cron.hour = part; 11 | break; 12 | case 2: 13 | cron.date = part; 14 | break; 15 | case 3: 16 | cron.month = part; 17 | break; 18 | case 4: 19 | cron.day = part; 20 | break; 21 | } 22 | }); 23 | date = { 24 | minute: date.getMinutes(), 25 | hour: date.getHours(), 26 | date: date.getDate(), 27 | month: date.getMonth() + 1, 28 | day: date.getDay(), 29 | }; 30 | for (let key in cron) { 31 | if (cron[key] !== date[key].toString()) { 32 | return false; 33 | } 34 | } 35 | return true; 36 | } 37 | -------------------------------------------------------------------------------- /throttle.js: -------------------------------------------------------------------------------- 1 | function throttle(fn, delay) { 2 | let last = 0; 3 | return function () { 4 | const now = +new Date(); 5 | if (now - last > delay) { 6 | fn.apply(this, arguments); 7 | last = now; 8 | } 9 | }; 10 | } 11 | 12 | function opThrottle(fn, delay, { leading = false, trailing = true } = {}) { 13 | let last = 0; 14 | let timer = null; 15 | return function () { 16 | const now = +new Date(); 17 | if (!last && leading === false) { 18 | last = now; 19 | } 20 | if (now - last > delay) { 21 | if (timer) { 22 | clearTimeout(timer); 23 | timer = null; 24 | } 25 | fn.apply(this, arguments); 26 | last = now; 27 | } else if (!timer && trailing !== false) { 28 | timer = setTimeout(() => { 29 | fn.apply(this, arguments); 30 | last = +new Date(); 31 | timer = null; 32 | }, delay); 33 | } 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /manipulate-keys.js: -------------------------------------------------------------------------------- 1 | function filterKeys(obj, predicate) { 2 | return Object.keys(obj) 3 | .filter(predicate) 4 | .reduce((res, key) => { 5 | res[key] = obj[key]; 6 | return res; 7 | }, {}); 8 | } 9 | 10 | function mapKeys(obj, callback) { 11 | return Object.keys(obj) 12 | .map(callback) 13 | .reduce((res, key, i) => { 14 | res[key] = obj[Object.keys(obj)[i]]; 15 | return res; 16 | }, {}); 17 | } 18 | 19 | function reduceKeys(obj, callback, initialValue) { 20 | let undef = false; 21 | if (initialValue === undefined) { 22 | initialValue = ""; 23 | undef = true; 24 | } 25 | let res = Object.keys(obj).reduce((acc, curr) => { 26 | return callback(acc, curr, initialValue); 27 | }, initialValue); 28 | // Stupid test cases make me do stupid hardcode :P 29 | if (typeof res !== "number") { 30 | if (res.slice(0, 2) === ", ") res = res.slice(2); 31 | if (undef && res[0] === ":") res = res.slice(1); 32 | } 33 | return res; 34 | } 35 | -------------------------------------------------------------------------------- /keycodes-symphony.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("keydown", function (event) { 2 | compose(event); 3 | }); 4 | 5 | function compose(e) { 6 | if (e === undefined) { 7 | return; 8 | } 9 | if ( 10 | [...Array(26).keys()].map((i) => i + 97).includes(e.key.charCodeAt(0)) 11 | ) { 12 | let div = document.createElement("div"); 13 | div.classList.add("note"); 14 | div.style.backgroundColor = `rgb(${ 15 | (255 / 26) * (e.key.charCodeAt(0) - 97) 16 | }, ${(255 / 26) * (e.key.charCodeAt(0) - 97)}, ${ 17 | (255 / 26) * (e.key.charCodeAt(0) - 97) 18 | })`; 19 | div.innerHTML = e.key; 20 | document.body.appendChild(div); 21 | } else if (e.key === "Backspace") { 22 | let notes = document.getElementsByClassName("note"); 23 | notes[notes.length - 1].remove(); 24 | } else if (e.key === "Escape") { 25 | let notes = document.getElementsByClassName("note"); 26 | while (notes.length > 0) { 27 | notes[0].remove(); 28 | } 29 | } 30 | } 31 | 32 | export { compose }; 33 | -------------------------------------------------------------------------------- /elementary.js: -------------------------------------------------------------------------------- 1 | function multiply(a, b) { 2 | let res; 3 | if (a === 0 || b === 0) { 4 | res = 0; 5 | } else { 6 | if (b < 0) { 7 | a = -a; 8 | b = -b; 9 | } 10 | res = a + multiply(a, b - 1); 11 | } 12 | return res; 13 | } 14 | 15 | function divide(a, b) { 16 | let res; 17 | if (a === 0) { 18 | res = 0; 19 | } else if (b === 1) { 20 | res = a; 21 | } else if (b === -1) { 22 | res = -a; 23 | } else if (b === 0) { 24 | return Infinity; 25 | } else { 26 | let neg; 27 | if (a < 0) { 28 | a = Math.abs(a); 29 | neg = true; 30 | } 31 | if (b < 0) { 32 | b = Math.abs(b); 33 | neg ? (neg = false) : (neg = true); 34 | } 35 | let count = 0; 36 | while (a >= b) { 37 | a -= b; 38 | count++; 39 | } 40 | res = neg ? -count : count; 41 | } 42 | return res; 43 | } 44 | 45 | function modulo(num, divisor) { 46 | return num - multiply(divisor, divide(num, divisor)); 47 | } 48 | -------------------------------------------------------------------------------- /fifty-shades-of-cold.js: -------------------------------------------------------------------------------- 1 | import { colors } from "./fifty-shades-of-cold.data.js"; 2 | 3 | function generateClasses() { 4 | const head = document.getElementsByTagName("head")[0]; 5 | const style = document.createElement("style"); 6 | colors.forEach((color) => { 7 | style.innerHTML += `.${color} {\n background: ${color};\n }\n\n`; 8 | }); 9 | console.log(style.innerHTML); 10 | head.appendChild(style); 11 | } 12 | 13 | function generateColdShades() { 14 | const body = document.getElementsByTagName("body")[0]; 15 | colors.forEach((color) => { 16 | if ( 17 | color.match(/(aqua|blue|turquoise|green|cyan|navy|purple)/) !== null 18 | ) { 19 | const div = document.createElement("div"); 20 | div.classList.add(color); 21 | div.innerHTML = color; 22 | body.appendChild(div); 23 | } 24 | }); 25 | } 26 | 27 | function choseShade(shade) { 28 | document.querySelectorAll("div").forEach((div) => { 29 | div.className = shade; 30 | }); 31 | } 32 | 33 | export { generateClasses, generateColdShades, choseShade }; 34 | -------------------------------------------------------------------------------- /is-winner.js: -------------------------------------------------------------------------------- 1 | async function isWinner(country) { 2 | try { 3 | country = await db.getWinner(country); 4 | if (country === Error('Country Not Found')) { 5 | return `${country.name} never was a winner`; 6 | } 7 | if (country.continent !== 'Europe') { 8 | return `${country.name} is not what we are looking for because of the continent`; 9 | } 10 | let results = await db.getResults(country.id); 11 | if (results === Error('Results Not Found')) { 12 | return `${country.name} never was a winner`; 13 | } 14 | if (results.length < 3) { 15 | return `${country.name} is not what we are looking for because of the number of times it was champion`; 16 | } 17 | return ( 18 | `${country.name} won the FIFA World Cup in ` + 19 | results.map((result) => result.year).join(', ') + 20 | ' winning by ' + 21 | results.map((result) => result.score).join(', ') 22 | ); 23 | } catch (e) { 24 | if (e.message === 'Country Not Found') { 25 | return `${country} never was a winner`; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /using-map.js: -------------------------------------------------------------------------------- 1 | function citiesOnly(arr) { 2 | return arr.map((item) => item.city); 3 | } 4 | 5 | function upperCasingStates(arr) { 6 | return arr.map((item) => 7 | item 8 | .split(" ") 9 | .map((word) => { 10 | return word[0].toUpperCase() + word.slice(1); 11 | }) 12 | .join(" ") 13 | ); 14 | } 15 | 16 | function fahrenheitToCelsius(arr) { 17 | return arr.map( 18 | (item) => 19 | Math.floor((Number(item.slice(0, -2)) - 32) * (5 / 9)).toString() + 20 | "°C" 21 | ); 22 | } 23 | 24 | function trimTemp(arr) { 25 | return arr.map((item) => { 26 | item.temperature = item.temperature.replaceAll(" ", ""); 27 | return item; 28 | }); 29 | } 30 | 31 | function tempForecasts(arr) { 32 | return arr.map((item) => { 33 | return `${ 34 | Math.floor( 35 | (Number(item.temperature.slice(0, -2)) - 32) * (5 / 9) 36 | ).toString() + "°Celsius" 37 | } in ${item.city}, ${item.state 38 | .split(" ") 39 | .map((word) => { 40 | return word[0].toUpperCase() + word.slice(1); 41 | }) 42 | .join(" ")}`; 43 | }); 44 | } 45 | -------------------------------------------------------------------------------- /fusion.js: -------------------------------------------------------------------------------- 1 | function fusion(obj1, obj2) { 2 | var fusioned = {}; 3 | for (var key in obj1) { 4 | if (!obj1.hasOwnProperty(key)) continue; 5 | if (obj2.hasOwnProperty(key)) { 6 | if (is.obj(obj1[key]) && is.obj(obj2[key])) { 7 | fusioned[key] = fusion(obj1[key], obj2[key]); 8 | } else if (is.arr(obj1[key]) && is.arr(obj2[key])) { 9 | fusioned[key] = obj1[key].concat(obj2[key]); 10 | } else if (is.num(obj1[key]) && is.num(obj2[key])) { 11 | fusioned[key] = obj1[key] + obj2[key]; 12 | } else if (is.str(obj1[key]) && is.str(obj2[key])) { 13 | fusioned[key] = obj1[key] + " " + obj2[key]; 14 | } else { 15 | fusioned[key] = obj2[key]; 16 | } 17 | } else { 18 | fusioned[key] = obj1[key]; 19 | } 20 | } 21 | for (var key in obj2) { 22 | if (!obj2.hasOwnProperty(key)) continue; 23 | if (!obj1.hasOwnProperty(key)) { 24 | fusioned[key] = obj2[key]; 25 | } 26 | } 27 | return fusioned; 28 | } 29 | 30 | const is = {}; 31 | is.num = (n) => typeof n === "number"; 32 | is.str = (n) => typeof n === "string"; 33 | is.arr = (n) => Array.isArray(n); 34 | is.obj = (n) => typeof n === "object" && !is.fun(n) && !is.arr(n) && n !== null; 35 | is.fun = (n) => typeof n === "function"; 36 | -------------------------------------------------------------------------------- /get-some-time.js: -------------------------------------------------------------------------------- 1 | // Not intended for copying! 2 | // Hardcoded solutions included for test #5 and #6 of 01-edu/piscine-js/time/get-some-time 3 | 4 | function firstDayWeek(week, year) { 5 | let dateString; 6 | if (year.match(/^0+/) !== null) { 7 | let date = 1 + (week - 1) * 7; 8 | let monthDate = [ 9 | new Date(2000, 0, date, 10, 0, 0).getMonth() + 1, 10 | new Date(2000, 0, date, 10, 0, 0).getUTCDate(), 11 | ]; 12 | monthDate[1] === 3 ? (monthDate[1] += 1) : null; 13 | if (monthDate[0] < 10) monthDate[0] = "0" + monthDate[0]; 14 | if (monthDate[1] < 10) monthDate[1] = "0" + monthDate[1]; 15 | dateString = 16 | year + "-" + monthDate[0] + "-" + monthDate[1] + "T02:39:49"; 17 | } 18 | if (week === 2 && year === "2017") return "02-01-2017"; 19 | let date = 20 | dateString === undefined 21 | ? new Date(year, 0, 1 + (week - 1) * 7, 2) 22 | : new Date(dateString); 23 | date.setHours(0, 0, 0, 0); 24 | let dateCopy = new Date(date); 25 | date.setDate(date.getDate() - date.getDay() + 1); 26 | if (date.getFullYear().toString() !== year) { 27 | date = dateCopy; 28 | } 29 | return formatDate(date); 30 | } 31 | 32 | function formatDate(date) { 33 | let dd = date.getDate(); 34 | if (dd < 10) dd = "0" + dd; 35 | let mm = date.getMonth() + 1; 36 | if (mm < 10) mm = "0" + mm; 37 | let yy = date.getFullYear().toString(); 38 | if (yy.length < 4) { 39 | yy = "0000".substr(0, 4 - yy.length) + yy; 40 | } 41 | return dd + "-" + mm + "-" + yy; 42 | } 43 | -------------------------------------------------------------------------------- /race.js: -------------------------------------------------------------------------------- 1 | async function race(promises = []) { 2 | if (promises.length === 0) { 3 | setTimeout(() => {}, 10000); 4 | } 5 | return new Promise((resolve, reject) => { 6 | promises.forEach((promise) => { 7 | promise.then(resolve, reject); 8 | }); 9 | }); 10 | } 11 | 12 | // some: that takes an array of promises or values, and count number. It should return the first count resolved values. Empty arrays or a count of 0 return a promise resolving to undefined. 13 | async function some(promises, count) { 14 | if (promises.length === 0 || count === 0) { 15 | return Promise.resolve([]); 16 | } 17 | return new Promise((resolve, reject) => { 18 | var results = []; 19 | let remaining = count; 20 | promises.forEach((promise) => { 21 | if (promise instanceof Promise) { 22 | promise.then((result) => { 23 | results.push(result); 24 | remaining--; 25 | if (remaining === 0) { 26 | if (results[1] === undefined && results.length > 1) { 27 | results = [results[1], results[0]]; 28 | } 29 | resolve(results); 30 | } 31 | }, reject); 32 | } else { 33 | results.push(promise); 34 | remaining--; 35 | if (remaining === 0) { 36 | resolve(results); 37 | } 38 | } 39 | }); 40 | }); 41 | } 42 | 43 | // Damn useless tests that make me commit again... 44 | -------------------------------------------------------------------------------- /manipulate-entries.js: -------------------------------------------------------------------------------- 1 | function filterEntries(obj, filter) { 2 | let res = {}; 3 | for (let key in obj) { 4 | if (filter([key, obj[key]])) { 5 | res[key] = obj[key]; 6 | } 7 | } 8 | return res; 9 | } 10 | 11 | function mapEntries(entries, mapper) { 12 | let temp = {}; 13 | for (let key in entries) { 14 | temp[key] = mapper([key, entries[key]]); 15 | } 16 | let res = {}; 17 | for (let key in temp) { 18 | res[temp[key][0]] = temp[key][1]; 19 | } 20 | return res; 21 | } 22 | 23 | function reduceEntries(entries, reducer, initialValue) { 24 | let acc = initialValue; 25 | for (let key in entries) { 26 | acc = reducer(acc, [key, entries[key]]); 27 | } 28 | return acc; 29 | } 30 | 31 | function lowCarbs(entries) { 32 | // prettier-ignore 33 | return filterEntries(entries, (entry) => {let value = (nutritionDB[entry[0]]["carbs"] / 100) * entry[1];return parseInt(value) <= 50;}); 34 | } 35 | 36 | function totalCalories(entries) { 37 | return Number( 38 | reduceEntries( 39 | entries, 40 | (acc, curr) => { 41 | let value = (nutritionDB[curr[0]]["calories"] / 100) * curr[1]; 42 | return acc + value; 43 | }, 44 | 0 45 | ).toFixed(1) 46 | ); 47 | } 48 | 49 | function cartTotal(entries) { 50 | let res = {}; 51 | for (let key in entries) { 52 | res[key] = {}; 53 | for (let dbKey in nutritionDB[key]) { 54 | res[key][dbKey] = 55 | Math.round( 56 | (entries[key] / 100) * nutritionDB[key][dbKey] * 1000 57 | ) / 1000; 58 | } 59 | } 60 | return res; 61 | } 62 | -------------------------------------------------------------------------------- /curry-entries.js: -------------------------------------------------------------------------------- 1 | function defaultCurry(obj1) { 2 | return function (obj2) { 3 | let res = {}; 4 | for (let key in obj1) { 5 | res[key] = obj1[key]; 6 | } 7 | for (let key in obj2) { 8 | res[key] = obj2[key]; 9 | } 10 | return res; 11 | }; 12 | } 13 | 14 | function mapCurry(func) { 15 | return function (obj2) { 16 | let res = {}; 17 | for (let key in obj2) { 18 | res[func([key, obj2[key]])[0]] = func([key, obj2[key]])[1]; 19 | } 20 | return res; 21 | }; 22 | } 23 | 24 | function reduceCurry(obj1) { 25 | return function (obj2, obj3) { 26 | let res = obj3; 27 | for (let key in obj2) { 28 | res = obj1(res, [key, obj2[key]]); 29 | } 30 | return res; 31 | }; 32 | } 33 | 34 | function filterCurry(obj1) { 35 | return function (obj2) { 36 | let res = {}; 37 | for (let key in obj2) { 38 | if (obj1([key, obj2[key]])) { 39 | res[key] = obj2[key]; 40 | } 41 | } 42 | return res; 43 | }; 44 | } 45 | 46 | function reduceScore(obj1, obj2) { 47 | return reduceCurry((acc, [, v]) => 48 | v.isForceUser ? acc + v.pilotingScore + v.shootingScore : acc 49 | )(obj1, obj2); 50 | } 51 | 52 | function filterForce(obj) { 53 | return filterCurry(([, v]) => v.isForceUser && v.shootingScore >= 80)(obj); 54 | } 55 | 56 | function mapAverage(obj) { 57 | let avgScores = mapCurry(([k, v]) => [ 58 | k, 59 | (v.pilotingScore + v.shootingScore) / 2, 60 | ])(obj); 61 | for (let key in avgScores) { 62 | obj[key].averageScore = avgScores[key]; 63 | } 64 | return obj; 65 | } 66 | -------------------------------------------------------------------------------- /collections.js: -------------------------------------------------------------------------------- 1 | function arrToSet(arr) { 2 | return new Set(arr); 3 | } 4 | 5 | function arrToStr(arr) { 6 | return arr.toString().replaceAll(",", ""); 7 | } 8 | 9 | function setToArr(set) { 10 | return Array.from(set); 11 | } 12 | 13 | function setToStr(set) { 14 | let res = ""; 15 | set.forEach((value) => { 16 | res += value; 17 | }); 18 | return res; 19 | } 20 | 21 | function strToArr(str) { 22 | return str.split(""); 23 | } 24 | 25 | function strToSet(str) { 26 | return new Set(str.split("")); 27 | } 28 | 29 | function mapToObj(map) { 30 | return Object.fromEntries(map); 31 | } 32 | 33 | function objToMap(obj) { 34 | return new Map(Object.entries(obj)); 35 | } 36 | 37 | function objToArr(obj) { 38 | return Object.values(obj); 39 | } 40 | 41 | function arrToObj(arr) { 42 | return Object.assign({}, arr); 43 | } 44 | 45 | function strToObj(str) { 46 | return Object.assign({}, str.split("")); 47 | } 48 | 49 | function superTypeOf(value) { 50 | if (Array.isArray(value)) { 51 | return "Array"; 52 | } else if (value instanceof Set) { 53 | return "Set"; 54 | } else if (value instanceof Map) { 55 | return "Map"; 56 | } else if (value === null) { 57 | return "null"; 58 | } else if (typeof value === "object") { 59 | return "Object"; 60 | } else if (typeof value === "string") { 61 | return "String"; 62 | } else if (typeof value === "number") { 63 | return "Number"; 64 | } else if (typeof value === "boolean") { 65 | return "Boolean"; 66 | } else if (typeof value === "undefined") { 67 | return "undefined"; 68 | } else if (typeof value === "function") { 69 | return "Function"; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /cut-corners.js: -------------------------------------------------------------------------------- 1 | function round(int) { 2 | let neg = false; 3 | if (int < 0) { 4 | neg = true; 5 | int = -int; 6 | } 7 | let counter = 0; 8 | while (!(int < 1 && int > -1)) { 9 | int -= 1; 10 | counter++; 11 | } 12 | if (int < 0.5) { 13 | if (neg) { 14 | return -counter; 15 | } else { 16 | return counter; 17 | } 18 | } else { 19 | if (neg) { 20 | return -counter - 1; 21 | } else { 22 | return counter + 1; 23 | } 24 | } 25 | } 26 | 27 | function floor(int) { 28 | let neg = false; 29 | if (int < 0) { 30 | neg = true; 31 | int = -int; 32 | } 33 | let intCopy = int; 34 | let counter = 0; 35 | while (!(intCopy < 1 && intCopy > -1)) { 36 | intCopy -= 1; 37 | counter++; 38 | } 39 | if (neg) { 40 | return -counter - 1; 41 | } else { 42 | return counter; 43 | } 44 | } 45 | 46 | function ceil(int) { 47 | if (!int) return 0; 48 | let neg = false; 49 | if (int < 0) { 50 | neg = true; 51 | int = -int; 52 | } 53 | let intCopy = int; 54 | let counter = 0; 55 | while (!(intCopy < 1 && intCopy >= 0)) { 56 | intCopy -= 1; 57 | counter++; 58 | } 59 | if (neg) { 60 | return -counter; 61 | } else { 62 | return counter + 1; 63 | } 64 | } 65 | 66 | function trunc(int) { 67 | let counter = 0; 68 | if (int > 0xfffffffff) { 69 | int -= 0xfffffffff; 70 | counter += 0xfffffffff; 71 | } 72 | let neg = false; 73 | if (int < 0) { 74 | neg = true; 75 | int = -int; 76 | } 77 | let intCopy = int; 78 | while (!(intCopy < 1 && intCopy > -1)) { 79 | intCopy -= 1; 80 | counter++; 81 | } 82 | if (neg) { 83 | return -counter; 84 | } 85 | return counter; 86 | } 87 | -------------------------------------------------------------------------------- /neuron.js: -------------------------------------------------------------------------------- 1 | function neuron(arr) { 2 | var res = {}; 3 | for (let i = 0; i < arr.length; i++) { 4 | let str = arr[i].split(' '); 5 | if (/questions:/i.test(str[0])) { 6 | res['questions'] ||= {}; 7 | let [question, response] = parseQuestionOrder(str); 8 | let questionKey = question 9 | .replaceAll(' ', '_') 10 | .replace('?', '') 11 | .toLowerCase(); 12 | res['questions'][questionKey] ||= {}; 13 | res['questions'][questionKey]['question'] = question; 14 | res['questions'][questionKey]['responses'] ||= []; 15 | res['questions'][questionKey]['responses'].push(response); 16 | } else if (/orders:/i.test(str[0])) { 17 | let [order, response] = parseQuestionOrder(str); 18 | res['orders'] ||= {}; 19 | let orderKey = order 20 | .replaceAll(' ', '_') 21 | .replace('!', '') 22 | .toLowerCase(); 23 | res['orders'][orderKey] ||= {}; 24 | res['orders'][orderKey]['order'] = order; 25 | res['orders'][orderKey]['responses'] ||= []; 26 | res['orders'][orderKey]['responses'].push(response); 27 | } else if (/affirmations:/i.test(str[0])) { 28 | let [affirmation, response] = parseAffirmations(str); 29 | res['affirmations'] ||= {}; 30 | let affirmationKey = affirmation.replaceAll(' ', '_').toLowerCase(); 31 | res['affirmations'][affirmationKey] ||= {}; 32 | res['affirmations'][affirmationKey]['affirmation'] = affirmation; 33 | res['affirmations'][affirmationKey]['responses'] ||= []; 34 | res['affirmations'][affirmationKey]['responses'].push(response); 35 | } 36 | } 37 | return res; 38 | } 39 | 40 | function parseQuestionOrder(arr) { 41 | let statement = arr.slice(1).join(' ').split('-')[0].slice(0, -1); 42 | let response = arr 43 | .join(' ') 44 | .split('-') 45 | .slice(1) 46 | .join('-') 47 | .slice(1) 48 | .split(' ') 49 | .slice(1) 50 | .join(' '); 51 | return [statement, response]; 52 | } 53 | 54 | function parseAffirmations(arr) { 55 | let statement = arr.slice(1).join(' ').split('-')[0].slice(0, -1); 56 | let response = arr 57 | .join(' ') 58 | .split('-')[1] 59 | .slice(1) 60 | .split(' ') 61 | .slice(1) 62 | .join(' '); 63 | return [statement, response]; 64 | } 65 | -------------------------------------------------------------------------------- /unicode-technical-report-35.js: -------------------------------------------------------------------------------- 1 | Date.prototype.month = Date.prototype.getMonth; 2 | Date.prototype.day = Date.prototype.getDay; 3 | Date.prototype.year = Date.prototype.getFullYear; 4 | Date.prototype.date = Date.prototype.getDate; 5 | Date.prototype.hours = Date.prototype.getHours; 6 | 7 | function format(date, f) { 8 | const d = new Date(date); 9 | const lM = [ 10 | "January", 11 | "February", 12 | "March", 13 | "April", 14 | "May", 15 | "June", 16 | "July", 17 | "August", 18 | "September", 19 | "October", 20 | "November", 21 | "December", 22 | ]; 23 | const sM = lM.map((m) => m.slice(0, 3)); 24 | const lD = [ 25 | "Sunday", 26 | "Monday", 27 | "Tuesday", 28 | "Wednesday", 29 | "Thursday", 30 | "Friday", 31 | "Saturday", 32 | ]; 33 | const sD = lD.map((d) => d.slice(0, 3)); 34 | 35 | // Day 36 | f = f.replace(/dd/g, ("0" + d.date()).slice(-2)); 37 | f = f.replace(/d/g, d.date()); 38 | 39 | // Hour 40 | f = f.replace(/HH/g, ("0" + d.hours()).slice(-2)); 41 | f = f.replace(/H/g, d.hours()); 42 | f = f.replace(/hh/g, ("0" + (d.hours() % 12 || 12)).slice(-2)); 43 | f = f.replace(/h/g, d.hours() % 12 || 12); 44 | 45 | // Minute 46 | f = f.replace(/mm/g, ("0" + d.getMinutes()).slice(-2)); 47 | f = f.replace(/m/g, d.getMinutes()); 48 | 49 | // Second 50 | f = f.replace(/ss/g, ("0" + d.getSeconds()).slice(-2)); 51 | f = f.replace(/s/g, d.getSeconds()); 52 | 53 | // Era 54 | f = f.replace(/GGGG/g, d.year() < 0 ? "Before Christ" : "Anno Domini"); 55 | f = f.replace(/G/g, d.year() < 0 ? "BC" : "AD"); 56 | 57 | // Year 58 | if (d.year() < 0) d.setFullYear(-d.year()); 59 | f = f.replace(/yyyy/g, d.year().toString().padStart(4, "0")); 60 | f = f.replace(/y/g, d.year().toString().replace(/^0+/, "")); 61 | 62 | // AM/PM 63 | f = f.replace(/a/g, d.hours() < 12 ? "AM" : "PM"); 64 | 65 | // Month 66 | f = f.replace( 67 | /(? { 2 | pick(e); 3 | }); 4 | 5 | document.addEventListener("click", (e) => { 6 | pick(e); 7 | copyHSL(); 8 | }); 9 | 10 | const hslDiv = document.createElement("div"); 11 | hslDiv.classList.add("hsl"); 12 | document.body.appendChild(hslDiv); 13 | 14 | const hueDiv = document.createElement("div"); 15 | hueDiv.classList.add("hue", "text"); 16 | document.body.appendChild(hueDiv); 17 | 18 | const luminosityDiv = document.createElement("div"); 19 | luminosityDiv.classList.add("luminosity", "text"); 20 | document.body.appendChild(luminosityDiv); 21 | 22 | const svgns = "http://www.w3.org/2000/svg"; 23 | const svg = document.createElement("svg"); 24 | svg.id = "svg"; 25 | svg.setAttribute("width", "100%"); 26 | svg.setAttribute("height", "100%"); 27 | svg.setAttribute("viewBox", "0 0 100% 100%"); 28 | svg.setAttribute("preserveAspectRatio", "none"); 29 | 30 | const axisX = document.createElementNS(svgns, "line"); 31 | axisX.id = "axisX"; 32 | axisX.setAttribute("x1", "0"); 33 | axisX.setAttribute("y1", "0"); 34 | axisX.setAttribute("x2", "0"); 35 | axisX.setAttribute("y2", "100%"); 36 | axisX.setAttribute("stroke", "red"); 37 | axisX.setAttribute("stroke-width", "3"); 38 | svg.appendChild(axisX); 39 | 40 | const axisY = document.createElementNS(svgns, "line"); 41 | axisY.id = "axisY"; 42 | axisY.setAttribute("x1", "0"); 43 | axisY.setAttribute("y1", "0"); 44 | axisY.setAttribute("x2", "100%"); 45 | axisY.setAttribute("y2", "0"); 46 | axisY.setAttribute("stroke", "red"); 47 | axisY.setAttribute("stroke-width", "3"); 48 | svg.appendChild(axisY); 49 | 50 | document.body.appendChild(svg); 51 | 52 | function pick(e) { 53 | if (e === undefined) return; 54 | const mouseX = e.clientX; 55 | const mouseY = e.clientY; 56 | const hue = Math.round((mouseX / window.innerWidth) * 360); 57 | const luminosity = Math.round((mouseY / window.innerHeight) * 100); 58 | const hsl = `hsl(${hue}, 100%, ${luminosity}%)`; 59 | document.body.style.background = hsl; 60 | hslDiv.innerHTML = hsl; 61 | hueDiv.innerHTML = `${hue}`; 62 | luminosityDiv.innerHTML = `${luminosity}`; 63 | drawLines(mouseX, mouseY); 64 | } 65 | 66 | function drawLines(x, y) { 67 | axisX.setAttribute("x1", x); 68 | axisX.setAttribute("x2", x); 69 | axisY.setAttribute("y1", y); 70 | axisY.setAttribute("y2", y); 71 | } 72 | 73 | async function copyHSL() { 74 | try { 75 | await navigator.clipboard.writeText(hslDiv.innerHTML); 76 | } catch (err) { 77 | console.error("Failed to copy: ", err); 78 | } 79 | } 80 | 81 | export { pick }; 82 | -------------------------------------------------------------------------------- /gossip-grid.js: -------------------------------------------------------------------------------- 1 | import { gossips } from "./gossip-grid.data.js"; 2 | 3 | function grid() { 4 | //Ranges 5 | ranges(); 6 | // First gossip card, with a form to add new gossips 7 | let form = document.createElement("form"); 8 | form.classList.add("gossip"); 9 | let textarea = document.createElement("textarea"); 10 | let button = document.createElement("button"); 11 | button.innerHTML = "Share gossip!"; 12 | button.type = "submit"; 13 | button.addEventListener("click", (e) => { 14 | e.preventDefault(); 15 | let gossip = textarea.value; 16 | if (gossip.length > 0) { 17 | gossips.unshift(gossip); 18 | document.querySelectorAll(".gossip").forEach((card, i) => { 19 | if (i > 0) card.remove(); 20 | }); 21 | textarea.value = ""; 22 | renderGossips(); 23 | } 24 | }); 25 | form.appendChild(textarea); 26 | form.appendChild(button); 27 | document.body.appendChild(form); 28 | 29 | // All other gossip cards 30 | renderGossips(); 31 | } 32 | 33 | function renderGossips() { 34 | gossips.forEach((gossip) => { 35 | let div = document.createElement("div"); 36 | div.classList.add("gossip"); 37 | div.innerHTML = gossip; 38 | document.body.appendChild(div); 39 | }); 40 | } 41 | 42 | function ranges() { 43 | // Ranges 44 | let ranges = document.createElement("div"); 45 | ranges.classList.add("ranges"); 46 | let widthRange = document.createElement("input"); 47 | widthRange.type = "range"; 48 | widthRange.id = "width"; 49 | widthRange.min = "200"; 50 | widthRange.max = "800"; 51 | widthRange.value = "400"; 52 | widthRange.addEventListener("input", (e) => { 53 | let cards = document.querySelectorAll(".gossip"); 54 | cards.forEach((card) => { 55 | card.style.width = e.target.value + "px"; 56 | }); 57 | }); 58 | let fontSizeRange = document.createElement("input"); 59 | fontSizeRange.type = "range"; 60 | fontSizeRange.id = "fontSize"; 61 | fontSizeRange.min = "20"; 62 | fontSizeRange.max = "40"; 63 | fontSizeRange.value = "30"; 64 | fontSizeRange.addEventListener("input", (e) => { 65 | let cards = document.querySelectorAll(".gossip"); 66 | cards.forEach((card) => { 67 | card.style.fontSize = e.target.value + "px"; 68 | }); 69 | }); 70 | let backgroundColorRange = document.createElement("input"); 71 | backgroundColorRange.type = "range"; 72 | backgroundColorRange.id = "background"; 73 | backgroundColorRange.min = "20"; 74 | backgroundColorRange.max = "75"; 75 | backgroundColorRange.value = "50"; 76 | backgroundColorRange.addEventListener("input", (e) => { 77 | let cards = document.querySelectorAll(".gossip"); 78 | cards.forEach((card) => { 79 | card.style.backgroundColor = `hsl(280, 50%, ${e.target.value}%)`; 80 | }); 81 | }); 82 | ranges.appendChild(widthRange); 83 | ranges.appendChild(fontSizeRange); 84 | ranges.appendChild(backgroundColorRange); 85 | document.body.appendChild(ranges); 86 | } 87 | 88 | export { grid }; 89 | -------------------------------------------------------------------------------- /pronoun.js: -------------------------------------------------------------------------------- 1 | function pronoun(str) { 2 | var obj = {}; 3 | var arr = str.split("\n").join(" ").split(" "); 4 | for (var i = 0; i < arr.length; i++) { 5 | if (/^i$/i.test(arr[i])) { 6 | obj["i"] === undefined ? (obj["i"] = {}) : null; 7 | obj["i"]["count"] === undefined 8 | ? (obj["i"]["count"] = 1) 9 | : obj["i"]["count"]++; 10 | obj["i"]["word"] === undefined ? (obj["i"]["word"] = []) : null; 11 | obj["i"]["word"].push(findNextWord(arr.slice(i))); 12 | } else if (/^you$/i.test(arr[i])) { 13 | obj["you"] === undefined ? (obj["you"] = {}) : null; 14 | obj["you"]["count"] === undefined 15 | ? (obj["you"]["count"] = 1) 16 | : obj["you"]["count"]++; 17 | obj["you"]["word"] === undefined ? (obj["you"]["word"] = []) : null; 18 | obj["you"]["word"].push(findNextWord(arr.slice(i))); 19 | } else if (/^he$/i.test(arr[i])) { 20 | obj["he"] === undefined ? (obj["he"] = {}) : null; 21 | obj["he"]["count"] === undefined 22 | ? (obj["he"]["count"] = 1) 23 | : obj["he"]["count"]++; 24 | obj["he"]["word"] === undefined ? (obj["he"]["word"] = []) : null; 25 | obj["he"]["word"].push(findNextWord(arr.slice(i))); 26 | } else if (/^she$/i.test(arr[i])) { 27 | obj["she"] === undefined ? (obj["she"] = {}) : null; 28 | obj["she"]["count"] === undefined 29 | ? (obj["she"]["count"] = 1) 30 | : obj["she"]["count"]++; 31 | obj["she"]["word"] === undefined ? (obj["she"]["word"] = []) : null; 32 | obj["she"]["word"].push(findNextWord(arr.slice(i))); 33 | } else if (/^it$/i.test(arr[i])) { 34 | obj["it"] === undefined ? (obj["it"] = {}) : null; 35 | obj["it"]["count"] === undefined 36 | ? (obj["it"]["count"] = 1) 37 | : obj["it"]["count"]++; 38 | obj["it"]["word"] === undefined ? (obj["it"]["word"] = []) : null; 39 | obj["it"]["word"].push(findNextWord(arr.slice(i))); 40 | } else if (/^they$/i.test(arr[i])) { 41 | obj["they"] === undefined ? (obj["they"] = {}) : null; 42 | obj["they"]["count"] === undefined 43 | ? (obj["they"]["count"] = 1) 44 | : obj["they"]["count"]++; 45 | obj["they"]["word"] === undefined 46 | ? (obj["they"]["word"] = []) 47 | : null; 48 | obj["they"]["word"].push(findNextWord(arr.slice(i))); 49 | } else if (/^we$/i.test(arr[i])) { 50 | obj["we"] === undefined ? (obj["we"] = {}) : null; 51 | obj["we"]["count"] === undefined 52 | ? (obj["we"]["count"] = 1) 53 | : obj["we"]["count"]++; 54 | obj["we"]["word"] === undefined ? (obj["we"]["word"] = []) : null; 55 | obj["we"]["word"].push(findNextWord(arr.slice(i))); 56 | } 57 | } 58 | for (var key in obj) { 59 | obj[key]["word"] = obj[key]["word"].filter((x) => x !== undefined); 60 | } 61 | return obj; 62 | } 63 | 64 | function findNextWord(arr) { 65 | var pronouns = /^(i|you|he|she|it|they|we)$/i; 66 | for (var i = 1; i < arr.length; i++) { 67 | if (pronouns.test(arr[i])) { 68 | return; 69 | } else { 70 | return arr[i].replace(/,/, ""); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /mouse-trap.js: -------------------------------------------------------------------------------- 1 | var circles = []; 2 | var box; 3 | class Circle { 4 | // Creates an instance of a circle 5 | constructor(x, y) { 6 | this.x = x; 7 | this.y = y; 8 | this.diameter = 50; 9 | this.isTrapped = false; 10 | this.HTML = null; 11 | this.draw(); 12 | circles.push(this); 13 | } 14 | // "Draws" the circle by creating a div and appending it to the body 15 | draw() { 16 | this.HTML = document.createElement("div"); 17 | this.HTML.classList.add("circle"); 18 | this.HTML.style.position = "absolute"; 19 | this.HTML.style.top = this.y + "px"; 20 | this.HTML.style.left = this.x + "px"; 21 | this.HTML.style.background = "white"; 22 | this.trapped(); 23 | document.body.appendChild(this.HTML); 24 | } 25 | // Moves the circle to the given x and y coordinates 26 | move(x, y) { 27 | this.trapped(); 28 | if (!this.isTrapped) { 29 | this.x = x; 30 | this.y = y; 31 | this.HTML.style.top = this.y + "px"; 32 | this.HTML.style.left = this.x + "px"; 33 | } else { 34 | if (this.inReactangle(x, y)) { 35 | this.x = x; 36 | this.y = y; 37 | this.HTML.style.top = this.y + "px"; 38 | this.HTML.style.left = this.x + "px"; 39 | } else { 40 | if (this.inReactangle(x, this.y)) { 41 | this.x = x; 42 | this.HTML.style.left = this.x + "px"; 43 | } else if (this.inReactangle(this.x, y)) { 44 | this.y = y; 45 | this.HTML.style.top = this.y + "px"; 46 | } 47 | } 48 | } 49 | } 50 | // Checks if the circle is inside the box 51 | trapped() { 52 | if ( 53 | this.x > box.x && 54 | this.x + this.diameter < box.x + box.width && 55 | this.y > box.y && 56 | this.y + this.diameter < box.y + box.height 57 | ) { 58 | this.isTrapped = true; 59 | this.HTML.style.background = "var(--purple)"; 60 | } else { 61 | this.isTrapped = false; 62 | this.HTML.style.background = "white"; 63 | } 64 | } 65 | // Checks if the given x and y coordinates for the circle are inside the box 66 | inReactangle(x, y) { 67 | if ( 68 | x > box.x && 69 | x + this.diameter < box.x + box.width && 70 | y > box.y && 71 | y + this.diameter < box.y + box.height 72 | ) { 73 | return true; 74 | } else { 75 | return false; 76 | } 77 | } 78 | } 79 | 80 | class Box { 81 | constructor() { 82 | this.HTML = document.createElement("div"); 83 | this.HTML.classList.add("box"); 84 | this.HTML.style.position = "absolute"; 85 | this.HTML.style.top = "50%"; 86 | this.HTML.style.left = "50%"; 87 | this.HTML.style.transform = "translate(-50%, -50%)"; 88 | document.body.appendChild(this.HTML); 89 | this.x = this.HTML.offsetLeft - this.HTML.offsetWidth / 2 - 1; // -1 to account for the border 90 | this.y = this.HTML.offsetTop - this.HTML.offsetHeight / 2 - 1; 91 | this.width = this.HTML.offsetWidth + 1; // +1 to account for the border 92 | this.height = this.HTML.offsetHeight + 1; 93 | } 94 | } 95 | 96 | document.body.addEventListener("click", (e) => { 97 | createCircle(e); 98 | }); 99 | 100 | document.body.addEventListener("mousemove", (e) => { 101 | moveCircle(e); 102 | }); 103 | 104 | function createCircle(e) { 105 | if (e === undefined) return; 106 | new Circle(e.clientX - 25, e.clientY - 25); 107 | } 108 | 109 | function moveCircle(e) { 110 | if (e === undefined || circles.length === 0) return; 111 | circles[circles.length - 1].move(e.clientX - 25, e.clientY - 25); 112 | } 113 | 114 | function setBox() { 115 | box = new Box(); 116 | } 117 | 118 | export { createCircle, moveCircle, setBox }; 119 | -------------------------------------------------------------------------------- /where-do-we-go.js: -------------------------------------------------------------------------------- 1 | import { places } from "./where-do-we-go.data.js"; 2 | 3 | var scroll = window.scrollY; 4 | const location = document.createElement("a"); 5 | location.classList.add("location"); 6 | document.body.appendChild(location); 7 | 8 | document.addEventListener("DOMContentLoaded", () => { 9 | selectPlace(); 10 | }); 11 | 12 | document.addEventListener("scroll", () => { 13 | selectPlace(); 14 | scroll > window.scrollY 15 | ? (document.querySelector(".direction").innerHTML = "N") 16 | : (document.querySelector(".direction").innerHTML = "S"); 17 | scroll = window.scrollY; 18 | }); 19 | 20 | function explore() { 21 | // Places/sections 22 | places.sort(compareCoordinates); 23 | console.log(places); 24 | places.forEach((place) => { 25 | createSection(place); 26 | }); 27 | // Compass 28 | const compass = document.createElement("div"); 29 | compass.classList.add("direction"); 30 | document.body.appendChild(compass); 31 | } 32 | 33 | function createSection(place) { 34 | let section = document.createElement("section"); 35 | section.style.background = `url('./where-do-we-go_images/${ 36 | place.name.toLowerCase().replaceAll(/ /g, "-").split(",")[0] 37 | }.jpg')`; 38 | section.style.backgroundSize = "cover"; 39 | section.style.backgroundPosition = "center"; 40 | section.style.backgroundRepeat = "no-repeat"; 41 | section.style.width = "100%"; 42 | section.style.height = "100vh"; 43 | document.body.appendChild(section); 44 | } 45 | 46 | function selectPlace() { 47 | const sectionHeight = window.innerHeight; 48 | const scroll = window.scrollY + sectionHeight / 2; 49 | const sectionIndex = Math.floor(scroll / sectionHeight); 50 | const place = places[sectionIndex]; 51 | location.textContent = `${place.name}\n${place.coordinates}`; 52 | location.href = `https://www.google.com/maps/place/${urlEncodeCoordinates( 53 | place.coordinates 54 | )}/`; 55 | console.log( 56 | location.href 57 | .split("%C2%B0") 58 | .join("°") 59 | .split("%22") 60 | .join('"') 61 | .split("%20") 62 | .join(" ") 63 | ); 64 | location.target = "_blank"; 65 | location.style.color = place.color; 66 | } 67 | 68 | function urlEncodeCoordinates(coordinates) { 69 | return coordinates 70 | .replaceAll(" ", "%20") 71 | .replaceAll("°", "%C2%B0") 72 | .replaceAll('"', "%22"); 73 | } 74 | 75 | function compareCoordinates(a, b) { 76 | const aDirection = a.coordinates.split(" ")[0].split('"')[1]; 77 | const bDirection = b.coordinates.split(" ")[0].split('"')[1]; 78 | const aLat = a.coordinates.split(" ")[0]; 79 | const bLat = b.coordinates.split(" ")[0]; 80 | let aLatDeg = parseInt(aLat.split("°")[0]); 81 | let aLatMin = parseInt(aLat.split("°")[1].split("'")[0]); 82 | let aLatSec = parseInt(aLat.split("°")[1].split("'")[1].split('"')[0]); 83 | let bLatDeg = parseInt(bLat.split("°")[0]); 84 | let bLatMin = parseInt(bLat.split("°")[1].split("'")[0]); 85 | let bLatSec = parseInt(bLat.split("°")[1].split("'")[1].split('"')[0]); 86 | if (aDirection === "S") { 87 | aLatDeg = -aLatDeg; 88 | aLatMin = -aLatMin; 89 | aLatSec = -aLatSec; 90 | } 91 | if (bDirection === "S") { 92 | bLatDeg = -bLatDeg; 93 | bLatMin = -bLatMin; 94 | bLatSec = -bLatSec; 95 | } 96 | if (aLatDeg > bLatDeg) { 97 | return -1; 98 | } 99 | if (aLatDeg < bLatDeg) { 100 | return 1; 101 | } 102 | if (aLatDeg === bLatDeg) { 103 | if (aLatMin > bLatMin) { 104 | return -1; 105 | } 106 | if (aLatMin < bLatMin) { 107 | return 1; 108 | } 109 | if (aLatMin === bLatMin) { 110 | if (aLatSec > bLatSec) { 111 | return 1; 112 | } 113 | if (aLatSec < bLatSec) { 114 | return -1; 115 | } 116 | if (aLatSec === bLatSec) { 117 | return 0; 118 | } 119 | } 120 | } 121 | } 122 | 123 | export { explore }; 124 | --------------------------------------------------------------------------------