[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules/\n*.log\nhaters/\n.idea/\n"
  },
  {
    "path": "01 - JavaScript Drum Kit/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JS Drum Kit</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n\n  <div class=\"keys\">\n    <div data-key=\"65\" class=\"key\">\n      <kbd>A</kbd>\n      <span class=\"sound\">clap</span>\n    </div>\n    <div data-key=\"83\" class=\"key\">\n      <kbd>S</kbd>\n      <span class=\"sound\">hihat</span>\n    </div>\n    <div data-key=\"68\" class=\"key\">\n      <kbd>D</kbd>\n      <span class=\"sound\">kick</span>\n    </div>\n    <div data-key=\"70\" class=\"key\">\n      <kbd>F</kbd>\n      <span class=\"sound\">openhat</span>\n    </div>\n    <div data-key=\"71\" class=\"key\">\n      <kbd>G</kbd>\n      <span class=\"sound\">boom</span>\n    </div>\n    <div data-key=\"72\" class=\"key\">\n      <kbd>H</kbd>\n      <span class=\"sound\">ride</span>\n    </div>\n    <div data-key=\"74\" class=\"key\">\n      <kbd>J</kbd>\n      <span class=\"sound\">snare</span>\n    </div>\n    <div data-key=\"75\" class=\"key\">\n      <kbd>K</kbd>\n      <span class=\"sound\">tom</span>\n    </div>\n    <div data-key=\"76\" class=\"key\">\n      <kbd>L</kbd>\n      <span class=\"sound\">tink</span>\n    </div>\n  </div>\n\n  <audio data-key=\"65\" src=\"sounds/clap.wav\"></audio>\n  <audio data-key=\"83\" src=\"sounds/hihat.wav\"></audio>\n  <audio data-key=\"68\" src=\"sounds/kick.wav\"></audio>\n  <audio data-key=\"70\" src=\"sounds/openhat.wav\"></audio>\n  <audio data-key=\"71\" src=\"sounds/boom.wav\"></audio>\n  <audio data-key=\"72\" src=\"sounds/ride.wav\"></audio>\n  <audio data-key=\"74\" src=\"sounds/snare.wav\"></audio>\n  <audio data-key=\"75\" src=\"sounds/tom.wav\"></audio>\n  <audio data-key=\"76\" src=\"sounds/tink.wav\"></audio>\n\n<script>\n  function removeTransition(e) {\n    if (e.propertyName !== 'transform') return;\n    e.target.classList.remove('playing');\n  }\n\n  function playSound(e) {\n    const audio = document.querySelector(`audio[data-key=\"${e.keyCode}\"]`);\n    const key = document.querySelector(`div[data-key=\"${e.keyCode}\"]`);\n    if (!audio) return;\n\n    key.classList.add('playing');\n    audio.currentTime = 0;\n    audio.play();\n  }\n\n  const keys = Array.from(document.querySelectorAll('.key'));\n  keys.forEach(key => key.addEventListener('transitionend', removeTransition));\n  window.addEventListener('keydown', playSound);\n</script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "01 - JavaScript Drum Kit/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JS Drum Kit</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n\n  <div class=\"keys\">\n    <div data-key=\"65\" class=\"key\">\n      <kbd>A</kbd>\n      <span class=\"sound\">clap</span>\n    </div>\n    <div data-key=\"83\" class=\"key\">\n      <kbd>S</kbd>\n      <span class=\"sound\">hihat</span>\n    </div>\n    <div data-key=\"68\" class=\"key\">\n      <kbd>D</kbd>\n      <span class=\"sound\">kick</span>\n    </div>\n    <div data-key=\"70\" class=\"key\">\n      <kbd>F</kbd>\n      <span class=\"sound\">openhat</span>\n    </div>\n    <div data-key=\"71\" class=\"key\">\n      <kbd>G</kbd>\n      <span class=\"sound\">boom</span>\n    </div>\n    <div data-key=\"72\" class=\"key\">\n      <kbd>H</kbd>\n      <span class=\"sound\">ride</span>\n    </div>\n    <div data-key=\"74\" class=\"key\">\n      <kbd>J</kbd>\n      <span class=\"sound\">snare</span>\n    </div>\n    <div data-key=\"75\" class=\"key\">\n      <kbd>K</kbd>\n      <span class=\"sound\">tom</span>\n    </div>\n    <div data-key=\"76\" class=\"key\">\n      <kbd>L</kbd>\n      <span class=\"sound\">tink</span>\n    </div>\n  </div>\n\n  <audio data-key=\"65\" src=\"sounds/clap.wav\"></audio>\n  <audio data-key=\"83\" src=\"sounds/hihat.wav\"></audio>\n  <audio data-key=\"68\" src=\"sounds/kick.wav\"></audio>\n  <audio data-key=\"70\" src=\"sounds/openhat.wav\"></audio>\n  <audio data-key=\"71\" src=\"sounds/boom.wav\"></audio>\n  <audio data-key=\"72\" src=\"sounds/ride.wav\"></audio>\n  <audio data-key=\"74\" src=\"sounds/snare.wav\"></audio>\n  <audio data-key=\"75\" src=\"sounds/tom.wav\"></audio>\n  <audio data-key=\"76\" src=\"sounds/tink.wav\"></audio>\n\n<script>\n\n</script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "01 - JavaScript Drum Kit/style.css",
    "content": "html {\n  font-size: 10px;\n  background: url('./background.jpg') bottom center;\n  background-size: cover;\n}\n\nbody,html {\n  margin: 0;\n  padding: 0;\n  font-family: sans-serif;\n}\n\n.keys {\n  display: flex;\n  flex: 1;\n  min-height: 100vh;\n  align-items: center;\n  justify-content: center;\n}\n\n.key {\n  border: .4rem solid black;\n  border-radius: .5rem;\n  margin: 1rem;\n  font-size: 1.5rem;\n  padding: 1rem .5rem;\n  transition: all .07s ease;\n  width: 10rem;\n  text-align: center;\n  color: white;\n  background: rgba(0,0,0,0.4);\n  text-shadow: 0 0 .5rem black;\n}\n\n.playing {\n  transform: scale(1.1);\n  border-color: #ffc600;\n  box-shadow: 0 0 1rem #ffc600;\n}\n\nkbd {\n  display: block;\n  font-size: 4rem;\n}\n\n.sound {\n  font-size: 1.2rem;\n  text-transform: uppercase;\n  letter-spacing: .1rem;\n  color: #ffc600;\n}\n"
  },
  {
    "path": "02 - JS and CSS Clock/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JS + CSS Clock</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n\n    <div class=\"clock\">\n      <div class=\"clock-face\">\n        <div class=\"hand hour-hand\"></div>\n        <div class=\"hand min-hand\"></div>\n        <div class=\"hand second-hand\"></div>\n      </div>\n    </div>\n\n\n  <style>\n    html {\n      background: #018DED url(https://unsplash.it/1500/1000?image=881&blur=5);\n      background-size: cover;\n      font-family: 'helvetica neue';\n      text-align: center;\n      font-size: 10px;\n    }\n\n    body {\n      margin: 0;\n      font-size: 2rem;\n      display: flex;\n      flex: 1;\n      min-height: 100vh;\n      align-items: center;\n    }\n\n    .clock {\n      width: 30rem;\n      height: 30rem;\n      border: 20px solid white;\n      border-radius: 50%;\n      margin: 50px auto;\n      position: relative;\n      padding: 2rem;\n      box-shadow:\n        0 0 0 4px rgba(0,0,0,0.1),\n        inset 0 0 0 3px #EFEFEF,\n        inset 0 0 10px black,\n        0 0 10px rgba(0,0,0,0.2);\n    }\n\n    .clock-face {\n      position: relative;\n      width: 100%;\n      height: 100%;\n      transform: translateY(-3px); /* account for the height of the clock hands */\n    }\n\n    .hand {\n      width: 50%;\n      height: 6px;\n      background: black;\n      position: absolute;\n      top: 50%;\n      transform-origin: 100%;\n      transform: rotate(90deg);\n      transition: all 0.05s;\n      transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);\n    }\n</style>\n\n<script>\n  const secondHand = document.querySelector('.second-hand');\n  const minsHand = document.querySelector('.min-hand');\n  const hourHand = document.querySelector('.hour-hand');\n\n  function setDate() {\n    const now = new Date();\n\n    const seconds = now.getSeconds();\n    const secondsDegrees = ((seconds / 60) * 360) + 90;\n    secondHand.style.transform = `rotate(${secondsDegrees}deg)`;\n\n    const mins = now.getMinutes();\n    const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;\n    minsHand.style.transform = `rotate(${minsDegrees}deg)`;\n\n    const hour = now.getHours();\n    const hourDegrees = ((hour / 12) * 360) + ((mins/60)*30) + 90;\n    hourHand.style.transform = `rotate(${hourDegrees}deg)`;\n  }\n\n  setInterval(setDate, 1000);\n\n  setDate();\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "02 - JS and CSS Clock/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JS + CSS Clock</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n\n    <div class=\"clock\">\n      <div class=\"clock-face\">\n        <div class=\"hand hour-hand\"></div>\n        <div class=\"hand min-hand\"></div>\n        <div class=\"hand second-hand\"></div>\n      </div>\n    </div>\n\n\n  <style>\n    html {\n      background: #018DED url(https://unsplash.it/1500/1000?image=881&blur=5);\n      background-size: cover;\n      font-family: 'helvetica neue';\n      text-align: center;\n      font-size: 10px;\n    }\n\n    body {\n      margin: 0;\n      font-size: 2rem;\n      display: flex;\n      flex: 1;\n      min-height: 100vh;\n      align-items: center;\n    }\n\n    .clock {\n      width: 30rem;\n      height: 30rem;\n      border: 20px solid white;\n      border-radius: 50%;\n      margin: 50px auto;\n      position: relative;\n      padding: 2rem;\n      box-shadow:\n        0 0 0 4px rgba(0,0,0,0.1),\n        inset 0 0 0 3px #EFEFEF,\n        inset 0 0 10px black,\n        0 0 10px rgba(0,0,0,0.2);\n    }\n\n    .clock-face {\n      position: relative;\n      width: 100%;\n      height: 100%;\n      transform: translateY(-3px); /* account for the height of the clock hands */\n    }\n\n    .hand {\n      width: 50%;\n      height: 6px;\n      background: black;\n      position: absolute;\n      top: 50%;\n    }\n\n  </style>\n\n  <script>\n\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "03 - CSS Variables/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Scoped CSS Variables and JS</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <h2>Update CSS Variables with <span class='hl'>JS</span></h2>\n\n  <div class=\"controls\">\n    <label for=\"spacing\">Spacing:</label>\n    <input id=\"spacing\" type=\"range\" name=\"spacing\" min=\"10\" max=\"200\" value=\"10\" data-sizing=\"px\">\n\n    <label for=\"blur\">Blur:</label>\n    <input id=\"blur\" type=\"range\" name=\"blur\" min=\"0\" max=\"25\" value=\"10\" data-sizing=\"px\">\n\n    <label for=\"base\">Base Color</label>\n    <input id=\"base\" type=\"color\" name=\"base\" value=\"#ffc600\">\n  </div>\n\n  <img src=\"https://source.unsplash.com/7bwQXzbF6KE/800x500\">\n\n  <style>\n    :root {\n      --base: #ffc600;\n      --spacing: 10px;\n      --blur: 10px;\n    }\n\n    img {\n      padding: var(--spacing);\n      background: var(--base);\n      filter: blur(var(--blur));\n    }\n\n    .hl {\n      color: var(--base);\n    }\n\n    /*\n      misc styles, nothing to do with CSS variables\n    */\n\n    body {\n      text-align: center;\n      background: #193549;\n      color: white;\n      font-family: 'helvetica neue', sans-serif;\n      font-weight: 100;\n      font-size: 50px;\n    }\n\n    .controls {\n      margin-bottom: 50px;\n    }\n\n    input {\n      width: 100px;\n    }\n  </style>\n\n  <script>\n    const inputs = document.querySelectorAll('.controls input');\n\n    function handleUpdate() {\n      const suffix = this.dataset.sizing || '';\n      document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);\n    }\n\n    inputs.forEach(input => input.addEventListener('change', handleUpdate));\n    inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));\n  </script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "03 - CSS Variables/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Scoped CSS Variables and JS</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <h2>Update CSS Variables with <span class='hl'>JS</span></h2>\n\n  <div class=\"controls\">\n    <label for=\"spacing\">Spacing:</label>\n    <input id=\"spacing\" type=\"range\" name=\"spacing\" min=\"10\" max=\"200\" value=\"10\" data-sizing=\"px\">\n\n    <label for=\"blur\">Blur:</label>\n    <input id=\"blur\" type=\"range\" name=\"blur\" min=\"0\" max=\"25\" value=\"10\" data-sizing=\"px\">\n\n    <label for=\"base\">Base Color</label>\n    <input id=\"base\" type=\"color\" name=\"base\" value=\"#ffc600\">\n  </div>\n\n  <img src=\"https://source.unsplash.com/7bwQXzbF6KE/800x500\">\n\n  <style>\n\n    /*\n      misc styles, nothing to do with CSS variables\n    */\n\n    body {\n      text-align: center;\n      background: #193549;\n      color: white;\n      font-family: 'helvetica neue', sans-serif;\n      font-weight: 100;\n      font-size: 50px;\n    }\n\n    .controls {\n      margin-bottom: 50px;\n    }\n\n    input {\n      width: 100px;\n    }\n  </style>\n\n  <script>\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "04 - Array Cardio Day 1/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Array Cardio 💪</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <p><em>Psst: have a look at the JavaScript Console</em> 💁</p>\n  <script>\n    // Get your shorts on - this is an array workout!\n    // ## Array Cardio Day 1\n\n    // Some data we can work with\n\n    const inventors = [\n      { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },\n      { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },\n      { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },\n      { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },\n      { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },\n      { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },\n      { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },\n      { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },\n      { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },\n      { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },\n      { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },\n      { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }\n    ];\n\n    const people = [\n      'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig',\n      'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving',\n      'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano',\n      'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose',\n      'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank'\n    ];\n\n    // Array.prototype.filter()\n    // 1. Filter the list of inventors for those who were born in the 1500's\n    const fifteen = inventors.filter(inventor => (inventor.year >= 1500 && inventor.year < 1600));\n\n    console.table(fifteen);\n\n    // Array.prototype.map()\n    // 2. Give us an array of the inventor first and last names\n    const fullNames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);\n    console.log(fullNames);\n\n    // Array.prototype.sort()\n    // 3. Sort the inventors by birthdate, oldest to youngest\n    // const ordered = inventors.sort(function(a, b) {\n    //   if(a.year > b.year) {\n    //     return 1;\n    //   } else {\n    //     return -1;\n    //   }\n    // });\n\n    const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);\n    console.table(ordered);\n\n    // Array.prototype.reduce()\n    // 4. How many years did all the inventors live?\n    const totalYears = inventors.reduce((total, inventor) => {\n      return total + (inventor.passed - inventor.year);\n    }, 0);\n\n    console.log(totalYears);\n\n    // 5. Sort the inventors by years lived\n    const oldest = inventors.sort(function(a, b) {\n      const lastInventor = a.passed - a.year;\n      const nextInventor = b.passed - b.year;\n      return lastInventor > nextInventor ? -1 : 1;\n    });\n    console.table(oldest);\n\n    // 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name\n    // https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris\n\n    // const category = document.querySelector('.mw-category');\n    // const links = Array.from(category.querySelectorAll('a'));\n    // const de = links\n    //             .map(link => link.textContent)\n    //             .filter(streetName => streetName.includes('de'));\n\n    // 7. sort Exercise\n    // Sort the people alphabetically by last name\n    const alpha = people.sort((lastOne, nextOne) => {\n      const [aLast, aFirst] = lastOne.split(', ');\n      const [bLast, bFirst] = nextOne.split(', ');\n      return aLast > bLast ? 1 : -1;\n    });\n    console.log(alpha);\n\n    // 8. Reduce Exercise\n    // Sum up the instances of each of these\n    const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck', 'pogostick'];\n\n    const transportation = data.reduce(function(obj, item) {\n      if (!obj[item]) {\n        obj[item] = 0;\n      }\n      obj[item]++;\n      return obj;\n    }, {});\n\n    console.log(transportation);\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "04 - Array Cardio Day 1/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Array Cardio 💪</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <p><em>Psst: have a look at the JavaScript Console</em> 💁</p>\n  <script>\n    // Get your shorts on - this is an array workout!\n    // ## Array Cardio Day 1\n\n    // Some data we can work with\n\n    const inventors = [\n      { first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },\n      { first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },\n      { first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },\n      { first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },\n      { first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },\n      { first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },\n      { first: 'Max', last: 'Planck', year: 1858, passed: 1947 },\n      { first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },\n      { first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },\n      { first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },\n      { first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },\n      { first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }\n    ];\n\n    const people = [\n      'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig',\n      'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving',\n      'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano',\n      'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose',\n      'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank'\n    ];\n    \n    // Array.prototype.filter()\n    // 1. Filter the list of inventors for those who were born in the 1500's\n\n    // Array.prototype.map()\n    // 2. Give us an array of the inventors first and last names\n\n    // Array.prototype.sort()\n    // 3. Sort the inventors by birthdate, oldest to youngest\n\n    // Array.prototype.reduce()\n    // 4. How many years did all the inventors live all together?\n\n    // 5. Sort the inventors by years lived\n\n    // 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name\n    // https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris\n\n\n    // 7. sort Exercise\n    // Sort the people alphabetically by last name\n\n    // 8. Reduce Exercise\n    // Sum up the instances of each of these\n    const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck' ];\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "05 - Flex Panel Gallery/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Flex Panels 💪</title>\n  <link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <style>\n    html {\n      box-sizing: border-box;\n      background: #ffc600;\n      font-family: 'helvetica neue';\n      font-size: 20px;\n      font-weight: 200;\n    }\n\n    body {\n      margin: 0;\n    }\n\n    *, *:before, *:after {\n      box-sizing: inherit;\n    }\n\n    .panels {\n      min-height: 100vh;\n      overflow: hidden;\n      display: flex;\n    }\n\n    .panel {\n      background: #6B0F9C;\n      box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);\n      color: white;\n      text-align: center;\n      align-items: center;\n      /* Safari transitionend event.propertyName === flex */\n      /* Chrome + FF transitionend event.propertyName === flex-grow */\n      transition:\n        font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),\n        flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),\n        background 0.2s;\n      font-size: 20px;\n      background-size: cover;\n      background-position: center;\n      flex: 1;\n      justify-content: center;\n      display: flex;\n      flex-direction: column;\n    }\n\n    .panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }\n    .panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }\n    .panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }\n    .panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }\n    .panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }\n\n    /* Flex Items */\n    .panel > * {\n      margin: 0;\n      width: 100%;\n      transition: transform 0.5s;\n      flex: 1 0 auto;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n    }\n\n    .panel > *:first-child { transform: translateY(-100%); }\n    .panel.open-active > *:first-child { transform: translateY(0); }\n    .panel > *:last-child { transform: translateY(100%); }\n    .panel.open-active > *:last-child { transform: translateY(0); }\n\n    .panel p {\n      text-transform: uppercase;\n      font-family: 'Amatic SC', cursive;\n      text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);\n      font-size: 2em;\n    }\n\n    .panel p:nth-child(2) {\n      font-size: 4em;\n    }\n\n    .panel.open {\n      flex: 5;\n      font-size: 40px;\n    }\n\n    @media only screen and (max-width: 600px) {\n      .panel p {\n        font-size: 1em;\n      }\n    }\n  </style>\n\n\n  <div class=\"panels\">\n    <div class=\"panel panel1\">\n      <p>Hey</p>\n      <p>Let's</p>\n      <p>Dance</p>\n    </div>\n    <div class=\"panel panel2\">\n      <p>Give</p>\n      <p>Take</p>\n      <p>Receive</p>\n    </div>\n    <div class=\"panel panel3\">\n      <p>Experience</p>\n      <p>It</p>\n      <p>Today</p>\n    </div>\n    <div class=\"panel panel4\">\n      <p>Give</p>\n      <p>All</p>\n      <p>You can</p>\n    </div>\n    <div class=\"panel panel5\">\n      <p>Life</p>\n      <p>In</p>\n      <p>Motion</p>\n    </div>\n  </div>\n\n  <script>\n    const panels = document.querySelectorAll('.panel');\n\n    function toggleOpen() {\n      console.log('Hello');\n      this.classList.toggle('open');\n    }\n\n    function toggleActive(e) {\n      console.log(e.propertyName);\n      if (e.propertyName.includes('flex')) {\n        this.classList.toggle('open-active');\n      }\n    }\n\n    panels.forEach(panel => panel.addEventListener('click', toggleOpen));\n    panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "05 - Flex Panel Gallery/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Flex Panels 💪</title>\n  <link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <style>\n    html {\n      box-sizing: border-box;\n      background: #ffc600;\n      font-family: 'helvetica neue';\n      font-size: 20px;\n      font-weight: 200;\n    }\n\n    body {\n      margin: 0;\n    }\n\n    *, *:before, *:after {\n      box-sizing: inherit;\n    }\n\n    .panels {\n      min-height: 100vh;\n      overflow: hidden;\n    }\n\n    .panel {\n      background: #6B0F9C;\n      box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);\n      color: white;\n      text-align: center;\n      align-items: center;\n      /* Safari transitionend event.propertyName === flex */\n      /* Chrome + FF transitionend event.propertyName === flex-grow */\n      transition:\n        font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),\n        flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),\n        background 0.2s;\n      font-size: 20px;\n      background-size: cover;\n      background-position: center;\n    }\n\n    .panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }\n    .panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }\n    .panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }\n    .panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }\n    .panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }\n\n    /* Flex Children */\n    .panel > * {\n      margin: 0;\n      width: 100%;\n      transition: transform 0.5s;\n    }\n\n    .panel p {\n      text-transform: uppercase;\n      font-family: 'Amatic SC', cursive;\n      text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);\n      font-size: 2em;\n    }\n\n    .panel p:nth-child(2) {\n      font-size: 4em;\n    }\n\n    .panel.open {\n      font-size: 40px;\n    }\n\n  </style>\n\n\n  <div class=\"panels\">\n    <div class=\"panel panel1\">\n      <p>Hey</p>\n      <p>Let's</p>\n      <p>Dance</p>\n    </div>\n    <div class=\"panel panel2\">\n      <p>Give</p>\n      <p>Take</p>\n      <p>Receive</p>\n    </div>\n    <div class=\"panel panel3\">\n      <p>Experience</p>\n      <p>It</p>\n      <p>Today</p>\n    </div>\n    <div class=\"panel panel4\">\n      <p>Give</p>\n      <p>All</p>\n      <p>You can</p>\n    </div>\n    <div class=\"panel panel5\">\n      <p>Life</p>\n      <p>In</p>\n      <p>Motion</p>\n    </div>\n  </div>\n\n  <script>\n\n  </script>\n\n\n\n</body>\n</html>\n"
  },
  {
    "path": "06 - Type Ahead/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Type Ahead 👀</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <form class=\"search-form\">\n    <input type=\"text\" class=\"search\" placeholder=\"City or State\">\n    <ul class=\"suggestions\">\n      <li>Filter for a city</li>\n      <li>or a state</li>\n    </ul>\n  </form>\n<script>\nconst endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';\n\nconst cities = [];\nfetch(endpoint)\n  .then(blob => blob.json())\n  .then(data => cities.push(...data));\n\nfunction findMatches(wordToMatch, cities) {\n  return cities.filter(place => {\n    // here we need to figure out if the city or state matches what was searched\n    const regex = new RegExp(wordToMatch, 'gi');\n    return place.city.match(regex) || place.state.match(regex)\n  });\n}\n\nfunction numberWithCommas(x) {\n  return x.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nfunction displayMatches() {\n  const matchArray = findMatches(this.value, cities);\n  const html = matchArray.map(place => {\n    const regex = new RegExp(this.value, 'gi');\n    const cityName = place.city.replace(regex, `<span class=\"hl\">${this.value}</span>`);\n    const stateName = place.state.replace(regex, `<span class=\"hl\">${this.value}</span>`);\n    return `\n      <li>\n        <span class=\"name\">${cityName}, ${stateName}</span>\n        <span class=\"population\">${numberWithCommas(place.population)}</span>\n      </li>\n    `;\n  }).join('');\n  suggestions.innerHTML = html;\n}\n\nconst searchInput = document.querySelector('.search');\nconst suggestions = document.querySelector('.suggestions');\n\nsearchInput.addEventListener('change', displayMatches);\nsearchInput.addEventListener('keyup', displayMatches);\n\n</script>\n  </body>\n</html>\n"
  },
  {
    "path": "06 - Type Ahead/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Type Ahead 👀</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <form class=\"search-form\">\n    <input type=\"text\" class=\"search\" placeholder=\"City or State\">\n    <ul class=\"suggestions\">\n      <li>Filter for a city</li>\n      <li>or a state</li>\n    </ul>\n  </form>\n<script>\nconst endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "06 - Type Ahead/style.css",
    "content": "html {\n  box-sizing: border-box;\n  background: #ffc600;\n  font-family: 'helvetica neue';\n  font-size: 20px;\n  font-weight: 200;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\ninput {\n  width: 100%;\n  padding: 20px;\n}\n\n.search-form {\n  max-width: 400px;\n  margin: 50px auto;\n}\n\ninput.search {\n  margin: 0;\n  text-align: center;\n  outline: 0;\n  border: 10px solid #F7F7F7;\n  width: 120%;\n  left: -10%;\n  position: relative;\n  top: 10px;\n  z-index: 2;\n  border-radius: 5px;\n  font-size: 40px;\n  box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);\n}\n\n.suggestions {\n  margin: 0;\n  padding: 0;\n  position: relative;\n  /*perspective: 20px;*/\n}\n\n.suggestions li {\n  background: white;\n  list-style: none;\n  border-bottom: 1px solid #D8D8D8;\n  box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);\n  margin: 0;\n  padding: 20px;\n  transition: background 0.2s;\n  display: flex;\n  justify-content: space-between;\n  text-transform: capitalize;\n}\n\n.suggestions li:nth-child(even) {\n  transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);\n  background: linear-gradient(to bottom,  #ffffff 0%,#EFEFEF 100%);\n}\n\n.suggestions li:nth-child(odd) {\n  transform: perspective(100px) rotateX(-3deg) translateY(3px);\n  background: linear-gradient(to top,  #ffffff 0%,#EFEFEF 100%);\n}\n\nspan.population {\n  font-size: 15px;\n}\n\n.hl {\n  background: #ffc600;\n}\n"
  },
  {
    "path": "07 - Array Cardio Day 2/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Array Cardio 💪💪</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <p><em>Psst: have a look at the JavaScript Console</em> 💁</p>\n  <script>\n    // ## Array Cardio Day 2\n\n    const people = [\n      { name: 'Wes', year: 1988 },\n      { name: 'Kait', year: 1986 },\n      { name: 'Irv', year: 1970 },\n      { name: 'Lux', year: 2015 }\n    ];\n\n    const comments = [\n      { text: 'Love this!', id: 523423 },\n      { text: 'Super good', id: 823423 },\n      { text: 'You are the best', id: 2039842 },\n      { text: 'Ramen is my fav food ever', id: 123523 },\n      { text: 'Nice Nice Nice!', id: 542328 }\n    ];\n\n    // Some and Every Checks\n    // Array.prototype.some() // is at least one person 19?\n    // const isAdult = people.some(function(person) {\n    //   const currentYear = (new Date()).getFullYear();\n    //   if(currentYear - person.year >= 19) {\n    //     return true;\n    //   }\n    // });\n\n    const isAdult = people.some(person => ((new Date()).getFullYear()) - person.year >= 19);\n\n    console.log({isAdult});\n    // Array.prototype.every() // is everyone 19?\n\n    const allAdults = people.every(person => ((new Date()).getFullYear()) - person.year >= 19);\n    console.log({allAdults});\n\n    // Array.prototype.find()\n    // Find is like filter, but instead returns just the one you are looking for\n    // find the comment with the ID of 823423\n\n\n    const comment = comments.find(comment => comment.id === 823423);\n\n    console.log(comment);\n\n    // Array.prototype.findIndex()\n    // Find the comment with this ID\n    // delete the comment with the ID of 823423\n    const index = comments.findIndex(comment => comment.id === 823423);\n    console.log(index);\n\n    // comments.splice(index, 1);\n\n    const newComments = [\n      ...comments.slice(0, index),\n      ...comments.slice(index + 1)\n    ];\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "07 - Array Cardio Day 2/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Array Cardio 💪💪</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <p><em>Psst: have a look at the JavaScript Console</em> 💁</p>\n  <script>\n    // ## Array Cardio Day 2\n\n    const people = [\n      { name: 'Wes', year: 1988 },\n      { name: 'Kait', year: 1986 },\n      { name: 'Irv', year: 1970 },\n      { name: 'Lux', year: 2015 }\n    ];\n\n    const comments = [\n      { text: 'Love this!', id: 523423 },\n      { text: 'Super good', id: 823423 },\n      { text: 'You are the best', id: 2039842 },\n      { text: 'Ramen is my fav food ever', id: 123523 },\n      { text: 'Nice Nice Nice!', id: 542328 }\n    ];\n\n    // Some and Every Checks\n    // Array.prototype.some() // is at least one person 19 or older?\n    // Array.prototype.every() // is everyone 19 or older?\n\n    // Array.prototype.find()\n    // Find is like filter, but instead returns just the one you are looking for\n    // find the comment with the ID of 823423\n\n    // Array.prototype.findIndex()\n    // Find the comment with this ID\n    // delete the comment with the ID of 823423\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "08 - Fun with HTML5 Canvas/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>HTML5 Canvas</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n<canvas id=\"draw\" width=\"800\" height=\"800\"></canvas>\n<script>\nconst canvas = document.querySelector('#draw');\nconst ctx = canvas.getContext('2d');\ncanvas.width = window.innerWidth;\ncanvas.height = window.innerHeight;\nctx.strokeStyle = '#BADA55';\nctx.lineJoin = 'round';\nctx.lineCap = 'round';\nctx.lineWidth = 100;\n// ctx.globalCompositeOperation = 'multiply';\n\nlet isDrawing = false;\nlet lastX = 0;\nlet lastY = 0;\nlet hue = 0;\nlet direction = true;\n\nfunction draw(e) {\n  if (!isDrawing) return; // stop the fn from running when they are not moused down\n  console.log(e);\n  ctx.strokeStyle = `hsl(${hue}, 100%, 50%)`;\n  ctx.beginPath();\n  // start from\n  ctx.moveTo(lastX, lastY);\n  // go to\n  ctx.lineTo(e.offsetX, e.offsetY);\n  ctx.stroke();\n  [lastX, lastY] = [e.offsetX, e.offsetY];\n\n  hue++;\n  if (hue >= 360) {\n    hue = 0;\n  }\n  if (ctx.lineWidth >= 100 || ctx.lineWidth <= 1) {\n    direction = !direction;\n  }\n\n  if(direction) {\n    ctx.lineWidth++;\n  } else {\n    ctx.lineWidth--;\n  }\n\n}\n\ncanvas.addEventListener('mousedown', (e) => {\n  isDrawing = true;\n  [lastX, lastY] = [e.offsetX, e.offsetY];\n});\n\n\ncanvas.addEventListener('mousemove', draw);\ncanvas.addEventListener('mouseup', () => isDrawing = false);\ncanvas.addEventListener('mouseout', () => isDrawing = false);\n\n</script>\n\n<style>\n  html, body {\n    margin: 0;\n  }\n</style>\n\n</body>\n</html>\n"
  },
  {
    "path": "08 - Fun with HTML5 Canvas/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>HTML5 Canvas</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n<canvas id=\"draw\" width=\"800\" height=\"800\"></canvas>\n<script>\n</script>\n\n<style>\n  html, body {\n    margin: 0;\n  }\n</style>\n\n</body>\n</html>\n"
  },
  {
    "path": "09 - Dev Tools Domination/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Console Tricks!</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <p onClick=\"makeGreen()\">×BREAK×DOWN×</p>\n\n  <script>\n    const dogs = [{ name: 'Snickers', age: 2 }, { name: 'hugo', age: 8 }];\n\n    function makeGreen() {\n      const p = document.querySelector('p');\n      p.style.color = '#BADA55';\n      p.style.fontSize = '50px';\n    }\n\n    // Regular\n    console.log('hello');\n\n    // Interpolated\n    console.log('Hello I am a %s string!', '💩');\n\n    // Styled\n    // console.log('%c I am some great text', 'font-size:50px; background:red; text-shadow: 10px 10px 0 blue')\n\n    // warning!\n    console.warn('OH NOOO');\n\n    // Error :|\n    console.error('Shit!');\n\n    // Info\n    console.info('Crocodiles eat 3-4 people per year');\n\n    // Testing\n    const p = document.querySelector('p');\n\n    console.assert(p.classList.contains('ouch'), 'That is wrong!');\n\n    // clearing\n    console.clear();\n\n    // Viewing DOM Elements\n    console.log(p);\n    console.dir(p);\n\n    console.clear();\n\n    // Grouping together\n    dogs.forEach(dog => {\n      console.groupCollapsed(`${dog.name}`);\n      console.log(`This is ${dog.name}`);\n      console.log(`${dog.name} is ${dog.age} years old`);\n      console.log(`${dog.name} is ${dog.age * 7} dog years old`);\n      console.groupEnd(`${dog.name}`);\n    });\n\n    // counting\n\n    console.count('Wes');\n    console.count('Wes');\n    console.count('Steve');\n    console.count('Steve');\n    console.count('Wes');\n    console.count('Steve');\n    console.count('Wes');\n    console.count('Steve');\n    console.count('Steve');\n    console.count('Steve');\n    console.count('Steve');\n    console.count('Steve');\n\n    // timing\n    console.time('fetching data');\n    fetch('https://api.github.com/users/wesbos')\n      .then(data => data.json())\n      .then(data => {\n        console.timeEnd('fetching data');\n        console.log(data);\n      });\n\n    console.table(dogs);\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "09 - Dev Tools Domination/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Console Tricks!</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <p onClick=\"makeGreen()\">×BREAK×DOWN×</p>\n\n  <script>\n    const dogs = [{ name: 'Snickers', age: 2 }, { name: 'hugo', age: 8 }];\n\n    function makeGreen() {\n      const p = document.querySelector('p');\n      p.style.color = '#BADA55';\n      p.style.fontSize = '50px';\n    }\n\n    // Regular\n\n    // Interpolated\n\n    // Styled\n\n    // warning!\n\n    // Error :|\n\n    // Info\n\n    // Testing\n\n    // clearing\n\n    // Viewing DOM Elements\n\n    // Grouping together\n\n    // counting\n\n    // timing\n\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "10 - Hold Shift and Check Checkboxes/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Hold Shift to Check Multiple Checkboxes</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <style>\n\n    html {\n      font-family: sans-serif;\n      background: #ffc600;\n    }\n\n    .inbox {\n      max-width: 400px;\n      margin: 50px auto;\n      background: white;\n      border-radius: 5px;\n      box-shadow: 10px 10px 0 rgba(0,0,0,0.1);\n    }\n\n    .item {\n      display: flex;\n      align-items: center;\n      border-bottom: 1px solid #F1F1F1;\n    }\n\n    .item:last-child {\n      border-bottom: 0;\n    }\n\n\n    input:checked + p {\n      background: #F9F9F9;\n      text-decoration: line-through;\n    }\n\n    input[type=\"checkbox\"] {\n      margin: 20px;\n    }\n\n    p {\n      margin: 0;\n      padding: 20px;\n      transition: background 0.2s;\n      flex: 1;\n      font-family: 'helvetica neue';\n      font-size: 20px;\n      font-weight: 200;\n      border-left: 1px solid #D1E2FF;\n    }\n  </style>\n   <!--\n   The following is a common layout you would see in an email client.\n\n   When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes in-between those two checkboxes should be checked.\n\n  -->\n  <div class=\"inbox\">\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>This is an inbox layout.</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Check one item</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Hold down your Shift key</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Check a lower item</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Everything in between should also be set to checked</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Try do it without any libraries</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Just regular JavaScript</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Good Luck!</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Don't forget to tweet your result!</p>\n    </div>\n  </div>\n\n<script>\nconst checkboxes = document.querySelectorAll('.inbox input[type=\"checkbox\"]');\n\nlet lastChecked;\n\nfunction handleCheck(e) {\n  // Check if they had the shift key down\n  // AND check that they are checking it\n  let inBetween = false;\n  if (e.shiftKey && this.checked) {\n    // go ahead and do what we please\n    // loop over every single checkbox\n    checkboxes.forEach(checkbox => {\n      console.log(checkbox);\n      if (checkbox === this || checkbox === lastChecked) {\n        inBetween = !inBetween;\n        console.log('Starting to check them in between!');\n      }\n\n      if (inBetween) {\n        checkbox.checked = true;\n      }\n    });\n  }\n\n  lastChecked = this;\n}\n\ncheckboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "10 - Hold Shift and Check Checkboxes/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Hold Shift to Check Multiple Checkboxes</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <style>\n\n    html {\n      font-family: sans-serif;\n      background: #ffc600;\n    }\n\n    .inbox {\n      max-width: 400px;\n      margin: 50px auto;\n      background: white;\n      border-radius: 5px;\n      box-shadow: 10px 10px 0 rgba(0,0,0,0.1);\n    }\n\n    .item {\n      display: flex;\n      align-items: center;\n      border-bottom: 1px solid #F1F1F1;\n    }\n\n    .item:last-child {\n      border-bottom: 0;\n    }\n\n    input:checked + p {\n      background: #F9F9F9;\n      text-decoration: line-through;\n    }\n\n    input[type=\"checkbox\"] {\n      margin: 20px;\n    }\n\n    p {\n      margin: 0;\n      padding: 20px;\n      transition: background 0.2s;\n      flex: 1;\n      font-family:'helvetica neue';\n      font-size: 20px;\n      font-weight: 200;\n      border-left: 1px solid #D1E2FF;\n    }\n  </style>\n   <!--\n   The following is a common layout you would see in an email client.\n\n   When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes inbetween those two checkboxes should be checked.\n\n  -->\n  <div class=\"inbox\">\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>This is an inbox layout.</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Check one item</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Hold down your Shift key</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Check a lower item</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Everything in between should also be set to checked</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Try to do it without any libraries</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Just regular JavaScript</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Good Luck!</p>\n    </div>\n    <div class=\"item\">\n      <input type=\"checkbox\">\n      <p>Don't forget to tweet your result!</p>\n    </div>\n  </div>\n\n<script>\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "11 - Custom Video Player/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>HTML Video Player</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n   <div class=\"player\">\n     <video class=\"player__video viewer\" src=\"652333414.mp4\"></video>\n\n     <div class=\"player__controls\">\n       <div class=\"progress\">\n        <div class=\"progress__filled\"></div>\n       </div>\n       <button class=\"player__button toggle\" title=\"Toggle Play\">►</button>\n       <input type=\"range\" name=\"volume\" class=\"player__slider\" min=\"0\" max=\"1\" step=\"0.05\" value=\"1\">\n       <input type=\"range\" name=\"playbackRate\" class=\"player__slider\" min=\"0.5\" max=\"2\" step=\"0.1\" value=\"1\">\n       <button data-skip=\"-10\" class=\"player__button\">« 10s</button>\n       <button data-skip=\"25\" class=\"player__button\">25s »</button>\n     </div>\n   </div>\n\n  <script src=\"scripts.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "11 - Custom Video Player/scripts-FINISHED.js",
    "content": "/* Get Our Elements */\nconst player = document.querySelector('.player');\nconst video = player.querySelector('.viewer');\nconst progress = player.querySelector('.progress');\nconst progressBar = player.querySelector('.progress__filled');\nconst toggle = player.querySelector('.toggle');\nconst skipButtons = player.querySelectorAll('[data-skip]');\nconst ranges = player.querySelectorAll('.player__slider');\n\n/* Build out functions */\nfunction togglePlay() {\n  const method = video.paused ? 'play' : 'pause';\n  video[method]();\n}\n\nfunction updateButton() {\n  const icon = this.paused ? '►' : '❚ ❚';\n  console.log(icon);\n  toggle.textContent = icon;\n}\n\nfunction skip() {\n video.currentTime += parseFloat(this.dataset.skip);\n}\n\nfunction handleRangeUpdate() {\n  video[this.name] = this.value;\n}\n\nfunction handleProgress() {\n  const percent = (video.currentTime / video.duration) * 100;\n  progressBar.style.flexBasis = `${percent}%`;\n}\n\nfunction scrub(e) {\n  const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;\n  video.currentTime = scrubTime;\n}\n\n/* Hook up the event listeners */\nvideo.addEventListener('click', togglePlay);\nvideo.addEventListener('play', updateButton);\nvideo.addEventListener('pause', updateButton);\nvideo.addEventListener('timeupdate', handleProgress);\n\ntoggle.addEventListener('click', togglePlay);\nskipButtons.forEach(button => button.addEventListener('click', skip));\nranges.forEach(range => range.addEventListener('change', handleRangeUpdate));\nranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));\n\nlet mousedown = false;\nprogress.addEventListener('click', scrub);\nprogress.addEventListener('mousemove', (e) => mousedown && scrub(e));\nprogress.addEventListener('mousedown', () => mousedown = true);\nprogress.addEventListener('mouseup', () => mousedown = false);\n"
  },
  {
    "path": "11 - Custom Video Player/scripts.js",
    "content": ""
  },
  {
    "path": "11 - Custom Video Player/style.css",
    "content": "html {\n  box-sizing: border-box;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nbody {\n  margin: 0;\n  padding: 0;\n  display: flex;\n  background: #7A419B;\n  min-height: 100vh;\n  background: linear-gradient(135deg, #7c1599 0%,#921099 48%,#7e4ae8 100%);\n  background-size: cover;\n  align-items: center;\n  justify-content: center;\n}\n\n.player {\n  max-width: 750px;\n  border: 5px solid rgba(0,0,0,0.2);\n  box-shadow: 0 0 20px rgba(0,0,0,0.2);\n  position: relative;\n  font-size: 0;\n  overflow: hidden;\n}\n\n/* This css is only applied when fullscreen is active. */\n.player:fullscreen {\n  max-width: none;\n  width: 100%;\n}\n\n.player:-webkit-full-screen {\n  max-width: none;\n  width: 100%;\n}\n\n.player__video {\n  width: 100%;\n}\n\n.player__button {\n  background: none;\n  border: 0;\n  line-height: 1;\n  color: white;\n  text-align: center;\n  outline: 0;\n  padding: 0;\n  cursor: pointer;\n  max-width: 50px;\n}\n\n.player__button:focus {\n  border-color: #ffc600;\n}\n\n.player__slider {\n  width: 10px;\n  height: 30px;\n}\n\n.player__controls {\n  display: flex;\n  position: absolute;\n  bottom: 0;\n  width: 100%;\n  transform: translateY(100%) translateY(-5px);\n  transition: all .3s;\n  flex-wrap: wrap;\n  background: rgba(0,0,0,0.1);\n}\n\n.player:hover .player__controls {\n  transform: translateY(0);\n}\n\n.player:hover .progress {\n  height: 15px;\n}\n\n.player__controls > * {\n  flex: 1;\n}\n\n.progress {\n  flex: 10;\n  position: relative;\n  display: flex;\n  flex-basis: 100%;\n  height: 5px;\n  transition: height 0.3s;\n  background: rgba(0,0,0,0.5);\n  cursor: ew-resize;\n}\n\n.progress__filled {\n  width: 50%;\n  background: #ffc600;\n  flex: 0;\n  flex-basis: 50%;\n}\n\n/* unholy css to style input type=\"range\" */\n\ninput[type=range] {\n  -webkit-appearance: none;\n  background: transparent;\n  width: 100%;\n  margin: 0 5px;\n}\n\ninput[type=range]:focus {\n  outline: none;\n}\n\ninput[type=range]::-webkit-slider-runnable-track {\n  width: 100%;\n  height: 8.4px;\n  cursor: pointer;\n  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);\n  background: rgba(255,255,255,0.8);\n  border-radius: 1.3px;\n  border: 0.2px solid rgba(1, 1, 1, 0);\n}\n\ninput[type=range]::-webkit-slider-thumb {\n  height: 15px;\n  width: 15px;\n  border-radius: 50px;\n  background: #ffc600;\n  cursor: pointer;\n  -webkit-appearance: none;\n  margin-top: -3.5px;\n  box-shadow:0 0 2px rgba(0,0,0,0.2);\n}\n\ninput[type=range]:focus::-webkit-slider-runnable-track {\n  background: #bada55;\n}\n\ninput[type=range]::-moz-range-track {\n  width: 100%;\n  height: 8.4px;\n  cursor: pointer;\n  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);\n  background: #ffffff;\n  border-radius: 1.3px;\n  border: 0.2px solid rgba(1, 1, 1, 0);\n}\n\ninput[type=range]::-moz-range-thumb {\n  box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);\n  height: 15px;\n  width: 15px;\n  border-radius: 50px;\n  background: #ffc600;\n  cursor: pointer;\n}\n"
  },
  {
    "path": "12 - Key Sequence Detection/cornify.js",
    "content": "/*\n\n    _______      ,-----.    .-------.    ,---.   .--..-./`)  ________    ____     __\n   /   __  \\   .'  .-,  '.  |  _ _   \\   |    \\  |  |\\ .-.')|        |   \\   \\   /  /\n  | ,_/  \\__) / ,-.|  \\ _ \\ | ( ' )  |   |  ,  \\ |  |/ `-' \\|   .----'    \\  _. /  '\n,-./  )      ;  \\  '_ /  | :|(_ o _) /   |  |\\_ \\|  | `-'`\"`|  _|____      _( )_ .'\n\\  '_ '`)    |  _`,/ \\ _/  || (_,_).' __ |  _( )_\\  | .---. |_( )_   | ___(_ o _)'\n > (_)  )  __: (  '\\_/ \\   ;|  |\\ \\  |  || (_ o _)  | |   | (_ o._)__||   |(_,_)'\n(  .  .-'_/  )\\ `\"/  \\  ) / |  | \\ `'   /|  (_,_)\\  | |   | |(_,_)    |   `-'  /\n `-'`-'     /  '. \\_/``\".'  |  |  \\    / |  |    |  | |   | |   |      \\      /\n   `._____.'     '-----'    ''-'   `'-'  '--'    '--' '---' '---'       `-..-'\n\n  This script has been modified by @wesbos because\n  https://twitter.com/wesbos/status/1657012836403388416\n\n*/\n\nvar cornify_count = 0;\nvar cornify_add = function (options) {\n  // Track how often we cornified.\n  cornify_count += 1;\n\n  // Prepare our lovely variables.\n  var cornify_url = \"https://www.cornify.com/\";\n  var numType = \"px\";\n  var heightRandom = Math.random() * 0.75;\n  var windowHeight = 768;\n  var windowWidth = 1024;\n  var height = 0;\n  var width = 0;\n  var de = document.documentElement;\n  var transform = \"translate(-50%, -50%)\";\n  var showGrandUnicorn = cornify_count == 15;\n\n  // Create a container for our 'corn or 'bow.\n  var div = document.createElement(\"div\");\n  div.style.position = \"fixed\";\n  div.className = \"__cornify_unicorn\";\n  div.style.zIndex = 143143;\n  div.style.outline = 0;\n  div.onclick = cornify_add; // Click for more magic.\n\n  // Get the window width and height - requires some cross browser checking.\n  if (typeof window.innerHeight == \"number\") {\n    windowHeight = window.innerHeight;\n    windowWidth = window.innerWidth;\n  } else if (de && de.clientHeight) {\n    windowHeight = de.clientHeight;\n    windowWidth = de.clientWidth;\n  } else {\n    numType = \"%\";\n    height = Math.round(height * 100) + \"%\";\n  }\n\n  if (showGrandUnicorn) {\n    // Clicking 15 times summons the grand unicorn - which is centered on the screen.\n    div.style.top = \"50%\";\n    div.style.left = \"50%\";\n    div.style.zIndex = 143143143;\n  } else {\n    // Otherwise we randomize the position.\n    div.style.top = Math.round(Math.random() * 100) + \"%\";\n    div.style.left = Math.round(Math.random() * 100) + \"%\";\n\n    transform += \" rotate(\" + Math.round(Math.random() * 10 - 5) + \"deg)\";\n  }\n\n  // Create the image element.\n  var img = document.createElement(\"img\");\n  img.style.opacity = 0;\n  img.style.transition = \"all .1s linear\";\n  img.alt = \"A lovely unicorn or rainbow\";\n  img.onload = function () {\n    img.style.opacity = 1;\n  };\n\n  // Used as a cache buster so the browser makes a new request every time instead of usign the previous, cached one.\n  var currentTime = new Date();\n  var submitTime = currentTime.getTime();\n\n  if (showGrandUnicorn) {\n    // Caching doesn't matter for the Grand Unicorn.\n    submitTime = 0;\n  }\n\n  // Construct our unicorn & rainbow request.\n  var url = `https://www.cornify.com/corns/${\n    Math.random() > 0.5 ? \"r\" : \"u\"\n  }${Math.ceil(Math.random() * 7)}.gif`;\n\n  // Add younicorns if requested.\n  if (options && (options.y || options.younicorns)) {\n    url += \"&y=\" + (options.y ? options.y : options.younicorns);\n\n    if (Math.random() > 0.5) {\n      // Flip horizontally at random.\n      if (transform.length > 0) {\n        transform += \" scaleX(-1)\";\n      }\n    }\n  }\n\n  div.style.transform = transform;\n  div.style.MozTransform = transform;\n  div.style.webkitTransform = transform;\n\n  img.setAttribute(\"src\", url);\n\n  // Add a nice hover wigggle.\n  img.style.transition = \"all .1s linear\";\n\n  div.onmouseover = function () {\n    var size = 1 + Math.round(Math.random() * 10) / 100;\n    var angle = Math.round(Math.random() * 20 - 10);\n    var result = \"rotate(\" + angle + \"deg) scale(\" + size + \",\" + size + \")\";\n    img.style.transform = result;\n    img.style.MozTransform = result;\n    img.style.webkitTransform = result;\n  };\n\n  div.onmouseout = function () {\n    var size = 0.9 + Math.round(Math.random() * 10) / 100;\n    var angle = Math.round(Math.random() * 6 - 3);\n    var result = \"rotate(\" + angle + \"deg) scale(\" + size + \",\" + size + \")\";\n    img.style.transform = result;\n    img.style.MozTransform = result;\n    img.style.webkitTransform = result;\n  };\n\n  // Append our container DIV to the page.\n  var body = document.getElementsByTagName(\"body\")[0];\n  body.appendChild(div);\n  div.appendChild(img);\n\n  // Hooray - now we have a sparkly unicorn (or rainbow) on the page. Another cornification well done. Congrats!\n\n  // When clicking 5 times, add a custom stylesheet to make the page look awesome.\n  if (cornify_count == 5) {\n    var cssExisting = document.getElementById(\"__cornify_css\");\n\n    if (!cssExisting) {\n      var head = document.getElementsByTagName(\"head\")[0];\n      var css = document.createElement(\"link\");\n      css.id = \"__cornify_css\";\n      css.type = \"text/css\";\n      css.rel = \"stylesheet\";\n      css.href = \"https://www.cornify.com/css/cornify.css\";\n      css.media = \"screen\";\n      head.appendChild(css);\n    }\n    cornify_replace();\n  }\n\n  cornify_updatecount();\n\n  // Trigger an event on the document.\n  var event = new Event(\"cornify\");\n  document.dispatchEvent(event);\n};\n\n// Tracks how often we cornified.\nvar cornify_updatecount = function () {\n  var id = \"__cornify_count\";\n  var p = document.getElementById(id);\n\n  if (p == null) {\n    var p = document.createElement(\"p\");\n    p.id = id;\n    p.style.position = \"fixed\";\n    p.style.bottom = \"5px\";\n    p.style.left = \"0px\";\n    p.style.right = \"0px\";\n    p.style.zIndex = \"1000000000\";\n    p.style.color = \"#ff00ff\";\n    p.style.textAlign = \"center\";\n    p.style.fontSize = \"24px\";\n    p.style.fontFamily = \"'Comic Sans MS', 'Comic Sans', 'Marker Felt', serif\"; // Only the best!\n    p.style.textTransform = \"uppercase\";\n    var body = document.getElementsByTagName(\"body\")[0];\n    body.appendChild(p);\n  }\n\n  if (cornify_count == 1) {\n    p.innerHTML = \"You cornified!\";\n  } else {\n    p.innerHTML = \"You cornified \" + cornify_count + \" times!\";\n  }\n\n  // Stores our count in a cookie for our next session.\n  cornify_setcookie(\"cornify\", cornify_count + \"\", 1000);\n};\n\nvar cornify_setcookie = function (name, value, days) {\n  var d = new Date();\n  d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);\n  var expires = \"expires=\" + d.toGMTString();\n  document.cookie = name + \"=\" + value + \"; \" + expires;\n};\n\nvar cornify_getcookie = function (cname) {\n  var name = cname + \"=\";\n  var ca = document.cookie.split(\";\");\n  for (var i = 0; i < ca.length; i++) {\n    var c = ca[i].trim();\n    if (c.indexOf(name) == 0) {\n      return c.substring(name.length, c.length);\n    }\n  }\n  return \"\";\n};\n\n// Retrieve our click count from the cookie when we start up.\ncornify_count = parseInt(cornify_getcookie(\"cornify\"));\nif (isNaN(cornify_count)) {\n  cornify_count = 0;\n}\n\n// Adds happy words at the beginning of all headers on the page.\nvar cornify_replace = function () {\n  // Replace text.\n  var hc = 6;\n  var hs;\n  var h;\n  var k;\n  var words = [\n    \"Happy\",\n    \"Sparkly\",\n    \"Glittery\",\n    \"Fun\",\n    \"Magical\",\n    \"Lovely\",\n    \"Cute\",\n    \"Charming\",\n    \"Amazing\",\n    \"Wonderful\",\n  ];\n  while (hc >= 1) {\n    hs = document.getElementsByTagName(\"h\" + hc);\n    for (k = 0; k < hs.length; k++) {\n      h = hs[k];\n      h.innerHTML =\n        words[Math.floor(Math.random() * words.length)] + \" \" + h.innerHTML;\n    }\n    hc -= 1;\n  }\n};\n\n// Adds happy words at the beginning of all headers on the page.\nvar cornify_replace = function () {\n  var headerTypeIndex = 6;\n  var headerElements;\n  var headerElement;\n  var i;\n  var magicalWords = [\n    \"Happy\",\n    \"Sparkly\",\n    \"Glittery\",\n    \"Fun\",\n    \"Magical\",\n    \"Lovely\",\n    \"Cute\",\n    \"Charming\",\n    \"Amazing\",\n    \"Wonderful\",\n  ];\n\n  while (headerTypeIndex >= 1) {\n    headerElements = document.getElementsByTagName(\"h\" + headerTypeIndex);\n\n    for (i = 0; i < headerElements.length; i++) {\n      headerElement = headerElements[i];\n      headerElement.innerHTML =\n        magicalWords[Math.floor(Math.random() * magicalWords.length)] +\n        \" \" +\n        headerElement.innerHTML;\n    }\n\n    headerTypeIndex -= 1;\n  }\n};\n\n// Clicking the rainbow cupcake button makes all the unicorns\n// disappear (should only be used in an emergency, since it's sad).\nvar cornify_click_cupcake_button = function () {\n  var doc = document;\n\n  var corns = doc.getElementsByClassName(\"__cornify_unicorn\");\n  if (corns) {\n    for (var i = 0; i < corns.length; i++) {\n      corns[i].parentNode.removeChild(corns[i]);\n    }\n  }\n\n  // Remove our counter.\n  var button = doc.getElementById(\"__cornify_count\");\n  if (button) {\n    button.parentNode.removeChild(button);\n  }\n\n  // Remove the cupcake button.\n  var button = doc.getElementById(\"__cornify_cupcake_button\");\n  if (button) {\n    button.parentNode.removeChild(button);\n  }\n\n  var event = new Event(\"cornify-clear\");\n  document.dispatchEvent(event);\n};\n\n// Add the rainbow cupcake button to the page.\nvar cornify_add_cupcake_button = function () {\n  var id = \"__cornify_cupcake_button\";\n  var doc = document;\n  var button = doc.getElementById(id);\n\n  if (!button) {\n    button = doc.createElement(\"div\");\n    button.id = id;\n    button.onclick = cornify_click_cupcake_button;\n    button.style.position = \"fixed\";\n    button.style.top = \"10px\";\n    button.style.right = \"10px\";\n    button.style.zIndex = 2147483640;\n    button.setAttribute(\"aria-label\", \"Hide unicorns and rainbows\");\n\n    var image = document.createElement(\"img\");\n    image.src = \"https://www.cornify.com/assets/cornify-cupcake-button.png\";\n    image.alt = \"Cupcake button\";\n    image.width = 50;\n    image.height = 50;\n    image.style.width = \"50px !important\";\n    image.style.height = \"50px !important\";\n    image.style.display = \"block !important\";\n    image.style.cursor = \"pointer !important\";\n    image.style.margin = \"0 !important\";\n    image.style.padding = \"0 !important\";\n    button.appendChild(image);\n\n    doc.getElementsByTagName(\"body\")[0].appendChild(button);\n  }\n};\n\n// Adapted from http://www.snaptortoise.com/konami-js/\nvar cornami = {\n  input: \"\",\n  pattern: \"38384040373937396665\",\n  clear: setTimeout(\"cornami.clear_input()\", 5000),\n  load: function () {\n    window.document.onkeydown = function (event) {\n      if (cornami.input == cornami.pattern) {\n        cornify_add();\n        clearTimeout(cornami.clear);\n        return;\n      } else {\n        cornami.input += event.keyCode;\n        if (cornami.input == cornami.pattern) {\n          cornify_add();\n        }\n        clearTimeout(cornami.clear);\n        cornami.clear = setTimeout(\"cornami.clear_input()\", 5000);\n      }\n    };\n  },\n  clear_input: function () {\n    cornami.input = \"\";\n    clearTimeout(cornami.clear);\n  },\n};\n\ncornami.load();\n"
  },
  {
    "path": "12 - Key Sequence Detection/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Key Detection</title>\n    <script type=\"text/javascript\" src=\"./cornify.js\"></script>\n    <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n  </head>\n  <body>\n    <script>\n      const pressed = [];\n      const secretCode = \"wesbos\";\n\n      window.addEventListener(\"keyup\", (e) => {\n        console.log(e.key);\n        pressed.push(e.key);\n        pressed.splice(\n          -secretCode.length - 1,\n          pressed.length - secretCode.length\n        );\n        if (pressed.join(\"\").includes(secretCode)) {\n          console.log(\"DING DING!\");\n          cornify_add();\n        }\n        console.log(pressed);\n      });\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "12 - Key Sequence Detection/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Key Detection</title>\n    <script type=\"text/javascript\" src=\"./cornify.js\"></script>\n    <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n  </head>\n  <body>\n    <script></script>\n  </body>\n</html>\n"
  },
  {
    "path": "13 - Slide in on Scroll/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Document</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <div class=\"site-wrap\">\n\n    <h1>Slide in on Scroll</h1>\n\n    <p>Consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariaturlores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Adipisicing elit. Tempore tempora rerum..</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-left slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>\n\n    <img src=\"http://unsplash.it/400/401\" class=\"align-right slide-in\">\n\n    <p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>\n\n    <img src=\"http://unsplash.it/200/500\" class=\"align-left slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet <img src=\"http://unsplash.it/200/200\" class=\"align-right slide-in\"> temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis</p>\n\n\n    <p>laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-right slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n\n\n\n\n  </div>\n\n  <script>\n    function debounce(func, wait = 20, immediate = true) {\n      var timeout;\n      return function() {\n        var context = this, args = arguments;\n        var later = function() {\n          timeout = null;\n          if (!immediate) func.apply(context, args);\n        };\n        var callNow = immediate && !timeout;\n        clearTimeout(timeout);\n        timeout = setTimeout(later, wait);\n        if (callNow) func.apply(context, args);\n      };\n    };\n\n    const sliderImages = document.querySelectorAll('.slide-in');\n\n    function checkSlide() {\n      sliderImages.forEach(sliderImage => {\n        // half way through the image\n        const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2;\n        // bottom of the image\n        const imageBottom = sliderImage.offsetTop + sliderImage.height;\n        const isHalfShown = slideInAt > sliderImage.offsetTop;\n        const isNotScrolledPast = window.scrollY < imageBottom;\n        if (isHalfShown && isNotScrolledPast) {\n          sliderImage.classList.add('active');\n        } else {\n          sliderImage.classList.remove('active');\n        }\n      });\n    }\n\n    window.addEventListener('scroll', debounce(checkSlide));\n\n  </script>\n\n  <style>\n    html {\n      box-sizing: border-box;\n      background: #ffc600;\n      font-family: 'helvetica neue';\n      font-size: 20px;\n      font-weight: 200;\n    }\n\n    body {\n      margin: 0;\n    }\n\n    *, *:before, *:after {\n      box-sizing: inherit;\n    }\n\n    h1 {\n      margin-top: 0;\n    }\n\n    .site-wrap {\n      max-width: 700px;\n      margin: 100px auto;\n      background: white;\n      padding: 40px;\n      text-align: justify;\n    }\n\n    .align-left {\n      float: left;\n      margin-right: 20px;\n    }\n\n    .align-right {\n      float: right;\n      margin-left: 20px;\n    }\n\n    .slide-in {\n      opacity: 0;\n      transition: all .5s;\n    }\n\n    .align-left.slide-in {\n      transform: translateX(-30%) scale(0.95);\n    }\n\n    .align-right.slide-in {\n      transform: translateX(30%) scale(0.95);\n    }\n\n    .slide-in.active {\n      opacity: 1;\n      transform: translateX(0%) scale(1);\n    }\n\n  </style>\n\n</body>\n</html>\n"
  },
  {
    "path": "13 - Slide in on Scroll/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Document</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <div class=\"site-wrap\">\n\n    <h1>Slide in on Scroll</h1>\n\n    <p>Consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariaturlores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Adipisicing elit. Tempore tempora rerum..</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-left slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>\n\n    <img src=\"http://unsplash.it/400/401\" class=\"align-right slide-in\">\n\n    <p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>\n\n    <img src=\"http://unsplash.it/200/500\" class=\"align-left slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet <img src=\"http://unsplash.it/200/200\" class=\"align-right slide-in\"> temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis</p>\n\n\n    <p>laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-right slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n\n\n\n\n  </div>\n\n  <script>\n    function debounce(func, wait = 20, immediate = true) {\n      var timeout;\n      return function() {\n        var context = this, args = arguments;\n        var later = function() {\n          timeout = null;\n          if (!immediate) func.apply(context, args);\n        };\n        var callNow = immediate && !timeout;\n        clearTimeout(timeout);\n        timeout = setTimeout(later, wait);\n        if (callNow) func.apply(context, args);\n      };\n    }\n\n  </script>\n\n  <style>\n    html {\n      box-sizing: border-box;\n      background: #ffc600;\n      font-family: 'helvetica neue';\n      font-size: 20px;\n      font-weight: 200;\n    }\n\n    body {\n      margin: 0;\n    }\n\n    *, *:before, *:after {\n      box-sizing: inherit;\n    }\n\n    h1 {\n      margin-top: 0;\n    }\n\n    .site-wrap {\n      max-width: 700px;\n      margin: 100px auto;\n      background: white;\n      padding: 40px;\n      text-align: justify;\n    }\n\n    .align-left {\n      float: left;\n      margin-right: 20px;\n    }\n\n    .align-right {\n      float: right;\n      margin-left: 20px;\n    }\n\n    .slide-in {\n      opacity: 0;\n      transition: all .5s;\n    }\n\n    .align-left.slide-in {\n      transform: translateX(-30%) scale(0.95);\n    }\n\n    .align-right.slide-in {\n      transform: translateX(30%) scale(0.95);\n    }\n\n    .slide-in.active {\n      opacity: 1;\n      transform: translateX(0%) scale(1);\n    }\n\n  </style>\n\n</body>\n</html>\n"
  },
  {
    "path": "14 - JavaScript References VS Copying/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JS Reference VS Copy</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <script>\n    // start with strings, numbers and booleans\n    // let age = 100;\n    // let age2 = age;\n    // console.log(age, age2);\n    // age = 200;\n    // console.log(age, age2);\n\n    // let name = 'Wes';\n    // let name2 = name;\n    // console.log(name, name2);\n    // name = 'wesley';\n    // console.log(name, name2);\n\n    // Let's say we have an array\n    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];\n\n    // and we want to make a copy of it.\n    const team = players;\n\n    console.log(players, team);\n    // You might think we can just do something like this:\n    // team[3] = 'Lux';\n\n    // however what happens when we update that array?\n\n    // now here is the problem!\n\n    // oh no - we have edited the original array too!\n\n    // Why? It's because that is an array reference, not an array copy. They both point to the same array!\n\n    // So, how do we fix this? We take a copy instead!\n    const team2 = players.slice();\n\n    // one way\n\n    // or create a new array and concat the old one in\n    const team3 = [].concat(players);\n\n    // or use the new ES6 Spread\n    const team4 = [...players];\n    team4[3] = 'heeee hawww';\n    console.log(team4);\n\n    const team5 = Array.from(players);\n\n    // now when we update it, the original one isn't changed\n\n    // The same thing goes for objects, let's say we have a person object\n\n    // with Objects\n    const person = {\n      name: 'Wes Bos',\n      age: 80\n    };\n\n    // and think we make a copy:\n    // const captain = person;\n    // captain.number = 99;\n\n    // how do we take a copy instead?\n    const cap2 = Object.assign({}, person, { number: 99, age: 12 });\n    console.log(cap2);\n\n    // We will hopefully soon see the object ...spread\n    // const cap3 = {...person};\n\n    // Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.\n\n    const wes = {\n      name: 'Wes',\n      age: 100,\n      social: {\n        twitter: '@wesbos',\n        facebook: 'wesbos.developer'\n      }\n    };\n\n    console.clear();\n    console.log(wes);\n\n    const dev = Object.assign({}, wes);\n\n    const dev2 = JSON.parse(JSON.stringify(wes));\n\n\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "14 - JavaScript References VS Copying/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>JS Reference VS Copy</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <script>\n    // start with strings, numbers and booleans\n\n    // Let's say we have an array\n    const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];\n\n    // and we want to make a copy of it.\n\n    // You might think we can just do something like this:\n\n    // however what happens when we update that array?\n\n    // now here is the problem!\n\n    // oh no - we have edited the original array too!\n\n    // Why? It's because that is an array reference, not an array copy. They both point to the same array!\n\n    // So, how do we fix this? We take a copy instead!\n\n    // one way\n\n    // or create a new array and concat the old one in\n\n    // or use the new ES6 Spread\n\n    // now when we update it, the original one isn't changed\n\n    // The same thing goes for objects, let's say we have a person object\n\n    // with Objects\n    const person = {\n      name: 'Wes Bos',\n      age: 80\n    };\n\n    // and think we make a copy:\n\n    // how do we take a copy instead?\n\n    // We will hopefully soon see the object ...spread\n\n    // Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.\n\n  </script>\n\n</body>\n</html>\n"
  },
  {
    "path": "15 - LocalStorage/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>LocalStorage</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <!--\n      Fish SVG Cred:\n      https://thenounproject.com/search/?q=fish&i=589236\n   -->\n\n   <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 512 512\" enable-background=\"new 0 0 512 512\" xml:space=\"preserve\"><g><path d=\"M495.9,425.3H16.1c-5.2,0-10.1,2.9-12.5,7.6c-2.4,4.7-2.1,10.3,0.9,14.6l39,56.4c2.6,3.8,7,6.1,11.6,6.1h401.7   c4.6,0,9-2.3,11.6-6.1l39-56.4c3-4.3,3.3-9.9,0.9-14.6C506,428.2,501.1,425.3,495.9,425.3z M449.4,481.8H62.6L43,453.6H469   L449.4,481.8z\"/><path d=\"M158.3,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1c-7.8,0-14.1,6.3-14.1,14.1v64.5   C144.2,115.7,150.5,122,158.3,122z\"/><path d=\"M245.1,94.7c7.8,0,14.1-6.3,14.1-14.1V16.1c0-7.8-6.3-14.1-14.1-14.1C237.3,2,231,8.3,231,16.1v64.5   C231,88.4,237.3,94.7,245.1,94.7z\"/><path d=\"M331.9,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1s-14.1,6.3-14.1,14.1v64.5   C317.8,115.7,324.1,122,331.9,122z\"/><path d=\"M9.6,385.2c5.3,2.8,11.8,1.9,16.2-2.2l50.6-47.7c56.7,46.5,126.6,71.9,198.3,71.9c0,0,0,0,0,0   c87.5,0,169.7-36.6,231.4-103.2c5-5.4,5-13.8,0-19.2c-61.8-66.5-144-103.2-231.4-103.2c-72,0-142.2,25.6-199,72.5l-50-47.1   c-4.4-4.1-10.9-5-16.2-2.2c-5.3,2.8-8.3,8.7-7.4,14.6l11.6,75L2.2,370.6C1.3,376.5,4.2,382.4,9.6,385.2z M380.9,230.8   c34.9,14.3,67.2,35.7,95.3,63.6c-10.1,10-20.8,19.2-31.9,27.5c-22.4-3.3-29.6-8.8-30.7-9.7c-4-5.7-11.8-7.7-18.1-4.4   c-6.9,3.6-9.5,12.2-5.9,19.1c1.9,3.5,7.3,10.3,22.4,16c-10.1,5.7-20.5,10.7-31.1,15.1C352.4,320.2,352.4,268.6,380.9,230.8z    M36.3,255.6l29.4,27.7c5.3,5,13.6,5.1,19.1,0.3c53.2-47.6,120.7-73.7,190-73.7c26.9,0,53.2,3.9,78.5,11.3   c-29.3,44.6-29.3,102,0,146.6c-25.3,7.4-51.6,11.3-78.5,11.3c-69,0-136.3-26-189.4-73.2c-2.7-2.4-13.4-6.3-19.1,0.3l-30.1,28.3   l5.7-40C42.2,293,36.3,255.6,36.3,255.6z\"/><circle cx=\"398.8\" cy=\"273.8\" r=\"14.1\"/></g></svg>\n\n  <div class=\"wrapper\">\n    <h2>LOCAL TAPAS</h2>\n    <p></p>\n    <ul class=\"plates\">\n      <li>Loading Tapas...</li>\n    </ul>\n    <form class=\"add-items\">\n      <input type=\"text\" name=\"item\" placeholder=\"Item Name\" required>\n      <input type=\"submit\" value=\"+ Add Item\">\n    </form>\n  </div>\n\n<script>\n  const addItems = document.querySelector('.add-items');\n  const itemsList = document.querySelector('.plates');\n  const items = JSON.parse(localStorage.getItem('items')) || [];\n\n  function addItem(e) {\n    e.preventDefault();\n    const text = (this.querySelector('[name=item]')).value;\n    const item = {\n      text,\n      done: false\n    };\n\n    items.push(item);\n    populateList(items, itemsList);\n    localStorage.setItem('items', JSON.stringify(items));\n    this.reset();\n  }\n\n  function populateList(plates = [], platesList) {\n    platesList.innerHTML = plates.map((plate, i) => {\n      return `\n        <li>\n          <input type=\"checkbox\" data-index=${i} id=\"item${i}\" ${plate.done ? 'checked' : ''} />\n          <label for=\"item${i}\">${plate.text}</label>\n        </li>\n      `;\n    }).join('');\n  }\n\n  function toggleDone(e) {\n    if (!e.target.matches('input')) return; // skip this unless it's an input\n    const el = e.target;\n    const index = el.dataset.index;\n    items[index].done = !items[index].done;\n    localStorage.setItem('items', JSON.stringify(items));\n    populateList(items, itemsList);\n  }\n\n  addItems.addEventListener('submit', addItem);\n  itemsList.addEventListener('click', toggleDone);\n\n  populateList(items, itemsList);\n\n</script>\n\n\n</body>\n</html>\n\n"
  },
  {
    "path": "15 - LocalStorage/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>LocalStorage</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <!--\n      Fish SVG Cred:\n      https://thenounproject.com/search/?q=fish&i=589236\n   -->\n\n   <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 512 512\" enable-background=\"new 0 0 512 512\" xml:space=\"preserve\"><g><path d=\"M495.9,425.3H16.1c-5.2,0-10.1,2.9-12.5,7.6c-2.4,4.7-2.1,10.3,0.9,14.6l39,56.4c2.6,3.8,7,6.1,11.6,6.1h401.7   c4.6,0,9-2.3,11.6-6.1l39-56.4c3-4.3,3.3-9.9,0.9-14.6C506,428.2,501.1,425.3,495.9,425.3z M449.4,481.8H62.6L43,453.6H469   L449.4,481.8z\"/><path d=\"M158.3,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1c-7.8,0-14.1,6.3-14.1,14.1v64.5   C144.2,115.7,150.5,122,158.3,122z\"/><path d=\"M245.1,94.7c7.8,0,14.1-6.3,14.1-14.1V16.1c0-7.8-6.3-14.1-14.1-14.1C237.3,2,231,8.3,231,16.1v64.5   C231,88.4,237.3,94.7,245.1,94.7z\"/><path d=\"M331.9,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1s-14.1,6.3-14.1,14.1v64.5   C317.8,115.7,324.1,122,331.9,122z\"/><path d=\"M9.6,385.2c5.3,2.8,11.8,1.9,16.2-2.2l50.6-47.7c56.7,46.5,126.6,71.9,198.3,71.9c0,0,0,0,0,0   c87.5,0,169.7-36.6,231.4-103.2c5-5.4,5-13.8,0-19.2c-61.8-66.5-144-103.2-231.4-103.2c-72,0-142.2,25.6-199,72.5l-50-47.1   c-4.4-4.1-10.9-5-16.2-2.2c-5.3,2.8-8.3,8.7-7.4,14.6l11.6,75L2.2,370.6C1.3,376.5,4.2,382.4,9.6,385.2z M380.9,230.8   c34.9,14.3,67.2,35.7,95.3,63.6c-10.1,10-20.8,19.2-31.9,27.5c-22.4-3.3-29.6-8.8-30.7-9.7c-4-5.7-11.8-7.7-18.1-4.4   c-6.9,3.6-9.5,12.2-5.9,19.1c1.9,3.5,7.3,10.3,22.4,16c-10.1,5.7-20.5,10.7-31.1,15.1C352.4,320.2,352.4,268.6,380.9,230.8z    M36.3,255.6l29.4,27.7c5.3,5,13.6,5.1,19.1,0.3c53.2-47.6,120.7-73.7,190-73.7c26.9,0,53.2,3.9,78.5,11.3   c-29.3,44.6-29.3,102,0,146.6c-25.3,7.4-51.6,11.3-78.5,11.3c-69,0-136.3-26-189.4-73.2c-2.7-2.4-13.4-6.3-19.1,0.3l-30.1,28.3   l5.7-40C42.2,293,36.3,255.6,36.3,255.6z\"/><circle cx=\"398.8\" cy=\"273.8\" r=\"14.1\"/></g></svg>\n\n  <div class=\"wrapper\">\n    <h2>LOCAL TAPAS</h2>\n    <p></p>\n    <ul class=\"plates\">\n      <li>Loading Tapas...</li>\n    </ul>\n    <form class=\"add-items\">\n      <input type=\"text\" name=\"item\" placeholder=\"Item Name\" required>\n      <input type=\"submit\" value=\"+ Add Item\">\n    </form>\n  </div>\n\n<script>\n  const addItems = document.querySelector('.add-items');\n  const itemsList = document.querySelector('.plates');\n  const items = [];\n\n</script>\n\n\n</body>\n</html>\n\n"
  },
  {
    "path": "15 - LocalStorage/style.css",
    "content": "html {\n  box-sizing: border-box;\n  background: url(\"oh-la-la.jpeg\") center no-repeat;\n  background-size: cover;\n  min-height: 100vh;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  text-align: center;\n  font-family: Futura, \"Trebuchet MS\", Arial, sans-serif;\n}\n\n*,\n*:before,\n*:after {\n  box-sizing: inherit;\n}\n\nsvg {\n  fill: white;\n  background: rgba(0, 0, 0, 0.1);\n  padding: 20px;\n  border-radius: 50%;\n  width: 200px;\n  margin-bottom: 50px;\n}\n\n.wrapper {\n  padding: 20px;\n  max-width: 350px;\n  background: rgba(255, 255, 255, 0.95);\n  box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1);\n}\n\nh2 {\n  text-align: center;\n  margin: 0;\n  font-weight: 200;\n}\n\n.plates {\n  margin: 0;\n  padding: 0;\n  text-align: left;\n  list-style: none;\n}\n\n.plates li {\n  border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n  padding: 10px 0;\n  font-weight: 100;\n  display: flex;\n}\n\n.plates label {\n  flex: 1;\n  cursor: pointer;\n}\n\n.plates input {\n  display: none;\n}\n\n.plates input + label:before {\n  content: \"⬜️\";\n  margin-right: 10px;\n}\n\n.plates input:checked + label:before {\n  content: \"🌮\";\n}\n\n.add-items {\n  margin-top: 20px;\n}\n\n.add-items input {\n  padding: 10px;\n  outline: 0;\n  border: 1px solid rgba(0, 0, 0, 0.1);\n}\n"
  },
  {
    "path": "16 - Mouse Move Shadow/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Mouse Shadow</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <div class=\"hero\">\n    <h1 contenteditable>🔥WOAH!</h1>\n  </div>\n\n  <style>\n  html {\n    color: black;\n    font-family: sans-serif;\n  }\n\n  body {\n    margin: 0;\n  }\n\n  .hero {\n    min-height: 100vh;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    color: black;\n  }\n\n  h1 {\n    text-shadow: 10px 10px 0 rgba(0,0,0,1);\n    font-size: 100px;\n  }\n  </style>\n\n<script>\n  const hero = document.querySelector('.hero');\n  const text = hero.querySelector('h1');\n  const walk = 500; // 500px\n\n  function shadow(e) {\n    const { offsetWidth: width, offsetHeight: height } = hero;\n    let { offsetX: x, offsetY: y } = e;\n\n    if (this !== e.target) {\n      x = x + e.target.offsetLeft;\n      y = y + e.target.offsetTop;\n    }\n\n    const xWalk = Math.round((x / width * walk) - (walk / 2));\n    const yWalk = Math.round((y / height * walk) - (walk / 2));\n\n    text.style.textShadow = `\n      ${xWalk}px ${yWalk}px 0 rgba(255,0,255,0.7),\n      ${xWalk * -1}px ${yWalk}px 0 rgba(0,255,255,0.7),\n      ${yWalk}px ${xWalk * -1}px 0 rgba(0,255,0,0.7),\n      ${yWalk * -1}px ${xWalk}px 0 rgba(0,0,255,0.7)\n    `;\n\n  }\n\n  hero.addEventListener('mousemove', shadow);\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "16 - Mouse Move Shadow/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Mouse Shadow</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <div class=\"hero\">\n    <h1 contenteditable>🔥WOAH!</h1>\n  </div>\n\n  <style>\n  html {\n    color: black;\n    font-family: sans-serif;\n  }\n\n  body {\n    margin: 0;\n  }\n\n  .hero {\n    min-height: 100vh;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    color: black;\n  }\n\n  h1 {\n    text-shadow: 10px 10px 0 rgba(0,0,0,1);\n    font-size: 100px;\n  }\n  </style>\n\n<script>\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "17 - Sort Without Articles/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Sort Without Articles</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <style>\n    body {\n      margin: 0;\n      font-family: sans-serif;\n      background: url(\"https://source.unsplash.com/nDqA4d5NL0k/2000x2000\");\n      background-size: cover;\n      display: flex;\n      align-items: center;\n      min-height: 100vh;\n    }\n\n    #bands {\n      list-style: inside square;\n      font-size: 20px;\n      background: white;\n      width: 500px;\n      margin: auto;\n      padding: 0;\n      box-shadow: 0 0 0 20px rgba(0, 0, 0, 0.05);\n    }\n\n    #bands li {\n      border-bottom: 1px solid #efefef;\n      padding: 20px;\n    }\n\n    #bands li:last-child {\n      border-bottom: 0;\n    }\n\n    a {\n      color: #ffc600;\n      text-decoration: none;\n    }\n\n  </style>\n\n  <ul id=\"bands\"></ul>\n\n<script>\nconst bands = ['The Plot in You', 'The Devil Wears Prada', 'Pierce the Veil', 'Norma Jean', 'The Bled', 'Say Anything', 'The Midway State', 'We Came as Romans', 'Counterparts', 'Oh, Sleeper', 'A Skylit Drive', 'Anywhere But Here', 'An Old Dog'];\n\nfunction strip(bandName) {\n  return bandName.replace(/^(a |the |an )/i, '').trim();\n}\n\nconst sortedBands = bands.sort((a, b) => strip(a) > strip(b) ? 1 : -1);\n\ndocument.querySelector('#bands').innerHTML =\n  sortedBands\n    .map(band => `<li>${band}</li>`)\n    .join('');\n\nconsole.log(sortedBands);\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "17 - Sort Without Articles/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Sort Without Articles</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <style>\n    body {\n      margin: 0;\n      font-family: sans-serif;\n      background: url(\"https://source.unsplash.com/nDqA4d5NL0k/2000x2000\");\n      background-size: cover;\n      display: flex;\n      align-items: center;\n      min-height: 100vh;\n    }\n\n    #bands {\n      list-style: inside square;\n      font-size: 20px;\n      background: white;\n      width: 500px;\n      margin: auto;\n      padding: 0;\n      box-shadow: 0 0 0 20px rgba(0, 0, 0, 0.05);\n    }\n\n    #bands li {\n      border-bottom: 1px solid #efefef;\n      padding: 20px;\n    }\n\n    #bands li:last-child {\n      border-bottom: 0;\n    }\n\n    a {\n      color: #ffc600;\n      text-decoration: none;\n    }\n\n  </style>\n\n  <ul id=\"bands\"></ul>\n\n<script>\nconst bands = ['The Plot in You', 'The Devil Wears Prada', 'Pierce the Veil', 'Norma Jean', 'The Bled', 'Say Anything', 'The Midway State', 'We Came as Romans', 'Counterparts', 'Oh, Sleeper', 'A Skylit Drive', 'Anywhere But Here', 'An Old Dog'];\n\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "18 - Adding Up Times with Reduce/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Videos</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <ul class=\"videos\">\n    <li data-time=\"5:43\">\n      Video 1\n    </li>\n    <li data-time=\"2:33\">\n      Video 2\n    </li>\n    <li data-time=\"3:45\">\n      Video 3\n    </li>\n    <li data-time=\"0:47\">\n      Video 4\n    </li>\n    <li data-time=\"5:21\">\n      Video 5\n    </li>\n    <li data-time=\"6:56\">\n      Video 6\n    </li>\n    <li data-time=\"3:46\">\n      Video 7\n    </li>\n    <li data-time=\"5:25\">\n      Video 8\n    </li>\n    <li data-time=\"3:14\">\n      Video 9\n    </li>\n    <li data-time=\"3:31\">\n      Video 10\n    </li>\n    <li data-time=\"5:59\">\n      Video 11\n    </li>\n    <li data-time=\"3:07\">\n      Video 12\n    </li>\n    <li data-time=\"11:29\">\n      Video 13\n    </li>\n    <li data-time=\"8:57\">\n      Video 14\n    </li>\n    <li data-time=\"5:49\">\n      Video 15\n    </li>\n    <li data-time=\"5:52\">\n      Video 16\n    </li>\n    <li data-time=\"5:50\">\n      Video 17\n    </li>\n    <li data-time=\"9:13\">\n      Video 18\n    </li>\n    <li data-time=\"11:51\">\n      Video 19\n    </li>\n    <li data-time=\"7:58\">\n      Video 20\n    </li>\n    <li data-time=\"4:40\">\n      Video 21\n    </li>\n    <li data-time=\"4:45\">\n      Video 22\n    </li>\n    <li data-time=\"6:46\">\n      Video 23\n    </li>\n    <li data-time=\"7:24\">\n      Video 24\n    </li>\n    <li data-time=\"7:12\">\n      Video 25\n    </li>\n    <li data-time=\"5:23\">\n      Video 26\n    </li>\n    <li data-time=\"3:34\">\n      Video 27\n    </li>\n    <li data-time=\"8:22\">\n      Video 28\n    </li>\n    <li data-time=\"5:17\">\n      Video 29\n    </li>\n    <li data-time=\"3:10\">\n      Video 30\n    </li>\n    <li data-time=\"4:43\">\n      Video 31\n    </li>\n    <li data-time=\"19:43\">\n      Video 32\n    </li>\n    <li data-time=\"0:47\">\n      Video 33\n    </li>\n    <li data-time=\"0:47\">\n      Video 34\n    </li>\n    <li data-time=\"3:14\">\n      Video 35\n    </li>\n    <li data-time=\"3:59\">\n      Video 36\n    </li>\n    <li data-time=\"2:43\">\n      Video 37\n    </li>\n    <li data-time=\"4:17\">\n      Video 38\n    </li>\n    <li data-time=\"6:56\">\n      Video 39\n    </li>\n    <li data-time=\"3:05\">\n      Video 40\n    </li>\n    <li data-time=\"2:06\">\n      Video 41\n    </li>\n    <li data-time=\"1:59\">\n      Video 42\n    </li>\n    <li data-time=\"1:49\">\n      Video 43\n    </li>\n    <li data-time=\"3:36\">\n      Video 44\n    </li>\n    <li data-time=\"7:10\">\n      Video 45\n    </li>\n    <li data-time=\"3:44\">\n      Video 46\n    </li>\n    <li data-time=\"3:44\">\n      Video 47\n    </li>\n    <li data-time=\"4:36\">\n      Video 48\n    </li>\n    <li data-time=\"3:16\">\n      Video 49\n    </li>\n    <li data-time=\"1:10\">\n      Video 50\n    </li>\n    <li data-time=\"6:10\">\n      Video 51\n    </li>\n    <li data-time=\"2:14\">\n      Video 52\n    </li>\n    <li data-time=\"3:44\">\n      Video 53\n    </li>\n    <li data-time=\"5:05\">\n      Video 54\n    </li>\n    <li data-time=\"6:03\">\n      Video 55\n    </li>\n    <li data-time=\"12:39\">\n      Video 56\n    </li>\n    <li data-time=\"1:56\">\n      Video 57\n    </li>\n    <li data-time=\"4:04\">\n      Video 58\n    </li>\n  </ul>\n<script>\n\n  const timeNodes = Array.from(document.querySelectorAll('[data-time]'));\n\n  const seconds = timeNodes\n    .map(node => node.dataset.time)\n    .map(timeCode => {\n      const [mins, secs] = timeCode.split(':').map(parseFloat);\n      return (mins * 60) + secs;\n    })\n    .reduce((total, vidSeconds) => total + vidSeconds);\n\n    let secondsLeft = seconds;\n    const hours = Math.floor(secondsLeft / 3600);\n    secondsLeft = secondsLeft % 3600;\n\n    const mins = Math.floor(secondsLeft / 60);\n    secondsLeft = secondsLeft % 60;\n\n    console.log(hours, mins, secondsLeft);\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "18 - Adding Up Times with Reduce/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Videos</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <ul class=\"videos\">\n    <li data-time=\"5:43\">\n      Video 1\n    </li>\n    <li data-time=\"2:33\">\n      Video 2\n    </li>\n    <li data-time=\"3:45\">\n      Video 3\n    </li>\n    <li data-time=\"0:47\">\n      Video 4\n    </li>\n    <li data-time=\"5:21\">\n      Video 5\n    </li>\n    <li data-time=\"6:56\">\n      Video 6\n    </li>\n    <li data-time=\"3:46\">\n      Video 7\n    </li>\n    <li data-time=\"5:25\">\n      Video 8\n    </li>\n    <li data-time=\"3:14\">\n      Video 9\n    </li>\n    <li data-time=\"3:31\">\n      Video 10\n    </li>\n    <li data-time=\"5:59\">\n      Video 11\n    </li>\n    <li data-time=\"3:07\">\n      Video 12\n    </li>\n    <li data-time=\"11:29\">\n      Video 13\n    </li>\n    <li data-time=\"8:57\">\n      Video 14\n    </li>\n    <li data-time=\"5:49\">\n      Video 15\n    </li>\n    <li data-time=\"5:52\">\n      Video 16\n    </li>\n    <li data-time=\"5:50\">\n      Video 17\n    </li>\n    <li data-time=\"9:13\">\n      Video 18\n    </li>\n    <li data-time=\"11:51\">\n      Video 19\n    </li>\n    <li data-time=\"7:58\">\n      Video 20\n    </li>\n    <li data-time=\"4:40\">\n      Video 21\n    </li>\n    <li data-time=\"4:45\">\n      Video 22\n    </li>\n    <li data-time=\"6:46\">\n      Video 23\n    </li>\n    <li data-time=\"7:24\">\n      Video 24\n    </li>\n    <li data-time=\"7:12\">\n      Video 25\n    </li>\n    <li data-time=\"5:23\">\n      Video 26\n    </li>\n    <li data-time=\"3:34\">\n      Video 27\n    </li>\n    <li data-time=\"8:22\">\n      Video 28\n    </li>\n    <li data-time=\"5:17\">\n      Video 29\n    </li>\n    <li data-time=\"3:10\">\n      Video 30\n    </li>\n    <li data-time=\"4:43\">\n      Video 31\n    </li>\n    <li data-time=\"19:43\">\n      Video 32\n    </li>\n    <li data-time=\"0:47\">\n      Video 33\n    </li>\n    <li data-time=\"0:47\">\n      Video 34\n    </li>\n    <li data-time=\"3:14\">\n      Video 35\n    </li>\n    <li data-time=\"3:59\">\n      Video 36\n    </li>\n    <li data-time=\"2:43\">\n      Video 37\n    </li>\n    <li data-time=\"4:17\">\n      Video 38\n    </li>\n    <li data-time=\"6:56\">\n      Video 39\n    </li>\n    <li data-time=\"3:05\">\n      Video 40\n    </li>\n    <li data-time=\"2:06\">\n      Video 41\n    </li>\n    <li data-time=\"1:59\">\n      Video 42\n    </li>\n    <li data-time=\"1:49\">\n      Video 43\n    </li>\n    <li data-time=\"3:36\">\n      Video 44\n    </li>\n    <li data-time=\"7:10\">\n      Video 45\n    </li>\n    <li data-time=\"3:44\">\n      Video 46\n    </li>\n    <li data-time=\"3:44\">\n      Video 47\n    </li>\n    <li data-time=\"4:36\">\n      Video 48\n    </li>\n    <li data-time=\"3:16\">\n      Video 49\n    </li>\n    <li data-time=\"1:10\">\n      Video 50\n    </li>\n    <li data-time=\"6:10\">\n      Video 51\n    </li>\n    <li data-time=\"2:14\">\n      Video 52\n    </li>\n    <li data-time=\"3:44\">\n      Video 53\n    </li>\n    <li data-time=\"5:05\">\n      Video 54\n    </li>\n    <li data-time=\"6:03\">\n      Video 55\n    </li>\n    <li data-time=\"12:39\">\n      Video 56\n    </li>\n    <li data-time=\"1:56\">\n      Video 57\n    </li>\n    <li data-time=\"4:04\">\n      Video 58\n    </li>\n  </ul>\n<script>\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "19 - Webcam Fun/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Get User Media Code Along!</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <div class=\"photobooth\">\n    <div class=\"controls\">\n      <button onClick=\"takePhoto()\">Take Photo</button>\n<!--       <div class=\"rgb\">\n        <label for=\"rmin\">Red Min:</label>\n        <input type=\"range\" min=0 max=255 name=\"rmin\">\n        <label for=\"rmax\">Red Max:</label>\n        <input type=\"range\" min=0 max=255 name=\"rmax\">\n\n        <br>\n\n        <label for=\"gmin\">Green Min:</label>\n        <input type=\"range\" min=0 max=255 name=\"gmin\">\n        <label for=\"gmax\">Green Max:</label>\n        <input type=\"range\" min=0 max=255 name=\"gmax\">\n\n        <br>\n\n        <label for=\"bmin\">Blue Min:</label>\n        <input type=\"range\" min=0 max=255 name=\"bmin\">\n        <label for=\"bmax\">Blue Max:</label>\n        <input type=\"range\" min=0 max=255 name=\"bmax\">\n      </div> -->\n    </div>\n\n    <canvas class=\"photo\"></canvas>\n    <video class=\"player\"></video>\n    <div class=\"strip\"></div>\n  </div>\n\n  <audio class=\"snap\" src=\"./snap.mp3\" hidden></audio>\n\n  <script src=\"scripts.js\"></script>\n\n</body>\n</html>\n"
  },
  {
    "path": "19 - Webcam Fun/package.json",
    "content": "{\n  \"name\": \"gum\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"scripts.js\",\n  \"scripts\": {\n    \"start\": \"browser-sync start --server --files \\\"*.css, *.html, *.js\\\"\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"browser-sync\": \"^2.12.5 <2.23.2\"\n  }\n}\n"
  },
  {
    "path": "19 - Webcam Fun/scripts-FINISHED.js",
    "content": "const video = document.querySelector('.player');\nconst canvas = document.querySelector('.photo');\nconst ctx = canvas.getContext('2d');\nconst strip = document.querySelector('.strip');\nconst snap = document.querySelector('.snap');\n\nfunction getVideo() {\n  navigator.mediaDevices.getUserMedia({ video: true, audio: false })\n    .then(localMediaStream => {\n      console.log(localMediaStream);\n    \n//  DEPRECIATION : \n//       The following has been depreceated by major browsers as of Chrome and Firefox.\n//       video.src = window.URL.createObjectURL(localMediaStream);\n//       Please refer to these:\n//       Deprecated  - https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL\n//       Newer Syntax - https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject\n      \n      video.srcObject = localMediaStream;\n      video.play();\n    })\n    .catch(err => {\n      console.error(`OH NO!!!`, err);\n    });\n}\n\nfunction paintToCanvas() {\n  const width = video.videoWidth;\n  const height = video.videoHeight;\n  canvas.width = width;\n  canvas.height = height;\n\n  return setInterval(() => {\n    ctx.drawImage(video, 0, 0, width, height);\n    // take the pixels out\n    let pixels = ctx.getImageData(0, 0, width, height);\n    // mess with them\n    // pixels = redEffect(pixels);\n\n    pixels = rgbSplit(pixels);\n    // ctx.globalAlpha = 0.8;\n\n    // pixels = greenScreen(pixels);\n    // put them back\n    ctx.putImageData(pixels, 0, 0);\n  }, 16);\n}\n\nfunction takePhoto() {\n  // played the sound\n  snap.currentTime = 0;\n  snap.play();\n\n  // take the data out of the canvas\n  const data = canvas.toDataURL('image/jpeg');\n  const link = document.createElement('a');\n  link.href = data;\n  link.setAttribute('download', 'handsome');\n  link.innerHTML = `<img src=\"${data}\" alt=\"Handsome Man\" />`;\n  strip.insertBefore(link, strip.firstChild);\n}\n\nfunction redEffect(pixels) {\n  for (let i = 0; i < pixels.data.length; i+=4) {\n    pixels.data[i + 0] = pixels.data[i + 0] + 200; // RED\n    pixels.data[i + 1] = pixels.data[i + 1] - 50; // GREEN\n    pixels.data[i + 2] = pixels.data[i + 2] * 0.5; // Blue\n  }\n  return pixels;\n}\n\nfunction rgbSplit(pixels) {\n  for (let i = 0; i < pixels.data.length; i+=4) {\n    pixels.data[i - 150] = pixels.data[i + 0]; // RED\n    pixels.data[i + 500] = pixels.data[i + 1]; // GREEN\n    pixels.data[i - 550] = pixels.data[i + 2]; // Blue\n  }\n  return pixels;\n}\n\nfunction greenScreen(pixels) {\n  const levels = {};\n\n  document.querySelectorAll('.rgb input').forEach((input) => {\n    levels[input.name] = input.value;\n  });\n\n  for (i = 0; i < pixels.data.length; i = i + 4) {\n    red = pixels.data[i + 0];\n    green = pixels.data[i + 1];\n    blue = pixels.data[i + 2];\n    alpha = pixels.data[i + 3];\n\n    if (red >= levels.rmin\n      && green >= levels.gmin\n      && blue >= levels.bmin\n      && red <= levels.rmax\n      && green <= levels.gmax\n      && blue <= levels.bmax) {\n      // take it out!\n      pixels.data[i + 3] = 0;\n    }\n  }\n\n  return pixels;\n}\n\ngetVideo();\n\nvideo.addEventListener('canplay', paintToCanvas);\n"
  },
  {
    "path": "19 - Webcam Fun/scripts.js",
    "content": "const video = document.querySelector('.player');\nconst canvas = document.querySelector('.photo');\nconst ctx = canvas.getContext('2d');\nconst strip = document.querySelector('.strip');\nconst snap = document.querySelector('.snap');\n"
  },
  {
    "path": "19 - Webcam Fun/style.css",
    "content": "html {\n  box-sizing: border-box;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nhtml {\n  font-size: 10px;\n  background: #ffc600;\n}\n\n.photobooth {\n  background: white;\n  max-width: 150rem;\n  margin: 2rem auto;\n  border-radius: 2px;\n}\n\n/*clearfix*/\n.photobooth:after {\n  content: '';\n  display: block;\n  clear: both;\n}\n\n.photo {\n  width: 100%;\n  float: left;\n}\n\n.player {\n  position: absolute;\n  top: 20px;\n  right: 20px;\n  width:200px;\n}\n\n/*\n  Strip!\n*/\n\n.strip {\n  padding: 2rem;\n}\n\n.strip img {\n  width: 100px;\n  overflow-x: scroll;\n  padding: 0.8rem 0.8rem 2.5rem 0.8rem;\n  box-shadow: 0 0 3px rgba(0,0,0,0.2);\n  background: white;\n}\n\n.strip a:nth-child(5n+1) img { transform: rotate(10deg); }\n.strip a:nth-child(5n+2) img { transform: rotate(-2deg); }\n.strip a:nth-child(5n+3) img { transform: rotate(8deg); }\n.strip a:nth-child(5n+4) img { transform: rotate(-11deg); }\n.strip a:nth-child(5n+5) img { transform: rotate(12deg); }\n"
  },
  {
    "path": "20 - Speech Detection/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Speech Detection</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <div class=\"words\" contenteditable>\n  </div>\n\n<script>\n  window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;\n\n  const recognition = new SpeechRecognition();\n  recognition.interimResults = true;\n  recognition.lang = 'en-US';\n\n  let p = document.createElement('p');\n  const words = document.querySelector('.words');\n  words.appendChild(p);\n\n  recognition.addEventListener('result', e => {\n    const transcript = Array.from(e.results)\n      .map(result => result[0])\n      .map(result => result.transcript)\n      .join('');\n\n      const poopScript = transcript.replace(/poop|poo|shit|dump/gi, '💩');\n      p.textContent = poopScript;\n\n      if (e.results[0].isFinal) {\n        p = document.createElement('p');\n        words.appendChild(p);\n      }\n  });\n\n  recognition.addEventListener('end', recognition.start);\n\n  recognition.start();\n\n</script>\n\n\n  <style>\n    html {\n      font-size: 10px;\n    }\n\n    body {\n      background: #ffc600;\n      font-family: 'helvetica neue';\n      font-weight: 200;\n      font-size: 20px;\n    }\n\n    .words {\n      max-width: 500px;\n      margin: 50px auto;\n      background: white;\n      border-radius: 5px;\n      box-shadow: 10px 10px 0 rgba(0,0,0,0.1);\n      padding: 1rem 2rem 1rem 5rem;\n      background: -webkit-gradient(linear, 0 0, 0 100%, from(#d9eaf3), color-stop(4%, #fff)) 0 4px;\n      background-size: 100% 3rem;\n      position: relative;\n      line-height: 3rem;\n    }\n\n    p {\n      margin: 0 0 3rem;\n    }\n\n    .words:before {\n      content: '';\n      position: absolute;\n      width: 4px;\n      top: 0;\n      left: 30px;\n      bottom: 0;\n      border: 1px solid;\n      border-color: transparent #efe4e4;\n    }\n  </style>\n\n</body>\n</html>\n"
  },
  {
    "path": "20 - Speech Detection/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Speech Detection</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <div class=\"words\" contenteditable>\n  </div>\n\n<script>\n  window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;\n\n\n</script>\n\n\n  <style>\n    html {\n      font-size: 10px;\n    }\n\n    body {\n      background: #ffc600;\n      font-family: 'helvetica neue';\n      font-weight: 200;\n      font-size: 20px;\n    }\n\n    .words {\n      max-width: 500px;\n      margin: 50px auto;\n      background: white;\n      border-radius: 5px;\n      box-shadow: 10px 10px 0 rgba(0,0,0,0.1);\n      padding: 1rem 2rem 1rem 5rem;\n      background: -webkit-gradient(linear, 0 0, 0 100%, from(#d9eaf3), color-stop(4%, #fff)) 0 4px;\n      background-size: 100% 3rem;\n      position: relative;\n      line-height: 3rem;\n    }\n\n    p {\n      margin: 0 0 3rem;\n    }\n\n    .words:before {\n      content: '';\n      position: absolute;\n      width: 4px;\n      top: 0;\n      left: 30px;\n      bottom: 0;\n      border: 1px solid;\n      border-color: transparent #efe4e4;\n    }\n  </style>\n\n</body>\n</html>\n"
  },
  {
    "path": "20 - Speech Detection/package.json",
    "content": "{\n  \"name\": \"gum\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"scripts.js\",\n  \"scripts\": {\n    \"start\": \"browser-sync start --directory --server --files \\\"*.css, *.html, *.js\\\"\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"browser-sync\": \"^2.12.5 <2.23.2\"\n  }\n}\n"
  },
  {
    "path": "21 - Geolocation/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Document</title>\n  <meta name=\"viewport\" content=\"width=device-width\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <svg class=\"arrow\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 64 64\" enable-background=\"new 0 0 64 64\" xml:space=\"preserve\"><g><path fill=\"#ffffff\" d=\"M32,1.824C15.361,1.824,1.825,15.361,1.825,32c0,16.639,13.537,30.176,30.175,30.176   S62.175,48.639,62.175,32C62.175,15.361,48.639,1.824,32,1.824z M29.715,3.988h1.12l2.333,3.807V3.988h1.069v5.701h-1.155   l-2.298-3.718v3.718h-1.069V3.988z M9.323,33.917H8.102l-1.136-4.262l-1.132,4.262H4.587l-1.361-5.701h1.178l0.859,3.916   l1.042-3.916h1.369l0.999,3.982l0.875-3.982h1.159L9.323,33.917z M33.995,59.828c-0.181,0.285-0.438,0.497-0.77,0.636   c-0.332,0.139-0.745,0.208-1.241,0.208c-0.721,0-1.274-0.167-1.661-0.5c-0.386-0.333-0.617-0.819-0.692-1.456l1.12-0.109   c0.067,0.376,0.204,0.652,0.41,0.828c0.206,0.176,0.484,0.264,0.834,0.264c0.371,0,0.65-0.078,0.838-0.235   c0.188-0.157,0.282-0.34,0.282-0.55c0-0.135-0.04-0.25-0.119-0.344c-0.079-0.095-0.217-0.177-0.414-0.247   c-0.135-0.047-0.442-0.13-0.922-0.249c-0.617-0.153-1.05-0.341-1.299-0.564c-0.35-0.314-0.525-0.696-0.525-1.147   c0-0.29,0.082-0.562,0.247-0.815c0.165-0.253,0.402-0.445,0.712-0.577c0.31-0.132,0.684-0.198,1.122-0.198   c0.716,0,1.254,0.157,1.616,0.471c0.362,0.314,0.552,0.733,0.57,1.256l-1.151,0.051c-0.049-0.293-0.155-0.504-0.317-0.632   c-0.162-0.128-0.405-0.193-0.729-0.193c-0.334,0-0.596,0.069-0.786,0.206c-0.122,0.088-0.183,0.206-0.183,0.354   c0,0.135,0.057,0.25,0.171,0.346c0.145,0.122,0.498,0.249,1.058,0.381c0.56,0.132,0.974,0.269,1.243,0.41   c0.268,0.141,0.478,0.334,0.63,0.58c0.152,0.245,0.227,0.548,0.227,0.908C34.267,59.237,34.176,59.543,33.995,59.828z M32,52.795   c-11.466,0-20.795-9.329-20.795-20.795c0-11.466,9.329-20.795,20.795-20.795S52.795,20.534,52.795,32   C52.795,43.466,43.466,52.795,32,52.795z M55.014,33.917v-5.701h4.227v0.965h-3.076v1.264h2.862v0.96h-2.862v1.552h3.185v0.961   H55.014z\"/><g><path fill=\"#000000\" d=\"M48.904,31.863c-4.074-1.358-8.148-2.717-12.226-4.066c-0.265-0.087-0.399-0.223-0.486-0.486    c-1.349-4.077-2.708-8.151-4.066-12.226c-0.029-0.087-0.074-0.169-0.132-0.3c-0.054,0.152-0.09,0.245-0.122,0.34    c-1.352,4.053-2.707,8.104-4.048,12.161c-0.096,0.292-0.246,0.428-0.532,0.522c-4.056,1.342-8.108,2.696-12.16,4.049    c-0.097,0.032-0.189,0.074-0.344,0.137c0.172,0.06,0.267,0.093,0.362,0.125c4.074,1.358,8.148,2.717,12.224,4.072    c0.204,0.068,0.337,0.158,0.412,0.386c1.243,3.757,2.498,7.511,3.75,11.265c0.144,0.432,0.291,0.862,0.463,1.373    c0.068-0.185,0.108-0.285,0.142-0.386c1.349-4.042,2.701-8.083,4.04-12.128c0.094-0.284,0.231-0.438,0.523-0.534    c4.056-1.341,8.108-2.696,12.161-4.048c0.099-0.033,0.195-0.076,0.347-0.137C49.067,31.925,48.987,31.891,48.904,31.863z     M37.475,32.038c-1.316,0.439-2.631,0.879-3.947,1.314c-0.095,0.031-0.139,0.081-0.17,0.173c-0.434,1.313-0.873,2.625-1.311,3.937    c-0.012,0.033-0.024,0.066-0.046,0.126c-0.056-0.166-0.104-0.306-0.15-0.446c-0.407-1.219-0.814-2.437-1.218-3.657    c-0.025-0.074-0.068-0.104-0.134-0.125c-1.323-0.44-2.646-0.881-3.968-1.322c-0.031-0.01-0.062-0.022-0.118-0.041    c0.05-0.02,0.081-0.034,0.112-0.045c1.315-0.439,2.631-0.879,3.947-1.314c0.093-0.03,0.142-0.075,0.173-0.17    c0.435-1.316,0.875-2.632,1.314-3.947c0.01-0.031,0.022-0.062,0.039-0.11c0.019,0.042,0.033,0.069,0.043,0.097    c0.441,1.323,0.882,2.645,1.321,3.969c0.028,0.085,0.072,0.129,0.158,0.158c1.324,0.438,2.646,0.879,3.969,1.32    c0.027,0.009,0.053,0.02,0.1,0.038C37.538,32.013,37.507,32.027,37.475,32.038z\"/><path fill=\"#000000\" d=\"M24.436,27.633c-1.069-2.137-2.119-4.237-3.216-6.43c2.189,1.094,4.292,2.145,6.433,3.216    c-0.359,0.713-0.706,1.404-1.057,2.091c-0.023,0.045-0.078,0.082-0.127,0.106C25.807,26.949,25.143,27.28,24.436,27.633z\"/><path fill=\"#000000\" d=\"M39.573,27.632c-0.696-0.348-1.351-0.673-2.002-1.005c-0.076-0.038-0.155-0.104-0.193-0.177    c-0.338-0.661-0.666-1.326-1.019-2.033c2.121-1.061,4.228-2.115,6.43-3.217C41.69,23.399,40.635,25.509,39.573,27.632z\"/><path fill=\"#000000\" d=\"M24.436,36.339c0.712,0.357,1.394,0.698,2.074,1.043c0.046,0.024,0.088,0.073,0.113,0.121    c0.339,0.671,0.674,1.345,1.028,2.051c-2.126,1.063-4.232,2.117-6.43,3.216C22.317,40.577,23.37,38.472,24.436,36.339z\"/><path fill=\"#000000\" d=\"M36.358,39.555c0.354-0.707,0.688-1.38,1.028-2.05c0.028-0.056,0.084-0.111,0.14-0.139    c0.67-0.339,1.343-0.674,2.047-1.026c1.066,2.131,2.118,4.235,3.215,6.43C40.601,41.676,38.503,40.628,36.358,39.555z\"/></g></g></svg>\n\n\n  <h1 class=\"speed\">\n    <span class=\"speed-value\">0</span>\n    <span class=\"units\">KM/H</span>\n  </h1>\n\n  <style>\n    html {\n      font-size: 100px;\n    }\n\n    body {\n      margin: 0;\n      font-family: sans-serif;\n      min-height: 100vh;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      flex-direction: column;\n      background:\n        radial-gradient(black 15%, transparent 16%) 0 0,\n        radial-gradient(black 15%, transparent 16%) 8px 8px,\n        radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,\n        radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;\n      background-color: #282828;\n      background-size: 16px 16px;\n      background-attachment: fixed;\n    }\n\n    .arrow {\n      width: 250px;\n      overflow: hidden;\n      transition: all 0.2s;\n      transform: rotate(0deg);\n      display: inline-block;\n    }\n\n    h1 {\n      color: white;\n      font-weight: 100;\n      font-size: 60px;\n      display: flex;\n      align-items: center;\n    }\n\n    .units {\n      font-size: 15px;\n    }\n    /*Compass: https://thenounproject.com/search/?q=compass&i=592352*/\n  </style>\n  <script>\n    const arrow = document.querySelector('.arrow');\n    const speed = document.querySelector('.speed-value');\n\n    navigator.geolocation.watchPosition((data) => {\n      console.log(data);\n      speed.textContent = data.coords.speed;\n      arrow.style.transform = `rotate(${data.coords.heading}deg)`;\n    }, (err) => {\n      console.error(err);\n    });\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "21 - Geolocation/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Document</title>\n  <meta name=\"viewport\" content=\"width=device-width\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <svg class=\"arrow\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 64 64\" enable-background=\"new 0 0 64 64\" xml:space=\"preserve\"><g><path fill=\"#ffffff\" d=\"M32,1.824C15.361,1.824,1.825,15.361,1.825,32c0,16.639,13.537,30.176,30.175,30.176   S62.175,48.639,62.175,32C62.175,15.361,48.639,1.824,32,1.824z M29.715,3.988h1.12l2.333,3.807V3.988h1.069v5.701h-1.155   l-2.298-3.718v3.718h-1.069V3.988z M9.323,33.917H8.102l-1.136-4.262l-1.132,4.262H4.587l-1.361-5.701h1.178l0.859,3.916   l1.042-3.916h1.369l0.999,3.982l0.875-3.982h1.159L9.323,33.917z M33.995,59.828c-0.181,0.285-0.438,0.497-0.77,0.636   c-0.332,0.139-0.745,0.208-1.241,0.208c-0.721,0-1.274-0.167-1.661-0.5c-0.386-0.333-0.617-0.819-0.692-1.456l1.12-0.109   c0.067,0.376,0.204,0.652,0.41,0.828c0.206,0.176,0.484,0.264,0.834,0.264c0.371,0,0.65-0.078,0.838-0.235   c0.188-0.157,0.282-0.34,0.282-0.55c0-0.135-0.04-0.25-0.119-0.344c-0.079-0.095-0.217-0.177-0.414-0.247   c-0.135-0.047-0.442-0.13-0.922-0.249c-0.617-0.153-1.05-0.341-1.299-0.564c-0.35-0.314-0.525-0.696-0.525-1.147   c0-0.29,0.082-0.562,0.247-0.815c0.165-0.253,0.402-0.445,0.712-0.577c0.31-0.132,0.684-0.198,1.122-0.198   c0.716,0,1.254,0.157,1.616,0.471c0.362,0.314,0.552,0.733,0.57,1.256l-1.151,0.051c-0.049-0.293-0.155-0.504-0.317-0.632   c-0.162-0.128-0.405-0.193-0.729-0.193c-0.334,0-0.596,0.069-0.786,0.206c-0.122,0.088-0.183,0.206-0.183,0.354   c0,0.135,0.057,0.25,0.171,0.346c0.145,0.122,0.498,0.249,1.058,0.381c0.56,0.132,0.974,0.269,1.243,0.41   c0.268,0.141,0.478,0.334,0.63,0.58c0.152,0.245,0.227,0.548,0.227,0.908C34.267,59.237,34.176,59.543,33.995,59.828z M32,52.795   c-11.466,0-20.795-9.329-20.795-20.795c0-11.466,9.329-20.795,20.795-20.795S52.795,20.534,52.795,32   C52.795,43.466,43.466,52.795,32,52.795z M55.014,33.917v-5.701h4.227v0.965h-3.076v1.264h2.862v0.96h-2.862v1.552h3.185v0.961   H55.014z\"/><g><path fill=\"#000000\" d=\"M48.904,31.863c-4.074-1.358-8.148-2.717-12.226-4.066c-0.265-0.087-0.399-0.223-0.486-0.486    c-1.349-4.077-2.708-8.151-4.066-12.226c-0.029-0.087-0.074-0.169-0.132-0.3c-0.054,0.152-0.09,0.245-0.122,0.34    c-1.352,4.053-2.707,8.104-4.048,12.161c-0.096,0.292-0.246,0.428-0.532,0.522c-4.056,1.342-8.108,2.696-12.16,4.049    c-0.097,0.032-0.189,0.074-0.344,0.137c0.172,0.06,0.267,0.093,0.362,0.125c4.074,1.358,8.148,2.717,12.224,4.072    c0.204,0.068,0.337,0.158,0.412,0.386c1.243,3.757,2.498,7.511,3.75,11.265c0.144,0.432,0.291,0.862,0.463,1.373    c0.068-0.185,0.108-0.285,0.142-0.386c1.349-4.042,2.701-8.083,4.04-12.128c0.094-0.284,0.231-0.438,0.523-0.534    c4.056-1.341,8.108-2.696,12.161-4.048c0.099-0.033,0.195-0.076,0.347-0.137C49.067,31.925,48.987,31.891,48.904,31.863z     M37.475,32.038c-1.316,0.439-2.631,0.879-3.947,1.314c-0.095,0.031-0.139,0.081-0.17,0.173c-0.434,1.313-0.873,2.625-1.311,3.937    c-0.012,0.033-0.024,0.066-0.046,0.126c-0.056-0.166-0.104-0.306-0.15-0.446c-0.407-1.219-0.814-2.437-1.218-3.657    c-0.025-0.074-0.068-0.104-0.134-0.125c-1.323-0.44-2.646-0.881-3.968-1.322c-0.031-0.01-0.062-0.022-0.118-0.041    c0.05-0.02,0.081-0.034,0.112-0.045c1.315-0.439,2.631-0.879,3.947-1.314c0.093-0.03,0.142-0.075,0.173-0.17    c0.435-1.316,0.875-2.632,1.314-3.947c0.01-0.031,0.022-0.062,0.039-0.11c0.019,0.042,0.033,0.069,0.043,0.097    c0.441,1.323,0.882,2.645,1.321,3.969c0.028,0.085,0.072,0.129,0.158,0.158c1.324,0.438,2.646,0.879,3.969,1.32    c0.027,0.009,0.053,0.02,0.1,0.038C37.538,32.013,37.507,32.027,37.475,32.038z\"/><path fill=\"#000000\" d=\"M24.436,27.633c-1.069-2.137-2.119-4.237-3.216-6.43c2.189,1.094,4.292,2.145,6.433,3.216    c-0.359,0.713-0.706,1.404-1.057,2.091c-0.023,0.045-0.078,0.082-0.127,0.106C25.807,26.949,25.143,27.28,24.436,27.633z\"/><path fill=\"#000000\" d=\"M39.573,27.632c-0.696-0.348-1.351-0.673-2.002-1.005c-0.076-0.038-0.155-0.104-0.193-0.177    c-0.338-0.661-0.666-1.326-1.019-2.033c2.121-1.061,4.228-2.115,6.43-3.217C41.69,23.399,40.635,25.509,39.573,27.632z\"/><path fill=\"#000000\" d=\"M24.436,36.339c0.712,0.357,1.394,0.698,2.074,1.043c0.046,0.024,0.088,0.073,0.113,0.121    c0.339,0.671,0.674,1.345,1.028,2.051c-2.126,1.063-4.232,2.117-6.43,3.216C22.317,40.577,23.37,38.472,24.436,36.339z\"/><path fill=\"#000000\" d=\"M36.358,39.555c0.354-0.707,0.688-1.38,1.028-2.05c0.028-0.056,0.084-0.111,0.14-0.139    c0.67-0.339,1.343-0.674,2.047-1.026c1.066,2.131,2.118,4.235,3.215,6.43C40.601,41.676,38.503,40.628,36.358,39.555z\"/></g></g></svg>\n\n\n  <h1 class=\"speed\">\n    <span class=\"speed-value\">0</span>\n    <span class=\"units\">KM/H</span>\n  </h1>\n\n  <style>\n    html {\n      font-size: 100px;\n    }\n\n    body {\n      margin: 0;\n      font-family: sans-serif;\n      min-height: 100vh;\n      display: flex;\n      justify-content: center;\n      align-items: center;\n      flex-direction: column;\n      background:\n        radial-gradient(black 15%, transparent 16%) 0 0,\n        radial-gradient(black 15%, transparent 16%) 8px 8px,\n        radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,\n        radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;\n      background-color: #282828;\n      background-size: 16px 16px;\n      background-attachment: fixed;\n    }\n\n    .arrow {\n      width: 250px;\n      overflow: hidden;\n      transition: all 0.2s;\n      transform: rotate(0deg);\n      display: inline-block;\n    }\n\n    h1 {\n      color: white;\n      font-weight: 100;\n      font-size: 60px;\n      display: flex;\n      align-items: center;\n    }\n\n    .units {\n      font-size: 15px;\n    }\n    /*Compass: https://thenounproject.com/search/?q=compass&i=592352*/\n  </style>\n  <script>\n  </script>\n</body>\n</html>\n"
  },
  {
    "path": "21 - Geolocation/package.json",
    "content": "{\n  \"name\": \"gum\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"scripts.js\",\n  \"scripts\": {\n    \"start\": \"browser-sync start --directory --server --files \\\"*.css, *.html, *.js\\\" --https\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"browser-sync\": \"^2.12.5 <2.23.2\"\n  }\n}\n"
  },
  {
    "path": "22 - Follow Along Link Highlighter/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>👀👀👀Follow Along Nav</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n    <nav>\n      <ul class=\"menu\">\n        <li><a href=\"\">Home</a></li>\n        <li><a href=\"\">Order Status</a></li>\n        <li><a href=\"\">Tweets</a></li>\n        <li><a href=\"\">Read Our History</a></li>\n        <li><a href=\"\">Contact Us</a></li>\n      </ul>\n    </nav>\n\n    <div class=\"wrapper\">\n      <p>Lorem ipsum dolor sit amet, <a href=\"\">consectetur</a> adipisicing elit. Est <a href=\"\">explicabo</a> unde natus necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>\n      <p>Aspernatur sapiente quae sint <a href=\"\">soluta</a> modi, atque praesentium laborum pariatur earum <a href=\"\">quaerat</a> cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>\n      <p>Cum ipsam quod, incidunt sit ex <a href=\"\">tempore</a> placeat maxime <a href=\"\">corrupti</a> possimus <a href=\"\">veritatis</a> ipsum fugit recusandae est doloremque? Hic, <a href=\"\">quibusdam</a>, nulla.</p>\n      <p>Esse quibusdam, ad, ducimus cupiditate <a href=\"\">nulla</a>, quae magni odit <a href=\"\">totam</a> ut consequatur eveniet sunt quam provident sapiente dicta neque quod.</p>\n      <p>Aliquam <a href=\"\">dicta</a> sequi culpa fugiat <a href=\"\">consequuntur</a> pariatur optio ad minima, maxime <a href=\"\">odio</a>, distinctio magni impedit tempore enim repellendus <a href=\"\">repudiandae</a> quas!</p>\n    </div>\n\n<script>\n  const triggers = document.querySelectorAll('a');\n  const highlight = document.createElement('span');\n  highlight.classList.add('highlight');\n  document.body.appendChild(highlight);\n\n  function highlightLink() {\n    const linkCoords = this.getBoundingClientRect();\n    console.log(linkCoords);\n    const coords = {\n      width: linkCoords.width,\n      height: linkCoords.height,\n      top: linkCoords.top + window.scrollY,\n      left: linkCoords.left + window.scrollX\n    };\n\n    highlight.style.width = `${coords.width}px`;\n    highlight.style.height = `${coords.height}px`;\n    highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`;\n\n  }\n\n  triggers.forEach(a => a.addEventListener('mouseenter', highlightLink));\n\n</script>\n</body>\n</html>\n\n"
  },
  {
    "path": "22 - Follow Along Link Highlighter/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>👀👀👀Follow Along Nav</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n    <nav>\n      <ul class=\"menu\">\n        <li><a href=\"\">Home</a></li>\n        <li><a href=\"\">Order Status</a></li>\n        <li><a href=\"\">Tweets</a></li>\n        <li><a href=\"\">Read Our History</a></li>\n        <li><a href=\"\">Contact Us</a></li>\n      </ul>\n    </nav>\n\n    <div class=\"wrapper\">\n      <p>Lorem ipsum dolor sit amet, <a href=\"\">consectetur</a> adipisicing elit. Est <a href=\"\">explicabo</a> unde natus necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>\n      <p>Aspernatur sapiente quae sint <a href=\"\">soluta</a> modi, atque praesentium laborum pariatur earum <a href=\"\">quaerat</a> cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>\n      <p>Cum ipsam quod, incidunt sit ex <a href=\"\">tempore</a> placeat maxime <a href=\"\">corrupti</a> possimus <a href=\"\">veritatis</a> ipsum fugit recusandae est doloremque? Hic, <a href=\"\">quibusdam</a>, nulla.</p>\n      <p>Esse quibusdam, ad, ducimus cupiditate <a href=\"\">nulla</a>, quae magni odit <a href=\"\">totam</a> ut consequatur eveniet sunt quam provident sapiente dicta neque quod.</p>\n      <p>Aliquam <a href=\"\">dicta</a> sequi culpa fugiat <a href=\"\">consequuntur</a> pariatur optio ad minima, maxime <a href=\"\">odio</a>, distinctio magni impedit tempore enim repellendus <a href=\"\">repudiandae</a> quas!</p>\n    </div>\n\n  <script>\n    // 👀👀👀👀👀👀👀👀👀👀👀👀👀👀👀\n  </script>\n</body>\n</html>\n\n"
  },
  {
    "path": "22 - Follow Along Link Highlighter/style.css",
    "content": "html {\n  box-sizing: border-box;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nbody {\n  min-height: 100vh;\n  margin: 0; /* Important! */\n  font-family: sans-serif;\n  background:\n    linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),\n    linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),\n    linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),\n    linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);\n}\n\n.wrapper {\n  margin: 0 auto;\n  max-width: 500px;\n  font-size: 20px;\n  line-height: 2;\n  position: relative;\n}\n\na {\n  text-decoration: none;\n  color: black;\n  background: rgba(0,0,0,0.05);\n  border-radius: 20px;\n}\n\n.highlight {\n  transition: all 0.2s;\n  border-bottom: 2px solid white;\n  position: absolute;\n  top: 0;\n  background: white;\n  left: 0;\n  z-index: -1;\n  border-radius: 20px;\n  display: block;\n  box-shadow: 0 0 10px rgba(0,0,0,0.2);\n}\n\n.menu {\n  padding: 0;\n  display: flex;\n  list-style: none;\n  justify-content: center;\n  margin:100px 0;\n}\n\n.menu a {\n  display: inline-block;\n  padding: 5px;\n  margin: 0 20px;\n  color: black;\n}\n"
  },
  {
    "path": "23 - Speech Synthesis/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Speech Synthesis</title>\n  <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n    <div class=\"voiceinator\">\n\n      <h1>The Voiceinator 5000</h1>\n\n      <select name=\"voice\" id=\"voices\">\n        <option value=\"\">Select A Voice</option>\n      </select>\n\n      <label for=\"rate\">Rate:</label>\n      <input name=\"rate\" type=\"range\" min=\"0\" max=\"3\" value=\"1\" step=\"0.1\">\n\n      <label for=\"pitch\">Pitch:</label>\n\n      <input name=\"pitch\" type=\"range\" min=\"0\" max=\"2\" step=\"0.1\">\n      <textarea name=\"text\">Hello! I love JavaScript 👍</textarea>\n      <button id=\"stop\">Stop!</button>\n      <button id=\"speak\">Speak</button>\n\n    </div>\n\n<script>\n  const msg = new SpeechSynthesisUtterance();\n  let voices = [];\n  const voicesDropdown = document.querySelector('[name=\"voice\"]');\n  const options = document.querySelectorAll('[type=\"range\"], [name=\"text\"]');\n  const speakButton = document.querySelector('#speak');\n  const stopButton = document.querySelector('#stop');\n  msg.text = document.querySelector('[name=\"text\"]').value;\n\n  function populateVoices() {\n    voices = this.getVoices();\n    voicesDropdown.innerHTML = voices\n      .filter(voice => voice.lang.includes('en'))\n      .map(voice => `<option value=\"${voice.name}\">${voice.name} (${voice.lang})</option>`)\n      .join('');\n  }\n\n  function setVoice() {\n    msg.voice = voices.find(voice => voice.name === this.value);\n    toggle();\n  }\n\n  function toggle(startOver = true) {\n    speechSynthesis.cancel();\n    if (startOver) {\n      speechSynthesis.speak(msg);\n    }\n  }\n\n  function setOption() {\n    console.log(this.name, this.value);\n    msg[this.name] = this.value;\n    toggle();\n  }\n\n  speechSynthesis.addEventListener('voiceschanged', populateVoices);\n  voicesDropdown.addEventListener('change', setVoice);\n  options.forEach(option => option.addEventListener('change', setOption));\n  speakButton.addEventListener('click', toggle);\n  stopButton.addEventListener('click', () => toggle(false));\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "23 - Speech Synthesis/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Speech Synthesis</title>\n  <link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n    <div class=\"voiceinator\">\n\n      <h1>The Voiceinator 5000</h1>\n\n      <select name=\"voice\" id=\"voices\">\n        <option value=\"\">Select A Voice</option>\n      </select>\n\n      <label for=\"rate\">Rate:</label>\n      <input name=\"rate\" type=\"range\" min=\"0\" max=\"3\" value=\"1\" step=\"0.1\">\n\n      <label for=\"pitch\">Pitch:</label>\n\n      <input name=\"pitch\" type=\"range\" min=\"0\" max=\"2\" step=\"0.1\">\n      <textarea name=\"text\">Hello! I love JavaScript 👍</textarea>\n      <button id=\"stop\">Stop!</button>\n      <button id=\"speak\">Speak</button>\n\n    </div>\n\n<script>\n  const msg = new SpeechSynthesisUtterance();\n  let voices = [];\n  const voicesDropdown = document.querySelector('[name=\"voice\"]');\n  const options = document.querySelectorAll('[type=\"range\"], [name=\"text\"]');\n  const speakButton = document.querySelector('#speak');\n  const stopButton = document.querySelector('#stop');\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "23 - Speech Synthesis/style.css",
    "content": "html {\n  font-size: 10px;\n  box-sizing: border-box;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nbody {\n  margin: 0;\n  padding: 0;\n  font-family: sans-serif;\n  background-color: #3BC1AC;\n  display: flex;\n  min-height: 100vh;\n  align-items: center;\n\n  background-image:\n  radial-gradient(circle at 100% 150%, #3BC1AC 24%, #42D2BB 25%, #42D2BB 28%, #3BC1AC 29%, #3BC1AC 36%, #42D2BB 36%, #42D2BB 40%, transparent 40%, transparent),\n  radial-gradient(circle at 0    150%, #3BC1AC 24%, #42D2BB 25%, #42D2BB 28%, #3BC1AC 29%, #3BC1AC 36%, #42D2BB 36%, #42D2BB 40%, transparent 40%, transparent),\n  radial-gradient(circle at 50%  100%, #42D2BB 10%, #3BC1AC 11%, #3BC1AC 23%, #42D2BB 24%, #42D2BB 30%, #3BC1AC 31%, #3BC1AC 43%, #42D2BB 44%, #42D2BB 50%, #3BC1AC 51%, #3BC1AC 63%, #42D2BB 64%, #42D2BB 71%, transparent 71%, transparent),\n  radial-gradient(circle at 100% 50%, #42D2BB 5%, #3BC1AC 6%, #3BC1AC 15%, #42D2BB 16%, #42D2BB 20%, #3BC1AC 21%, #3BC1AC 30%, #42D2BB 31%, #42D2BB 35%, #3BC1AC 36%, #3BC1AC 45%, #42D2BB 46%, #42D2BB 49%, transparent 50%, transparent),\n  radial-gradient(circle at 0    50%, #42D2BB 5%, #3BC1AC 6%, #3BC1AC 15%, #42D2BB 16%, #42D2BB 20%, #3BC1AC 21%, #3BC1AC 30%, #42D2BB 31%, #42D2BB 35%, #3BC1AC 36%, #3BC1AC 45%, #42D2BB 46%, #42D2BB 49%, transparent 50%, transparent);\n  background-size:100px 50px;\n}\n\n.voiceinator {\n  padding: 2rem;\n  width: 50rem;\n  margin: 0 auto;\n  border-radius: 1rem;\n  position: relative;\n  background: white;\n  overflow: hidden;\n  z-index: 1;\n  box-shadow: 0 0 5px 5px rgba(0,0,0,0.1);\n}\n\nh1 {\n  width: calc(100% + 4rem);\n  margin: -2rem 0 2rem -2rem;\n  padding: .5rem;\n  background: #ffc600;\n  border-bottom: 5px solid #F3C010;\n  text-align: center;\n  font-size: 5rem;\n  font-weight: 100;\n  font-family: 'Pacifico', cursive;\n  text-shadow: 3px 3px 0 #F3C010;\n}\n\n.voiceinator input,\n.voiceinator button,\n.voiceinator select,\n.voiceinator textarea {\n  width: 100%;\n  display: block;\n  margin: 10px 0;\n  padding: 10px;\n  border: 0;\n  font-size: 2rem;\n  background: #F7F7F7;\n  outline: 0;\n}\n\ntextarea {\n  height: 20rem;\n}\n\n.voiceinator button {\n  background: #ffc600;\n  border: 0;\n  width: 49%;\n  float: left;\n  font-family: 'Pacifico', cursive;\n  margin-bottom: 0;\n  font-size: 2rem;\n  border-bottom: 5px solid #F3C010;\n  cursor: pointer;\n  position: relative;\n}\n\n.voiceinator button:active {\n  top: 2px;\n}\n\n.voiceinator button:nth-of-type(1) {\n  margin-right: 2%;\n}\n"
  },
  {
    "path": "24 - Sticky Nav/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Document</title>\n  <link rel=\"stylesheet\" href=\"style-FINISHED.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <header>\n    <h1>A story about getting lost.</h1>\n  </header>\n\n  <nav id=\"main\">\n    <ul>\n      <li class=\"logo\"><a href=\"#\">LOST.</a></li>\n      <li><a href=\"#\">Home</a></li>\n      <li><a href=\"#\">About</a></li>\n      <li><a href=\"#\">Images</a></li>\n      <li><a href=\"#\">Locations</a></li>\n      <li><a href=\"#\">Maps</a></li>\n    </ul>\n  </nav>\n\n  <div class=\"site-wrap\">\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <img src=\"http://unsplash.it/400/400\" class=\"align-left slide-in\">\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>\n    <img src=\"http://unsplash.it/400/400\" class=\"align-right slide-in\">\n    <p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n    <img src=\"http://unsplash.it/400/400\" class=\"align-right slide-in\">\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n  </div>\n\n  <script>\n    // Not a ton of code, but hard to\n    const nav = document.querySelector('#main');\n    let topOfNav = nav.offsetTop;\n\n    function fixNav() {\n      if (window.scrollY >= topOfNav) {\n        document.body.style.paddingTop = nav.offsetHeight + 'px';\n        document.body.classList.add('fixed-nav');\n      } else {\n        document.body.classList.remove('fixed-nav');\n        document.body.style.paddingTop = 0;\n      }\n    }\n\n    window.addEventListener('scroll', fixNav);\n\n  </script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "24 - Sticky Nav/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Sticky Nav</title>\n  <link rel=\"stylesheet\" href=\"style-START.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <header>\n    <h1>A story about getting lost.</h1>\n  </header>\n\n  <nav id=\"main\">\n    <ul>\n      <li class=\"logo\"><a href=\"#\">LOST.</a></li>\n      <li><a href=\"#\">Home</a></li>\n      <li><a href=\"#\">About</a></li>\n      <li><a href=\"#\">Images</a></li>\n      <li><a href=\"#\">Locations</a></li>\n      <li><a href=\"#\">Maps</a></li>\n    </ul>\n  </nav>\n\n  <div class=\"site-wrap\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-left slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-right slide-in\">\n\n    <p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>\n\n\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n\n    <img src=\"http://unsplash.it/400/400\" class=\"align-right slide-in\">\n\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>\n  </div>\n\n<script>\n\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "24 - Sticky Nav/style-FINISHED.css",
    "content": "html {\n  box-sizing: border-box;\n  background: #eeeeee;\n  font-family: 'helvetica neue';\n  font-size: 20px;\n  font-weight: 200;\n}\n\nbody {\n  margin: 0;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\n.site-wrap {\n  max-width: 700px;\n  margin: 70px auto;\n  background: white;\n  padding: 40px;\n  text-align: justify;\n  box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.05);\n  transform: scale(0.98);\n  transition: transform 0.5s;\n}\n\nbody.fixed-nav .site-wrap {\n  transform: scale(1);\n}\n\nheader {\n  text-align: center;\n  height: 50vh;\n  background: url(https://source.unsplash.com/GKN6rpDr0EI/960x640) bottom center no-repeat;\n  background-size: cover;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\nh1 {\n  color: white;\n  font-size: 7vw;\n  text-shadow: 3px 4px 0 rgba(0,0,0,0.2);\n}\n\nnav {\n  background: black;\n  top: 0;\n  width: 100%;\n  transition:all 0.5s;\n  position: relative;\n  z-index: 1;\n}\n\nbody.fixed-nav nav {\n  position: fixed;\n  box-shadow: 0 5px 0 rgba(0,0,0,0.1);\n}\n\nnav ul {\n  margin: 0;\n  padding: 0;\n  list-style: none;\n  display: flex;\n}\n\nnav li {\n  flex: 1;\n  text-align: center;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\nli.logo {\n  max-width: 0;\n  overflow: hidden;\n  background: white;\n  transition: all 0.5s;\n  font-weight: 600;\n  font-size: 30px;\n}\n\nli.logo a {\n  color: black;\n}\n\n.fixed-nav li.logo {\n  max-width: 500px;\n}\n\nnav a {\n  text-decoration: none;\n  padding: 20px;\n  display: inline-block;\n  color: white;\n  transition: all 0.2s;\n  text-transform: uppercase;\n}\n"
  },
  {
    "path": "24 - Sticky Nav/style-START.css",
    "content": "html {\n  box-sizing: border-box;\n  background: #eeeeee;\n  font-family: 'helvetica neue';\n  font-size: 20px;\n  font-weight: 200;\n}\n\nbody {\n  margin: 0;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\n.site-wrap {\n  max-width: 700px;\n  margin: 70px auto;\n  background: white;\n  padding: 40px;\n  text-align: justify;\n  box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.05);\n  transform: scale(0.98);\n  transition: transform 0.5s;\n}\n\nheader {\n  text-align: center;\n  height: 50vh;\n  background: url(https://source.unsplash.com/GKN6rpDr0EI/960x640) bottom center no-repeat;\n  background-size: cover;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\nh1 {\n  color: white;\n  font-size: 7vw;\n  text-shadow: 3px 4px 0 rgba(0,0,0,0.2);\n}\n\nnav {\n  background: black;\n  top: 0;\n  width: 100%;\n  transition: all 0.5s;\n  position: relative;\n  z-index: 1;\n}\n\nnav ul {\n  margin: 0;\n  padding:0;\n  list-style: none;\n  display: flex;\n}\n\nnav li {\n  flex: 1;\n  text-align: center;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n}\n\nli.logo {\n  max-width: 0;\n  overflow: hidden;\n  background: white;\n  transition: all .5s;\n  font-weight: 600;\n  font-size: 30px;\n}\n\nli.logo a {\n  color: black;\n}\n\nnav a {\n  text-decoration: none;\n  padding: 20px;\n  display: inline-block;\n  color: white;\n  transition: all 0.2s;\n  text-transform: uppercase;\n}\n"
  },
  {
    "path": "25 - Event Capture, Propagation, Bubbling and Once/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Understanding JavaScript's Capture</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body class=\"bod\">\n\n  <div class=\"one\">\n    <div class=\"two\">\n      <div class=\"three\">\n      </div>\n    </div>\n  </div>\n\n<style>\n  html {\n    box-sizing: border-box;\n  }\n\n  *, *:before, *:after {\n    box-sizing: inherit;\n  }\n\n  div {\n    width: 100%;\n    padding: 100px;\n  }\n\n  .one {\n    background: thistle;\n  }\n\n  .two {\n    background: mistyrose;\n  }\n\n  .three {\n    background: coral;\n  }\n</style>\n\n<button></button>\n<script>\n  const divs = document.querySelectorAll('div');\n  const button = document.querySelector('button');\n\n  function logText(e) {\n    console.log(this.classList.value);\n    // e.stopPropagation(); // stop bubbling!\n    // console.log(this);\n  }\n\n  divs.forEach(div => div.addEventListener('click', logText, {\n    capture: false,\n    once: true\n  }));\n\n  button.addEventListener('click', () => {\n    console.log('Click!!!');\n  }, {\n    once: true\n  });\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "25 - Event Capture, Propagation, Bubbling and Once/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Understanding JavaScript's Capture</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body class=\"bod\">\n\n  <div class=\"one\">\n    <div class=\"two\">\n      <div class=\"three\">\n      </div>\n    </div>\n  </div>\n\n<style>\n  html {\n    box-sizing: border-box;\n  }\n\n  *, *:before, *:after {\n    box-sizing: inherit;\n  }\n\n  div {\n    width: 100%;\n    padding: 100px;\n  }\n\n  .one {\n    background: thistle;\n  }\n\n  .two {\n    background: mistyrose;\n  }\n\n  .three {\n    background: coral;\n  }\n</style>\n\n<button></button>\n<script>\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "26 - Stripe Follow Along Nav/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Follow Along Nav</title>\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <h2>Cool</h2>\n  <nav class=\"top\">\n    <div class=\"dropdownBackground\">\n      <span class=\"arrow\"></span>\n    </div>\n\n    <ul class=\"cool\">\n      <li>\n        <a href=\"#\">About Me</a>\n        <div class=\"dropdown dropdown1\">\n          <div class=\"bio\">\n            <img src=\"https://logo.clearbit.com/wesbos.com\">\n            <p>Wes Bos sure does love web development. He teaches things like JavaScript, CSS and BBQ. Wait. BBQ isn't part of web development. It should be though!</p>\n          </div>\n        </div>\n      </li>\n      <li>\n        <a href=\"#\">Courses</a>\n        <ul class=\"dropdown courses\">\n          <li>\n            <span class=\"code\">RFB</span>\n            <a href=\"https://ReactForBeginners.com\">React For Beginners</a>\n          </li>\n          <li>\n            <span class=\"code\">ES6</span>\n            <a href=\"https://ES6.io\">ES6 For Everyone</a>\n          </li>\n          <li>\n            <span class=\"code\">NODE</span>\n            <a href=\"https://LearnNode.com\">Learn Node</a>\n          </li>\n          <li>\n            <span class=\"code\">STPU</span>\n            <a href=\"https://SublimeTextBook.com\">Sublime Text Power User</a>\n          </li>\n          <li>\n            <span class=\"code\">WTF</span>\n            <a href=\"http://Flexbox.io\">What The Flexbox?!</a>\n          </li>\n          <li>\n            <span class=\"code\">GRID</span>\n            <a href=\"https://CSSGrid.io\">CSS Grid</a>\n          </li>\n          <li>\n            <span class=\"code\">LRX</span>\n            <a href=\"http://LearnRedux.com\">Learn Redux</a>\n          </li>\n          <li>\n            <span class=\"code\">CLPU</span>\n            <a href=\"http://CommandLinePowerUser.com\">Command Line Power User</a>\n          </li>\n          <li>\n            <span class=\"code\">MMD</span>\n            <a href=\"http://MasteringMarkdown.com\">Mastering Markdown</a>\n          </li>\n        </ul>\n      </li>\n      <li>\n        <a href=\"#\">Other Links</a>\n        <ul class=\"dropdown dropdown3\">\n          <li><a class=\"button\" href=\"http://twitter.com/wesbos\">Twitter</a></li>\n          <li><a class=\"button\" href=\"http://facebook.com/wesbos.developer\">Facebook</a></li>\n          <li><a class=\"button\" href=\"http://wesbos.com\">Blog</a></li>\n          <li><a class=\"button\" href=\"http://wesbos.com/courses\">Course Catalog</a></li>\n        </ul>\n      </li>\n    </ul>\n  </nav>\n\n<style>\n  html {\n    box-sizing: border-box;\n    font-family: \"Arial Rounded MT Bold\", \"Helvetica Rounded\", Arial, sans-serif;\n  }\n\n  *, *:before, *:after {\n    box-sizing: inherit;\n  }\n\n  body {\n    margin: 0;\n    min-height: 100vh;\n    background:\n      linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),\n      linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),\n      linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),\n      linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);\n  }\n\n  h2 {\n    margin-top: 0;\n    padding-top: .8em;\n  }\n\n  nav {\n    position: relative;\n    perspective: 600px;\n  }\n\n  .cool > li > a {\n    color: yellow;\n    text-decoration: none;\n    font-size: 20px;\n    background: rgba(0,0,0,0.2);\n    padding: 10px 20px;\n    display: inline-block;\n    margin: 20px;\n    border-radius: 5px;\n  }\n\n  nav ul {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n    display: flex;\n    justify-content: center;\n  }\n\n  .cool > li {\n    position: relative;\n    display: flex;\n    justify-content: center;\n  }\n\n  .dropdown {\n    opacity: 0;\n    position: absolute;\n    overflow: hidden;\n    padding: 20px;\n    top: -20px;\n    border-radius: 2px;\n    transition: all 0.5s;\n    transform: translateY(100px);\n    will-change: opacity;\n    display: none;\n  }\n\n  .trigger-enter .dropdown {\n    display: block;\n  }\n\n  .trigger-enter-active .dropdown {\n    opacity: 1;\n  }\n\n  .dropdownBackground {\n    width: 100px;\n    height: 100px;\n    position: absolute;\n    background: #fff;\n    border-radius: 4px;\n    box-shadow: 0 50px 100px rgba(50,50,93,.1), 0 15px 35px rgba(50,50,93,.15), 0 5px 15px rgba(0,0,0,.1);\n    transition: all 0.3s, opacity 0.1s, transform 0.2s;\n    transform-origin: 50% 0;\n    display: flex;\n    justify-content: center;\n    opacity: 0;\n  }\n\n  .dropdownBackground.open {\n    opacity: 1;\n  }\n\n  .arrow {\n    position: absolute;\n    width: 20px;\n    height: 20px;\n    display: block;\n    background: white;\n    transform: translateY(-50%) rotate(45deg);\n  }\n\n  .bio {\n    min-width: 500px;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    line-height: 1.7;\n  }\n\n  .bio img {\n    float: left;\n    margin-right: 20px;\n  }\n\n  .courses {\n    min-width: 300px;\n  }\n\n  .courses li {\n    padding: 10px 0;\n    display: block;\n    border-bottom: 1px solid rgba(0,0,0,0.2);\n  }\n\n  .dropdown a {\n    text-decoration: none;\n    color: #ffc600;\n  }\n\n  a.button {\n    background: black;\n    display: block;\n    padding: 10px;\n    color: white;\n    margin-bottom: 10px;\n  }\n\n  /* Matches Twitter, TWITTER, twitter, tWitter, TWiTTeR... */\n  .button[href*=twitter] { background: #019FE9; }\n  .button[href*=facebook] { background: #3B5998; }\n  .button[href*=courses] { background: #ffc600; }\n</style>\n\n<script>\n  const triggers = document.querySelectorAll('.cool > li');\n  const background  = document.querySelector('.dropdownBackground');\n  const nav  = document.querySelector('.top');\n\n  function handleEnter() {\n    this.classList.add('trigger-enter');\n    setTimeout(() => this.classList.contains('trigger-enter') && this.classList.add('trigger-enter-active'), 150);\n    background.classList.add('open');\n\n    const dropdown = this.querySelector('.dropdown');\n    const dropdownCoords = dropdown.getBoundingClientRect();\n    const navCoords = nav.getBoundingClientRect();\n\n    const coords = {\n      height: dropdownCoords.height,\n      width: dropdownCoords.width,\n      top: dropdownCoords.top - navCoords.top,\n      left: dropdownCoords.left - navCoords.left\n    };\n\n    background.style.setProperty('width', `${coords.width}px`);\n    background.style.setProperty('height', `${coords.height}px`);\n    background.style.setProperty('transform', `translate(${coords.left}px, ${coords.top}px)`);\n  }\n\n  function handleLeave() {\n    this.classList.remove('trigger-enter', 'trigger-enter-active');\n    background.classList.remove('open');\n  }\n\n  triggers.forEach(trigger => trigger.addEventListener('mouseenter', handleEnter));\n  triggers.forEach(trigger => trigger.addEventListener('mouseleave', handleLeave));\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "26 - Stripe Follow Along Nav/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Follow Along Nav</title>\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <h2>Cool</h2>\n  <nav class=\"top\">\n    <div class=\"dropdownBackground\">\n      <span class=\"arrow\"></span>\n    </div>\n\n    <ul class=\"cool\">\n      <li>\n        <a href=\"#\">About Me</a>\n        <div class=\"dropdown dropdown1\">\n          <div class=\"bio\">\n            <img src=\"https://logo.clearbit.com/wesbos.com\">\n            <p>Wes Bos sure does love web development. He teaches things like JavaScript, CSS and BBQ. Wait. BBQ isn't part of web development. It should be though!</p>\n          </div>\n        </div>\n      </li>\n      <li>\n        <a href=\"#\">Courses</a>\n        <ul class=\"dropdown courses\">\n          <li>\n            <span class=\"code\">RFB</span>\n            <a href=\"https://ReactForBeginners.com\">React For Beginners</a>\n          </li>\n          <li>\n            <span class=\"code\">ES6</span>\n            <a href=\"https://ES6.io\">ES6 For Everyone</a>\n          </li>\n          <li>\n            <span class=\"code\">NODE</span>\n            <a href=\"https://LearnNode.com\">Learn Node</a>\n          </li>\n          <li>\n            <span class=\"code\">STPU</span>\n            <a href=\"https://SublimeTextBook.com\">Sublime Text Power User</a>\n          </li>\n          <li>\n            <span class=\"code\">WTF</span>\n            <a href=\"http://Flexbox.io\">What The Flexbox?!</a>\n          </li>\n          <li>\n            <span class=\"code\">GRID</span>\n            <a href=\"https://CSSGrid.io\">CSS Grid</a>\n          </li>\n          <li>\n            <span class=\"code\">LRX</span>\n            <a href=\"http://LearnRedux.com\">Learn Redux</a>\n          </li>\n          <li>\n            <span class=\"code\">CLPU</span>\n            <a href=\"http://CommandLinePowerUser.com\">Command Line Power User</a>\n          </li>\n          <li>\n            <span class=\"code\">MMD</span>\n            <a href=\"http://MasteringMarkdown.com\">Mastering Markdown</a>\n          </li>\n        </ul>\n      </li>\n      <li>\n        <a href=\"#\">Other Links</a>\n        <ul class=\"dropdown dropdown3\">\n          <li><a class=\"button\" href=\"http://twitter.com/wesbos\">Twitter</a></li>\n          <li><a class=\"button\" href=\"http://facebook.com/wesbos.developer\">Facebook</a></li>\n          <li><a class=\"button\" href=\"http://wesbos.com\">Blog</a></li>\n          <li><a class=\"button\" href=\"http://wesbos.com/courses\">Course Catalog</a></li>\n        </ul>\n      </li>\n    </ul>\n  </nav>\n\n<style>\n  html {\n    box-sizing: border-box;\n    font-family: \"Arial Rounded MT Bold\", \"Helvetica Rounded\", Arial, sans-serif;\n  }\n\n  *, *:before, *:after {\n    box-sizing: inherit;\n  }\n\n  body {\n    margin: 0;\n    min-height: 100vh;\n    background:\n      linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),\n      linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),\n      linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),\n      linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);\n  }\n\n  h2 {\n    margin-top: 0;\n    padding-top: .8em;\n  }\n\n  nav {\n    position: relative;\n    perspective: 600px;\n  }\n\n  .cool > li > a {\n    color: yellow;\n    text-decoration: none;\n    font-size: 20px;\n    background: rgba(0,0,0,0.2);\n    padding: 10px 20px;\n    display: inline-block;\n    margin: 20px;\n    border-radius: 5px;\n  }\n\n  nav ul {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n    display: flex;\n    justify-content: center;\n  }\n\n  .cool > li {\n    position: relative;\n    display: flex;\n    justify-content: center;\n  }\n\n  .dropdown {\n    opacity: 0;\n    position: absolute;\n    overflow: hidden;\n    padding: 20px;\n    top: -20px;\n    border-radius: 2px;\n    transition: all 0.5s;\n    transform: translateY(100px);\n    will-change: opacity;\n    display: none;\n  }\n\n  .trigger-enter .dropdown {\n    display: block;\n  }\n\n  .trigger-enter-active .dropdown {\n    opacity: 1;\n  }\n\n  .dropdownBackground {\n    width: 100px;\n    height: 100px;\n    position: absolute;\n    background: #fff;\n    border-radius: 4px;\n    box-shadow: 0 50px 100px rgba(50,50,93,.1), 0 15px 35px rgba(50,50,93,.15), 0 5px 15px rgba(0,0,0,.1);\n    transition: all 0.3s, opacity 0.1s, transform 0.2s;\n    transform-origin: 50% 0;\n    display: flex;\n    justify-content: center;\n    opacity:0;\n  }\n\n  .dropdownBackground.open {\n    opacity: 1;\n  }\n\n  .arrow {\n    position: absolute;\n    width: 20px;\n    height: 20px;\n    display: block;\n    background: white;\n    transform: translateY(-50%) rotate(45deg);\n  }\n\n  .bio {\n    min-width: 500px;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    line-height: 1.7;\n  }\n\n  .bio img {\n    float: left;\n    margin-right: 20px;\n  }\n\n  .courses {\n    min-width: 300px;\n  }\n\n  .courses li {\n    padding: 10px 0;\n    display: block;\n    border-bottom: 1px solid rgba(0,0,0,0.2);\n  }\n\n  .dropdown a {\n    text-decoration: none;\n    color: #ffc600;\n  }\n\n  a.button {\n    background: black;\n    display: block;\n    padding: 10px;\n    color: white;\n    margin-bottom: 10px;\n  }\n\n  /* Matches Twitter, TWITTER, twitter, tWitter, TWiTTeR... */\n  .button[href*=twitter] { background: #019FE9; }\n  .button[href*=facebook] { background: #3B5998; }\n  .button[href*=courses] { background: #ffc600; }\n</style>\n\n<script>\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "27 - Click and Drag/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Click and Drag</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n  <div class=\"items\">\n    <div class=\"item item1\">01</div>\n    <div class=\"item item2\">02</div>\n    <div class=\"item item3\">03</div>\n    <div class=\"item item4\">04</div>\n    <div class=\"item item5\">05</div>\n    <div class=\"item item6\">06</div>\n    <div class=\"item item7\">07</div>\n    <div class=\"item item8\">08</div>\n    <div class=\"item item9\">09</div>\n    <div class=\"item item10\">10</div>\n    <div class=\"item item11\">11</div>\n    <div class=\"item item12\">12</div>\n    <div class=\"item item13\">13</div>\n    <div class=\"item item14\">14</div>\n    <div class=\"item item15\">15</div>\n    <div class=\"item item16\">16</div>\n    <div class=\"item item17\">17</div>\n    <div class=\"item item18\">18</div>\n    <div class=\"item item19\">19</div>\n    <div class=\"item item20\">20</div>\n    <div class=\"item item21\">21</div>\n    <div class=\"item item22\">22</div>\n    <div class=\"item item23\">23</div>\n    <div class=\"item item24\">24</div>\n    <div class=\"item item25\">25</div>\n  </div>\n\n<script>\n  const slider = document.querySelector('.items');\n  let isDown = false;\n  let startX;\n  let scrollLeft;\n\n  slider.addEventListener('mousedown', (e) => {\n    isDown = true;\n    slider.classList.add('active');\n    startX = e.pageX - slider.offsetLeft;\n    scrollLeft = slider.scrollLeft;\n  });\n\n  slider.addEventListener('mouseleave', () => {\n    isDown = false;\n    slider.classList.remove('active');\n  });\n\n  slider.addEventListener('mouseup', () => {\n    isDown = false;\n    slider.classList.remove('active');\n  });\n\n  slider.addEventListener('mousemove', (e) => {\n    if (!isDown) return;  // stop the fn from running\n    e.preventDefault();\n    const x = e.pageX - slider.offsetLeft;\n    const walk = (x - startX) * 3;\n    slider.scrollLeft = scrollLeft - walk;\n  });\n\n</script>\n\n  </body>\n</html>\n"
  },
  {
    "path": "27 - Click and Drag/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Click and Drag</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <div class=\"items\">\n    <div class=\"item item1\">01</div>\n    <div class=\"item item2\">02</div>\n    <div class=\"item item3\">03</div>\n    <div class=\"item item4\">04</div>\n    <div class=\"item item5\">05</div>\n    <div class=\"item item6\">06</div>\n    <div class=\"item item7\">07</div>\n    <div class=\"item item8\">08</div>\n    <div class=\"item item9\">09</div>\n    <div class=\"item item10\">10</div>\n    <div class=\"item item11\">11</div>\n    <div class=\"item item12\">12</div>\n    <div class=\"item item13\">13</div>\n    <div class=\"item item14\">14</div>\n    <div class=\"item item15\">15</div>\n    <div class=\"item item16\">16</div>\n    <div class=\"item item17\">17</div>\n    <div class=\"item item18\">18</div>\n    <div class=\"item item19\">19</div>\n    <div class=\"item item20\">20</div>\n    <div class=\"item item21\">21</div>\n    <div class=\"item item22\">22</div>\n    <div class=\"item item23\">23</div>\n    <div class=\"item item24\">24</div>\n    <div class=\"item item25\">25</div>\n  </div>\n\n<script>\n</script>\n\n  </body>\n</html>\n"
  },
  {
    "path": "27 - Click and Drag/style.css",
    "content": "html {\n  box-sizing: border-box;\n  background: url('https://source.unsplash.com/NFs6dRTBgaM/2000x2000') fixed;\n  background-size: cover;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nbody {\n  min-height: 100vh;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  font-family: sans-serif;\n  font-size: 20px;\n  margin: 0;\n}\n\n.items {\n  height: 800px;\n  padding: 100px;\n  width: 100%;\n  border: 1px solid white;\n  overflow-x: scroll;\n  overflow-y: hidden;\n  white-space: nowrap;\n  user-select: none;\n  cursor: pointer;\n  transition: all 0.2s;\n  transform: scale(0.98);\n  will-change: transform;\n  position: relative;\n  background: rgba(255,255,255,0.1);\n  font-size: 0;\n  perspective: 500px;\n}\n\n.items.active {\n  background: rgba(255,255,255,0.3);\n  cursor: grabbing;\n  cursor: -webkit-grabbing;\n  transform: scale(1);\n}\n\n.item {\n  width: 200px;\n  height: calc(100% - 40px);\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  font-size: 80px;\n  font-weight: 100;\n  color: rgba(0,0,0,0.15);\n  box-shadow: inset 0 0 0 10px rgba(0,0,0,0.15);\n}\n\n.item:nth-child(9n+1) { background: dodgerblue;}\n.item:nth-child(9n+2) { background: goldenrod;}\n.item:nth-child(9n+3) { background: paleturquoise;}\n.item:nth-child(9n+4) { background: gold;}\n.item:nth-child(9n+5) { background: cadetblue;}\n.item:nth-child(9n+6) { background: tomato;}\n.item:nth-child(9n+7) { background: lightcoral;}\n.item:nth-child(9n+8) { background: darkslateblue;}\n.item:nth-child(9n+9) { background: rebeccapurple;}\n\n.item:nth-child(even) { transform: scaleX(1.31) rotateY(40deg); }\n.item:nth-child(odd) { transform: scaleX(1.31) rotateY(-40deg); }\n"
  },
  {
    "path": "28 - Video Speed Controller/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Video Speed Scrubber</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <div class=\"wrapper\">\n    <video class=\"flex\" width=\"765\" height=\"430\" src=\"http://clips.vorwaerts-gmbh.de/VfE_html5.mp4\" loop controls></video>\n    <div class=\"speed\">\n      <div class=\"speed-bar\">1×</div>\n    </div>\n  </div>\n\n<script>\n  const speed = document.querySelector('.speed');\n  const bar = speed.querySelector('.speed-bar');\n  const video = document.querySelector('.flex');\n\n  function handleMove(e) {\n      const y = e.pageY - this.offsetTop;\n      const percent = y / this.offsetHeight;\n      const min = 0.4;\n      const max = 4;\n      const height = Math.round(percent * 100) + '%';\n      const playbackRate = percent * (max - min) + min;\n      bar.style.height = height;\n      bar.textContent = playbackRate.toFixed(2) + '×';\n      video.playbackRate = playbackRate;\n    }\n\n  speed.addEventListener('mousemove', handleMove);\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "28 - Video Speed Controller/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Video Speed Scrubber</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <div class=\"wrapper\">\n    <video class=\"flex\" width=\"765\" height=\"430\" src=\"http://clips.vorwaerts-gmbh.de/VfE_html5.mp4\" loop controls></video>\n    <div class=\"speed\">\n      <div class=\"speed-bar\">1×</div>\n    </div>\n  </div>\n\n<script>\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "28 - Video Speed Controller/style.css",
    "content": "body {\n  margin: 0;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  min-height: 100vh;\n  background: #4C4C4C url('https://unsplash.it/1500/900?image=1021');\n  background-size: cover;\n  font-family: sans-serif;\n}\n\n.wrapper {\n  width: 850px;\n  display: flex;\n}\n\nvideo {\n  box-shadow: 0 0 1px 3px rgba(0,0,0,0.1);\n}\n\n.speed {\n  background: #efefef;\n  flex: 1;\n  display: flex;\n  align-items: flex-start;\n  margin: 10px;\n  border-radius: 50px;\n  box-shadow: 0 0 1px 3px rgba(0,0,0,0.1);\n  overflow: hidden;\n}\n\n.speed-bar {\n  width: 100%;\n  background: linear-gradient(-170deg, #2376ae 0%, #c16ecf 100%);\n  text-shadow: 1px 1px 0 rgba(0,0,0,0.2);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 2px;\n  color: white;\n  height: 16.3%;\n}\n"
  },
  {
    "path": "29 - Countdown Timer/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Countdown Timer</title>\n  <link href='https://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n  <div class=\"timer\">\n    <div class=\"timer__controls\">\n      <button data-time=\"20\" class=\"timer__button\">20 Secs</button>\n      <button data-time=\"300\" class=\"timer__button\">Work 5</button>\n      <button data-time=\"900\" class=\"timer__button\">Quick 15</button>\n      <button data-time=\"1200\" class=\"timer__button\">Snack 20</button>\n      <button data-time=\"3600\" class=\"timer__button\">Lunch Break</button>\n      <form name=\"customForm\" id=\"custom\">\n        <input type=\"text\" name=\"minutes\" placeholder=\"Enter Minutes\">\n      </form>\n    </div>\n    <div class=\"display\">\n      <h1 class=\"display__time-left\"></h1>\n      <p class=\"display__end-time\"></p>\n    </div>\n  </div>\n\n  <script src=\"scripts-START.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "29 - Countdown Timer/scripts-FINISHED.js",
    "content": "let countdown;\nconst timerDisplay = document.querySelector('.display__time-left');\nconst endTime = document.querySelector('.display__end-time');\nconst buttons = document.querySelectorAll('[data-time]');\n\nfunction timer(seconds) {\n  // clear any existing timers\n  clearInterval(countdown);\n\n  const now = Date.now();\n  const then = now + seconds * 1000;\n  displayTimeLeft(seconds);\n  displayEndTime(then);\n\n  countdown = setInterval(() => {\n    const secondsLeft = Math.round((then - Date.now()) / 1000);\n    // check if we should stop it!\n    if(secondsLeft < 0) {\n      clearInterval(countdown);\n      return;\n    }\n    // display it\n    displayTimeLeft(secondsLeft);\n  }, 1000);\n}\n\nfunction displayTimeLeft(seconds) {\n  const minutes = Math.floor(seconds / 60);\n  const remainderSeconds = seconds % 60;\n  const display = `${minutes}:${remainderSeconds < 10 ? '0' : '' }${remainderSeconds}`;\n  document.title = display;\n  timerDisplay.textContent = display;\n}\n\nfunction displayEndTime(timestamp) {\n  const end = new Date(timestamp);\n  const hour = end.getHours();\n  const adjustedHour = hour > 12 ? hour - 12 : hour;\n  const minutes = end.getMinutes();\n  endTime.textContent = `Be Back At ${adjustedHour}:${minutes < 10 ? '0' : ''}${minutes}`;\n}\n\nfunction startTimer() {\n  const seconds = parseInt(this.dataset.time);\n  timer(seconds);\n}\n\nbuttons.forEach(button => button.addEventListener('click', startTimer));\ndocument.customForm.addEventListener('submit', function(e) {\n  e.preventDefault();\n  const mins = this.minutes.value;\n  console.log(mins);\n  timer(mins * 60);\n  this.reset();\n});\n"
  },
  {
    "path": "29 - Countdown Timer/scripts-START.js",
    "content": ""
  },
  {
    "path": "29 - Countdown Timer/style.css",
    "content": "html {\n  box-sizing: border-box;\n  font-size: 10px;\n  background: #8E24AA;\n  background: linear-gradient(45deg,  #42a5f5 0%,#478ed1 50%,#0d47a1 100%);\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nbody {\n  margin: 0;\n  text-align: center;\n  font-family: 'Inconsolata', monospace;\n}\n\n.display__time-left {\n  font-weight: 100;\n  font-size: 20rem;\n  margin: 0;\n  color: white;\n  text-shadow: 4px 4px 0 rgba(0,0,0,0.05);\n}\n\n.timer {\n  display: flex;\n  min-height: 100vh;\n  flex-direction: column;\n}\n\n.timer__controls {\n  display: flex;\n}\n\n.timer__controls > * {\n  flex: 1;\n}\n\n.timer__controls form {\n  flex: 1;\n  display: flex;\n}\n\n.timer__controls input {\n  flex: 1;\n  border: 0;\n  padding: 2rem;\n}\n\n.timer__button {\n  background: none;\n  border: 0;\n  cursor: pointer;\n  color: white;\n  font-size: 2rem;\n  text-transform: uppercase;\n  background: rgba(0,0,0,0.1);\n  border-bottom: 3px solid rgba(0,0,0,0.2);\n  border-right: 1px solid rgba(0,0,0,0.2);\n  padding: 1rem;\n  font-family: 'Inconsolata', monospace;\n}\n\n.timer__button:hover,\n.timer__button:focus {\n  background: rgba(0,0,0,0.2);\n  outline: 0;\n}\n\n.display {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n}\n\n.display__end-time {\n  font-size: 4rem;\n  color: white;\n}\n"
  },
  {
    "path": "30 - Whack A Mole/index-FINISHED.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Whack A Mole!</title>\n  <link href='https://fonts.googleapis.com/css?family=Amatic+SC:400,700' rel='stylesheet' type='text/css'>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/✅\" />\n</head>\n<body>\n\n  <h1>Whack-a-mole! <span class=\"score\">0</span></h1>\n  <button onClick=\"startGame()\">Start!</button>\n\n  <div class=\"game\">\n    <div class=\"hole hole1\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole2\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole3\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole4\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole5\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole6\">\n      <div class=\"mole\"></div>\n    </div>\n  </div>\n\n<script>\n  const holes = document.querySelectorAll('.hole');\n  const scoreBoard = document.querySelector('.score');\n  const moles = document.querySelectorAll('.mole');\n  let lastHole;\n  let timeUp = false;\n  let score = 0;\n\n  function randomTime(min, max) {\n    return Math.round(Math.random() * (max - min) + min);\n  }\n\n  function randomHole(holes) {\n    const idx = Math.floor(Math.random() * holes.length);\n    const hole = holes[idx];\n    if (hole === lastHole) {\n      console.log('Ah nah thats the same one bud');\n      return randomHole(holes);\n    }\n    lastHole = hole;\n    return hole;\n  }\n\n  function peep() {\n    const time = randomTime(200, 1000);\n    const hole = randomHole(holes);\n    hole.classList.add('up');\n    setTimeout(() => {\n      hole.classList.remove('up');\n      if (!timeUp) peep();\n    }, time);\n  }\n\n  function startGame() {\n    scoreBoard.textContent = 0;\n    timeUp = false;\n    score = 0;\n    peep();\n    setTimeout(() => timeUp = true, 10000)\n  }\n\n  function bonk(e) {\n    if(!e.isTrusted) return; // cheater!\n    score++;\n    this.parentNode.classList.remove('up');\n    scoreBoard.textContent = score;\n  }\n\n  moles.forEach(mole => mole.addEventListener('click', bonk));\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "30 - Whack A Mole/index-START.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Whack A Mole!</title>\n  <link href='https://fonts.googleapis.com/css?family=Amatic+SC:400,700' rel='stylesheet' type='text/css'>\n  <link rel=\"stylesheet\" href=\"style.css\">\n  <link rel=\"icon\" href=\"https://fav.farm/🔥\" />\n</head>\n<body>\n\n  <h1>Whack-a-mole! <span class=\"score\">0</span></h1>\n  <button onClick=\"startGame()\">Start!</button>\n\n  <div class=\"game\">\n    <div class=\"hole hole1\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole2\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole3\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole4\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole5\">\n      <div class=\"mole\"></div>\n    </div>\n    <div class=\"hole hole6\">\n      <div class=\"mole\"></div>\n    </div>\n  </div>\n\n<script>\n  const holes = document.querySelectorAll('.hole');\n  const scoreBoard = document.querySelector('.score');\n  const moles = document.querySelectorAll('.mole');\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "30 - Whack A Mole/style.css",
    "content": "html {\n  box-sizing: border-box;\n  font-size: 10px;\n  background: #ffc600;\n}\n\n*, *:before, *:after {\n  box-sizing: inherit;\n}\n\nbody {\n  padding: 0;\n  margin: 0;\n  font-family: 'Amatic SC', cursive;\n}\n\nh1 {\n  text-align: center;\n  font-size: 10rem;\n  line-height: 1;\n  margin-bottom: 0;\n}\n\n.score {\n  background: rgba(255,255,255,0.2);\n  padding: 0 3rem;\n  line-height: 1;\n  border-radius: 1rem;\n}\n\n.game {\n  width: 600px;\n  height: 400px;\n  display: flex;\n  flex-wrap: wrap;\n  margin: 0 auto;\n}\n\n.hole {\n  flex: 1 0 33.33%;\n  overflow: hidden;\n  position: relative;\n}\n\n.hole:after {\n  display: block;\n  background: url(dirt.svg) bottom center no-repeat;\n  background-size: contain;\n  content: '';\n  width: 100%;\n  height:70px;\n  position: absolute;\n  z-index: 2;\n  bottom: -30px;\n}\n\n.mole {\n  background: url('mole.svg') bottom center no-repeat;\n  background-size: 60%;\n  position: absolute;\n  top: 100%;\n  width: 100%;\n  height: 100%;\n  transition:all 0.4s;\n}\n\n.hole.up .mole {\n  top: 0;\n}\n"
  },
  {
    "path": "PULL_REQUEST_TEMPLATE.md",
    "content": "<!-- \n👋👋👋👋👋👋👋👋👋👋👋👋👋👋\n👋👋👋Hello Friend!👋👋👋👋\n👋👋👋👋👋👋👋👋👋👋👋👋👋👋\n\nThanks for Submitting a pull request. Before you hit that button please make sure:\n\nThese files are meant to be 1:1 copies of what is done in the video. If you found a better / different way to do things or fixed a small bug, that is great great, but I will be keeping them the same as the videos to avoid confusing. \n\nSpelling mistakes / CSS updates / other clarifications are welcome as long as they don't change what is shown in the videos. \n\nI encourage you to blog about your implementation and add the link to this repo - that way everyone can benefit from it.\n\n-->\n"
  },
  {
    "path": "readme.md",
    "content": "﻿![](https://javascript30.com/images/JS3-social-share.png)\n\n# JavaScript30\n\nStarter Files + Completed solutions for the JavaScript 30 Day Challenge.\n\nGrab the course at [https://JavaScript30.com](https://JavaScript30.com)\n\n## Community #JavaScript30 Content\n\nFeel free to submit a PR by adding a link to your own recaps, guides, or reviews!\n\n* [Arjun Khode’s blog](http://thesagittariusme.blogspot.com/search/label/JS30) about summaries for each day, including fixed glitches, bugs and extra features.\n* [Nitish Dayal's Text Guides](https://github.com/nitishdayal/JavaScript30) are great for those who like reading over watching.\n* [Thorsten Frommen](https://tfrommen.de/tag/javascript-30/) shares how he solved the exercises before viewing the answers.\n* [Soyaine 写的中文指南](https://github.com/soyaine/JavaScript30)包含了过程记录和难点解释\n* [Aaron的语雀学习小组](https://github.com/A-aronYang/JavaScript30)包含中文文档，案例和相关资料\n* [乔木 录制的讲解视频](https://b23.tv/pSa7rdu) 看中文讲解视频一起学习 Javascript30 吧! Javascript30 中 CSS/JS/HTML 视频讲解\n* [Ayo Isaiah's](https://freshman.tech/archive/#javascript30) Recaps and Lessons Learned.\n* [Adriana Rios](https://stpcollabr8nlstn.github.io/JavaScript30/) shares her alternative solutions.\n* [Michael Einsohn](http://30daysofjs.michaeleinsohn.com) publishes each challenge after watching the video once.\n* [Mike Ekkel](https://medium.com/@mike_ekkel/javascript-30-a-30-day-vanilla-js-challenge-6a733fc9f62c#.9frjtaje9)\n* [Yusef Habib](https://github.com/yhabib/JavaScript30) lessons and tricks learned, and a [gh-page](https://yhabib.github.io/JavaScript30/) to see working all the mini-projects.\n* [Amelie Yeh](https://github.com/amelieyeh/JS30) 30 lesson notes with things I've learned, and those important recaps. and directly view my demos [here](https://amelieyeh.github.io/JS30/) 🇹🇼😄\n* [Winar](https://github.com/winar-jin/JavaScript30-Challenge)的JavaScript30天挑战，记录练习过程，重难点和其他的解决方案。🎨\n* [Rayhatron](https://rayhatron.github.io/blog/) - walkthroughs, recaps, and lessons learned.\n* [Andrei Dobra](https://github.com/andreidbr/JS30) Full repo with lessons learned and a [gh-page](https://andreidbr.github.io/JS30/) with all the exercises.\n* [从零到壹全栈部落](https://github.com/liyuechun/JavaScript30-liyuechun),春哥发起的从零到壹全栈部落，旨在带领大家一起学习，一起输出，文档化，代码化，中文视频化，全栈部落口号：输出是最好的学习方式。\n* [Usmaan Ali's](https://github.com/usyyy/javascript/blob/master/JavaScript30/analysis.md) summary of the technical skills learned from each project. He's also posting them as separate blog posts [here](https://medium.com/@usyyy).\n* [Axel](https://github.com/afuh/js30)'s lessons learned and a [showcase](https://afuh.github.io/js30/) with the projects.\n* [Chris](https://github.com/dwatow/JavaScript30) 中文實戰，目標描述、過程紀錄。\n* [Muhammad D. Ramadhan's](https://miayam.github.io) blog. He shamlesly mixed his personal life with 30 day JavaScript challenge to increase his learning retention. He also summarised the challenge on [one single page](https://miayam.github.io/js30). Do not read his blog!\n* [Lee Keitel's Blog](https://blog.keitel.xyz/categories/javascript30/) includes summaries of each lesson, what I learned from each one, and my thoughts about the topic taught and using them in the future.\n* [Dustin Hsiao](https://github.com/dustinhsiao21/Javascript30-dustin) 包含了各篇介紹、 效果Demo、各篇詳解及記錄過程，附上部分延伸閱讀及[gh-page](https://dustinhsiao21.github.io/Javascript30-dustin/)。\n* [GuaHsu](https://github.com/guahsu/JavaScript30) - 紀錄各篇練習過程與心得，並嘗試擴充部分練習，也做了一個包含全部練習的[介紹站](http://guahsu.io/JavaScript30/)🇹🇼\n* [Daniela](https://github.com/misslild)'s completed challenges on [GitHub Pages](https://misslild.github.io/WesBos-30day-Coding-challenge/) and [Codepen](https://codepen.io/collection/DapZeP/) :raised_hands: :muscle: :+1:\n* [Dmitrii Pashutskii's](https://github.com/guar47) code of all challenges on [GitHub with Pages](https://github.com/guar47/javascript30Summary) and review [blog posts](https://blog.dpashutskii.com/tag/javascript30/).\n* [Abid Hasan's](https://github.com/sabidhasan/javascript-30) completion of all challenges. This was awesome!! Learned so much! :+1:\n* [Yusong Notes](https://sky172839465.github.io/course/js30) Records Yusong JS 30 days note and demo. :star2:\n* [Ding's Implementation](https://github.com/Ding-Fan/javascript30) code and online demo.\n* [Herminio Torres](https://github.com/herminiotorres/JavaScript30) lessons and tricks learned, and a [gh-page](https://herminiotorres.github.io/JavaScript30/) to see working all the mini-projects.\n* [Dmytro Borysovskyi](https://github.com/dimabory) says many thanks for the course to Wes 🤝 It was incredible challenge 👌 The full repository with code available [here](https://github.com/dimabory/dimabory.github.io/tree/gh-pages/src/components/JavaScript30Days) and demos can be reached by the link to [gh-pages](https://dimabory.github.io/#/js30days).👍👍👍\n* [Kizito](https://github.com/akhilome/)'s follow along [repo](https://github.com/akhilome/js30) with [completed challenges](https://akhilome.github.io/js30) and [notes](https://akhilome.github.io/js30/notes).\n* [VannTile](https://github.com/vanntile)'s [repository](https://github.com/vanntile/JavaScript30) and [GitHub Pages showcase](https://vanntile.github.io/JavaScript30/). Thank you for a great ⌨️ experience.\n* [Alex Kim](https://github.com/Alex-K1m/js30-challenge) completed all the challenges. You can check them out at [GitHub pages](https://alex-k1m.github.io/js30-challenge/).\n* [Mikhail Thomas](https://github.com/seckela) created [JS30++](https://github.com/seckela/js30plusplus) to add another level of challenge on top of this already great course.\n* [Ramon Morcillo](https://github.com/reymon359/JavaScript30) finished this awesome challenge!. You can see the showcase of his implementations on [this link](https://reymon359.github.io/JavaScript30/).\n* [Santiago Escobar](https://github.com/sescobar99)'s [repository](https://github.com/sescobar99/javascript30-challenge) and [GitHub Pages showcase](https://sescobar99.github.io/javascript30-challenge/).\n* [Harry Xie](https://github.com/a90100/JavaScript30) 紀錄 30 天的練習筆記在 [此連結](https://github.com/a90100/JavaScript30).\n* [ Van Ribeiro's ](https://vanribeiro-30daysofjavascript.netlify.app/) about demos and recaps. On [GitHub Repo](https://github.com/vanribeiro/30days-Of-JavaScript) there's a summary about what was learned and researched.\n* [Mugilan](https://github.com/Mugilan-Codes) is currently doing this challenge. Check out his [Repo](https://github.com/Mugilan-Codes/javascript-30) and the [Live Demo](https://mugilan-codes.github.io/javascript-30/).\n* [Eshan Vohra](https://github.com/eshanvohra) is currently doing this challenge. Check out my repo [here](https://github.com/eshanvohra/JavaScript30).\n* [RegusAl](https://github.com/RegusAl) is currently doing this challenge. Check out my repo [here](https://github.com/RegusAl/JavaScript30).\n* [Ayush Gupta's](https://javascript30.ayushgupta.tech/) implementation of JavaScript30 challenge with some add-ons & updated design.\n* [filipkowal](https://github.com/filipkowal/JS30-05-Flex-Panels-Deactivate) Fix to flex panels (5th  day) so the panels deactivate when clicked on another one.\n* [Mo. Saif's](https://github.com/MoSaif00)note on lessons learned and a [gh-pages showcase](https://mosaif00.github.io/30-Days-JavaScript-Challenge/) for the projects.\n* [Stiaannel's](https://stiaannel.co.za/my-projects/javascript30) implementation of the Javascript30 challenge, with small design changes and a couple of extra features.\n* [Kelly CHI's](https://kellychi22.github.io/JavaScript30/) complete JavaScript30 challenges! Click the links to check demos and notes of each challenge. 🇹🇼 🌟\n* [Issam Seghir](https://issam-seghir.github.io/JavaScript30/)  added custom solutions and styles 🍧, improved performance, including fixed bugs/issus 💢. , added articles for each exercise 📝.\n\n## Alternative Implementations\nHere are some links of people who have done the tutorials, but in a different language or framework:\n\n* [Thomas Mattacchione](https://github.com/tkjone/clojurescript-30) JavaScript 30 written in ClojureScript.\n* [Dave Follett's](https://github.com/davefollett) blog series, [A New Vue on #JavaScript30](https://davefollett.io/categories/a-new-vue-on-javascript30/), where he explores re-implementing #JavaScript30 projects using [Vue](https://vuejs.org).\n* [Akinjide Bankole](https://github.com/akinjide/JS30days) used Node.js with [Jade](http://jadelang.net) to solve the exercises.\n* [Adrien Poly](https://github.com/adrienpoly/javascript30-stimulus) a modest attempt to convert Drum Kit, Video Player, Local Tapas, TypeHead to [Stimulus JS](https://stimulusjs.org/) framework in a Rails App.\n* [Bogdan Lazar](https://github.com/tricinel/TypeScript30) all the JavaScript 30 written in [TypeScript](https://www.typescriptlang.org/).\n* [Will Wager](https://github.com/wwags33/JavaScript30) another [TypeScript](https://www.typescriptlang.org/) implementation!\n* [marcoSven](https://github.com/marcoSven) solution suggestion for [10 - Hold Shift and Check Checkboxes](https://github.com/marcoSven/JavaScript30/blob/master/10%20-%20Hold%20Shift%20and%20Check%20Checkboxes/index-FINISHED.html).\n* [ALMaclaine](https://github.com/almaclaine) Javascript 30 written in [Dart 2.0](https://github.com/ALMaclaine/Dart30).\n* [Connie Leung](https://github.com/railsstudent) Javascript 30 written in [Angular and RxJS](https://github.com/railsstudent/ng-rxjs-30).\n\n## A note on Pull Requests\n\nThese are meant to be 1:1 copies of what is done in the video. If you found a better / different way to do things, great, but I will be keeping them the same as the videos.\n\nThe starter files + solutions will be updated if/when the videos are updated.\n\nThanks!\n"
  }
]