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 'use strict' // npm pack // Packs the specified package into a .tgz file, which can then // be installed. // Set this early to avoid issues with circular dependencies. module.exports = pack const BB = require('bluebird') const byteSize = require('byte-size') const cacache = require('cacache') const columnify = require('columnify') const cp = require('child_process') const deprCheck = require('./utils/depr-check') const fpm = require('./fetch-package-metadata') const fs = require('graceful-fs') const install = require('./install') const lifecycle = BB.promisify(require('./utils/lifecycle')) const log = require('npmlog') const move = require('move-concurrently') const npm = require('./npm') const npmConfig = require('./config/figgy-config.js') const output = require('./utils/output') const pacote = require('pacote') const path = require('path') const PassThrough = require('stream').PassThrough const pathIsInside = require('path-is-inside') const pipe = BB.promisify(require('mississippi').pipe) const prepublishWarning = require('./utils/warn-deprecated')('prepublish-on-install') const pinflight = require('promise-inflight') const readJson = BB.promisify(require('read-package-json')) const tar = require('tar') const packlist = require('npm-packlist') const ssri = require('ssri') pack.usage = 'npm pack [[<@scope>/]...] [--dry-run]' // if it can be installed, it can be packed. pack.completion = install.completion function pack (args, silent, cb) { const cwd = process.cwd() if (typeof cb !== 'function') { cb = silent silent = false } if (args.length === 0) args = ['.'] BB.all( args.map((arg) => pack_(arg, cwd)) ).then((tarballs) => { if (!silent && npm.config.get('json')) { output(JSON.stringify(tarballs, null, 2)) } else if (!silent) { tarballs.forEach(logContents) output(tarballs.map((f) => path.relative(cwd, f.filename)).join('\n')) } return tarballs }).nodeify(cb) } function pack_ (pkg, dir) { return BB.fromNode((cb) => fpm(pkg, dir, cb)).then((mani) => { let name = mani.name[0] === '@' // scoped packages get special treatment ? mani.name.substr(1).replace(/\//g, '-') : mani.name const target = `${name}-${mani.version}.tgz` return pinflight(target, () => { const dryRun = npm.config.get('dry-run') if (mani._requested.type === 'directory') { return prepareDirectory(mani._resolved) .then(() => { return packDirectory(mani, mani._resolved, target, target, true, dryRun) }) } else if (dryRun) { log.verbose('pack', '--dry-run mode enabled. Skipping write.') return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'packing'}, (tmp) => { const tmpTarget = path.join(tmp, path.basename(target)) return packFromPackage(pkg, tmpTarget, target) }) } else { return packFromPackage(pkg, target, target) } }) }) } function packFromPackage (arg, target, filename) { const opts = npmConfig() return pacote.tarball.toFile(arg, target, opts) .then(() => cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'unpacking'}, (tmp) => { const tmpTarget = path.join(tmp, filename) return pacote.extract(arg, tmpTarget, opts) .then(() => readJson(path.join(tmpTarget, 'package.json'))) })) .then((pkg) => getContents(pkg, target, filename)) } module.exports.prepareDirectory = prepareDirectory function prepareDirectory (dir) { return readJson(path.join(dir, 'package.json')).then((pkg) => { if (!pkg.name) { throw new Error('package.json requires a "name" field') } if (!pkg.version) { throw new Error('package.json requires a valid "version" field') } if (!pathIsInside(dir, npm.tmp)) { if (pkg.scripts && pkg.scripts.prepublish) { prepublishWarning([ 'As of npm@5, `prepublish` scripts are deprecated.', 'Use `prepare` for build steps and `prepublishOnly` for upload-only.', 'See the deprecation note in `npm help scripts` for more information.' ]) } if (npm.config.get('ignore-prepublish')) { return lifecycle(pkg, 'prepare', dir).then(() => pkg) } else { return lifecycle(pkg, 'prepublish', dir).then(() => { return lifecycle(pkg, 'prepare', dir) }).then(() => pkg) } } return pkg }) } module.exports.packDirectory = packDirectory function packDirectory (mani, dir, target, filename, logIt, dryRun) { deprCheck(mani) return readJson(path.join(dir, 'package.json')).then((pkg) => { return lifecycle(pkg, 'prepack', dir) }).then(() => { return readJson(path.join(dir, 'package.json')) }).then((pkg) => { return cacache.tmp.withTmp(npm.tmp, {tmpPrefix: 'packing'}, (tmp) => { const tmpTarget = path.join(tmp, path.basename(target)) const tarOpt = { file: tmpTarget, cwd: dir, prefix: 'package/', portable: true, // Provide a specific date in the 1980s for the benefit of zip, // which is confounded by files dated at the Unix epoch 0. mtime: new Date('1985-10-26T08:15:00.000Z'), gzip: true } return BB.resolve(packlist({ path: dir })) // NOTE: node-tar does some Magic Stuff depending on prefixes for files // specifically with @ signs, so we just neutralize that one // and any such future "features" by prepending `./` .then((files) => tar.create(tarOpt, files.map((f) => `./${f}`))) .then(() => getContents(pkg, tmpTarget, filename, logIt)) // thread the content info through .tap(() => { if (dryRun) { log.verbose('pack', '--dry-run mode enabled. Skipping write.') } else { return move(tmpTarget, target, {Promise: BB, fs}) } }) .tap(() => lifecycle(pkg, 'postpack', dir)) }) }) } module.exports.logContents = logContents function logContents (tarball) { log.notice('') log.notice('', `${npm.config.get('unicode') ? '📦 ' : 'package:'} ${tarball.name}@${tarball.version}`) log.notice('=== Tarball Contents ===') if (tarball.files.length) { log.notice('', columnify(tarball.files.map((f) => { const bytes = byteSize(f.size) return {path: f.path, size: `${bytes.value}${bytes.unit}`} }), { include: ['size', 'path'], showHeaders: false })) } if (tarball.bundled.length) { log.notice('=== Bundled Dependencies ===') tarball.bundled.forEach((name) => log.notice('', name)) } log.notice('=== Tarball Details ===') log.notice('', columnify([ {name: 'name:', value: tarball.name}, {name: 'version:', value: tarball.version}, tarball.filename && {name: 'filename:', value: tarball.filename}, {name: 'package size:', value: byteSize(tarball.size)}, {name: 'unpacked size:', value: byteSize(tarball.unpackedSize)}, {name: 'shasum:', value: tarball.shasum}, { name: 'integrity:', value: tarball.integrity.toString().substr(0, 20) + '[...]' + tarball.integrity.toString().substr(80)}, tarball.bundled.length && {name: 'bundled deps:', value: tarball.bundled.length}, tarball.bundled.length && {name: 'bundled files:', value: tarball.entryCount - tarball.files.length}, tarball.bundled.length && {name: 'own files:', value: tarball.files.length}, {name: 'total files:', value: tarball.entryCount} ].filter((x) => x), { include: ['name', 'value'], showHeaders: false })) log.notice('', '') } module.exports.getContents = getContents function getContents (pkg, target, filename, silent) { const bundledWanted = new Set( pkg.bundleDependencies || pkg.bundledDependencies || [] ) const files = [] const bundled = new Set() let totalEntries = 0 let totalEntrySize = 0 return tar.t({ file: target, onentry (entry) { totalEntries++ totalEntrySize += entry.size const p = entry.path if (p.startsWith('package/node_modules/')) { const name = p.match(/^package\/node_modules\/((?:@[^/]+\/)?[^/]+)/)[1] if (bundledWanted.has(name)) { bundled.add(name) } } else { files.push({ path: entry.path.replace(/^package\//, ''), size: entry.size, mode: entry.mode }) } }, strip: 1 }) .then(() => BB.all([ BB.fromNode((cb) => fs.stat(target, cb)), ssri.fromStream(fs.createReadStream(target), { algorithms: ['sha1', 'sha512'] }) ])) .then(([stat, integrity]) => { const shasum = integrity['sha1'][0].hexDigest() return { id: pkg._id, name: pkg.name, version: pkg.version, from: pkg._from, size: stat.size, unpackedSize: totalEntrySize, shasum, integrity: ssri.parse(integrity['sha512'][0]), filename, files, entryCount: totalEntries, bundled: Array.from(bundled) } }) } const PASSTHROUGH_OPTS = [ 'always-auth', 'auth-type', 'ca', 'cafile', 'cert', 'git', 'local-address', 'maxsockets', 'offline', 'prefer-offline', 'prefer-online', 'proxy', 'https-proxy', 'registry', 'send-metrics', 'sso-poll-frequency', 'sso-type', 'strict-ssl' ] module.exports.packGitDep = packGitDep function packGitDep (manifest, dir) { const stream = new PassThrough() readJson(path.join(dir, 'package.json')).then((pkg) => { if (pkg.scripts && pkg.scripts.prepare) { log.verbose('prepareGitDep', `${manifest._spec}: installing devDeps and running prepare script.`) const cliArgs = PASSTHROUGH_OPTS.reduce((acc, opt) => { if (npm.config.get(opt, 'cli') != null) { acc.push(`--${opt}=${npm.config.get(opt)}`) } return acc }, []) const child = cp.spawn(process.env.NODE || process.execPath, [ require.resolve('../bin/npm-cli.js'), 'install', '--dev', '--prod', '--ignore-prepublish', '--no-progress', '--no-save' ].concat(cliArgs), { cwd: dir, env: process.env }) let errData = [] let errDataLen = 0 let outData = [] let outDataLen = 0 child.stdout.on('data', (data) => { outData.push(data) outDataLen += data.length log.gauge.pulse('preparing git package') }) child.stderr.on('data', (data) => { errData.push(data) errDataLen += data.length log.gauge.pulse('preparing git package') }) return BB.fromNode((cb) => { child.on('error', cb) child.on('exit', (code, signal) => { if (code > 0) { const err = new Error(`${signal}: npm exited with code ${code} while attempting to build ${manifest._requested}. Clone the repository manually and run 'npm install' in it for more information.`) err.code = code err.signal = signal cb(err) } else { cb() } }) }).then(() => { if (outDataLen > 0) log.silly('prepareGitDep', '1>', Buffer.concat(outData, outDataLen).toString()) if (errDataLen > 0) log.silly('prepareGitDep', '2>', Buffer.concat(errData, errDataLen).toString()) }, (err) => { if (outDataLen > 0) log.error('prepareGitDep', '1>', Buffer.concat(outData, outDataLen).toString()) if (errDataLen > 0) log.error('prepareGitDep', '2>', Buffer.concat(errData, errDataLen).toString()) throw err }) } }).then(() => { return readJson(path.join(dir, 'package.json')) }).then((pkg) => { return cacache.tmp.withTmp(npm.tmp, { tmpPrefix: 'pacote-packing' }, (tmp) => { const tmpTar = path.join(tmp, 'package.tgz') return packDirectory(manifest, dir, tmpTar).then(() => { return pipe(fs.createReadStream(tmpTar), stream) }) }) }).catch((err) => stream.emit('error', err)) return stream }