text: /*!
   * stacktrace-metadata <https://github.com/tunnckoCore/stacktrace-metadata>
   *
   * Copyright (c) Charlike Mike Reagent <@tunnckoCore> (https://i.am.charlike.online)
   * Released under the MIT license.
   */
  
  'use strict'
  
  var extend = require('extend-shallow')
  var findCallsite = require('find-callsite')
  var clean = require('clean-stacktrace')
  var metadata = require('clean-stacktrace-metadata')
  var relativePaths = require('clean-stacktrace-relative-paths')
  
  /**
   * > Cleans stack trace and attaches few more metadata properties,
   * such as `at`, `line`, `column`, `filename` and `place`. By default
   * it cleans stack, makes is short (4 length) and makes paths relative.
   * But all this is controllable through `options` object.
   * Throws `TypeError` if `error` is not an instance of Error.
   *
   * **Example**
   *
   * ```js
   * const metadata = require('stacktrace-metadata')
   *
   * const error = new Error('foo quxie')
   * error.stack = `Error: foo quxie
   *     at zazz (/home/charlike/apps/alwa.js:8:10)
   *     at module.exports (/home/charlike/apps/foo.js:6:3)
   *     at Object.<anonymous> (/home/charlike/apps/dush.js:45:3)
   *     at Module._compile (module.js:409:26)
   *     at Object.Module._extensions..js (module.js:416:10)
   *     at Module.load (module.js:343:32)
   *     at Function.Module._load (module.js:300:12)
   *     at Function.Module.runMain (module.js:441:10)
   *     at startup (node.js:139:18)
   * `
   * const err = metadata(error)
   *
   * console.log(err.line) // => 8
   * console.log(err.column) // => 10
   * console.log(err.filename) // => 'alwa.js'
   * console.log(err.place) // => 'zazz'
   * console.log(err.at) // => 'zazz (alwa.js:8:10)'
   * console.log(err.stack)
   * // =>
   * // Error: foo quxie
   * //     at zazz (alwa.js:8:10)
   * //     at module.exports (foo.js:6:3)
   * //     at Object.<anonymous> (dush.js:45:3)
   * ```
   *
   * @name   stacktraceMetadata
   * @param  {Error} `error` real error object, checked against `instanceof Error`
   * @param  {Object} `options` optional options object for more control
   * @param  {Boolean} `options.cleanStack` if `false` won't clean stack trace from node internals
   * @param  {Boolean} `options.shortStack` if `false` full stack traces, otherwise they are just four
   * @param  {Boolean} `options.showStack` if `false` the error.stack will be empty string
   * @param  {Boolean} `options.relativePaths` if `false` paths in stack traces will be absolute
   * @param  {Function} `options.mapper` called on each line of the stack with `(line, index)` signature
   * @param  {String} `options.cwd` current working directory, default `process.cwd()`
   * @return {Error} same error object, but modified
   * @throws {TypeError} If `error` not instance of Error
   * @api public
   */
  
  module.exports = function stacktraceMetadata (error, options) {
    if (!(error instanceof Error)) {
      throw new TypeError('stacktrace-metadata: expect `error` to be real error')
    }
  
    if (typeof error.stack === 'string' && error.stack.length) {
      var opts = extend({
        showStack: true,
        shortStack: true,
        cleanStack: true,
        relativePaths: true
      }, options)
  
      var relative = function relative (val) {
        return opts.relativePaths ? relativePaths(opts.cwd)(val) : val
      }
  
      var stack = clean(error.stack, function mapper (line, index) {
        line = typeof opts.mapper === 'function'
          ? (opts.mapper(line, index) || line)
          : line
        line = relative(line)
        return line
      })
  
      if (!opts.cleanStack) {
        stack = error.stack
      }
  
      var at = findCallsite(stack, opts)
      metadata(mapdata(error))(at)
  
      stack = opts.shortStack
        ? stack.split('\n').splice(0, 4).join('\n')
        : stack
  
      error.stack = opts.showStack ? stack : ''
      return error
    }
  
    return error
  }
  
  function mapdata (error) {
    return function mapper (_, info) {
      var atLine = info.place.length ? [
        info.place,
        ' ('
      ] : []
  
      atLine = atLine.concat([
        info.filename,
        ':',
        info.line,
        ':',
        info.column
      ])
  
      atLine = info.place.length ? atLine.concat(')') : atLine
      error.at = atLine.join('')
  
      error.line = info.line
      error.place = info.place
      error.column = info.column
      error.filename = info.filename
    }
  }
  