JFIF  ` ` ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 85 C   !"$"$ C hh"       } !1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz      w !1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz   ? .(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((+QI3L( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( @y -#yIޚXP2$袊 ( ( ( ( ( ( ( ( ( ( ( ( ( ( 3FE a(dN^M4GӁMoO$dssYz4]4+HM9վ2#OL@ܟH O@}LYW=p3! 7'Z&;" zםg|Ij~DǶr^2sI🆒TS(2?y}xmux#sھ[Cqg0mr\ ҏĺҋ{d^Rrr#mOŬ]\>uKcq*?ɯL񆥥Ƕ[ĆlO b[2+'c9Yl{I`:R fڽ;g8jc}ZC)ʑX匌J@:(P Hzh@#֌6Y$ʹ -ڛhJۆqi7s^{|c)]zyۿP+𗈬MaH_?LfG/U ( ( ( ( ( ( ( ("iX1?.ቨ.a?6I"|O+<.2H]aizhV3G8v|t".RcR7t+d(E~0 zD$r2ۜ~oC+Qsvx~%8 ~_|@Nկ81\gNMI#x ÞƠ W Cidlu;$1G5xh\NM#oL Zv6u+fd$HbaKiܻN?ʥt0F۟+g ]Q+r{8"28S4.ofXɑ|֗ x&s_Мp{W.14h~RME;XVX`q֡|:֢oB1fSBP_ WI~Ծ<04%ar UΉ>cy ~1b5w|Iϊ1ٯ4D`A y{-+N SkڲVCXR)M^ѠSc^3! }b}VBَ'9ִ/j~!]/DY_'׿} UQDRBͲ>GLsSnJQ(W Cx`rbF }G:~çivZ1Q =V&,gߥI}kdsѻ4RVEPEPEPEPEPEPH)I1@ (;=7JkO8j_ ٛVr\Q0 "=_Z;-8*ᛯ[ino ZU>#/9]x0]> 3u&%S9/PQVҭtIbxP ==*9 jPX7uMr3<`Z\g:^qV \WKg.잹ȩZ]][Pi۬h=V'O2VK0 TI`z'_֚CH/G Է4V 5, up쇖?夿w5j9]APn<:cs[V57 ]vAl*բp֖Z Pu{ _N]6@ȫaՏ@6sX+W1q@ tX 鴫`I8h3D Gm vCċiҝzRzP!Ҕ`p:P }>5|4VR!-䝒I,O98(=e"|ۦuK *pl?B k@u=$ Mz%%Sr~SsW۴ͧ1;Lg99qw:)Ծ~Ǟ+|7s]Md 9)V5"ھ;/?p MLGN=ҾÈ67c&XL1#}0瞾o};^̠yJ}}ǡǾ%!<zbfEe}I]ֽ NzZ-T0I WiiehRin-lPN׉bgfIìh% $L vˆ*n.Kr{waҷRnGz<+d63G <M4Ҽ' m4H ǪՅ$qpxZZ)gڊ(((((( W|sZ|akmD:rJELr~wkMCX _v4E|!e u.W%1zu?θߎ b%#QB#ApN9^78R ᭭DdA&ӶJ:h9>ct`lҝQ+9 erGn"  0=*(((((&4u+`=cpoōj:-pwp~Q*%*nH/=6a#4׎cÚwyC޾W})ǚEEQ4w_JȨÔjf5>Ϟ[<t(c ~m1K#SI1S@ Z@5F)E0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( )8;qzj6:s3yv ӥ b|J ͭj'*"㔃Ty ėc^lb=$7 N4a. R#!{\ts '᳣xj ao% T9ڔ4|QwZ|Z20k G>xO^;]o..tn7h ֆ[\y5/glKv:xu^)-_ۏLwOY5y` 6gҴ/ɬi[X~77O_ x>}NU =?=6;XDa+XSHRlA Q<7ֺ8@ԊzSA7qB Z(AEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP^WZ#GkM-] eRH-##0'TH( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ^cef6b88lr1ڀ< &[^dB>ץYYh#0JpP c4  QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE QE var CC = require('config-chain').ConfigChain var inherits = require('inherits') var configDefs = require('./defaults.js') var types = configDefs.types var once = require('once') var fs = require('fs') var path = require('path') var nopt = require('nopt') var ini = require('ini') var Umask = configDefs.Umask var mkdirp = require('gentle-fs').mkdir var umask = require('../utils/umask') var isWindows = require('../utils/is-windows.js') exports.load = load exports.Conf = Conf exports.loaded = false exports.rootConf = null exports.usingBuiltin = false exports.defs = configDefs Object.defineProperty(exports, 'defaults', { get: function () { return configDefs.defaults }, enumerable: true }) Object.defineProperty(exports, 'types', { get: function () { return configDefs.types }, enumerable: true }) exports.validate = validate var myUid = process.getuid && process.getuid() var myGid = process.getgid && process.getgid() var loading = false var loadCbs = [] function load () { var cli, builtin, cb for (var i = 0; i < arguments.length; i++) { switch (typeof arguments[i]) { case 'string': builtin = arguments[i]; break case 'object': cli = arguments[i]; break case 'function': cb = arguments[i]; break } } if (!cb) cb = function () {} if (exports.loaded) { var ret = exports.loaded if (cli) { ret = new Conf(ret) ret.unshift(cli) } return process.nextTick(cb.bind(null, null, ret)) } // either a fresh object, or a clone of the passed in obj if (!cli) { cli = {} } else { cli = Object.keys(cli).reduce(function (c, k) { c[k] = cli[k] return c }, {}) } loadCbs.push(cb) if (loading) return loading = true cb = once(function (er, conf) { if (!er) { exports.loaded = conf loading = false } loadCbs.forEach(function (fn) { fn(er, conf) }) loadCbs.length = 0 }) // check for a builtin if provided. exports.usingBuiltin = !!builtin var rc = exports.rootConf = new Conf() if (builtin) { rc.addFile(builtin, 'builtin') } else { rc.add({}, 'builtin') } rc.on('load', function () { load_(builtin, rc, cli, cb) }) rc.on('error', cb) } function load_ (builtin, rc, cli, cb) { var defaults = configDefs.defaults var conf = new Conf(rc) conf.usingBuiltin = !!builtin conf.add(cli, 'cli') conf.addEnv() conf.loadPrefix(function (er) { if (er) return cb(er) // If you're doing `npm --userconfig=~/foo.npmrc` then you'd expect // that ~/.npmrc won't override the stuff in ~/foo.npmrc (or, indeed // be used at all). // // However, if the cwd is ~, then ~/.npmrc is the home for the project // config, and will override the userconfig. // // If you're not setting the userconfig explicitly, then it will be loaded // twice, which is harmless but excessive. If you *are* setting the // userconfig explicitly then it will override your explicit intent, and // that IS harmful and unexpected. // // Solution: Do not load project config file that is the same as either // the default or resolved userconfig value. npm will log a "verbose" // message about this when it happens, but it is a rare enough edge case // that we don't have to be super concerned about it. var projectConf = path.resolve(conf.localPrefix, '.npmrc') var defaultUserConfig = rc.get('userconfig') var resolvedUserConfig = conf.get('userconfig') if (!conf.get('global') && projectConf !== defaultUserConfig && projectConf !== resolvedUserConfig) { conf.addFile(projectConf, 'project') conf.once('load', afterPrefix) } else { conf.add({}, 'project') afterPrefix() } }) function afterPrefix () { conf.addFile(conf.get('userconfig'), 'user') conf.once('error', cb) conf.once('load', afterUser) } function afterUser () { // globalconfig and globalignorefile defaults // need to respond to the 'prefix' setting up to this point. // Eg, `npm config get globalconfig --prefix ~/local` should // return `~/local/etc/npmrc` // annoying humans and their expectations! if (conf.get('prefix')) { var etc = path.resolve(conf.get('prefix'), 'etc') defaults.globalconfig = path.resolve(etc, 'npmrc') defaults.globalignorefile = path.resolve(etc, 'npmignore') } conf.addFile(conf.get('globalconfig'), 'global') // move the builtin into the conf stack now. conf.root = defaults conf.add(rc.shift(), 'builtin') conf.once('load', function () { conf.loadExtras(afterExtras) }) } function afterExtras (er) { if (er) return cb(er) // warn about invalid bits. validate(conf) var cafile = conf.get('cafile') if (cafile) { return conf.loadCAFile(cafile, finalize) } finalize() } function finalize (er) { if (er) { return cb(er) } exports.loaded = conf cb(er, conf) } } // Basically the same as CC, but: // 1. Always ini // 2. Parses environment variable names in field values // 3. Field values that start with ~/ are replaced with process.env.HOME // 4. Can inherit from another Conf object, using it as the base. inherits(Conf, CC) function Conf (base) { if (!(this instanceof Conf)) return new Conf(base) CC.call(this) if (base) { if (base instanceof Conf) { this.root = base.list[0] || base.root } else { this.root = base } } else { this.root = configDefs.defaults } } Conf.prototype.loadPrefix = require('./load-prefix.js') Conf.prototype.loadCAFile = require('./load-cafile.js') Conf.prototype.setUser = require('./set-user.js') Conf.prototype.getCredentialsByURI = require('./get-credentials-by-uri.js') Conf.prototype.setCredentialsByURI = require('./set-credentials-by-uri.js') Conf.prototype.clearCredentialsByURI = require('./clear-credentials-by-uri.js') Conf.prototype.loadExtras = function (cb) { this.setUser(function (er) { if (er) return cb(er) // Without prefix, nothing will ever work mkdirp(this.prefix, cb) }.bind(this)) } Conf.prototype.save = function (where, cb) { var target = this.sources[where] if (!target || !(target.path || target.source) || !target.data) { var er if (where !== 'builtin') er = new Error('bad save target: ' + where) if (cb) { process.nextTick(cb.bind(null, er)) return this } return this.emit('error', er) } if (target.source) { var pref = target.prefix || '' Object.keys(target.data).forEach(function (k) { target.source[pref + k] = target.data[k] }) if (cb) process.nextTick(cb) return this } var data = ini.stringify(target.data) var then = function then (er) { if (er) return done(er) fs.chmod(target.path, mode, done) } var done = function done (er) { if (er) { if (cb) return cb(er) else return this.emit('error', er) } this._saving-- if (this._saving === 0) { if (cb) cb() this.emit('save') } } then = then.bind(this) done = done.bind(this) this._saving++ var mode = where === 'user' ? '0600' : '0666' if (!data.trim()) { fs.unlink(target.path, function () { // ignore the possible error (e.g. the file doesn't exist) done(null) }) } else { // we don't have to use inferOwner here, because gentle-fs will // mkdir with the correctly inferred ownership. Just preserve it. const dir = path.dirname(target.path) mkdirp(dir, function (er) { if (er) return then(er) fs.stat(dir, (er, st) => { if (er) return then(er) fs.writeFile(target.path, data, 'utf8', function (er) { if (er) return then(er) if (myUid === 0 && (myUid !== st.uid || myGid !== st.gid)) { fs.chown(target.path, st.uid, st.gid, then) } else { then() } }) }) }) } return this } Conf.prototype.addFile = function (file, name) { name = name || file var marker = { __source__: name } this.sources[name] = { path: file, type: 'ini' } this.push(marker) this._await() fs.readFile(file, 'utf8', function (er, data) { // just ignore missing files. if (er) return this.add({}, marker) this.addString(data, file, 'ini', marker) }.bind(this)) return this } // always ini files. Conf.prototype.parse = function (content, file) { return CC.prototype.parse.call(this, content, file, 'ini') } Conf.prototype.add = function (data, marker) { try { Object.keys(data).forEach(function (k) { const newKey = envReplace(k) const newField = parseField(data[k], newKey) delete data[k] data[newKey] = newField }) } catch (e) { this.emit('error', e) return this } return CC.prototype.add.call(this, data, marker) } Conf.prototype.addEnv = function (env) { env = env || process.env var conf = {} Object.keys(env) .filter(function (k) { return k.match(/^npm_config_/i) }) .forEach(function (k) { if (!env[k]) return // leave first char untouched, even if // it is a '_' - convert all other to '-' var p = k.toLowerCase() .replace(/^npm_config_/, '') .replace(/(?!^)_/g, '-') conf[p] = env[k] }) return CC.prototype.addEnv.call(this, '', conf, 'env') } function parseField (f, k) { if (typeof f !== 'string' && !(f instanceof String)) return f // type can be an array or single thing. var typeList = [].concat(types[k]) var isPath = typeList.indexOf(path) !== -1 var isBool = typeList.indexOf(Boolean) !== -1 var isString = typeList.indexOf(String) !== -1 var isUmask = typeList.indexOf(Umask) !== -1 var isNumber = typeList.indexOf(Number) !== -1 f = ('' + f).trim() if (f.match(/^".*"$/)) { try { f = JSON.parse(f) } catch (e) { throw new Error('Failed parsing JSON config key ' + k + ': ' + f) } } if (isBool && !isString && f === '') return true switch (f) { case 'true': return true case 'false': return false case 'null': return null case 'undefined': return undefined } f = envReplace(f) if (isPath) { var homePattern = isWindows ? /^~(\/|\\)/ : /^~\// if (f.match(homePattern) && process.env.HOME) { f = path.resolve(process.env.HOME, f.substr(2)) } f = path.resolve(f) } if (isUmask) f = umask.fromString(f) if (isNumber && !isNaN(f)) f = +f return f } function envReplace (f) { if (typeof f !== 'string' || !f) return f // replace any ${ENV} values with the appropriate environ. var envExpr = /(\\*)\$\{([^}]+)\}/g return f.replace(envExpr, function (orig, esc, name) { esc = esc.length && esc.length % 2 if (esc) return orig if (undefined === process.env[name]) { throw new Error('Failed to replace env in config: ' + orig) } return process.env[name] }) } function validate (cl) { // warn about invalid configs at every level. cl.list.forEach(function (conf) { nopt.clean(conf, configDefs.types) }) nopt.clean(cl.root, configDefs.types) }