(function() {

  var defaults = {
    documentPrefix: 'notes',
    settings: {
      theme: {
        background: 'linear-gradient(90deg, #614385 10%, #516395 90%)',
        color: 'white'
      }
    }
  };

  var documentId = setDocumentId(location.hash.replace(/^#/, ''));
  var editor = document.getElementById('js-editor');

  populateStorage('settings', defaults.settings);
  populateStorage(documentId, []);

  var settings = JSON.parse(localStorage.getItem('settings'));
  var notes = JSON.parse(localStorage.getItem(documentId));

  // initialize settings
  setSettings(settings.theme);

  // load notes into editor
  editor.value = notes.join('\n');

  editor.addEventListener('input', debounce(function(e) {
    updateNotes(editor);
  }, 100), false);

  /**
   * setDocumentId
   * @param {String} name
   * @param {String} prefix
   */
  function setDocumentId(name) {
    return (name === '') ? defaults.documentPrefix : defaults.documentPrefix + name.charAt(0).toUpperCase() + name.slice(1);
  }

  function getLineNumber(editor) {
    return editor.value.substr(0, editor.selectionStart).split('\n').length;
  }

  /**
   * updateNotes
   * @param  {Element} editor
   */
  function updateNotes(editor) {
    localStorage.setItem(documentId, JSON.stringify(editor.value.split('\n')));
  }

  /**
   * setSettings
   * @param  {Object} settings
   */
  function setSettings(settings) {
    for (var key in settings) {
      if (settings.hasOwnProperty(key)) {
        document.documentElement.style[key] = settings[key];
      }
    }
  }

  /**
   * populateStorage
   * @param  {String} key
   * @param  {Object} props
   */
  function populateStorage(key, props) {
    if (!localStorage.getItem(key)) {
      localStorage.setItem(key, JSON.stringify(props));
    }
  }

  /**
   * Returns a debounced function that will make sure the given
   * function is not triggered too much.
   *
   * @param  {Function} fn Function to debounce.
   * @param  {Number}   debounceDuration OPTIONAL. The amount of time in milliseconds for which we will debounce the function. (defaults to 100ms)
   * @return {Function}
   */
  function debounce(fn, debounceDuration) {
    debounceDuration = debounceDuration || 100;
    return function() {
      if (!fn.debouncing) {
        var args = Array.prototype.slice.apply(arguments);
        fn.lastReturnVal = fn.apply(window, args);
        fn.debouncing = true;
      }
      clearTimeout(fn.debounceTimeout);
      fn.debounceTimeout = setTimeout(function(){
        fn.debouncing = false;
      }, debounceDuration);
      return fn.lastReturnVal;
    };
  }

  /**
   * loadTheme
   * @param  {JSON}   json
   */
  window.loadTheme = function(json) {
    settings.theme = JSON.parse(json);
    localStorage.setItem('settings', JSON.stringify(settings));
    setSettings(settings.theme);
  };

  /**
   * getDocumentNames
   * @return {Array}  Names (`document.hash`) of all existing documents
   */
  window.getDocumentNames = function() {
    var documentNames = [];
    for (i = 0; i < localStorage.length; i++) {
      if (localStorage.key(i) !== defaults.documentPrefix && localStorage.key(i).indexOf(defaults.documentPrefix) === 0) {
        documentNames.push(localStorage.key(i).replace(defaults.documentPrefix, ''));
      }
    }
    return documentNames;
  };

})();

@@ -3319,14 +3319,534 @@
 ;%0A  %7D;%0A%0A
+  var banner = '             _ %5Cn            %7C %7C %5Cn _ __   ___ %7C %7C_ ___  ___ %5Cn%7C %5C'_ %5C%5C / _ %5C%5C%7C __/ _ %5C%5C/ __%7C %5Cn%7C %7C %7C %7C (_) %7C %7C%7C  __/%5C%5C__ %5C%5C %5Cn%7C_%7C %7C_%7C%5C%5C___/ %5C%5C__%5C%5C___%7C%7C___/%5Cn%5Cn%5Cn';%0A  console.log('%25c' + banner, 'color: rgba(0, 0, 0, .8);');%0A  console.group('Usage:');%0A  console.log('Just type in some notes.');%0A  console.log('Your notes get saved instantly after every key you press.');%0A  console.groupEnd();%0A%0A  console.log('%5Cn');%0A%0A  console.group('Hidden features:');%0A  console.log('Wait for it.')%0A  console.groupEnd();%0A
 %7D)();%0A

add console docs