text: (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  'use strict';
  
  var socket = io();
  
  $('#Formulario_create').submit(function () {
  	socket.emit('new personaje', {
  		id: '',
  		name: $('#personaje_name').val(),
  		occupation: $('#personaje_occupation').val(),
  		group: $('#personaje_group').val(),
  		age: $('#personaje_age').val(),
  		photo: $('#personaje_photo').val()
  	});
  
  	$('#personaje_name').val('');
  	$('#personaje_occupation').val('');
  	$('#personaje_group').val('');
  	$('#personaje_age').val('');
  	$('#personaje_photo').val('');
  	return false;
  });
  
  socket.on('new personaje', function (content) {
  	var template = '<article class="Personajes-app__read__item">\n\t\t\t\t\t        <div class="item__title">\n\t\t\t\t\t          <h2>' + content.name + '</h2>\n\t\t\t\t\t        </div>\n\t\t\t\t\t        <figure class="item__imagen"><img src=" ' + content.photo + ' "/></figure>\n\t\t\t\t\t        <div class="item__data">\n\t\t\t\t\t\t          <div class="item__data--rate">\n\t\t\t\t\t\t            <p class="rate__right"> <span class="icon-heart-on"></span><span id="like-cant">7</span>\n\t\t\t\t\t\t              <p>Likes</p>\n\t\t\t\t\t\t            </p>\n\t\t\t\t\t\t            <p class="rate__left"> <span class="icon-bubbles2"> </span><span id="comment-cant">23</span>\n\t\t\t\t\t\t              <p>Comentarios</p>\n\t\t\t\t\t\t            </p>\n\t\t\t\t\t\t          </div>\n\t\t\t\t\t\t          <div class="item__data--author"><strong>By:</strong>\n\t\t\t\t\t\t            <figure><img src="./images/favicon.ico" width="20"/></figure>\n\t\t\t\t\t\t            <p>@joelengt</p>\n\t\t\t\t\t\t          </div>\n\t\t\t\t\t        </div>\n\t\t\t\t\t        <div class="item__detalles">\n\t\t\t\t\t\t          <span>\n\t\t\t\t\t\t          \t  <strong>Serie/Grupo:</strong>\n\t\t\t\t\t\t              <p>' + content.group + '</p>\n\t\t\t\t\t              </span>\n\t\t\t\t\t               <span>\n\t\t\t\t\t\t          \t  <strong>Ocupación:</strong>\n\t\t\t\t\t\t              <p>' + content.occupation + '</p>\n\t\t\t\t\t              </span>\n\t\t\t\t\t               <span>\n\t\t\t\t\t\t          \t  <strong>Edad:</strong>\n\t\t\t\t\t\t              <p>' + content.age + '</p>\n\t\t\t\t\t              </span>\n\t\t\t\t\t        </div>\n\t\t\t\t\t        <div class="item__action">\n\t\t\t\t\t\t          <div class="action--like"><a href="#" class="btn-like  icon-heart-off  color-gray"></a></div>\n\t\t\t\t\t\t          <div class="action--comment">\n\t\t\t\t\t              <input type="text" placeholder="Añade un Comentario..."/>\n\t\t\t\t\t          </div>\n\t\t\t\t\t          <div class="action--settings">\n\t\t\t\t\t\t          <a href="/detalle/' + content.id + '" class="icon-settings"></a>\n\t\t\t\t\t          </div>\n\t\t\t\t\t        </div>\n\t\t\t\t      </article>';
  
  	$('#pj_item').prepend(template);
  });
  
  },{}],2:[function(require,module,exports){
  'use strict';
  
  var _page = require('page');
  
  var _page2 = _interopRequireDefault(_page);
  
  var _index = require('./renderPersonajes/index');
  
  var _index2 = _interopRequireDefault(_index);
  
  var _index3 = require('./renderDetalles/index');
  
  var _index4 = _interopRequireDefault(_index3);
  
  var _index5 = require('./renderEdit/index');
  
  var _index6 = _interopRequireDefault(_index5);
  
  require('./staticInteraction/btn_publicar');
  
  require('./staticInteraction/like_buttom');
  
  require('./createPersonaje/add_real_time');
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  var formlulario_Create = $('#From_create');
  
  (0, _page2.default)('/demo', function (ctx, next) {
  	$('.Personajes-app__box').find('#From_edit').remove();
  
  	// if(!localStorage.apipersonajes) {
  
  	$.ajax('/api/personajes', {
  		success: function success(personajes) {
  			$('body').find('.loader').remove();
  			$('#pj_item').find('.Personajes-app__read__item').remove();
  			(0, _index2.default)(personajes);
  
  			// Guardando en el localStorage
  			// localStorage.setItem('apipersonajes', JSON.stringify(personajes))
  		}
  	});
  
  	// } else {
  	// 	// Leyendo del localStorage
  	// 	renderPersonajes(JSON.parse(localStorage.apipersonajes))
  
  	// }
  });
  
  (0, _page2.default)('/detalle/:id', function (ctx, next) {
  	var id = ctx.params.id;
  	$.ajax('/api/personajes/' + id, {
  		success: function success(personaje) {
  			$('#pj_item').find('.Personajes-app__read__item').remove();
  			(0, _index4.default)(personaje);
  		}
  	});
  });
  
  (0, _page2.default)('/delete/:id', function (ctx, next) {
  	var id = ctx.params.id;
  
  	$.post('/api/personaje/' + id + '?_method=delete', {
  		success: function success() {
  			window.location.href = '/demo';
  		}
  	});
  });
  
  (0, _page2.default)('/edit/:id', function (ctx, next) {
  	var id = ctx.params.id;
  
  	$.ajax('/api/personajes/' + id, {
  		success: function success(personaje) {
  
  			$('.Personajes-app__box').find('.Personajes-app__form').remove();
  			$('#pj_item').find('.Personajes-app__read__item').remove();
  			console.log('Render Edit');
  			(0, _index6.default)(personaje);
  		}
  	});
  });
  
  (0, _page2.default)('/update/:id', function (ctx, next) {
  	var id = ctx.params.id;
  
  	var personaje = {
  		id: '',
  		name: $('#personaje_name').val(),
  		occupation: $('#personaje_occupation').val(),
  		group: $('#personaje_group').val(),
  		age: $('#personaje_age').val(),
  		photo: $('#personaje_photo').val()
  	};
  
  	$.ajax({
  		data: personaje,
  		url: '/api/personaje/' + id + '?_method=put',
  		type: 'post',
  		success: function success(res) {
  			console.log(res);
  
  			$('.Personajes-app__box').find('#From_edit').remove();
  
  			$.ajax('/api/personajes/' + id, {
  				success: function success(personaje) {
  					$('#pj_item').find('.Personajes-app__read__item').remove();
  					(0, _index4.default)(personaje);
  				}
  			});
  		}
  	});
  });
  
  (0, _page2.default)();
  
  },{"./createPersonaje/add_real_time":1,"./renderDetalles/index":3,"./renderEdit/index":4,"./renderPersonajes/index":5,"./staticInteraction/btn_publicar":6,"./staticInteraction/like_buttom":7,"page":9}],3:[function(require,module,exports){
  'use strict';
  
  Object.defineProperty(exports, "__esModule", {
  	value: true
  });
  exports.default = renderDetalles;
  function renderDetalles(elemento) {
  
  	var personaje = elemento[0];
  
  	var template = '<article class="Personajes-app__read__item">\n\t\t\t\t        <div class="item__title">\n\t\t\t\t          <h2>' + personaje.name + '</h2>\n\t\t\t\t        </div>\n\t\t\t\t        <figure class="item__imagen"><img src=" ' + personaje.photo + ' "/></figure>\n\t\t\t\t        <div class="item__data">\n\t\t\t\t\t          <div class="item__data--rate">\n\t\t\t\t\t            <p class="rate__right"> <span class="icon-heart-on"></span><span id="like-cant">7</span>\n\t\t\t\t\t              <p>Likes</p>\n\t\t\t\t\t            </p>\n\t\t\t\t\t            <p class="rate__left"> <span class="icon-bubbles2"> </span><span id="comment-cant">23</span>\n\t\t\t\t\t              <p>Comentarios</p>\n\t\t\t\t\t            </p>\n\t\t\t\t\t          </div>\n\t\t\t\t\t          <div class="item__data--author"><strong>By:</strong>\n\t\t\t\t\t            <figure><img src="../images/favicon.ico" width="20"/></figure>\n\t\t\t\t\t            <p>@joelengt</p>\n\t\t\t\t\t          </div>\n\t\t\t\t        </div>\n\t\t\t\t        <div class="item__detalles">\n\t\t\t\t\t          <span>\n\t\t\t\t\t          \t  <strong>Serie/Grupo:</strong>\n\t\t\t\t\t              <p>' + personaje.group + '</p>\n\t\t\t\t              </span>\n\t\t\t\t               <span>\n\t\t\t\t\t          \t  <strong>Ocupación:</strong>\n\t\t\t\t\t              <p>' + personaje.occupation + '</p>\n\t\t\t\t              </span>\n\t\t\t\t               <span>\n\t\t\t\t\t          \t  <strong>Edad:</strong>\n\t\t\t\t\t              <p>' + personaje.age + '</p>\n\t\t\t\t              </span>\n\t\t\t\t        </div>\n\t\t\t\t        <div class="item__action">\n\t\t\t\t          <div class="action--comment">\n\t\t\t\t          \t  <a class="btn-blue" href="/edit/' + personaje._id + '">Editar</a>\n\t\t\t\t          \t  <a class="btn-red" href="/delete/' + personaje._id + '">Eliminar</a>\n\t\t\t\t          </div>\n\t\t\t\t        </div>\n\t\t\t      </article>';
  
  	$('#pj_item').append(template);
  }
  
  },{}],4:[function(require,module,exports){
  'use strict';
  
  Object.defineProperty(exports, "__esModule", {
  	value: true
  });
  exports.default = renderEdit;
  function renderEdit(elemento) {
  
  	var personaje = elemento[0];
  
  	var template = '<div class="Personajes-app__form" id="From_edit">\n\t\t\t\t\t      <h2>Editar Personaje</h2>\n\t\t\t\t\t      <form action="" id="Formulario_edit">\n\t\t\t\t\t\t        <div>\n\t\t\t\t\t\t          <label>Nombre:</label>\n\t\t\t\t\t\t          <input type="text" id="personaje_name" value="' + personaje.name + '" placeholder="Nombre del Personaje" name="name" autocomplete="off" required="required"/>\n\t\t\t\t\t\t        </div>\n\t\t\t\t\t\t        <div>\n\t\t\t\t\t\t          <label>Ocupacion del Personaje:</label>\n\t\t\t\t\t\t          <input type="text" id="personaje_occupation" value="' + personaje.occupation + '" placeholder="El personaje es un..." name="occupation" autocomplete="off" required="required"/>\n\t\t\t\t\t\t        </div>\n\t\t\t\t\t\t        <div>\n\t\t\t\t\t\t          <label>Serie, Pelicula o Grupo:</label>\n\t\t\t\t\t\t          <input type="text" id="personaje_group" value="' + personaje.group + '" placeholder="El personaje es de..." name="group" autocomplete="off" required="required"/>\n\t\t\t\t\t\t        </div>\n\t\t\t\t\t\t        <div>\n\t\t\t\t\t              <label>Edad:</label>\n\t\t\t\t\t\t          <input type="text" id="personaje_age" value="' + personaje.age + '" placeholder="Edad del Personaje" name="age" autocomplete="off" required="required"/>\n\t\t\t\t\t\t        </div>\n\t\t\t\t\t\t        <div>\n\t\t\t\t\t\t          <label>Url Imagen:</label>\n\t\t\t\t\t\t          <input type="text" id="personaje_photo" value="' + personaje.photo + '" placeholder="Pega un Enlace/URL de la imagen del Personaje" name="photo" autocomplete="off" required="required"/>\n\t\t\t\t\t            </div>\n\t\t\t\t\t            <a id="btn_send" href="/update/' + personaje._id + '" class="btn_update btn-blue">Guardar Cambios</a>\n\t\t\t\t\t      </form>\n\t\t\t\t\t    </div>';
  
  	$('.Personajes-app__box').append(template);
  	console.log('Render Edit2');
  }
  
  },{}],5:[function(require,module,exports){
  'use strict';
  
  Object.defineProperty(exports, "__esModule", {
  	value: true
  });
  exports.default = renderPersonajes;
  function renderPersonajes(personajes) {
  
  	for (var i = personajes.length - 1; i >= 0; i--) {
  		var personaje = personajes[i];
  
  		var template = '<article class="Personajes-app__read__item">\n\t\t\t\t\t        <div class="item__title">\n\t\t\t\t\t          <h2>' + personaje.name + '</h2>\n\t\t\t\t\t        </div>\n\t\t\t\t\t        <figure class="item__imagen"><img src=" ' + personaje.photo + ' "/></figure>\n\t\t\t\t\t        <div class="item__data">\n\t\t\t\t\t\t          <div class="item__data--rate">\n\t\t\t\t\t\t            <p class="rate__right"> <span class="icon-heart-on"></span><span id="like-cant">7</span>\n\t\t\t\t\t\t              <p>Likes</p>\n\t\t\t\t\t\t            </p>\n\t\t\t\t\t\t            <p class="rate__left"> <span class="icon-bubbles2"> </span><span id="comment-cant">23</span>\n\t\t\t\t\t\t              <p>Comentarios</p>\n\t\t\t\t\t\t            </p>\n\t\t\t\t\t\t          </div>\n\t\t\t\t\t\t          <div class="item__data--author"><strong>By:</strong>\n\t\t\t\t\t\t            <figure><img src="./images/favicon.ico" width="20"/></figure>\n\t\t\t\t\t\t            <p>@joelengt</p>\n\t\t\t\t\t\t          </div>\n\t\t\t\t\t        </div>\n\t\t\t\t\t        <div class="item__detalles">\n\t\t\t\t\t\t          <span>\n\t\t\t\t\t\t          \t  <strong>Serie/Grupo:</strong>\n\t\t\t\t\t\t              <p>' + personaje.group + '</p>\n\t\t\t\t\t              </span>\n\t\t\t\t\t               <span>\n\t\t\t\t\t\t          \t  <strong>Ocupación:</strong>\n\t\t\t\t\t\t              <p>' + personaje.occupation + '</p>\n\t\t\t\t\t              </span>\n\t\t\t\t\t               <span>\n\t\t\t\t\t\t          \t  <strong>Edad:</strong>\n\t\t\t\t\t\t              <p>' + personaje.age + '</p>\n\t\t\t\t\t              </span>\n\t\t\t\t\t        </div>\n\t\t\t\t\t        <div class="item__action">\n\t\t\t\t\t\t          <div class="action--like"><a href="#" class="btn-like  icon-heart-off  color-gray"></a></div>\n\t\t\t\t\t\t          <div class="action--comment">\n\t\t\t\t\t              <input type="text" placeholder="Añade un Comentario..."/>\n\t\t\t\t\t          </div>\n\t\t\t\t\t          <div class="action--settings">\n\t\t\t\t\t\t          <a href="/detalle/' + personaje._id + '" class="icon-settings"></a>\n\t\t\t\t\t          </div>\n\t\t\t\t\t        </div>\n\t\t\t\t      </article>';
  
  		$('#pj_item').append(template);
  	}
  }
  
  },{}],6:[function(require,module,exports){
  'use strict';
  
  var $form_publicar = $('#Formulario_create');
  var $btn_publicar = $('#btn_publicar');
  var $btn_personajes = $('#btn_personajes');
  
  $btn_publicar.on('click', OpenPublicar);
  
  function OpenPublicar() {
  	$form_publicar.slideToggle();
  	return false;
  }
  
  $btn_personajes.on('click', GoPersonajes);
  
  function GoPersonajes() {
  	window.location.href = '/demo';
  }
  
  },{}],7:[function(require,module,exports){
  'use strict';
  
  var $btn_likes_off = document.querySelectorAll('.icon-heart-off');
  var $btn_likes_on = document.querySelectorAll('.icon-heart-on');
  
  for (var i = $btn_likes_off.length - 1; i >= 0; i--) {
  	var el = $btn_likes_off[i];
  	el.addEventListener('click', HeartOn);
  }
  
  for (var i = $btn_likes_on.length - 1; i >= 0; i--) {
  	var el = $btn_likes_on[i];
  	el.addEventListener('click', HeartOff);
  }
  
  function HeartOn() {
  	defaultPrevented();
  	this.parentNode.classList.remove('icon-heart-off');
  	this.parentNode.classList.add('icon-heart-on');
  }
  
  function HeartOff() {
  	defaultPrevented();
  	this.parentNode.classList.add('icon-heart-off');
  	this.parentNode.classList.remove('icon-heart-on');
  }
  
  },{}],8:[function(require,module,exports){
  // shim for using process in browser
  
  var process = module.exports = {};
  var queue = [];
  var draining = false;
  var currentQueue;
  var queueIndex = -1;
  
  function cleanUpNextTick() {
      draining = false;
      if (currentQueue.length) {
          queue = currentQueue.concat(queue);
      } else {
          queueIndex = -1;
      }
      if (queue.length) {
          drainQueue();
      }
  }
  
  function drainQueue() {
      if (draining) {
          return;
      }
      var timeout = setTimeout(cleanUpNextTick);
      draining = true;
  
      var len = queue.length;
      while(len) {
          currentQueue = queue;
          queue = [];
          while (++queueIndex < len) {
              if (currentQueue) {
                  currentQueue[queueIndex].run();
              }
          }
          queueIndex = -1;
          len = queue.length;
      }
      currentQueue = null;
      draining = false;
      clearTimeout(timeout);
  }
  
  process.nextTick = function (fun) {
      var args = new Array(arguments.length - 1);
      if (arguments.length > 1) {
          for (var i = 1; i < arguments.length; i++) {
              args[i - 1] = arguments[i];
          }
      }
      queue.push(new Item(fun, args));
      if (queue.length === 1 && !draining) {
          setTimeout(drainQueue, 0);
      }
  };
  
  // v8 likes predictible objects
  function Item(fun, array) {
      this.fun = fun;
      this.array = array;
  }
  Item.prototype.run = function () {
      this.fun.apply(null, this.array);
  };
  process.title = 'browser';
  process.browser = true;
  process.env = {};
  process.argv = [];
  process.version = ''; // empty string to avoid regexp issues
  process.versions = {};
  
  function noop() {}
  
  process.on = noop;
  process.addListener = noop;
  process.once = noop;
  process.off = noop;
  process.removeListener = noop;
  process.removeAllListeners = noop;
  process.emit = noop;
  
  process.binding = function (name) {
      throw new Error('process.binding is not supported');
  };
  
  process.cwd = function () { return '/' };
  process.chdir = function (dir) {
      throw new Error('process.chdir is not supported');
  };
  process.umask = function() { return 0; };
  
  },{}],9:[function(require,module,exports){
  (function (process){
    /* globals require, module */
  
    'use strict';
  
    /**
     * Module dependencies.
     */
  
    var pathtoRegexp = require('path-to-regexp');
  
    /**
     * Module exports.
     */
  
    module.exports = page;
  
    /**
     * Detect click event
     */
    var clickEvent = ('undefined' !== typeof document) && document.ontouchstart ? 'touchstart' : 'click';
  
    /**
     * To work properly with the URL
     * history.location generated polyfill in https://github.com/devote/HTML5-History-API
     */
  
    var location = ('undefined' !== typeof window) && (window.history.location || window.location);
  
    /**
     * Perform initial dispatch.
     */
  
    var dispatch = true;
  
  
    /**
     * Decode URL components (query string, pathname, hash).
     * Accommodates both regular percent encoding and x-www-form-urlencoded format.
     */
    var decodeURLComponents = true;
  
    /**
     * Base path.
     */
  
    var base = '';
  
    /**
     * Running flag.
     */
  
    var running;
  
    /**
     * HashBang option
     */
  
    var hashbang = false;
  
    /**
     * Previous context, for capturing
     * page exit events.
     */
  
    var prevContext;
  
    /**
     * Register `path` with callback `fn()`,
     * or route `path`, or redirection,
     * or `page.start()`.
     *
     *   page(fn);
     *   page('*', fn);
     *   page('/user/:id', load, user);
     *   page('/user/' + user.id, { some: 'thing' });
     *   page('/user/' + user.id);
     *   page('/from', '/to')
     *   page();
     *
     * @param {string|!Function|!Object} path
     * @param {Function=} fn
     * @api public
     */
  
    function page(path, fn) {
      // <callback>
      if ('function' === typeof path) {
        return page('*', path);
      }
  
      // route <path> to <callback ...>
      if ('function' === typeof fn) {
        var route = new Route(/** @type {string} */ (path));
        for (var i = 1; i < arguments.length; ++i) {
          page.callbacks.push(route.middleware(arguments[i]));
        }
        // show <path> with [state]
      } else if ('string' === typeof path) {
        page['string' === typeof fn ? 'redirect' : 'show'](path, fn);
        // start [options]
      } else {
        page.start(path);
      }
    }
  
    /**
     * Callback functions.
     */
  
    page.callbacks = [];
    page.exits = [];
  
    /**
     * Current path being processed
     * @type {string}
     */
    page.current = '';
  
    /**
     * Number of pages navigated to.
     * @type {number}
     *
     *     page.len == 0;
     *     page('/login');
     *     page.len == 1;
     */
  
    page.len = 0;
  
    /**
     * Get or set basepath to `path`.
     *
     * @param {string} path
     * @api public
     */
  
    page.base = function(path) {
      if (0 === arguments.length) return base;
      base = path;
    };
  
    /**
     * Bind with the given `options`.
     *
     * Options:
     *
     *    - `click` bind to click events [true]
     *    - `popstate` bind to popstate [true]
     *    - `dispatch` perform initial dispatch [true]
     *
     * @param {Object} options
     * @api public
     */
  
    page.start = function(options) {
      options = options || {};
      if (running) return;
      running = true;
      if (false === options.dispatch) dispatch = false;
      if (false === options.decodeURLComponents) decodeURLComponents = false;
      if (false !== options.popstate) window.addEventListener('popstate', onpopstate, false);
      if (false !== options.click) {
        document.addEventListener(clickEvent, onclick, false);
      }
      if (true === options.hashbang) hashbang = true;
      if (!dispatch) return;
      var url = (hashbang && ~location.hash.indexOf('#!')) ? location.hash.substr(2) + location.search : location.pathname + location.search + location.hash;
      page.replace(url, null, true, dispatch);
    };
  
    /**
     * Unbind click and popstate event handlers.
     *
     * @api public
     */
  
    page.stop = function() {
      if (!running) return;
      page.current = '';
      page.len = 0;
      running = false;
      document.removeEventListener(clickEvent, onclick, false);
      window.removeEventListener('popstate', onpopstate, false);
    };
  
    /**
     * Show `path` with optional `state` object.
     *
     * @param {string} path
     * @param {Object=} state
     * @param {boolean=} dispatch
     * @param {boolean=} push
     * @return {!Context}
     * @api public
     */
  
    page.show = function(path, state, dispatch, push) {
      var ctx = new Context(path, state);
      page.current = ctx.path;
      if (false !== dispatch) page.dispatch(ctx);
      if (false !== ctx.handled && false !== push) ctx.pushState();
      return ctx;
    };
  
    /**
     * Goes back in the history
     * Back should always let the current route push state and then go back.
     *
     * @param {string} path - fallback path to go back if no more history exists, if undefined defaults to page.base
     * @param {Object=} state
     * @api public
     */
  
    page.back = function(path, state) {
      if (page.len > 0) {
        // this may need more testing to see if all browsers
        // wait for the next tick to go back in history
        history.back();
        page.len--;
      } else if (path) {
        setTimeout(function() {
          page.show(path, state);
        });
      }else{
        setTimeout(function() {
          page.show(base, state);
        });
      }
    };
  
  
    /**
     * Register route to redirect from one path to other
     * or just redirect to another route
     *
     * @param {string} from - if param 'to' is undefined redirects to 'from'
     * @param {string=} to
     * @api public
     */
    page.redirect = function(from, to) {
      // Define route from a path to another
      if ('string' === typeof from && 'string' === typeof to) {
        page(from, function(e) {
          setTimeout(function() {
            page.replace(/** @type {!string} */ (to));
          }, 0);
        });
      }
  
      // Wait for the push state and replace it with another
      if ('string' === typeof from && 'undefined' === typeof to) {
        setTimeout(function() {
          page.replace(from);
        }, 0);
      }
    };
  
    /**
     * Replace `path` with optional `state` object.
     *
     * @param {string} path
     * @param {Object=} state
     * @param {boolean=} init
     * @param {boolean=} dispatch
     * @return {!Context}
     * @api public
     */
  
  
    page.replace = function(path, state, init, dispatch) {
      var ctx = new Context(path, state);
      page.current = ctx.path;
      ctx.init = init;
      ctx.save(); // save before dispatching, which may redirect
      if (false !== dispatch) page.dispatch(ctx);
      return ctx;
    };
  
    /**
     * Dispatch the given `ctx`.
     *
     * @param {Context} ctx
     * @api private
     */
    page.dispatch = function(ctx) {
      var prev = prevContext,
        i = 0,
        j = 0;
  
      prevContext = ctx;
  
      function nextExit() {
        var fn = page.exits[j++];
        if (!fn) return nextEnter();
        fn(prev, nextExit);
      }
  
      function nextEnter() {
        var fn = page.callbacks[i++];
  
        if (ctx.path !== page.current) {
          ctx.handled = false;
          return;
        }
        if (!fn) return unhandled(ctx);
        fn(ctx, nextEnter);
      }
  
      if (prev) {
        nextExit();
      } else {
        nextEnter();
      }
    };
  
    /**
     * Unhandled `ctx`. When it's not the initial
     * popstate then redirect. If you wish to handle
     * 404s on your own use `page('*', callback)`.
     *
     * @param {Context} ctx
     * @api private
     */
    function unhandled(ctx) {
      if (ctx.handled) return;
      var current;
  
      if (hashbang) {
        current = base + location.hash.replace('#!', '');
      } else {
        current = location.pathname + location.search;
      }
  
      if (current === ctx.canonicalPath) return;
      page.stop();
      ctx.handled = false;
      location.href = ctx.canonicalPath;
    }
  
    /**
     * Register an exit route on `path` with
     * callback `fn()`, which will be called
     * on the previous context when a new
     * page is visited.
     */
    page.exit = function(path, fn) {
      if (typeof path === 'function') {
        return page.exit('*', path);
      }
  
      var route = new Route(path);
      for (var i = 1; i < arguments.length; ++i) {
        page.exits.push(route.middleware(arguments[i]));
      }
    };
  
    /**
     * Remove URL encoding from the given `str`.
     * Accommodates whitespace in both x-www-form-urlencoded
     * and regular percent-encoded form.
     *
     * @param {string} val - URL component to decode
     */
    function decodeURLEncodedURIComponent(val) {
      if (typeof val !== 'string') { return val; }
      return decodeURLComponents ? decodeURIComponent(val.replace(/\+/g, ' ')) : val;
    }
  
    /**
     * Initialize a new "request" `Context`
     * with the given `path` and optional initial `state`.
     *
     * @constructor
     * @param {string} path
     * @param {Object=} state
     * @api public
     */
  
    function Context(path, state) {
      if ('/' === path[0] && 0 !== path.indexOf(base)) path = base + (hashbang ? '#!' : '') + path;
      var i = path.indexOf('?');
  
      this.canonicalPath = path;
      this.path = path.replace(base, '') || '/';
      if (hashbang) this.path = this.path.replace('#!', '') || '/';
  
      this.title = document.title;
      this.state = state || {};
      this.state.path = path;
      this.querystring = ~i ? decodeURLEncodedURIComponent(path.slice(i + 1)) : '';
      this.pathname = decodeURLEncodedURIComponent(~i ? path.slice(0, i) : path);
      this.params = {};
  
      // fragment
      this.hash = '';
      if (!hashbang) {
        if (!~this.path.indexOf('#')) return;
        var parts = this.path.split('#');
        this.path = parts[0];
        this.hash = decodeURLEncodedURIComponent(parts[1]) || '';
        this.querystring = this.querystring.split('#')[0];
      }
    }
  
    /**
     * Expose `Context`.
     */
  
    page.Context = Context;
  
    /**
     * Push state.
     *
     * @api private
     */
  
    Context.prototype.pushState = function() {
      page.len++;
      history.pushState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
    };
  
    /**
     * Save the context state.
     *
     * @api public
     */
  
    Context.prototype.save = function() {
      history.replaceState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
    };
  
    /**
     * Initialize `Route` with the given HTTP `path`,
     * and an array of `callbacks` and `options`.
     *
     * Options:
     *
     *   - `sensitive`    enable case-sensitive routes
     *   - `strict`       enable strict matching for trailing slashes
     *
     * @constructor
     * @param {string} path
     * @param {Object=} options
     * @api private
     */
  
    function Route(path, options) {
      options = options || {};
      this.path = (path === '*') ? '(.*)' : path;
      this.method = 'GET';
      this.regexp = pathtoRegexp(this.path,
        this.keys = [],
        options);
    }
  
    /**
     * Expose `Route`.
     */
  
    page.Route = Route;
  
    /**
     * Return route middleware with
     * the given callback `fn()`.
     *
     * @param {Function} fn
     * @return {Function}
     * @api public
     */
  
    Route.prototype.middleware = function(fn) {
      var self = this;
      return function(ctx, next) {
        if (self.match(ctx.path, ctx.params)) return fn(ctx, next);
        next();
      };
    };
  
    /**
     * Check if this route matches `path`, if so
     * populate `params`.
     *
     * @param {string} path
     * @param {Object} params
     * @return {boolean}
     * @api private
     */
  
    Route.prototype.match = function(path, params) {
      var keys = this.keys,
        qsIndex = path.indexOf('?'),
        pathname = ~qsIndex ? path.slice(0, qsIndex) : path,
        m = this.regexp.exec(decodeURIComponent(pathname));
  
      if (!m) return false;
  
      for (var i = 1, len = m.length; i < len; ++i) {
        var key = keys[i - 1];
        var val = decodeURLEncodedURIComponent(m[i]);
        if (val !== undefined || !(hasOwnProperty.call(params, key.name))) {
          params[key.name] = val;
        }
      }
  
      return true;
    };
  
  
    /**
     * Handle "populate" events.
     */
  
    var onpopstate = (function () {
      var loaded = false;
      if ('undefined' === typeof window) {
        return;
      }
      if (document.readyState === 'complete') {
        loaded = true;
      } else {
        window.addEventListener('load', function() {
          setTimeout(function() {
            loaded = true;
          }, 0);
        });
      }
      return function onpopstate(e) {
        if (!loaded) return;
        if (e.state) {
          var path = e.state.path;
          page.replace(path, e.state);
        } else {
          page.show(location.pathname + location.hash, undefined, undefined, false);
        }
      };
    })();
    /**
     * Handle "click" events.
     */
  
    function onclick(e) {
  
      if (1 !== which(e)) return;
  
      if (e.metaKey || e.ctrlKey || e.shiftKey) return;
      if (e.defaultPrevented) return;
  
  
  
      // ensure link
      // use shadow dom when available
      var el = e.path ? e.path[0] : e.target;
      while (el && 'A' !== el.nodeName) el = el.parentNode;
      if (!el || 'A' !== el.nodeName) return;
  
  
  
      // Ignore if tag has
      // 1. "download" attribute
      // 2. rel="external" attribute
      if (el.hasAttribute('download') || el.getAttribute('rel') === 'external') return;
  
      // ensure non-hash for the same path
      var link = el.getAttribute('href');
      if (!hashbang && el.pathname === location.pathname && (el.hash || '#' === link)) return;
  
  
  
      // Check for mailto: in the href
      if (link && link.indexOf('mailto:') > -1) return;
  
      // check target
      if (el.target) return;
  
      // x-origin
      if (!sameOrigin(el.href)) return;
  
  
  
      // rebuild path
      var path = el.pathname + el.search + (el.hash || '');
  
      // strip leading "/[drive letter]:" on NW.js on Windows
      if (typeof process !== 'undefined' && path.match(/^\/[a-zA-Z]:\//)) {
        path = path.replace(/^\/[a-zA-Z]:\//, '/');
      }
  
      // same page
      var orig = path;
  
      if (path.indexOf(base) === 0) {
        path = path.substr(base.length);
      }
  
      if (hashbang) path = path.replace('#!', '');
  
      if (base && orig === path) return;
  
      e.preventDefault();
      page.show(orig);
    }
  
    /**
     * Event button.
     */
  
    function which(e) {
      e = e || window.event;
      return null === e.which ? e.button : e.which;
    }
  
    /**
     * Check if `href` is the same origin.
     */
  
    function sameOrigin(href) {
      var origin = location.protocol + '//' + location.hostname;
      if (location.port) origin += ':' + location.port;
      return (href && (0 === href.indexOf(origin)));
    }
  
    page.sameOrigin = sameOrigin;
  
  }).call(this,require('_process'))
  },{"_process":8,"path-to-regexp":10}],10:[function(require,module,exports){
  var isarray = require('isarray')
  
  /**
   * Expose `pathToRegexp`.
   */
  module.exports = pathToRegexp
  module.exports.parse = parse
  module.exports.compile = compile
  module.exports.tokensToFunction = tokensToFunction
  module.exports.tokensToRegExp = tokensToRegExp
  
  /**
   * The main path matching regexp utility.
   *
   * @type {RegExp}
   */
  var PATH_REGEXP = new RegExp([
    // Match escaped characters that would otherwise appear in future matches.
    // This allows the user to escape special characters that won't transform.
    '(\\\\.)',
    // Match Express-style parameters and un-named parameters with a prefix
    // and optional suffixes. Matches appear as:
    //
    // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
    // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined, undefined]
    // "/*"            => ["/", undefined, undefined, undefined, undefined, "*"]
    '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))'
  ].join('|'), 'g')
  
  /**
   * Parse a string for the raw tokens.
   *
   * @param  {String} str
   * @return {Array}
   */
  function parse (str) {
    var tokens = []
    var key = 0
    var index = 0
    var path = ''
    var res
  
    while ((res = PATH_REGEXP.exec(str)) != null) {
      var m = res[0]
      var escaped = res[1]
      var offset = res.index
      path += str.slice(index, offset)
      index = offset + m.length
  
      // Ignore already escaped sequences.
      if (escaped) {
        path += escaped[1]
        continue
      }
  
      // Push the current path onto the tokens.
      if (path) {
        tokens.push(path)
        path = ''
      }
  
      var prefix = res[2]
      var name = res[3]
      var capture = res[4]
      var group = res[5]
      var suffix = res[6]
      var asterisk = res[7]
  
      var repeat = suffix === '+' || suffix === '*'
      var optional = suffix === '?' || suffix === '*'
      var delimiter = prefix || '/'
      var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')
  
      tokens.push({
        name: name || key++,
        prefix: prefix || '',
        delimiter: delimiter,
        optional: optional,
        repeat: repeat,
        pattern: escapeGroup(pattern)
      })
    }
  
    // Match any characters still remaining.
    if (index < str.length) {
      path += str.substr(index)
    }
  
    // If the path exists, push it onto the end.
    if (path) {
      tokens.push(path)
    }
  
    return tokens
  }
  
  /**
   * Compile a string to a template function for the path.
   *
   * @param  {String}   str
   * @return {Function}
   */
  function compile (str) {
    return tokensToFunction(parse(str))
  }
  
  /**
   * Expose a method for transforming tokens into the path function.
   */
  function tokensToFunction (tokens) {
    // Compile all the tokens into regexps.
    var matches = new Array(tokens.length)
  
    // Compile all the patterns before compilation.
    for (var i = 0; i < tokens.length; i++) {
      if (typeof tokens[i] === 'object') {
        matches[i] = new RegExp('^' + tokens[i].pattern + '$')
      }
    }
  
    return function (obj) {
      var path = ''
      var data = obj || {}
  
      for (var i = 0; i < tokens.length; i++) {
        var token = tokens[i]
  
        if (typeof token === 'string') {
          path += token
  
          continue
        }
  
        var value = data[token.name]
        var segment
  
        if (value == null) {
          if (token.optional) {
            continue
          } else {
            throw new TypeError('Expected "' + token.name + '" to be defined')
          }
        }
  
        if (isarray(value)) {
          if (!token.repeat) {
            throw new TypeError('Expected "' + token.name + '" to not repeat, but received "' + value + '"')
          }
  
          if (value.length === 0) {
            if (token.optional) {
              continue
            } else {
              throw new TypeError('Expected "' + token.name + '" to not be empty')
            }
          }
  
          for (var j = 0; j < value.length; j++) {
            segment = encodeURIComponent(value[j])
  
            if (!matches[i].test(segment)) {
              throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
            }
  
            path += (j === 0 ? token.prefix : token.delimiter) + segment
          }
  
          continue
        }
  
        segment = encodeURIComponent(value)
  
        if (!matches[i].test(segment)) {
          throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
        }
  
        path += token.prefix + segment
      }
  
      return path
    }
  }
  
  /**
   * Escape a regular expression string.
   *
   * @param  {String} str
   * @return {String}
   */
  function escapeString (str) {
    return str.replace(/([.+*?=^!:${}()[\]|\/])/g, '\\$1')
  }
  
  /**
   * Escape the capturing group by escaping special characters and meaning.
   *
   * @param  {String} group
   * @return {String}
   */
  function escapeGroup (group) {
    return group.replace(/([=!:$\/()])/g, '\\$1')
  }
  
  /**
   * Attach the keys as a property of the regexp.
   *
   * @param  {RegExp} re
   * @param  {Array}  keys
   * @return {RegExp}
   */
  function attachKeys (re, keys) {
    re.keys = keys
    return re
  }
  
  /**
   * Get the flags for a regexp from the options.
   *
   * @param  {Object} options
   * @return {String}
   */
  function flags (options) {
    return options.sensitive ? '' : 'i'
  }
  
  /**
   * Pull out keys from a regexp.
   *
   * @param  {RegExp} path
   * @param  {Array}  keys
   * @return {RegExp}
   */
  function regexpToRegexp (path, keys) {
    // Use a negative lookahead to match only capturing groups.
    var groups = path.source.match(/\((?!\?)/g)
  
    if (groups) {
      for (var i = 0; i < groups.length; i++) {
        keys.push({
          name: i,
          prefix: null,
          delimiter: null,
          optional: false,
          repeat: false,
          pattern: null
        })
      }
    }
  
    return attachKeys(path, keys)
  }
  
  /**
   * Transform an array into a regexp.
   *
   * @param  {Array}  path
   * @param  {Array}  keys
   * @param  {Object} options
   * @return {RegExp}
   */
  function arrayToRegexp (path, keys, options) {
    var parts = []
  
    for (var i = 0; i < path.length; i++) {
      parts.push(pathToRegexp(path[i], keys, options).source)
    }
  
    var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
  
    return attachKeys(regexp, keys)
  }
  
  /**
   * Create a path regexp from string input.
   *
   * @param  {String} path
   * @param  {Array}  keys
   * @param  {Object} options
   * @return {RegExp}
   */
  function stringToRegexp (path, keys, options) {
    var tokens = parse(path)
    var re = tokensToRegExp(tokens, options)
  
    // Attach keys back to the regexp.
    for (var i = 0; i < tokens.length; i++) {
      if (typeof tokens[i] !== 'string') {
        keys.push(tokens[i])
      }
    }
  
    return attachKeys(re, keys)
  }
  
  /**
   * Expose a function for taking tokens and returning a RegExp.
   *
   * @param  {Array}  tokens
   * @param  {Array}  keys
   * @param  {Object} options
   * @return {RegExp}
   */
  function tokensToRegExp (tokens, options) {
    options = options || {}
  
    var strict = options.strict
    var end = options.end !== false
    var route = ''
    var lastToken = tokens[tokens.length - 1]
    var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)
  
    // Iterate over the tokens and create our regexp string.
    for (var i = 0; i < tokens.length; i++) {
      var token = tokens[i]
  
      if (typeof token === 'string') {
        route += escapeString(token)
      } else {
        var prefix = escapeString(token.prefix)
        var capture = token.pattern
  
        if (token.repeat) {
          capture += '(?:' + prefix + capture + ')*'
        }
  
        if (token.optional) {
          if (prefix) {
            capture = '(?:' + prefix + '(' + capture + '))?'
          } else {
            capture = '(' + capture + ')?'
          }
        } else {
          capture = prefix + '(' + capture + ')'
        }
  
        route += capture
      }
    }
  
    // In non-strict mode we allow a slash at the end of match. If the path to
    // match already ends with a slash, we remove it for consistency. The slash
    // is valid at the end of a path match, not in the middle. This is important
    // in non-ending mode, where "/test/" shouldn't match "/test//route".
    if (!strict) {
      route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'
    }
  
    if (end) {
      route += '$'
    } else {
      // In non-ending mode, we need the capturing groups to match as much as
      // possible by using a positive lookahead to the end or next path segment.
      route += strict && endsWithSlash ? '' : '(?=\\/|$)'
    }
  
    return new RegExp('^' + route, flags(options))
  }
  
  /**
   * Normalize the given path string, returning a regular expression.
   *
   * An empty array can be passed in for the keys, which will hold the
   * placeholder key descriptions. For example, using `/user/:id`, `keys` will
   * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
   *
   * @param  {(String|RegExp|Array)} path
   * @param  {Array}                 [keys]
   * @param  {Object}                [options]
   * @return {RegExp}
   */
  function pathToRegexp (path, keys, options) {
    keys = keys || []
  
    if (!isarray(keys)) {
      options = keys
      keys = []
    } else if (!options) {
      options = {}
    }
  
    if (path instanceof RegExp) {
      return regexpToRegexp(path, keys, options)
    }
  
    if (isarray(path)) {
      return arrayToRegexp(path, keys, options)
    }
  
    return stringToRegexp(path, keys, options)
  }
  
  },{"isarray":11}],11:[function(require,module,exports){
  module.exports = Array.isArray || function (arr) {
    return Object.prototype.toString.call(arr) == '[object Array]';
  };
  
  },{}]},{},[2]);
  