const isWindows = process.platform === 'win32' ||
							 | 
						|
								    process.env.OSTYPE === 'cygwin' ||
							 | 
						|
								    process.env.OSTYPE === 'msys'
							 | 
						|
								
							 | 
						|
								const path = require('path')
							 | 
						|
								const COLON = isWindows ? ';' : ':'
							 | 
						|
								const isexe = require('isexe')
							 | 
						|
								
							 | 
						|
								const getNotFoundError = (cmd) =>
							 | 
						|
								  Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' })
							 | 
						|
								
							 | 
						|
								const getPathInfo = (cmd, opt) => {
							 | 
						|
								  const colon = opt.colon || COLON
							 | 
						|
								
							 | 
						|
								  // If it has a slash, then we don't bother searching the pathenv.
							 | 
						|
								  // just check the file itself, and that's it.
							 | 
						|
								  const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? ['']
							 | 
						|
								    : (
							 | 
						|
								      [
							 | 
						|
								        // windows always checks the cwd first
							 | 
						|
								        ...(isWindows ? [process.cwd()] : []),
							 | 
						|
								        ...(opt.path || process.env.PATH ||
							 | 
						|
								          /* istanbul ignore next: very unusual */ '').split(colon),
							 | 
						|
								      ]
							 | 
						|
								    )
							 | 
						|
								  const pathExtExe = isWindows
							 | 
						|
								    ? opt.pathExt || process.env.PATHEXT || '.EXE;.CMD;.BAT;.COM'
							 | 
						|
								    : ''
							 | 
						|
								  const pathExt = isWindows ? pathExtExe.split(colon) : ['']
							 | 
						|
								
							 | 
						|
								  if (isWindows) {
							 | 
						|
								    if (cmd.indexOf('.') !== -1 && pathExt[0] !== '')
							 | 
						|
								      pathExt.unshift('')
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  return {
							 | 
						|
								    pathEnv,
							 | 
						|
								    pathExt,
							 | 
						|
								    pathExtExe,
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const which = (cmd, opt, cb) => {
							 | 
						|
								  if (typeof opt === 'function') {
							 | 
						|
								    cb = opt
							 | 
						|
								    opt = {}
							 | 
						|
								  }
							 | 
						|
								  if (!opt)
							 | 
						|
								    opt = {}
							 | 
						|
								
							 | 
						|
								  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)
							 | 
						|
								  const found = []
							 | 
						|
								
							 | 
						|
								  const step = i => new Promise((resolve, reject) => {
							 | 
						|
								    if (i === pathEnv.length)
							 | 
						|
								      return opt.all && found.length ? resolve(found)
							 | 
						|
								        : reject(getNotFoundError(cmd))
							 | 
						|
								
							 | 
						|
								    const ppRaw = pathEnv[i]
							 | 
						|
								    const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw
							 | 
						|
								
							 | 
						|
								    const pCmd = path.join(pathPart, cmd)
							 | 
						|
								    const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd
							 | 
						|
								      : pCmd
							 | 
						|
								
							 | 
						|
								    resolve(subStep(p, i, 0))
							 | 
						|
								  })
							 | 
						|
								
							 | 
						|
								  const subStep = (p, i, ii) => new Promise((resolve, reject) => {
							 | 
						|
								    if (ii === pathExt.length)
							 | 
						|
								      return resolve(step(i + 1))
							 | 
						|
								    const ext = pathExt[ii]
							 | 
						|
								    isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
							 | 
						|
								      if (!er && is) {
							 | 
						|
								        if (opt.all)
							 | 
						|
								          found.push(p + ext)
							 | 
						|
								        else
							 | 
						|
								          return resolve(p + ext)
							 | 
						|
								      }
							 | 
						|
								      return resolve(subStep(p, i, ii + 1))
							 | 
						|
								    })
							 | 
						|
								  })
							 | 
						|
								
							 | 
						|
								  return cb ? step(0).then(res => cb(null, res), cb) : step(0)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const whichSync = (cmd, opt) => {
							 | 
						|
								  opt = opt || {}
							 | 
						|
								
							 | 
						|
								  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt)
							 | 
						|
								  const found = []
							 | 
						|
								
							 | 
						|
								  for (let i = 0; i < pathEnv.length; i ++) {
							 | 
						|
								    const ppRaw = pathEnv[i]
							 | 
						|
								    const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw
							 | 
						|
								
							 | 
						|
								    const pCmd = path.join(pathPart, cmd)
							 | 
						|
								    const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd
							 | 
						|
								      : pCmd
							 | 
						|
								
							 | 
						|
								    for (let j = 0; j < pathExt.length; j ++) {
							 | 
						|
								      const cur = p + pathExt[j]
							 | 
						|
								      try {
							 | 
						|
								        const is = isexe.sync(cur, { pathExt: pathExtExe })
							 | 
						|
								        if (is) {
							 | 
						|
								          if (opt.all)
							 | 
						|
								            found.push(cur)
							 | 
						|
								          else
							 | 
						|
								            return cur
							 | 
						|
								        }
							 | 
						|
								      } catch (ex) {}
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  if (opt.all && found.length)
							 | 
						|
								    return found
							 | 
						|
								
							 | 
						|
								  if (opt.nothrow)
							 | 
						|
								    return null
							 | 
						|
								
							 | 
						|
								  throw getNotFoundError(cmd)
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								module.exports = which
							 | 
						|
								which.sync = whichSync
							 |