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 /* eslint-disable standard/no-callback-literal */ module.exports = distTag const BB = require('bluebird') const figgyPudding = require('figgy-pudding') const log = require('npmlog') const npa = require('libnpm/parse-arg') const npmConfig = require('./config/figgy-config.js') const output = require('./utils/output.js') const otplease = require('./utils/otplease.js') const readLocalPkg = BB.promisify(require('./utils/read-local-package.js')) const regFetch = require('libnpm/fetch') const semver = require('semver') const usage = require('./utils/usage') const DistTagOpts = figgyPudding({ tag: {} }) distTag.usage = usage( 'dist-tag', 'npm dist-tag add @ []' + '\nnpm dist-tag rm ' + '\nnpm dist-tag ls []' ) distTag.completion = function (opts, cb) { var argv = opts.conf.argv.remain if (argv.length === 2) { return cb(null, ['add', 'rm', 'ls']) } switch (argv[2]) { default: return cb() } } function UsageError () { throw Object.assign(new Error('Usage:\n' + distTag.usage), { code: 'EUSAGE' }) } function distTag ([cmd, pkg, tag], cb) { const opts = DistTagOpts(npmConfig()) return BB.try(() => { switch (cmd) { case 'add': case 'a': case 'set': case 's': return add(pkg, tag, opts) case 'rm': case 'r': case 'del': case 'd': case 'remove': return remove(pkg, tag, opts) case 'ls': case 'l': case 'sl': case 'list': return list(pkg, opts) default: if (!pkg) { return list(cmd, opts) } else { UsageError() } } }).then( x => cb(null, x), err => { if (err.code === 'EUSAGE') { cb(err.message) } else { cb(err) } } ) } function add (spec, tag, opts) { spec = npa(spec || '') const version = spec.rawSpec const t = (tag || opts.tag).trim() log.verbose('dist-tag add', t, 'to', spec.name + '@' + version) if (!spec || !version || !t) UsageError() if (semver.validRange(t)) { throw new Error('Tag name must not be a valid SemVer range: ' + t) } return fetchTags(spec, opts).then(tags => { if (tags[t] === version) { log.warn('dist-tag add', t, 'is already set to version', version) return } tags[t] = version const url = `/-/package/${spec.escapedName}/dist-tags/${encodeURIComponent(t)}` const reqOpts = opts.concat({ method: 'PUT', body: JSON.stringify(version), headers: { 'content-type': 'application/json' }, spec }) return otplease(reqOpts, reqOpts => regFetch(url, reqOpts)).then(() => { output(`+${t}: ${spec.name}@${version}`) }) }) } function remove (spec, tag, opts) { spec = npa(spec || '') log.verbose('dist-tag del', tag, 'from', spec.name) return fetchTags(spec, opts).then(tags => { if (!tags[tag]) { log.info('dist-tag del', tag, 'is not a dist-tag on', spec.name) throw new Error(tag + ' is not a dist-tag on ' + spec.name) } const version = tags[tag] delete tags[tag] const url = `/-/package/${spec.escapedName}/dist-tags/${encodeURIComponent(tag)}` const reqOpts = opts.concat({ method: 'DELETE', spec }) return otplease(reqOpts, reqOpts => regFetch(url, reqOpts)).then(() => { output(`-${tag}: ${spec.name}@${version}`) }) }) } function list (spec, opts) { if (!spec) { return readLocalPkg().then(pkg => { if (!pkg) { UsageError() } return list(pkg, opts) }) } spec = npa(spec) return fetchTags(spec, opts).then(tags => { var msg = Object.keys(tags).map(k => `${k}: ${tags[k]}`).sort().join('\n') output(msg) return tags }, err => { log.error('dist-tag ls', "Couldn't get dist-tag data for", spec) throw err }) } function fetchTags (spec, opts) { return regFetch.json( `/-/package/${spec.escapedName}/dist-tags`, opts.concat({ 'prefer-online': true, spec }) ).then(data => { if (data && typeof data === 'object') delete data._etag if (!data || !Object.keys(data).length) { throw new Error('No dist-tags found for ' + spec.name) } return data }) }