Index: frontend/node_modules/parseurl/index.js
===================================================================
--- frontend/node_modules/parseurl/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/parseurl/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,158 @@
+/*!
+ * parseurl
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2014-2017 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var url = require('url')
+var parse = url.parse
+var Url = url.Url
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = parseurl
+module.exports.original = originalurl
+
+/**
+ * Parse the `req` url with memoization.
+ *
+ * @param {ServerRequest} req
+ * @return {Object}
+ * @public
+ */
+
+function parseurl (req) {
+  var url = req.url
+
+  if (url === undefined) {
+    // URL is undefined
+    return undefined
+  }
+
+  var parsed = req._parsedUrl
+
+  if (fresh(url, parsed)) {
+    // Return cached URL parse
+    return parsed
+  }
+
+  // Parse the URL
+  parsed = fastparse(url)
+  parsed._raw = url
+
+  return (req._parsedUrl = parsed)
+};
+
+/**
+ * Parse the `req` original url with fallback and memoization.
+ *
+ * @param {ServerRequest} req
+ * @return {Object}
+ * @public
+ */
+
+function originalurl (req) {
+  var url = req.originalUrl
+
+  if (typeof url !== 'string') {
+    // Fallback
+    return parseurl(req)
+  }
+
+  var parsed = req._parsedOriginalUrl
+
+  if (fresh(url, parsed)) {
+    // Return cached URL parse
+    return parsed
+  }
+
+  // Parse the URL
+  parsed = fastparse(url)
+  parsed._raw = url
+
+  return (req._parsedOriginalUrl = parsed)
+};
+
+/**
+ * Parse the `str` url with fast-path short-cut.
+ *
+ * @param {string} str
+ * @return {Object}
+ * @private
+ */
+
+function fastparse (str) {
+  if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) {
+    return parse(str)
+  }
+
+  var pathname = str
+  var query = null
+  var search = null
+
+  // This takes the regexp from https://github.com/joyent/node/pull/7878
+  // Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/
+  // And unrolls it into a for loop
+  for (var i = 1; i < str.length; i++) {
+    switch (str.charCodeAt(i)) {
+      case 0x3f: /* ?  */
+        if (search === null) {
+          pathname = str.substring(0, i)
+          query = str.substring(i + 1)
+          search = str.substring(i)
+        }
+        break
+      case 0x09: /* \t */
+      case 0x0a: /* \n */
+      case 0x0c: /* \f */
+      case 0x0d: /* \r */
+      case 0x20: /*    */
+      case 0x23: /* #  */
+      case 0xa0:
+      case 0xfeff:
+        return parse(str)
+    }
+  }
+
+  var url = Url !== undefined
+    ? new Url()
+    : {}
+
+  url.path = str
+  url.href = str
+  url.pathname = pathname
+
+  if (search !== null) {
+    url.query = query
+    url.search = search
+  }
+
+  return url
+}
+
+/**
+ * Determine if parsed is still fresh for url.
+ *
+ * @param {string} url
+ * @param {object} parsedUrl
+ * @return {boolean}
+ * @private
+ */
+
+function fresh (url, parsedUrl) {
+  return typeof parsedUrl === 'object' &&
+    parsedUrl !== null &&
+    (Url === undefined || parsedUrl instanceof Url) &&
+    parsedUrl._raw === url
+}
