/* Typewriter text animation */

document.addEventListener("DOMContentLoaded", () => {
  window.typewriter = {
    element: document.getElementById("typewriter"),
    contents: [
      "I write code.\xa0",
      "I write software.\xa0",
      "I write websites.\xa0",
      "I write apps.\xa0",
      "I write libraries.\xa0",
      "I write simulations.\xa0",
      "I design experiences.\xa0",
      "I design interfaces.\xa0"
    ],
    contentIndex: 0,

    // A random delay in ms will be chosen from this range. The resulting delay
    // is multiplied for typing, so this isn't exact.
    typingDelay: [50, 100],

    /* Find common words that two strings start with. */
    _commonStart(a, b) {
      const aWords = a.split(" ");
      const bWords = b.split(" ");

      const commonWords = [];
      for (let i = 0; i < aWords.length; i++) {
        if (aWords[i] === bWords[i]) {
          commonWords.push(aWords[i]);
        } else {
          return commonWords.join(" ");
        }
      }
    },

    /* Get instructions for transforming between two strings in the form of
     * number of characters to delete and characters to add.
     */
    _transitionDescription(a, b) {
      const common = this._commonStart(a, b);
      const numCharactersToDelete = a.length - common.length;
      const charactersToAdd = b.slice(common.length);
      return {
        del: numCharactersToDelete,
        add: charactersToAdd
      };
    },

    _getTypingDelay() {
      return Math.floor((Math.random() * (this.typingDelay[1] - this.typingDelay[0])) + this.typingDelay[0]);
    },

    /* Animate bacspacing by a given number of characters */
    backspace(num, callback) {
      let content;
      let toGo = num;
      callback = callback || (() => {});
      this._backspace1 = () => {
        if (toGo === 0) {
          callback();
        } else {
          content = this.element.textContent;
          this.element.textContent = content.slice(0, content.length - 1);
          toGo--;
          setTimeout(() => window.typewriter._backspace1(), this._getTypingDelay());
        }
      };
      this._backspace1();
    },

    /* Animate inserting a given string at the end of the text */
    type(text, callback) {
      let i = 0;
      callback = callback || (() => {});
      this._type1 = () => {
        if (i === text.length) {
          callback();
        } else {
          this.element.textContent += text[i];
          i++;
          setTimeout(() => window.typewriter._type1(), this._getTypingDelay() * 1.5);
        }
      };
      this._type1();
    },

    /* Animate advancing to the next phrase */
    next(callback) {
      this.contentIndex++;
      // Loop back
      if (this.contentIndex === this.contents.length) {
        this.contentIndex = 0;
      }
      // Make changes
      const changesNeeded = this._transitionDescription(
        this.element.textContent,
        this.contents[this.contentIndex]
      );
      this.backspace(changesNeeded.del, () => {
        setTimeout(() => window.typewriter.type(changesNeeded.add, callback), 200);
      });
    },

    /* Fill the element with the first phrase (non-animated) and set up other
     * miscellaneous details.
     */
    init() {
      this.element.textContent = this.contents[0];
      this._startOnScroll = () => {
        if (
          window.scrollY + window.innerHeight > this.element.offsetTop + (this.element.offsetHeight / 2)
        ) {
          setTimeout(() => window.typewriter.play(), 1000);
          window.removeEventListener("scroll", scrollFunc);
        }
      };
      function scrollFunc() {
        window.typewriter._startOnScroll();
      }
      window.addEventListener("scroll", scrollFunc);
    },

    /* Recursively continue advancing */
    play() {
      this.next(() => {
        setTimeout(() => window.typewriter.play(), 3000);
      });
    }

  };

  window.typewriter.init();
});

@@ -52,17 +52,17 @@
 istener(
-%22
+'
 DOMConte
@@ -69,17 +69,17 @@
 ntLoaded
-%22
+'
 , () =%3E 
@@ -141,17 +141,17 @@
 entById(
-%22
+'
 typewrit
@@ -152,17 +152,17 @@
 pewriter
-%22
+'
 ),%0A    c
@@ -174,25 +174,25 @@
 ts: %5B%0A      
-%22
+'
 I write code
@@ -192,33 +192,33 @@
 te code.%5Cxa0
-%22
+'
 ,%0A      
 %22I write sof
@@ -197,33 +197,33 @@
 de.%5Cxa0',%0A      
-%22
+'
 I write software
@@ -223,33 +223,33 @@
 oftware.%5Cxa0
-%22
+'
 ,%0A      
 %22I write web
@@ -228,33 +228,33 @@
 re.%5Cxa0',%0A      
-%22
+'
 I write websites
@@ -254,33 +254,33 @@
 ebsites.%5Cxa0
-%22
+'
 ,%0A      
 %22I write app
@@ -259,33 +259,33 @@
 es.%5Cxa0',%0A      
-%22
+'
 I write apps.%5Cxa
@@ -281,33 +281,33 @@
 te apps.%5Cxa0
-%22
+'
 ,%0A      
 %22I write lib
@@ -286,33 +286,33 @@
 ps.%5Cxa0',%0A      
-%22
+'
 I write librarie
@@ -317,25 +317,25 @@
 ies.%5Cxa0
-%22
+'
 ,%0A      
 %22I write
@@ -326,17 +326,17 @@
 ,%0A      
-%22
+'
 I write 
@@ -347,33 +347,33 @@
 lations.%5Cxa0
-%22
+'
 ,%0A      
 %22I design ex
@@ -352,33 +352,33 @@
 ns.%5Cxa0',%0A      
-%22
+'
 I design experie
@@ -390,17 +390,17 @@
 %5Cxa0
-%22
+'
 ,%0A      
 %22I d
@@ -395,17 +395,17 @@
 ,%0A      
-%22
+'
 I design
@@ -420,17 +420,17 @@
 ces.%5Cxa0
-%22
+'
 %0A    %5D,%0A
@@ -725,19 +725,19 @@
 a.split(
-%22 %22
+' '
 );%0A     
@@ -760,19 +760,19 @@
 b.split(
-%22 %22
+' '
 );%0A%0A    
@@ -978,11 +978,11 @@
 oin(
-%22 %22
+' '
 );%0A 
@@ -3544,32 +3544,32 @@
 entListener(
-%22
+'
 scroll
-%22
+'
 , scrollFunc
@@ -3706,16 +3706,16 @@
 ner(
-%22
+'
 scroll
-%22
+'
 , sc

Use single quotes in typewriter