| 'use strict' | 
|   | 
| const assert = require('assert') | 
| const Buffer = require('buffer').Buffer | 
| const realZlib = require('zlib') | 
|   | 
| const constants = exports.constants = require('./constants.js') | 
| const Minipass = require('minipass') | 
|   | 
| const OriginalBufferConcat = Buffer.concat | 
|   | 
| const _superWrite = Symbol('_superWrite') | 
| class ZlibError extends Error { | 
|   constructor (err) { | 
|     super('zlib: ' + err.message) | 
|     this.code = err.code | 
|     this.errno = err.errno | 
|     /* istanbul ignore if */ | 
|     if (!this.code) | 
|       this.code = 'ZLIB_ERROR' | 
|   | 
|     this.message = 'zlib: ' + err.message | 
|     Error.captureStackTrace(this, this.constructor) | 
|   } | 
|   | 
|   get name () { | 
|     return 'ZlibError' | 
|   } | 
| } | 
|   | 
| // the Zlib class they all inherit from | 
| // This thing manages the queue of requests, and returns | 
| // true or false if there is anything in the queue when | 
| // you call the .write() method. | 
| const _opts = Symbol('opts') | 
| const _flushFlag = Symbol('flushFlag') | 
| const _finishFlushFlag = Symbol('finishFlushFlag') | 
| const _fullFlushFlag = Symbol('fullFlushFlag') | 
| const _handle = Symbol('handle') | 
| const _onError = Symbol('onError') | 
| const _sawError = Symbol('sawError') | 
| const _level = Symbol('level') | 
| const _strategy = Symbol('strategy') | 
| const _ended = Symbol('ended') | 
| const _defaultFullFlush = Symbol('_defaultFullFlush') | 
|   | 
| class ZlibBase extends Minipass { | 
|   constructor (opts, mode) { | 
|     if (!opts || typeof opts !== 'object') | 
|       throw new TypeError('invalid options for ZlibBase constructor') | 
|   | 
|     super(opts) | 
|     this[_sawError] = false | 
|     this[_ended] = false | 
|     this[_opts] = opts | 
|   | 
|     this[_flushFlag] = opts.flush | 
|     this[_finishFlushFlag] = opts.finishFlush | 
|     // this will throw if any options are invalid for the class selected | 
|     try { | 
|       this[_handle] = new realZlib[mode](opts) | 
|     } catch (er) { | 
|       // make sure that all errors get decorated properly | 
|       throw new ZlibError(er) | 
|     } | 
|   | 
|     this[_onError] = (err) => { | 
|       // no sense raising multiple errors, since we abort on the first one. | 
|       if (this[_sawError]) | 
|         return | 
|   | 
|       this[_sawError] = true | 
|   | 
|       // there is no way to cleanly recover. | 
|       // continuing only obscures problems. | 
|       this.close() | 
|       this.emit('error', err) | 
|     } | 
|   | 
|     this[_handle].on('error', er => this[_onError](new ZlibError(er))) | 
|     this.once('end', () => this.close) | 
|   } | 
|   | 
|   close () { | 
|     if (this[_handle]) { | 
|       this[_handle].close() | 
|       this[_handle] = null | 
|       this.emit('close') | 
|     } | 
|   } | 
|   | 
|   reset () { | 
|     if (!this[_sawError]) { | 
|       assert(this[_handle], 'zlib binding closed') | 
|       return this[_handle].reset() | 
|     } | 
|   } | 
|   | 
|   flush (flushFlag) { | 
|     if (this.ended) | 
|       return | 
|   | 
|     if (typeof flushFlag !== 'number') | 
|       flushFlag = this[_fullFlushFlag] | 
|     this.write(Object.assign(Buffer.alloc(0), { [_flushFlag]: flushFlag })) | 
|   } | 
|   | 
|   end (chunk, encoding, cb) { | 
|     if (chunk) | 
|       this.write(chunk, encoding) | 
|     this.flush(this[_finishFlushFlag]) | 
|     this[_ended] = true | 
|     return super.end(null, null, cb) | 
|   } | 
|   | 
|   get ended () { | 
|     return this[_ended] | 
|   } | 
|   | 
|   write (chunk, encoding, cb) { | 
|     // process the chunk using the sync process | 
|     // then super.write() all the outputted chunks | 
|     if (typeof encoding === 'function') | 
|       cb = encoding, encoding = 'utf8' | 
|   | 
|     if (typeof chunk === 'string') | 
|       chunk = Buffer.from(chunk, encoding) | 
|   | 
|     if (this[_sawError]) | 
|       return | 
|     assert(this[_handle], 'zlib binding closed') | 
|   | 
|     // _processChunk tries to .close() the native handle after it's done, so we | 
|     // intercept that by temporarily making it a no-op. | 
|     const nativeHandle = this[_handle]._handle | 
|     const originalNativeClose = nativeHandle.close | 
|     nativeHandle.close = () => {} | 
|     const originalClose = this[_handle].close | 
|     this[_handle].close = () => {} | 
|     // It also calls `Buffer.concat()` at the end, which may be convenient | 
|     // for some, but which we are not interested in as it slows us down. | 
|     Buffer.concat = (args) => args | 
|     let result | 
|     try { | 
|       const flushFlag = typeof chunk[_flushFlag] === 'number' | 
|         ? chunk[_flushFlag] : this[_flushFlag] | 
|       result = this[_handle]._processChunk(chunk, flushFlag) | 
|       // if we don't throw, reset it back how it was | 
|       Buffer.concat = OriginalBufferConcat | 
|     } catch (err) { | 
|       // or if we do, put Buffer.concat() back before we emit error | 
|       // Error events call into user code, which may call Buffer.concat() | 
|       Buffer.concat = OriginalBufferConcat | 
|       this[_onError](new ZlibError(err)) | 
|     } finally { | 
|       if (this[_handle]) { | 
|         // Core zlib resets `_handle` to null after attempting to close the | 
|         // native handle. Our no-op handler prevented actual closure, but we | 
|         // need to restore the `._handle` property. | 
|         this[_handle]._handle = nativeHandle | 
|         nativeHandle.close = originalNativeClose | 
|         this[_handle].close = originalClose | 
|         // `_processChunk()` adds an 'error' listener. If we don't remove it | 
|         // after each call, these handlers start piling up. | 
|         this[_handle].removeAllListeners('error') | 
|         // make sure OUR error listener is still attached tho | 
|       } | 
|     } | 
|   | 
|     if (this[_handle]) | 
|       this[_handle].on('error', er => this[_onError](new ZlibError(er))) | 
|   | 
|     let writeReturn | 
|     if (result) { | 
|       if (Array.isArray(result) && result.length > 0) { | 
|         // The first buffer is always `handle._outBuffer`, which would be | 
|         // re-used for later invocations; so, we always have to copy that one. | 
|         writeReturn = this[_superWrite](Buffer.from(result[0])) | 
|         for (let i = 1; i < result.length; i++) { | 
|           writeReturn = this[_superWrite](result[i]) | 
|         } | 
|       } else { | 
|         writeReturn = this[_superWrite](Buffer.from(result)) | 
|       } | 
|     } | 
|   | 
|     if (cb) | 
|       cb() | 
|     return writeReturn | 
|   } | 
|   | 
|   [_superWrite] (data) { | 
|     return super.write(data) | 
|   } | 
| } | 
|   | 
| class Zlib extends ZlibBase { | 
|   constructor (opts, mode) { | 
|     opts = opts || {} | 
|   | 
|     opts.flush = opts.flush || constants.Z_NO_FLUSH | 
|     opts.finishFlush = opts.finishFlush || constants.Z_FINISH | 
|     super(opts, mode) | 
|   | 
|     this[_fullFlushFlag] = constants.Z_FULL_FLUSH | 
|     this[_level] = opts.level | 
|     this[_strategy] = opts.strategy | 
|   } | 
|   | 
|   params (level, strategy) { | 
|     if (this[_sawError]) | 
|       return | 
|   | 
|     if (!this[_handle]) | 
|       throw new Error('cannot switch params when binding is closed') | 
|   | 
|     // no way to test this without also not supporting params at all | 
|     /* istanbul ignore if */ | 
|     if (!this[_handle].params) | 
|       throw new Error('not supported in this implementation') | 
|   | 
|     if (this[_level] !== level || this[_strategy] !== strategy) { | 
|       this.flush(constants.Z_SYNC_FLUSH) | 
|       assert(this[_handle], 'zlib binding closed') | 
|       // .params() calls .flush(), but the latter is always async in the | 
|       // core zlib. We override .flush() temporarily to intercept that and | 
|       // flush synchronously. | 
|       const origFlush = this[_handle].flush | 
|       this[_handle].flush = (flushFlag, cb) => { | 
|         this.flush(flushFlag) | 
|         cb() | 
|       } | 
|       try { | 
|         this[_handle].params(level, strategy) | 
|       } finally { | 
|         this[_handle].flush = origFlush | 
|       } | 
|       /* istanbul ignore else */ | 
|       if (this[_handle]) { | 
|         this[_level] = level | 
|         this[_strategy] = strategy | 
|       } | 
|     } | 
|   } | 
| } | 
|   | 
| // minimal 2-byte header | 
| class Deflate extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'Deflate') | 
|   } | 
| } | 
|   | 
| class Inflate extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'Inflate') | 
|   } | 
| } | 
|   | 
| // gzip - bigger header, same deflate compression | 
| const _portable = Symbol('_portable') | 
| class Gzip extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'Gzip') | 
|     this[_portable] = opts && !!opts.portable | 
|   } | 
|   | 
|   [_superWrite] (data) { | 
|     if (!this[_portable]) | 
|       return super[_superWrite](data) | 
|   | 
|     // we'll always get the header emitted in one first chunk | 
|     // overwrite the OS indicator byte with 0xFF | 
|     this[_portable] = false | 
|     data[9] = 255 | 
|     return super[_superWrite](data) | 
|   } | 
| } | 
|   | 
| class Gunzip extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'Gunzip') | 
|   } | 
| } | 
|   | 
| // raw - no header | 
| class DeflateRaw extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'DeflateRaw') | 
|   } | 
| } | 
|   | 
| class InflateRaw extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'InflateRaw') | 
|   } | 
| } | 
|   | 
| // auto-detect header. | 
| class Unzip extends Zlib { | 
|   constructor (opts) { | 
|     super(opts, 'Unzip') | 
|   } | 
| } | 
|   | 
| class Brotli extends ZlibBase { | 
|   constructor (opts, mode) { | 
|     opts = opts || {} | 
|   | 
|     opts.flush = opts.flush || constants.BROTLI_OPERATION_PROCESS | 
|     opts.finishFlush = opts.finishFlush || constants.BROTLI_OPERATION_FINISH | 
|   | 
|     super(opts, mode) | 
|   | 
|     this[_fullFlushFlag] = constants.BROTLI_OPERATION_FLUSH | 
|   } | 
| } | 
|   | 
| class BrotliCompress extends Brotli { | 
|   constructor (opts) { | 
|     super(opts, 'BrotliCompress') | 
|   } | 
| } | 
|   | 
| class BrotliDecompress extends Brotli { | 
|   constructor (opts) { | 
|     super(opts, 'BrotliDecompress') | 
|   } | 
| } | 
|   | 
| exports.Deflate = Deflate | 
| exports.Inflate = Inflate | 
| exports.Gzip = Gzip | 
| exports.Gunzip = Gunzip | 
| exports.DeflateRaw = DeflateRaw | 
| exports.InflateRaw = InflateRaw | 
| exports.Unzip = Unzip | 
| /* istanbul ignore else */ | 
| if (typeof realZlib.BrotliCompress === 'function') { | 
|   exports.BrotliCompress = BrotliCompress | 
|   exports.BrotliDecompress = BrotliDecompress | 
| } else { | 
|   exports.BrotliCompress = exports.BrotliDecompress = class { | 
|     constructor () { | 
|       throw new Error('Brotli is not supported in this version of Node.js') | 
|     } | 
|   } | 
| } |