{"version":3,"sources":["jsdelivr-header.js","/npm/find-my-way@9.3.0/index.js"],"names":[],"mappings":"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","file":"/npm/find-my-way@9.3.0/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/find-my-way@9.3.0/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict'\n\n/*\n  Char codes:\n    '!': 33 - !\n    '#': 35 - %23\n    '$': 36 - %24\n    '%': 37 - %25\n    '&': 38 - %26\n    ''': 39 - '\n    '(': 40 - (\n    ')': 41 - )\n    '*': 42 - *\n    '+': 43 - %2B\n    ',': 44 - %2C\n    '-': 45 - -\n    '.': 46 - .\n    '/': 47 - %2F\n    ':': 58 - %3A\n    ';': 59 - %3B\n    '=': 61 - %3D\n    '?': 63 - %3F\n    '@': 64 - %40\n    '_': 95 - _\n    '~': 126 - ~\n*/\n\nconst assert = require('node:assert')\nconst querystring = require('fast-querystring')\nconst isRegexSafe = require('safe-regex2')\nconst deepEqual = require('fast-deep-equal')\nconst { prettyPrintTree } = require('./lib/pretty-print')\nconst { StaticNode, NODE_TYPES } = require('./lib/node')\nconst Constrainer = require('./lib/constrainer')\nconst httpMethods = require('./lib/http-methods')\nconst httpMethodStrategy = require('./lib/strategies/http-method')\nconst { safeDecodeURI, safeDecodeURIComponent } = require('./lib/url-sanitizer')\n\nconst FULL_PATH_REGEXP = /^https?:\\/\\/.*?\\//\nconst OPTIONAL_PARAM_REGEXP = /(\\/:[^/()]*?)\\?(\\/?)/\nconst ESCAPE_REGEXP = /[.*+?^${}()|[\\]\\\\]/g\nconst REMOVE_DUPLICATE_SLASHES_REGEXP = /\\/\\/+/g\n\nif (!isRegexSafe(FULL_PATH_REGEXP)) {\n  throw new Error('the FULL_PATH_REGEXP is not safe, update this module')\n}\n\nif (!isRegexSafe(OPTIONAL_PARAM_REGEXP)) {\n  throw new Error('the OPTIONAL_PARAM_REGEXP is not safe, update this module')\n}\n\nif (!isRegexSafe(ESCAPE_REGEXP)) {\n  throw new Error('the ESCAPE_REGEXP is not safe, update this module')\n}\n\nif (!isRegexSafe(REMOVE_DUPLICATE_SLASHES_REGEXP)) {\n  throw new Error('the REMOVE_DUPLICATE_SLASHES_REGEXP is not safe, update this module')\n}\n\nfunction Router (opts) {\n  if (!(this instanceof Router)) {\n    return new Router(opts)\n  }\n  opts = opts || {}\n  this._opts = opts\n\n  if (opts.defaultRoute) {\n    assert(typeof opts.defaultRoute === 'function', 'The default route must be a function')\n    this.defaultRoute = opts.defaultRoute\n  } else {\n    this.defaultRoute = null\n  }\n\n  if (opts.onBadUrl) {\n    assert(typeof opts.onBadUrl === 'function', 'The bad url handler must be a function')\n    this.onBadUrl = opts.onBadUrl\n  } else {\n    this.onBadUrl = null\n  }\n\n  if (opts.buildPrettyMeta) {\n    assert(typeof opts.buildPrettyMeta === 'function', 'buildPrettyMeta must be a function')\n    this.buildPrettyMeta = opts.buildPrettyMeta\n  } else {\n    this.buildPrettyMeta = defaultBuildPrettyMeta\n  }\n\n  if (opts.querystringParser) {\n    assert(typeof opts.querystringParser === 'function', 'querystringParser must be a function')\n    this.querystringParser = opts.querystringParser\n  } else {\n    this.querystringParser = (query) => query.length === 0 ? {} : querystring.parse(query)\n  }\n\n  this.caseSensitive = opts.caseSensitive === undefined ? true : opts.caseSensitive\n  this.ignoreTrailingSlash = opts.ignoreTrailingSlash || false\n  this.ignoreDuplicateSlashes = opts.ignoreDuplicateSlashes || false\n  this.maxParamLength = opts.maxParamLength || 100\n  this.allowUnsafeRegex = opts.allowUnsafeRegex || false\n  this.constrainer = new Constrainer(opts.constraints)\n  this.useSemicolonDelimiter = opts.useSemicolonDelimiter || false\n\n  this.routes = []\n  this.trees = {}\n}\n\nRouter.prototype.on = function on (method, path, opts, handler, store) {\n  if (typeof opts === 'function') {\n    if (handler !== undefined) {\n      store = handler\n    }\n    handler = opts\n    opts = {}\n  }\n  // path validation\n  assert(typeof path === 'string', 'Path should be a string')\n  assert(path.length > 0, 'The path could not be empty')\n  assert(path[0] === '/' || path[0] === '*', 'The first character of a path should be `/` or `*`')\n  // handler validation\n  assert(typeof handler === 'function', 'Handler should be a function')\n\n  // path ends with optional parameter\n  const optionalParamMatch = path.match(OPTIONAL_PARAM_REGEXP)\n  if (optionalParamMatch) {\n    assert(path.length === optionalParamMatch.index + optionalParamMatch[0].length, 'Optional Parameter needs to be the last parameter of the path')\n\n    const pathFull = path.replace(OPTIONAL_PARAM_REGEXP, '$1$2')\n    const pathOptional = path.replace(OPTIONAL_PARAM_REGEXP, '$2') || '/'\n\n    this.on(method, pathFull, opts, handler, store)\n    this.on(method, pathOptional, opts, handler, store)\n    return\n  }\n\n  const route = path\n\n  if (this.ignoreDuplicateSlashes) {\n    path = removeDuplicateSlashes(path)\n  }\n\n  if (this.ignoreTrailingSlash) {\n    path = trimLastSlash(path)\n  }\n\n  const methods = Array.isArray(method) ? method : [method]\n  for (const method of methods) {\n    assert(typeof method === 'string', 'Method should be a string')\n    assert(httpMethods.includes(method), `Method '${method}' is not an http method.`)\n    this._on(method, path, opts, handler, store, route)\n  }\n}\n\nRouter.prototype._on = function _on (method, path, opts, handler, store) {\n  let constraints = {}\n  if (opts.constraints !== undefined) {\n    assert(typeof opts.constraints === 'object' && opts.constraints !== null, 'Constraints should be an object')\n    if (Object.keys(opts.constraints).length !== 0) {\n      constraints = opts.constraints\n    }\n  }\n\n  this.constrainer.validateConstraints(constraints)\n  // Let the constrainer know if any constraints are being used now\n  this.constrainer.noteUsage(constraints)\n\n  // Boot the tree for this method if it doesn't exist yet\n  if (this.trees[method] === undefined) {\n    this.trees[method] = new StaticNode('/')\n  }\n\n  let pattern = path\n  if (pattern === '*' && this.trees[method].prefix.length !== 0) {\n    const currentRoot = this.trees[method]\n    this.trees[method] = new StaticNode('')\n    this.trees[method].staticChildren['/'] = currentRoot\n  }\n\n  let currentNode = this.trees[method]\n  let parentNodePathIndex = currentNode.prefix.length\n\n  const params = []\n  for (let i = 0; i <= pattern.length; i++) {\n    if (pattern.charCodeAt(i) === 58 && pattern.charCodeAt(i + 1) === 58) {\n      // It's a double colon\n      i++\n      continue\n    }\n\n    const isParametricNode = pattern.charCodeAt(i) === 58 && pattern.charCodeAt(i + 1) !== 58\n    const isWildcardNode = pattern.charCodeAt(i) === 42\n\n    if (isParametricNode || isWildcardNode || (i === pattern.length && i !== parentNodePathIndex)) {\n      let staticNodePath = pattern.slice(parentNodePathIndex, i)\n      if (!this.caseSensitive) {\n        staticNodePath = staticNodePath.toLowerCase()\n      }\n      staticNodePath = staticNodePath.replaceAll('::', ':')\n      staticNodePath = staticNodePath.replaceAll('%', '%25')\n      // add the static part of the route to the tree\n      currentNode = currentNode.createStaticChild(staticNodePath)\n    }\n\n    if (isParametricNode) {\n      let isRegexNode = false\n      let isParamSafe = true\n      let backtrack = ''\n      const regexps = []\n\n      let lastParamStartIndex = i + 1\n      for (let j = lastParamStartIndex; ; j++) {\n        const charCode = pattern.charCodeAt(j)\n\n        const isRegexParam = charCode === 40\n        const isStaticPart = charCode === 45 || charCode === 46\n        const isEndOfNode = charCode === 47 || j === pattern.length\n\n        if (isRegexParam || isStaticPart || isEndOfNode) {\n          const paramName = pattern.slice(lastParamStartIndex, j)\n          params.push(paramName)\n\n          isRegexNode = isRegexNode || isRegexParam || isStaticPart\n\n          if (isRegexParam) {\n            const endOfRegexIndex = getClosingParenthensePosition(pattern, j)\n            const regexString = pattern.slice(j, endOfRegexIndex + 1)\n\n            if (!this.allowUnsafeRegex) {\n              assert(isRegexSafe(new RegExp(regexString)), `The regex '${regexString}' is not safe!`)\n            }\n\n            regexps.push(trimRegExpStartAndEnd(regexString))\n\n            j = endOfRegexIndex + 1\n            isParamSafe = true\n          } else {\n            regexps.push(isParamSafe ? '(.*?)' : `(${backtrack}|(?:(?!${backtrack}).)*)`)\n            isParamSafe = false\n          }\n\n          const staticPartStartIndex = j\n          for (; j < pattern.length; j++) {\n            const charCode = pattern.charCodeAt(j)\n            if (charCode === 47) break\n            if (charCode === 58) {\n              const nextCharCode = pattern.charCodeAt(j + 1)\n              if (nextCharCode === 58) j++\n              else break\n            }\n          }\n\n          let staticPart = pattern.slice(staticPartStartIndex, j)\n          if (staticPart) {\n            staticPart = staticPart.replaceAll('::', ':')\n            staticPart = staticPart.replaceAll('%', '%25')\n            regexps.push(backtrack = escapeRegExp(staticPart))\n          }\n\n          lastParamStartIndex = j + 1\n\n          if (isEndOfNode || pattern.charCodeAt(j) === 47 || j === pattern.length) {\n            const nodePattern = isRegexNode ? '()' + staticPart : staticPart\n            const nodePath = pattern.slice(i, j)\n\n            pattern = pattern.slice(0, i + 1) + nodePattern + pattern.slice(j)\n            i += nodePattern.length\n\n            const regex = isRegexNode ? new RegExp('^' + regexps.join('') + '$') : null\n            currentNode = currentNode.createParametricChild(regex, staticPart || null, nodePath)\n            parentNodePathIndex = i + 1\n            break\n          }\n        }\n      }\n    } else if (isWildcardNode) {\n      // add the wildcard parameter\n      params.push('*')\n      currentNode = currentNode.createWildcardChild()\n      parentNodePathIndex = i + 1\n\n      if (i !== pattern.length - 1) {\n        throw new Error('Wildcard must be the last character in the route')\n      }\n    }\n  }\n\n  if (!this.caseSensitive) {\n    pattern = pattern.toLowerCase()\n  }\n\n  if (pattern === '*') {\n    pattern = '/*'\n  }\n\n  for (const existRoute of this.routes) {\n    const routeConstraints = existRoute.opts.constraints || {}\n    if (\n      existRoute.method === method &&\n      existRoute.pattern === pattern &&\n      deepEqual(routeConstraints, constraints)\n    ) {\n      throw new Error(`Method '${method}' already declared for route '${pattern}' with constraints '${JSON.stringify(constraints)}'`)\n    }\n  }\n\n  const route = { method, path, pattern, params, opts, handler, store }\n  this.routes.push(route)\n  currentNode.addRoute(route, this.constrainer)\n}\n\nRouter.prototype.hasRoute = function hasRoute (method, path, constraints) {\n  const route = this.findRoute(method, path, constraints)\n  return route !== null\n}\n\nRouter.prototype.findRoute = function findNode (method, path, constraints = {}) {\n  if (this.trees[method] === undefined) {\n    return null\n  }\n\n  let pattern = path\n\n  let currentNode = this.trees[method]\n  let parentNodePathIndex = currentNode.prefix.length\n\n  const params = []\n  for (let i = 0; i <= pattern.length; i++) {\n    if (pattern.charCodeAt(i) === 58 && pattern.charCodeAt(i + 1) === 58) {\n      // It's a double colon\n      i++\n      continue\n    }\n\n    const isParametricNode = pattern.charCodeAt(i) === 58 && pattern.charCodeAt(i + 1) !== 58\n    const isWildcardNode = pattern.charCodeAt(i) === 42\n\n    if (isParametricNode || isWildcardNode || (i === pattern.length && i !== parentNodePathIndex)) {\n      let staticNodePath = pattern.slice(parentNodePathIndex, i)\n      if (!this.caseSensitive) {\n        staticNodePath = staticNodePath.toLowerCase()\n      }\n      staticNodePath = staticNodePath.replaceAll('::', ':')\n      staticNodePath = staticNodePath.replaceAll('%', '%25')\n      // add the static part of the route to the tree\n      currentNode = currentNode.getStaticChild(staticNodePath)\n      if (currentNode === null) {\n        return null\n      }\n    }\n\n    if (isParametricNode) {\n      let isRegexNode = false\n      let isParamSafe = true\n      let backtrack = ''\n      const regexps = []\n\n      let lastParamStartIndex = i + 1\n      for (let j = lastParamStartIndex; ; j++) {\n        const charCode = pattern.charCodeAt(j)\n\n        const isRegexParam = charCode === 40\n        const isStaticPart = charCode === 45 || charCode === 46\n        const isEndOfNode = charCode === 47 || j === pattern.length\n\n        if (isRegexParam || isStaticPart || isEndOfNode) {\n          const paramName = pattern.slice(lastParamStartIndex, j)\n          params.push(paramName)\n\n          isRegexNode = isRegexNode || isRegexParam || isStaticPart\n\n          if (isRegexParam) {\n            const endOfRegexIndex = getClosingParenthensePosition(pattern, j)\n            const regexString = pattern.slice(j, endOfRegexIndex + 1)\n\n            if (!this.allowUnsafeRegex) {\n              assert(isRegexSafe(new RegExp(regexString)), `The regex '${regexString}' is not safe!`)\n            }\n\n            regexps.push(trimRegExpStartAndEnd(regexString))\n\n            j = endOfRegexIndex + 1\n            isParamSafe = false\n          } else {\n            regexps.push(isParamSafe ? '(.*?)' : `(${backtrack}|(?:(?!${backtrack}).)*)`)\n            isParamSafe = false\n          }\n\n          const staticPartStartIndex = j\n          for (; j < pattern.length; j++) {\n            const charCode = pattern.charCodeAt(j)\n            if (charCode === 47) break\n            if (charCode === 58) {\n              const nextCharCode = pattern.charCodeAt(j + 1)\n              if (nextCharCode === 58) j++\n              else break\n            }\n          }\n\n          let staticPart = pattern.slice(staticPartStartIndex, j)\n          if (staticPart) {\n            staticPart = staticPart.replaceAll('::', ':')\n            staticPart = staticPart.replaceAll('%', '%25')\n            regexps.push(backtrack = escapeRegExp(staticPart))\n          }\n\n          lastParamStartIndex = j + 1\n\n          if (isEndOfNode || pattern.charCodeAt(j) === 47 || j === pattern.length) {\n            const nodePattern = isRegexNode ? '()' + staticPart : staticPart\n            const nodePath = pattern.slice(i, j)\n\n            pattern = pattern.slice(0, i + 1) + nodePattern + pattern.slice(j)\n            i += nodePattern.length\n\n            const regex = isRegexNode ? new RegExp('^' + regexps.join('') + '$') : null\n            currentNode = currentNode.getParametricChild(regex, staticPart || null, nodePath)\n            if (currentNode === null) {\n              return null\n            }\n            parentNodePathIndex = i + 1\n            break\n          }\n        }\n      }\n    } else if (isWildcardNode) {\n      // add the wildcard parameter\n      params.push('*')\n      currentNode = currentNode.getWildcardChild()\n\n      parentNodePathIndex = i + 1\n\n      if (i !== pattern.length - 1) {\n        throw new Error('Wildcard must be the last character in the route')\n      }\n    }\n  }\n\n  if (!this.caseSensitive) {\n    pattern = pattern.toLowerCase()\n  }\n\n  for (const existRoute of this.routes) {\n    const routeConstraints = existRoute.opts.constraints || {}\n    if (\n      existRoute.method === method &&\n      existRoute.pattern === pattern &&\n      deepEqual(routeConstraints, constraints)\n    ) {\n      return {\n        handler: existRoute.handler,\n        store: existRoute.store,\n        params: existRoute.params\n      }\n    }\n  }\n\n  return null\n}\n\nRouter.prototype.hasConstraintStrategy = function (strategyName) {\n  return this.constrainer.hasConstraintStrategy(strategyName)\n}\n\nRouter.prototype.addConstraintStrategy = function (constraints) {\n  this.constrainer.addConstraintStrategy(constraints)\n  this._rebuild(this.routes)\n}\n\nRouter.prototype.reset = function reset () {\n  this.trees = {}\n  this.routes = []\n}\n\nRouter.prototype.off = function off (method, path, constraints) {\n  // path validation\n  assert(typeof path === 'string', 'Path should be a string')\n  assert(path.length > 0, 'The path could not be empty')\n  assert(path[0] === '/' || path[0] === '*', 'The first character of a path should be `/` or `*`')\n  // options validation\n  assert(\n    typeof constraints === 'undefined' ||\n    (typeof constraints === 'object' && !Array.isArray(constraints) && constraints !== null),\n    'Constraints should be an object or undefined.')\n\n  // path ends with optional parameter\n  const optionalParamMatch = path.match(OPTIONAL_PARAM_REGEXP)\n  if (optionalParamMatch) {\n    assert(path.length === optionalParamMatch.index + optionalParamMatch[0].length, 'Optional Parameter needs to be the last parameter of the path')\n\n    const pathFull = path.replace(OPTIONAL_PARAM_REGEXP, '$1$2')\n    const pathOptional = path.replace(OPTIONAL_PARAM_REGEXP, '$2')\n\n    this.off(method, pathFull, constraints)\n    this.off(method, pathOptional, constraints)\n    return\n  }\n\n  if (this.ignoreDuplicateSlashes) {\n    path = removeDuplicateSlashes(path)\n  }\n\n  if (this.ignoreTrailingSlash) {\n    path = trimLastSlash(path)\n  }\n\n  const methods = Array.isArray(method) ? method : [method]\n  for (const method of methods) {\n    this._off(method, path, constraints)\n  }\n}\n\nRouter.prototype._off = function _off (method, path, constraints) {\n  // method validation\n  assert(typeof method === 'string', 'Method should be a string')\n  assert(httpMethods.includes(method), `Method '${method}' is not an http method.`)\n\n  function matcherWithoutConstraints (route) {\n    return method !== route.method || path !== route.path\n  }\n\n  function matcherWithConstraints (route) {\n    return matcherWithoutConstraints(route) || !deepEqual(constraints, route.opts.constraints || {})\n  }\n\n  const predicate = constraints ? matcherWithConstraints : matcherWithoutConstraints\n\n  // Rebuild tree without the specific route\n  const newRoutes = this.routes.filter(predicate)\n  this._rebuild(newRoutes)\n}\n\nRouter.prototype.lookup = function lookup (req, res, ctx, done) {\n  if (typeof ctx === 'function') {\n    done = ctx\n    ctx = undefined\n  }\n\n  if (done === undefined) {\n    const constraints = this.constrainer.deriveConstraints(req, ctx)\n    const handle = this.find(req.method, req.url, constraints)\n    return this.callHandler(handle, req, res, ctx)\n  }\n\n  this.constrainer.deriveConstraints(req, ctx, (err, constraints) => {\n    if (err !== null) {\n      done(err)\n      return\n    }\n\n    try {\n      const handle = this.find(req.method, req.url, constraints)\n      const result = this.callHandler(handle, req, res, ctx)\n      done(null, result)\n    } catch (err) {\n      done(err)\n    }\n  })\n}\n\nRouter.prototype.callHandler = function callHandler (handle, req, res, ctx) {\n  if (handle === null) return this._defaultRoute(req, res, ctx)\n  return ctx === undefined\n    ? handle.handler(req, res, handle.params, handle.store, handle.searchParams)\n    : handle.handler.call(ctx, req, res, handle.params, handle.store, handle.searchParams)\n}\n\nRouter.prototype.find = function find (method, path, derivedConstraints) {\n  let currentNode = this.trees[method]\n  if (currentNode === undefined) return null\n\n  if (path.charCodeAt(0) !== 47) { // 47 is '/'\n    path = path.replace(FULL_PATH_REGEXP, '/')\n  }\n\n  // This must be run before sanitizeUrl as the resulting function\n  // .sliceParameter must be constructed with same URL string used\n  // throughout the rest of this function.\n  if (this.ignoreDuplicateSlashes) {\n    path = removeDuplicateSlashes(path)\n  }\n\n  let sanitizedUrl\n  let querystring\n  let shouldDecodeParam\n\n  try {\n    sanitizedUrl = safeDecodeURI(path, this.useSemicolonDelimiter)\n    path = sanitizedUrl.path\n    querystring = sanitizedUrl.querystring\n    shouldDecodeParam = sanitizedUrl.shouldDecodeParam\n  } catch (error) {\n    return this._onBadUrl(path)\n  }\n\n  if (this.ignoreTrailingSlash) {\n    path = trimLastSlash(path)\n  }\n\n  const originPath = path\n\n  if (this.caseSensitive === false) {\n    path = path.toLowerCase()\n  }\n\n  const maxParamLength = this.maxParamLength\n\n  let pathIndex = currentNode.prefix.length\n  const params = []\n  const pathLen = path.length\n\n  const brothersNodesStack = []\n\n  while (true) {\n    if (pathIndex === pathLen && currentNode.isLeafNode) {\n      const handle = currentNode.handlerStorage.getMatchingHandler(derivedConstraints)\n      if (handle !== null) {\n        return {\n          handler: handle.handler,\n          store: handle.store,\n          params: handle._createParamsObject(params),\n          searchParams: this.querystringParser(querystring)\n        }\n      }\n    }\n\n    let node = currentNode.getNextNode(path, pathIndex, brothersNodesStack, params.length)\n\n    if (node === null) {\n      if (brothersNodesStack.length === 0) {\n        return null\n      }\n\n      const brotherNodeState = brothersNodesStack.pop()\n      pathIndex = brotherNodeState.brotherPathIndex\n      params.splice(brotherNodeState.paramsCount)\n      node = brotherNodeState.brotherNode\n    }\n\n    currentNode = node\n\n    // static route\n    if (currentNode.kind === NODE_TYPES.STATIC) {\n      pathIndex += currentNode.prefix.length\n      continue\n    }\n\n    if (currentNode.kind === NODE_TYPES.WILDCARD) {\n      let param = originPath.slice(pathIndex)\n      if (shouldDecodeParam) {\n        param = safeDecodeURIComponent(param)\n      }\n\n      params.push(param)\n      pathIndex = pathLen\n      continue\n    }\n\n    // parametric node\n    let paramEndIndex = originPath.indexOf('/', pathIndex)\n    if (paramEndIndex === -1) {\n      paramEndIndex = pathLen\n    }\n\n    let param = originPath.slice(pathIndex, paramEndIndex)\n    if (shouldDecodeParam) {\n      param = safeDecodeURIComponent(param)\n    }\n\n    if (currentNode.isRegex) {\n      const matchedParameters = currentNode.regex.exec(param)\n      if (matchedParameters === null) continue\n\n      for (let i = 1; i < matchedParameters.length; i++) {\n        const matchedParam = matchedParameters[i]\n        if (matchedParam.length > maxParamLength) {\n          return null\n        }\n        params.push(matchedParam)\n      }\n    } else {\n      if (param.length > maxParamLength) {\n        return null\n      }\n      params.push(param)\n    }\n\n    pathIndex = paramEndIndex\n  }\n}\n\nRouter.prototype._rebuild = function (routes) {\n  this.reset()\n\n  for (const route of routes) {\n    const { method, path, opts, handler, store } = route\n    this._on(method, path, opts, handler, store)\n  }\n}\n\nRouter.prototype._defaultRoute = function (req, res, ctx) {\n  if (this.defaultRoute !== null) {\n    return ctx === undefined\n      ? this.defaultRoute(req, res)\n      : this.defaultRoute.call(ctx, req, res)\n  } else {\n    res.statusCode = 404\n    res.end()\n  }\n}\n\nRouter.prototype._onBadUrl = function (path) {\n  if (this.onBadUrl === null) {\n    return null\n  }\n  const onBadUrl = this.onBadUrl\n  return {\n    handler: (req, res, ctx) => onBadUrl(path, req, res),\n    params: {},\n    store: null\n  }\n}\n\nRouter.prototype.prettyPrint = function (options = {}) {\n  const method = options.method\n\n  options.buildPrettyMeta = this.buildPrettyMeta.bind(this)\n\n  let tree = null\n  if (method === undefined) {\n    const { version, host, ...constraints } = this.constrainer.strategies\n    constraints[httpMethodStrategy.name] = httpMethodStrategy\n\n    const mergedRouter = new Router({ ...this._opts, constraints })\n    const mergedRoutes = this.routes.map(route => {\n      const constraints = {\n        ...route.opts.constraints,\n        [httpMethodStrategy.name]: route.method\n      }\n      return { ...route, method: 'MERGED', opts: { constraints } }\n    })\n    mergedRouter._rebuild(mergedRoutes)\n    tree = mergedRouter.trees.MERGED\n  } else {\n    tree = this.trees[method]\n  }\n\n  if (tree == null) return '(empty tree)'\n  return prettyPrintTree(tree, options)\n}\n\nfor (const i in httpMethods) {\n  /* eslint no-prototype-builtins: \"off\" */\n  if (!httpMethods.hasOwnProperty(i)) continue\n  const m = httpMethods[i]\n  const methodName = m.toLowerCase()\n\n  Router.prototype[methodName] = function (path, handler, store) {\n    return this.on(m, path, handler, store)\n  }\n}\n\nRouter.prototype.all = function (path, handler, store) {\n  this.on(httpMethods, path, handler, store)\n}\n\nmodule.exports = Router\n\nfunction escapeRegExp (string) {\n  return string.replace(ESCAPE_REGEXP, '\\\\$&')\n}\n\nfunction removeDuplicateSlashes (path) {\n  return path.indexOf('//') !== -1 ? path.replace(REMOVE_DUPLICATE_SLASHES_REGEXP, '/') : path\n}\n\nfunction trimLastSlash (path) {\n  if (path.length > 1 && path.charCodeAt(path.length - 1) === 47) {\n    return path.slice(0, -1)\n  }\n  return path\n}\n\nfunction trimRegExpStartAndEnd (regexString) {\n  // removes chars that marks start \"^\" and end \"$\" of regexp\n  if (regexString.charCodeAt(1) === 94) {\n    regexString = regexString.slice(0, 1) + regexString.slice(2)\n  }\n\n  if (regexString.charCodeAt(regexString.length - 2) === 36) {\n    regexString = regexString.slice(0, regexString.length - 2) + regexString.slice(regexString.length - 1)\n  }\n\n  return regexString\n}\n\nfunction getClosingParenthensePosition (path, idx) {\n  // `path.indexOf()` will always return the first position of the closing parenthese,\n  // but it's inefficient for grouped or wrong regexp expressions.\n  // see issues #62 and #63 for more info\n\n  let parentheses = 1\n\n  while (idx < path.length) {\n    idx++\n\n    // ignore skipped chars \"\\\"\n    if (path.charCodeAt(idx) === 92) {\n      idx++\n      continue\n    }\n\n    if (path.charCodeAt(idx) === 41) {\n      parentheses--\n    } else if (path.charCodeAt(idx) === 40) {\n      parentheses++\n    }\n\n    if (!parentheses) return idx\n  }\n\n  throw new TypeError('Invalid regexp expression in \"' + path + '\"')\n}\n\nfunction defaultBuildPrettyMeta (route) {\n  // buildPrettyMeta function must return an object, which will be parsed into key/value pairs for display\n  if (!route) return {}\n  if (!route.store) return {}\n  return Object.assign({}, route.store)\n}\n"]}