text: /**
   * Script for login.ejs
   */
  // Validation Regexes.
  const validUsername         = /^[a-zA-Z0-9_]{1,16}$/
  const basicEmail            = /^\S+@\S+\.\S+$/
  //const validEmail          = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i
  
  // Login Elements
  const loginCancelContainer  = document.getElementById('loginCancelContainer')
  const loginCancelButton     = document.getElementById('loginCancelButton')
  const loginEmailError       = document.getElementById('loginEmailError')
  const loginUsername         = document.getElementById('loginUsername')
  const loginPasswordError    = document.getElementById('loginPasswordError')
  const loginPassword         = document.getElementById('loginPassword')
  const checkmarkContainer    = document.getElementById('checkmarkContainer')
  const loginRememberOption   = document.getElementById('loginRememberOption')
  const loginButton           = document.getElementById('loginButton')
  const loginForm             = document.getElementById('loginForm')
  
  // Control variables.
  let lu = false, lp = false
  
  const loggerLogin = LoggerUtil('%c[Login]', 'color: #000668; font-weight: bold')
  
  
  /**
   * Show a login error.
   * 
   * @param {HTMLElement} element The element on which to display the error.
   * @param {string} value The error text.
   */
  function showError(element, value){
      element.innerHTML = value
      element.style.opacity = 1
  }
  
  /**
   * Shake a login error to add emphasis.
   * 
   * @param {HTMLElement} element The element to shake.
   */
  function shakeError(element){
      if(element.style.opacity == 1){
          element.classList.remove('shake')
          void element.offsetWidth
          element.classList.add('shake')
      }
  }
  
  /**
   * Validate that an email field is neither empty nor invalid.
   * 
   * @param {string} value The email value.
   */
  function validateEmail(value){
      if(value){
          if(!basicEmail.test(value) && !validUsername.test(value)){
              showError(loginEmailError, Lang.queryJS('login.error.invalidValue'))
              loginDisabled(true)
              lu = false
          } else {
              loginEmailError.style.opacity = 0
              lu = true
              if(lp){
                  loginDisabled(false)
              }
          }
      } else {
          lu = false
          showError(loginEmailError, Lang.queryJS('login.error.requiredValue'))
          loginDisabled(true)
      }
  }
  
  /**
   * Validate that the password field is not empty.
   * 
   * @param {string} value The password value.
   */
  function validatePassword(value){
      if(value){
          loginPasswordError.style.opacity = 0
          lp = true
          if(lu){
              loginDisabled(false)
          }
      } else {
          lp = false
          showError(loginPasswordError, Lang.queryJS('login.error.invalidValue'))
          loginDisabled(true)
      }
  }
  
  // Emphasize errors with shake when focus is lost.
  loginUsername.addEventListener('focusout', (e) => {
      validateEmail(e.target.value)
      shakeError(loginEmailError)
  })
  loginPassword.addEventListener('focusout', (e) => {
      validatePassword(e.target.value)
      shakeError(loginPasswordError)
  })
  
  // Validate input for each field.
  loginUsername.addEventListener('input', (e) => {
      validateEmail(e.target.value)
  })
  loginPassword.addEventListener('input', (e) => {
      validatePassword(e.target.value)
  })
  
  /**
   * Enable or disable the login button.
   * 
   * @param {boolean} v True to enable, false to disable.
   */
  function loginDisabled(v){
      if(loginButton.disabled !== v){
          loginButton.disabled = v
      }
  }
  
  /**
   * Enable or disable loading elements.
   * 
   * @param {boolean} v True to enable, false to disable.
   */
  function loginLoading(v){
      if(v){
          loginButton.setAttribute('loading', v)
          loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.login'), Lang.queryJS('login.loggingIn'))
      } else {
          loginButton.removeAttribute('loading')
          loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.login'))
      }
  }
  
  /**
   * Enable or disable login form.
   * 
   * @param {boolean} v True to enable, false to disable.
   */
  function formDisabled(v){
      loginDisabled(v)
      loginCancelButton.disabled = v
      loginUsername.disabled = v
      loginPassword.disabled = v
      if(v){
          checkmarkContainer.setAttribute('disabled', v)
      } else {
          checkmarkContainer.removeAttribute('disabled')
      }
      loginRememberOption.disabled = v
  }
  
  let loginViewOnSuccess = VIEWS.landing
  let loginViewOnCancel = VIEWS.settings
  let loginViewCancelHandler
  
  function loginCancelEnabled(val){
      if(val){
          $(loginCancelContainer).show()
      } else {
          $(loginCancelContainer).hide()
      }
  }
  
  loginCancelButton.onclick = (e) => {
      switchView(getCurrentView(), loginViewOnCancel, 500, 500, () => {
          loginUsername.value = ''
          loginPassword.value = ''
          loginCancelEnabled(false)
          if(loginViewCancelHandler != null){
              loginViewCancelHandler()
              loginViewCancelHandler = null
          }
      })
  }
  
  // Disable default form behavior.
  loginForm.onsubmit = () => { return false }
  
  // Bind login button behavior.
  loginButton.addEventListener('click', () => {
      // Disable form.
      formDisabled(true)
  
      // Show loading stuff.
      loginLoading(true)
  
      AuthManager.addAccount(loginUsername.value, loginPassword.value).then((value) => {
          updateSelectedAccount(value)
          loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.loggingIn'), Lang.queryJS('login.success'))
          $('.circle-loader').toggleClass('load-complete')
          $('.checkmark').toggle()
          setTimeout(() => {
              switchView(VIEWS.login, loginViewOnSuccess, 500, 500, () => {
                  // Temporary workaround
                  if(loginViewOnSuccess === VIEWS.settings){
                      prepareSettings()
                  }
                  loginViewOnSuccess = VIEWS.landing // Reset this for good measure.
                  loginCancelEnabled(false) // Reset this for good measure.
                  loginViewCancelHandler = null // Reset this for good measure.
                  loginUsername.value = ''
                  loginPassword.value = ''
                  $('.circle-loader').toggleClass('load-complete')
                  $('.checkmark').toggle()
                  loginLoading(false)
                  loginButton.innerHTML = loginButton.innerHTML.replace(Lang.queryJS('login.success'), Lang.queryJS('login.login'))
                  formDisabled(false)
              })
          }, 1000)
      }).catch((displayableError) => {
          loginLoading(false)
          setOverlayContent(displayableError.title, displayableError.desc, Lang.queryJS('login.tryAgain'))
          setOverlayHandler(() => {
              formDisabled(false)
              toggleOverlay(false)
          })
          toggleOverlay(true)
          loggerLogin.log('Error while logging in.', displayableError)
      })
  
  })