| 'use strict'; | 
|   | 
| // (C) 1995-2013 Jean-loup Gailly and Mark Adler | 
| // (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin | 
| // | 
| // This software is provided 'as-is', without any express or implied | 
| // warranty. In no event will the authors be held liable for any damages | 
| // arising from the use of this software. | 
| // | 
| // Permission is granted to anyone to use this software for any purpose, | 
| // including commercial applications, and to alter it and redistribute it | 
| // freely, subject to the following restrictions: | 
| // | 
| // 1. The origin of this software must not be misrepresented; you must not | 
| //   claim that you wrote the original software. If you use this software | 
| //   in a product, an acknowledgment in the product documentation would be | 
| //   appreciated but is not required. | 
| // 2. Altered source versions must be plainly marked as such, and must not be | 
| //   misrepresented as being the original software. | 
| // 3. This notice may not be removed or altered from any source distribution. | 
|   | 
| // See state defs from inflate.js | 
| var BAD = 30;       /* got a data error -- remain here until reset */ | 
| var TYPE = 12;      /* i: waiting for type bits, including last-flag bit */ | 
|   | 
| /* | 
|    Decode literal, length, and distance codes and write out the resulting | 
|    literal and match bytes until either not enough input or output is | 
|    available, an end-of-block is encountered, or a data error is encountered. | 
|    When large enough input and output buffers are supplied to inflate(), for | 
|    example, a 16K input buffer and a 64K output buffer, more than 95% of the | 
|    inflate execution time is spent in this routine. | 
|   | 
|    Entry assumptions: | 
|   | 
|         state.mode === LEN | 
|         strm.avail_in >= 6 | 
|         strm.avail_out >= 258 | 
|         start >= strm.avail_out | 
|         state.bits < 8 | 
|   | 
|    On return, state.mode is one of: | 
|   | 
|         LEN -- ran out of enough output space or enough available input | 
|         TYPE -- reached end of block code, inflate() to interpret next block | 
|         BAD -- error in block data | 
|   | 
|    Notes: | 
|   | 
|     - The maximum input bits used by a length/distance pair is 15 bits for the | 
|       length code, 5 bits for the length extra, 15 bits for the distance code, | 
|       and 13 bits for the distance extra.  This totals 48 bits, or six bytes. | 
|       Therefore if strm.avail_in >= 6, then there is enough input to avoid | 
|       checking for available input while decoding. | 
|   | 
|     - The maximum bytes that a single length/distance pair can output is 258 | 
|       bytes, which is the maximum length that can be coded.  inflate_fast() | 
|       requires strm.avail_out >= 258 for each loop to avoid checking for | 
|       output space. | 
|  */ | 
| module.exports = function inflate_fast(strm, start) { | 
|   var state; | 
|   var _in;                    /* local strm.input */ | 
|   var last;                   /* have enough input while in < last */ | 
|   var _out;                   /* local strm.output */ | 
|   var beg;                    /* inflate()'s initial strm.output */ | 
|   var end;                    /* while out < end, enough space available */ | 
| //#ifdef INFLATE_STRICT | 
|   var dmax;                   /* maximum distance from zlib header */ | 
| //#endif | 
|   var wsize;                  /* window size or zero if not using window */ | 
|   var whave;                  /* valid bytes in the window */ | 
|   var wnext;                  /* window write index */ | 
|   // Use `s_window` instead `window`, avoid conflict with instrumentation tools | 
|   var s_window;               /* allocated sliding window, if wsize != 0 */ | 
|   var hold;                   /* local strm.hold */ | 
|   var bits;                   /* local strm.bits */ | 
|   var lcode;                  /* local strm.lencode */ | 
|   var dcode;                  /* local strm.distcode */ | 
|   var lmask;                  /* mask for first level of length codes */ | 
|   var dmask;                  /* mask for first level of distance codes */ | 
|   var here;                   /* retrieved table entry */ | 
|   var op;                     /* code bits, operation, extra bits, or */ | 
|                               /*  window position, window bytes to copy */ | 
|   var len;                    /* match length, unused bytes */ | 
|   var dist;                   /* match distance */ | 
|   var from;                   /* where to copy match from */ | 
|   var from_source; | 
|   | 
|   | 
|   var input, output; // JS specific, because we have no pointers | 
|   | 
|   /* copy state to local variables */ | 
|   state = strm.state; | 
|   //here = state.here; | 
|   _in = strm.next_in; | 
|   input = strm.input; | 
|   last = _in + (strm.avail_in - 5); | 
|   _out = strm.next_out; | 
|   output = strm.output; | 
|   beg = _out - (start - strm.avail_out); | 
|   end = _out + (strm.avail_out - 257); | 
| //#ifdef INFLATE_STRICT | 
|   dmax = state.dmax; | 
| //#endif | 
|   wsize = state.wsize; | 
|   whave = state.whave; | 
|   wnext = state.wnext; | 
|   s_window = state.window; | 
|   hold = state.hold; | 
|   bits = state.bits; | 
|   lcode = state.lencode; | 
|   dcode = state.distcode; | 
|   lmask = (1 << state.lenbits) - 1; | 
|   dmask = (1 << state.distbits) - 1; | 
|   | 
|   | 
|   /* decode literals and length/distances until end-of-block or not enough | 
|      input data or output space */ | 
|   | 
|   top: | 
|   do { | 
|     if (bits < 15) { | 
|       hold += input[_in++] << bits; | 
|       bits += 8; | 
|       hold += input[_in++] << bits; | 
|       bits += 8; | 
|     } | 
|   | 
|     here = lcode[hold & lmask]; | 
|   | 
|     dolen: | 
|     for (;;) { // Goto emulation | 
|       op = here >>> 24/*here.bits*/; | 
|       hold >>>= op; | 
|       bits -= op; | 
|       op = (here >>> 16) & 0xff/*here.op*/; | 
|       if (op === 0) {                          /* literal */ | 
|         //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? | 
|         //        "inflate:         literal '%c'\n" : | 
|         //        "inflate:         literal 0x%02x\n", here.val)); | 
|         output[_out++] = here & 0xffff/*here.val*/; | 
|       } | 
|       else if (op & 16) {                     /* length base */ | 
|         len = here & 0xffff/*here.val*/; | 
|         op &= 15;                           /* number of extra bits */ | 
|         if (op) { | 
|           if (bits < op) { | 
|             hold += input[_in++] << bits; | 
|             bits += 8; | 
|           } | 
|           len += hold & ((1 << op) - 1); | 
|           hold >>>= op; | 
|           bits -= op; | 
|         } | 
|         //Tracevv((stderr, "inflate:         length %u\n", len)); | 
|         if (bits < 15) { | 
|           hold += input[_in++] << bits; | 
|           bits += 8; | 
|           hold += input[_in++] << bits; | 
|           bits += 8; | 
|         } | 
|         here = dcode[hold & dmask]; | 
|   | 
|         dodist: | 
|         for (;;) { // goto emulation | 
|           op = here >>> 24/*here.bits*/; | 
|           hold >>>= op; | 
|           bits -= op; | 
|           op = (here >>> 16) & 0xff/*here.op*/; | 
|   | 
|           if (op & 16) {                      /* distance base */ | 
|             dist = here & 0xffff/*here.val*/; | 
|             op &= 15;                       /* number of extra bits */ | 
|             if (bits < op) { | 
|               hold += input[_in++] << bits; | 
|               bits += 8; | 
|               if (bits < op) { | 
|                 hold += input[_in++] << bits; | 
|                 bits += 8; | 
|               } | 
|             } | 
|             dist += hold & ((1 << op) - 1); | 
| //#ifdef INFLATE_STRICT | 
|             if (dist > dmax) { | 
|               strm.msg = 'invalid distance too far back'; | 
|               state.mode = BAD; | 
|               break top; | 
|             } | 
| //#endif | 
|             hold >>>= op; | 
|             bits -= op; | 
|             //Tracevv((stderr, "inflate:         distance %u\n", dist)); | 
|             op = _out - beg;                /* max distance in output */ | 
|             if (dist > op) {                /* see if copy from window */ | 
|               op = dist - op;               /* distance back in window */ | 
|               if (op > whave) { | 
|                 if (state.sane) { | 
|                   strm.msg = 'invalid distance too far back'; | 
|                   state.mode = BAD; | 
|                   break top; | 
|                 } | 
|   | 
| // (!) This block is disabled in zlib defaults, | 
| // don't enable it for binary compatibility | 
| //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR | 
| //                if (len <= op - whave) { | 
| //                  do { | 
| //                    output[_out++] = 0; | 
| //                  } while (--len); | 
| //                  continue top; | 
| //                } | 
| //                len -= op - whave; | 
| //                do { | 
| //                  output[_out++] = 0; | 
| //                } while (--op > whave); | 
| //                if (op === 0) { | 
| //                  from = _out - dist; | 
| //                  do { | 
| //                    output[_out++] = output[from++]; | 
| //                  } while (--len); | 
| //                  continue top; | 
| //                } | 
| //#endif | 
|               } | 
|               from = 0; // window index | 
|               from_source = s_window; | 
|               if (wnext === 0) {           /* very common case */ | 
|                 from += wsize - op; | 
|                 if (op < len) {         /* some from window */ | 
|                   len -= op; | 
|                   do { | 
|                     output[_out++] = s_window[from++]; | 
|                   } while (--op); | 
|                   from = _out - dist;  /* rest from output */ | 
|                   from_source = output; | 
|                 } | 
|               } | 
|               else if (wnext < op) {      /* wrap around window */ | 
|                 from += wsize + wnext - op; | 
|                 op -= wnext; | 
|                 if (op < len) {         /* some from end of window */ | 
|                   len -= op; | 
|                   do { | 
|                     output[_out++] = s_window[from++]; | 
|                   } while (--op); | 
|                   from = 0; | 
|                   if (wnext < len) {  /* some from start of window */ | 
|                     op = wnext; | 
|                     len -= op; | 
|                     do { | 
|                       output[_out++] = s_window[from++]; | 
|                     } while (--op); | 
|                     from = _out - dist;      /* rest from output */ | 
|                     from_source = output; | 
|                   } | 
|                 } | 
|               } | 
|               else {                      /* contiguous in window */ | 
|                 from += wnext - op; | 
|                 if (op < len) {         /* some from window */ | 
|                   len -= op; | 
|                   do { | 
|                     output[_out++] = s_window[from++]; | 
|                   } while (--op); | 
|                   from = _out - dist;  /* rest from output */ | 
|                   from_source = output; | 
|                 } | 
|               } | 
|               while (len > 2) { | 
|                 output[_out++] = from_source[from++]; | 
|                 output[_out++] = from_source[from++]; | 
|                 output[_out++] = from_source[from++]; | 
|                 len -= 3; | 
|               } | 
|               if (len) { | 
|                 output[_out++] = from_source[from++]; | 
|                 if (len > 1) { | 
|                   output[_out++] = from_source[from++]; | 
|                 } | 
|               } | 
|             } | 
|             else { | 
|               from = _out - dist;          /* copy direct from output */ | 
|               do {                        /* minimum length is three */ | 
|                 output[_out++] = output[from++]; | 
|                 output[_out++] = output[from++]; | 
|                 output[_out++] = output[from++]; | 
|                 len -= 3; | 
|               } while (len > 2); | 
|               if (len) { | 
|                 output[_out++] = output[from++]; | 
|                 if (len > 1) { | 
|                   output[_out++] = output[from++]; | 
|                 } | 
|               } | 
|             } | 
|           } | 
|           else if ((op & 64) === 0) {          /* 2nd level distance code */ | 
|             here = dcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; | 
|             continue dodist; | 
|           } | 
|           else { | 
|             strm.msg = 'invalid distance code'; | 
|             state.mode = BAD; | 
|             break top; | 
|           } | 
|   | 
|           break; // need to emulate goto via "continue" | 
|         } | 
|       } | 
|       else if ((op & 64) === 0) {              /* 2nd level length code */ | 
|         here = lcode[(here & 0xffff)/*here.val*/ + (hold & ((1 << op) - 1))]; | 
|         continue dolen; | 
|       } | 
|       else if (op & 32) {                     /* end-of-block */ | 
|         //Tracevv((stderr, "inflate:         end of block\n")); | 
|         state.mode = TYPE; | 
|         break top; | 
|       } | 
|       else { | 
|         strm.msg = 'invalid literal/length code'; | 
|         state.mode = BAD; | 
|         break top; | 
|       } | 
|   | 
|       break; // need to emulate goto via "continue" | 
|     } | 
|   } while (_in < last && _out < end); | 
|   | 
|   /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ | 
|   len = bits >> 3; | 
|   _in -= len; | 
|   bits -= len << 3; | 
|   hold &= (1 << bits) - 1; | 
|   | 
|   /* update state and return */ | 
|   strm.next_in = _in; | 
|   strm.next_out = _out; | 
|   strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last)); | 
|   strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end)); | 
|   state.hold = hold; | 
|   state.bits = bits; | 
|   return; | 
| }; |