text: // defaults, types, and shorthands.
  
  
  var path = require("path")
    , url = require("url")
    , Stream = require("stream").Stream
    , semver = require("semver")
    , stableFamily = semver.parse(process.version)
    , nopt = require("nopt")
    , os = require("os")
    , osenv = require("osenv")
    , umask = require("../utils/umask")
  
  var log
  try {
    log = require("npmlog")
  } catch (er) {
    var util = require("util")
    log = { warn: function (m) {
      console.warn(m + " " + util.format.apply(util, [].slice.call(arguments, 1)))
    } }
  }
  
  exports.Umask = Umask
  function Umask () {}
  function validateUmask (data, k, val) {
    return umask.validate(data, k, val)
  }
  
  function validateSemver (data, k, val) {
    if (!semver.valid(val)) return false
    data[k] = semver.valid(val)
  }
  
  function validateTag (data, k, val) {
    val = ("" + val).trim()
    if (!val || semver.validRange(val)) return false
    data[k] = val
  }
  
  function validateStream (data, k, val) {
    if (!(val instanceof Stream)) return false
    data[k] = val
  }
  
  nopt.typeDefs.semver = { type: semver, validate: validateSemver }
  nopt.typeDefs.Stream = { type: Stream, validate: validateStream }
  nopt.typeDefs.Umask = { type: Umask, validate: validateUmask }
  
  // Don't let --tag=1.2.3 ever be a thing
  var tag = {}
  nopt.typeDefs.tag = { type: tag, validate: validateTag }
  
  nopt.invalidHandler = function (k, val, type) {
    log.warn("invalid config", k + "=" + JSON.stringify(val))
  
    if (Array.isArray(type)) {
      if (type.indexOf(url) !== -1) type = url
      else if (type.indexOf(path) !== -1) type = path
    }
  
    switch (type) {
      case tag:
        log.warn("invalid config", "Tag must not be a SemVer range")
        break
      case Umask:
        log.warn("invalid config", "Must be umask, octal number in range 0000..0777")
        break
      case url:
        log.warn("invalid config", "Must be a full url with 'http://'")
        break
      case path:
        log.warn("invalid config", "Must be a valid filesystem path")
        break
      case Number:
        log.warn("invalid config", "Must be a numeric value")
        break
      case Stream:
        log.warn("invalid config", "Must be an instance of the Stream class")
        break
    }
  }
  
  if (!stableFamily || (+stableFamily.minor % 2)) stableFamily = null
  else stableFamily = stableFamily.major + "." + stableFamily.minor
  
  var defaults
  
  var temp = osenv.tmpdir()
  var home = osenv.home()
  
  var uidOrPid = process.getuid ? process.getuid() : process.pid
  
  if (home) process.env.HOME = home
  else home = path.resolve(temp, "npm-" + uidOrPid)
  
  var cacheExtra = process.platform === "win32" ? "npm-cache" : ".npm"
  var cacheRoot = process.platform === "win32" && process.env.APPDATA || home
  var cache = path.resolve(cacheRoot, cacheExtra)
  
  
  var globalPrefix
  Object.defineProperty(exports, "defaults", {get: function () {
    if (defaults) return defaults
  
    if (process.env.PREFIX) {
      globalPrefix = process.env.PREFIX
    } else if (process.platform === "win32") {
      // c:\node\node.exe --> prefix=c:\node\
      globalPrefix = path.dirname(process.execPath)
    } else {
      // /usr/local/bin/node --> prefix=/usr/local
      globalPrefix = path.dirname(path.dirname(process.execPath))
  
      // destdir only is respected on Unix
      if (process.env.DESTDIR) {
        globalPrefix = path.join(process.env.DESTDIR, globalPrefix)
      }
    }
  
    defaults = {
      access : null
      , "always-auth" : false
  
      , "bin-links" : true
      , browser : null
  
      , ca: null
      , cafile: null
  
      , cache : cache
  
      , "cache-lock-stale": 60000
      , "cache-lock-retries": 10
      , "cache-lock-wait": 10000
  
      , "cache-max": Infinity
      , "cache-min": 10
  
      , cert: null
  
      , color : true
      , depth: Infinity
      , description : true
      , dev : false
      , editor : osenv.editor()
      , "engine-strict": false
      , force : false
  
      , "fetch-retries": 2
      , "fetch-retry-factor": 10
      , "fetch-retry-mintimeout": 10000
      , "fetch-retry-maxtimeout": 60000
  
      , git: "git"
      , "git-tag-version": true
  
      , global : false
      , globalconfig : path.resolve(globalPrefix, "etc", "npmrc")
      , group : process.platform === "win32" ? 0
              : process.env.SUDO_GID || (process.getgid && process.getgid())
      , heading: "npm"
      , "if-present": false
      , "ignore-scripts": false
      , "init-module": path.resolve(home, ".npm-init.js")
      , "init-author-name" : ""
      , "init-author-email" : ""
      , "init-author-url" : ""
      , "init-version": "1.0.0"
      , "init-license": "ISC"
      , json: false
      , key: null
      , link: false
      , "local-address" : undefined
      , loglevel : "warn"
      , logstream : process.stderr
      , long : false
      , message : "%s"
      , "node-version" : process.version
      , npat : false
      , "onload-script" : false
      , optional: true
      , parseable : false
      , prefix : globalPrefix
      , production: process.env.NODE_ENV === "production"
      , "proprietary-attribs": true
      , proxy :  null
      , "https-proxy" : null
      , "user-agent" : "npm/{npm-version} "
                       + "node/{node-version} "
                       + "{platform} "
                       + "{arch}"
      , "rebuild-bundle" : true
      , registry : "https://registry.npmjs.org/"
      , rollback : true
      , save : false
      , "save-bundle": false
      , "save-dev" : false
      , "save-exact" : false
      , "save-optional" : false
      , "save-prefix": "^"
      , scope : ""
      , searchopts: ""
      , searchexclude: null
      , searchsort: "name"
      , shell : osenv.shell()
      , shrinkwrap: true
      , "sign-git-tag": false
      , spin: true
      , "strict-ssl": true
      , tag : "latest"
      , tmp : temp
      , unicode : true
      , "unsafe-perm" : process.platform === "win32"
                      || process.platform === "cygwin"
                      || !( process.getuid && process.setuid
                         && process.getgid && process.setgid )
                      || process.getuid() !== 0
      , usage : false
      , user : process.platform === "win32" ? 0 : "nobody"
      , userconfig : path.resolve(home, ".npmrc")
      , umask: process.umask ? process.umask() : umask.fromString("022")
      , version : false
      , versions : false
      , viewer: process.platform === "win32" ? "browser" : "man"
  
      , _exit : true
    }
  
    return defaults
  }})
  
  exports.types =
    { access : [null, "restricted", "public"]
    , "always-auth" : Boolean
    , "bin-links": Boolean
    , browser : [null, String]
    , ca: [null, String, Array]
    , cafile : path
    , cache : path
    , "cache-lock-stale": Number
    , "cache-lock-retries": Number
    , "cache-lock-wait": Number
    , "cache-max": Number
    , "cache-min": Number
    , cert: [null, String]
    , color : ["always", Boolean]
    , depth : Number
    , description : Boolean
    , dev : Boolean
    , editor : String
    , "engine-strict": Boolean
    , force : Boolean
    , "fetch-retries": Number
    , "fetch-retry-factor": Number
    , "fetch-retry-mintimeout": Number
    , "fetch-retry-maxtimeout": Number
    , git: String
    , "git-tag-version": Boolean
    , global : Boolean
    , globalconfig : path
    , group : [Number, String]
    , "https-proxy" : [null, url]
    , "user-agent" : String
    , "heading": String
    , "if-present": Boolean
    , "ignore-scripts": Boolean
    , "init-module": path
    , "init-author-name" : String
    , "init-author-email" : String
    , "init-author-url" : ["", url]
    , "init-license": String
    , "init-version": semver
    , json: Boolean
    , key: [null, String]
    , link: Boolean
    // local-address must be listed as an IP for a local network interface
    // must be IPv4 due to node bug
    , "local-address" : getLocalAddresses()
    , loglevel : ["silent", "error", "warn", "http", "info", "verbose", "silly"]
    , logstream : Stream
    , long : Boolean
    , message: String
    , "node-version" : [null, semver]
    , npat : Boolean
    , "onload-script" : [null, String]
    , optional: Boolean
    , parseable : Boolean
    , prefix: path
    , production: Boolean
    , "proprietary-attribs": Boolean
    , proxy : [null, false, url] // allow proxy to be disabled explicitly
    , "rebuild-bundle" : Boolean
    , registry : [null, url]
    , rollback : Boolean
    , save : Boolean
    , "save-bundle": Boolean
    , "save-dev" : Boolean
    , "save-exact" : Boolean
    , "save-optional" : Boolean
    , "save-prefix": String
    , scope : String
    , searchopts : String
    , searchexclude: [null, String]
    , searchsort: [ "name", "-name"
                  , "description", "-description"
                  , "author", "-author"
                  , "date", "-date"
                  , "keywords", "-keywords" ]
    , shell : String
    , shrinkwrap: Boolean
    , "sign-git-tag": Boolean
    , spin: ["always", Boolean]
    , "strict-ssl": Boolean
    , tag : tag
    , tmp : path
    , unicode : Boolean
    , "unsafe-perm" : Boolean
    , usage : Boolean
    , user : [Number, String]
    , userconfig : path
    , umask: Umask
    , version : Boolean
    , versions : Boolean
    , viewer: String
    , _exit : Boolean
    }
  
  function getLocalAddresses() {
    Object.keys(os.networkInterfaces()).map(function (nic) {
      return os.networkInterfaces()[nic].filter(function (addr) {
        return addr.family === "IPv4"
      })
      .map(function (addr) {
        return addr.address
      })
    }).reduce(function (curr, next) {
      return curr.concat(next)
    }, []).concat(undefined)
  }
  
  exports.shorthands =
    { s : ["--loglevel", "silent"]
    , d : ["--loglevel", "info"]
    , dd : ["--loglevel", "verbose"]
    , ddd : ["--loglevel", "silly"]
    , noreg : ["--no-registry"]
    , N : ["--no-registry"]
    , reg : ["--registry"]
    , "no-reg" : ["--no-registry"]
    , silent : ["--loglevel", "silent"]
    , verbose : ["--loglevel", "verbose"]
    , quiet: ["--loglevel", "warn"]
    , q: ["--loglevel", "warn"]
    , h : ["--usage"]
    , H : ["--usage"]
    , "?" : ["--usage"]
    , help : ["--usage"]
    , v : ["--version"]
    , f : ["--force"]
    , gangster : ["--force"]
    , gangsta : ["--force"]
    , desc : ["--description"]
    , "no-desc" : ["--no-description"]
    , "local" : ["--no-global"]
    , l : ["--long"]
    , m : ["--message"]
    , p : ["--parseable"]
    , porcelain : ["--parseable"]
    , g : ["--global"]
    , S : ["--save"]
    , D : ["--save-dev"]
    , E : ["--save-exact"]
    , O : ["--save-optional"]
    , y : ["--yes"]
    , n : ["--no-yes"]
    , B : ["--save-bundle"]
    , C : ["--prefix"]
    }
  