1 /**
  2  * @license
  3  * @licstart
  4 JSZip - A Javascript class for generating and reading zip files
  5 <http://stuartk.com/jszip>
  6 
  7 (c) 2009-2014 Stuart Knightley <stuart [at] stuartk.com>
  8 Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.
  9 
 10 JSZip uses the library pako released under the MIT license :
 11 https://github.com/nodeca/pako/blob/master/LICENSE
 12  * @licend
 13 */
 14 !function(e){
 15     // if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.JSZip=e()}
 16     var globalScope = typeof window !== "undefined" ? window : (typeof global !== "undefined" ? global : {}),
 17         externs = globalScope.externs || (globalScope.externs = {});
 18     externs.JSZip = e();
 19 }(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
 20 'use strict';
 21 // private property
 22 var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 23 
 24 
 25 // public method for encoding
 26 exports.encode = function(input, utf8) {
 27     var output = "";
 28     var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
 29     var i = 0;
 30 
 31     while (i < input.length) {
 32 
 33         chr1 = input.charCodeAt(i++);
 34         chr2 = input.charCodeAt(i++);
 35         chr3 = input.charCodeAt(i++);
 36 
 37         enc1 = chr1 >> 2;
 38         enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
 39         enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
 40         enc4 = chr3 & 63;
 41 
 42         if (isNaN(chr2)) {
 43             enc3 = enc4 = 64;
 44         }
 45         else if (isNaN(chr3)) {
 46             enc4 = 64;
 47         }
 48 
 49         output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
 50 
 51     }
 52 
 53     return output;
 54 };
 55 
 56 // public method for decoding
 57 exports.decode = function(input, utf8) {
 58     var output = "";
 59     var chr1, chr2, chr3;
 60     var enc1, enc2, enc3, enc4;
 61     var i = 0;
 62 
 63     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 64 
 65     while (i < input.length) {
 66 
 67         enc1 = _keyStr.indexOf(input.charAt(i++));
 68         enc2 = _keyStr.indexOf(input.charAt(i++));
 69         enc3 = _keyStr.indexOf(input.charAt(i++));
 70         enc4 = _keyStr.indexOf(input.charAt(i++));
 71 
 72         chr1 = (enc1 << 2) | (enc2 >> 4);
 73         chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
 74         chr3 = ((enc3 & 3) << 6) | enc4;
 75 
 76         output = output + String.fromCharCode(chr1);
 77 
 78         if (enc3 != 64) {
 79             output = output + String.fromCharCode(chr2);
 80         }
 81         if (enc4 != 64) {
 82             output = output + String.fromCharCode(chr3);
 83         }
 84 
 85     }
 86 
 87     return output;
 88 
 89 };
 90 
 91 },{}],2:[function(_dereq_,module,exports){
 92 'use strict';
 93 function CompressedObject() {
 94     this.compressedSize = 0;
 95     this.uncompressedSize = 0;
 96     this.crc32 = 0;
 97     this.compressionMethod = null;
 98     this.compressedContent = null;
 99 }
100 
101 CompressedObject.prototype = {
102     /**
103      * Return the decompressed content in an unspecified format.
104      * The format will depend on the decompressor.
105      * @return {Object} the decompressed content.
106      */
107     getContent: function() {
108         return null; // see implementation
109     },
110     /**
111      * Return the compressed content in an unspecified format.
112      * The format will depend on the compressed conten source.
113      * @return {Object} the compressed content.
114      */
115     getCompressedContent: function() {
116         return null; // see implementation
117     }
118 };
119 module.exports = CompressedObject;
120 
121 },{}],3:[function(_dereq_,module,exports){
122 'use strict';
123 exports.STORE = {
124     magic: "\x00\x00",
125     compress: function(content) {
126         return content; // no compression
127     },
128     uncompress: function(content) {
129         return content; // no compression
130     },
131     compressInputType: null,
132     uncompressInputType: null
133 };
134 exports.DEFLATE = _dereq_('./flate');
135 
136 },{"./flate":8}],4:[function(_dereq_,module,exports){
137 'use strict';
138 
139 var utils = _dereq_('./utils');
140 
141 var table = [
142     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
143     0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
144     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
145     0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
146     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
147     0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
148     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
149     0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
150     0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
151     0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
152     0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
153     0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
154     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
155     0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
156     0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
157     0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
158     0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
159     0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
160     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
161     0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
162     0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
163     0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
164     0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
165     0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
166     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
167     0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
168     0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
169     0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
170     0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
171     0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
172     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
173     0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
174     0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
175     0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
176     0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
177     0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
178     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
179     0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
180     0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
181     0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
182     0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
183     0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
184     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
185     0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
186     0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
187     0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
188     0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
189     0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
190     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
191     0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
192     0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
193     0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
194     0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
195     0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
196     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
197     0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
198     0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
199     0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
200     0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
201     0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
202     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
203     0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
204     0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
205     0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
206 ];
207 
208 /**
209  *
210  *  Javascript crc32
211  *  http://www.webtoolkit.info/
212  *
213  */
214 module.exports = function crc32(input, crc) {
215     if (typeof input === "undefined" || !input.length) {
216         return 0;
217     }
218 
219     var isArray = utils.getTypeOf(input) !== "string";
220 
221     if (typeof(crc) == "undefined") {
222         crc = 0;
223     }
224     var x = 0;
225     var y = 0;
226     var b = 0;
227 
228     crc = crc ^ (-1);
229     for (var i = 0, iTop = input.length; i < iTop; i++) {
230         b = isArray ? input[i] : input.charCodeAt(i);
231         y = (crc ^ b) & 0xFF;
232         x = table[y];
233         crc = (crc >>> 8) ^ x;
234     }
235 
236     return crc ^ (-1);
237 };
238 // vim: set shiftwidth=4 softtabstop=4:
239 
240 },{"./utils":21}],5:[function(_dereq_,module,exports){
241 'use strict';
242 var utils = _dereq_('./utils');
243 
244 function DataReader(data) {
245     this.data = null; // type : see implementation
246     this.length = 0;
247     this.index = 0;
248 }
249 DataReader.prototype = {
250     /**
251      * Check that the offset will not go too far.
252      * @param {string} offset the additional offset to check.
253      * @throws {Error} an Error if the offset is out of bounds.
254      */
255     checkOffset: function(offset) {
256         this.checkIndex(this.index + offset);
257     },
258     /**
259      * Check that the specifed index will not be too far.
260      * @param {string} newIndex the index to check.
261      * @throws {Error} an Error if the index is out of bounds.
262      */
263     checkIndex: function(newIndex) {
264         if (this.length < newIndex || newIndex < 0) {
265             throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?");
266         }
267     },
268     /**
269      * Change the index.
270      * @param {number} newIndex The new index.
271      * @throws {Error} if the new index is out of the data.
272      */
273     setIndex: function(newIndex) {
274         this.checkIndex(newIndex);
275         this.index = newIndex;
276     },
277     /**
278      * Skip the next n bytes.
279      * @param {number} n the number of bytes to skip.
280      * @throws {Error} if the new index is out of the data.
281      */
282     skip: function(n) {
283         this.setIndex(this.index + n);
284     },
285     /**
286      * Get the byte at the specified index.
287      * @param {number} i the index to use.
288      * @return {number} a byte.
289      */
290     byteAt: function(i) {
291         // see implementations
292     },
293     /**
294      * Get the next number with a given byte size.
295      * @param {number} size the number of bytes to read.
296      * @return {number} the corresponding number.
297      */
298     readInt: function(size) {
299         var result = 0,
300             i;
301         this.checkOffset(size);
302         for (i = this.index + size - 1; i >= this.index; i--) {
303             result = (result << 8) + this.byteAt(i);
304         }
305         this.index += size;
306         return result;
307     },
308     /**
309      * Get the next string with a given byte size.
310      * @param {number} size the number of bytes to read.
311      * @return {string} the corresponding string.
312      */
313     readString: function(size) {
314         return utils.transformTo("string", this.readData(size));
315     },
316     /**
317      * Get raw data without conversion, <size> bytes.
318      * @param {number} size the number of bytes to read.
319      * @return {Object} the raw data, implementation specific.
320      */
321     readData: function(size) {
322         // see implementations
323     },
324     /**
325      * Find the last occurence of a zip signature (4 bytes).
326      * @param {string} sig the signature to find.
327      * @return {number} the index of the last occurence, -1 if not found.
328      */
329     lastIndexOfSignature: function(sig) {
330         // see implementations
331     },
332     /**
333      * Get the next date.
334      * @return {Date} the date.
335      */
336     readDate: function() {
337         var dostime = this.readInt(4);
338         return new Date(
339         ((dostime >> 25) & 0x7f) + 1980, // year
340         ((dostime >> 21) & 0x0f) - 1, // month
341         (dostime >> 16) & 0x1f, // day
342         (dostime >> 11) & 0x1f, // hour
343         (dostime >> 5) & 0x3f, // minute
344         (dostime & 0x1f) << 1); // second
345     }
346 };
347 module.exports = DataReader;
348 
349 },{"./utils":21}],6:[function(_dereq_,module,exports){
350 'use strict';
351 exports.base64 = false;
352 exports.binary = false;
353 exports.dir = false;
354 exports.createFolders = false;
355 exports.date = null;
356 exports.compression = null;
357 exports.comment = null;
358 
359 },{}],7:[function(_dereq_,module,exports){
360 'use strict';
361 var utils = _dereq_('./utils');
362 
363 /**
364  * @deprecated
365  * This function will be removed in a future version without replacement.
366  */
367 exports.string2binary = function(str) {
368     return utils.string2binary(str);
369 };
370 
371 /**
372  * @deprecated
373  * This function will be removed in a future version without replacement.
374  */
375 exports.string2Uint8Array = function(str) {
376     return utils.transformTo("uint8array", str);
377 };
378 
379 /**
380  * @deprecated
381  * This function will be removed in a future version without replacement.
382  */
383 exports.uint8Array2String = function(array) {
384     return utils.transformTo("string", array);
385 };
386 
387 /**
388  * @deprecated
389  * This function will be removed in a future version without replacement.
390  */
391 exports.string2Blob = function(str) {
392     var buffer = utils.transformTo("arraybuffer", str);
393     return utils.arrayBuffer2Blob(buffer);
394 };
395 
396 /**
397  * @deprecated
398  * This function will be removed in a future version without replacement.
399  */
400 exports.arrayBuffer2Blob = function(buffer) {
401     return utils.arrayBuffer2Blob(buffer);
402 };
403 
404 /**
405  * @deprecated
406  * This function will be removed in a future version without replacement.
407  */
408 exports.transformTo = function(outputType, input) {
409     return utils.transformTo(outputType, input);
410 };
411 
412 /**
413  * @deprecated
414  * This function will be removed in a future version without replacement.
415  */
416 exports.getTypeOf = function(input) {
417     return utils.getTypeOf(input);
418 };
419 
420 /**
421  * @deprecated
422  * This function will be removed in a future version without replacement.
423  */
424 exports.checkSupport = function(type) {
425     return utils.checkSupport(type);
426 };
427 
428 /**
429  * @deprecated
430  * This value will be removed in a future version without replacement.
431  */
432 exports.MAX_VALUE_16BITS = utils.MAX_VALUE_16BITS;
433 
434 /**
435  * @deprecated
436  * This value will be removed in a future version without replacement.
437  */
438 exports.MAX_VALUE_32BITS = utils.MAX_VALUE_32BITS;
439 
440 
441 /**
442  * @deprecated
443  * This function will be removed in a future version without replacement.
444  */
445 exports.pretty = function(str) {
446     return utils.pretty(str);
447 };
448 
449 /**
450  * @deprecated
451  * This function will be removed in a future version without replacement.
452  */
453 exports.findCompression = function(compressionMethod) {
454     return utils.findCompression(compressionMethod);
455 };
456 
457 /**
458  * @deprecated
459  * This function will be removed in a future version without replacement.
460  */
461 exports.isRegExp = function (object) {
462     return utils.isRegExp(object);
463 };
464 
465 
466 },{"./utils":21}],8:[function(_dereq_,module,exports){
467 'use strict';
468 var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined');
469 
470 var pako = _dereq_("pako");
471 exports.uncompressInputType = USE_TYPEDARRAY ? "uint8array" : "array";
472 exports.compressInputType = USE_TYPEDARRAY ? "uint8array" : "array";
473 
474 exports.magic = "\x08\x00";
475 exports.compress = function(input) {
476     return pako.deflateRaw(input);
477 };
478 exports.uncompress =  function(input) {
479     return pako.inflateRaw(input);
480 };
481 
482 },{"pako":24}],9:[function(_dereq_,module,exports){
483 'use strict';
484 
485 var base64 = _dereq_('./base64');
486 
487 /**
488 Usage:
489    zip = new JSZip();
490    zip.file("hello.txt", "Hello, World!").file("tempfile", "nothing");
491    zip.folder("images").file("smile.gif", base64Data, {base64: true});
492    zip.file("Xmas.txt", "Ho ho ho !", {date : new Date("December 25, 2007 00:00:01")});
493    zip.remove("tempfile");
494 
495    base64zip = zip.generate();
496 
497 **/
498 
499 /**
500  * Representation a of zip file in js
501  * @constructor
502  * @param {(String|ArrayBuffer|Uint8Array)=} data the data to load, if any (optional).
503  * @param {Object=} options the options for creating this objects (optional).
504  */
505 function JSZip(data, options) {
506     // if this constructor is used without `new`, it adds `new` before itself:
507     if(!(this instanceof JSZip)) return new JSZip(data, options);
508 
509     // object containing the files :
510     // {
511     //   "folder/" : {...},
512     //   "folder/data.txt" : {...}
513     // }
514     this.files = {};
515 
516     this.comment = null;
517 
518     // Where we are in the hierarchy
519     this.root = "";
520     if (data) {
521         this.load(data, options);
522     }
523     this.clone = function() {
524         var newObj = new JSZip();
525         for (var i in this) {
526             if (typeof this[i] !== "function") {
527                 newObj[i] = this[i];
528             }
529         }
530         return newObj;
531     };
532 }
533 JSZip.prototype = _dereq_('./object');
534 JSZip.prototype.load = _dereq_('./load');
535 JSZip.support = _dereq_('./support');
536 JSZip.defaults = _dereq_('./defaults');
537 
538 /**
539  * @deprecated
540  * This namespace will be removed in a future version without replacement.
541  */
542 JSZip.utils = _dereq_('./deprecatedPublicUtils');
543 
544 JSZip.base64 = {
545     /**
546      * @deprecated
547      * This method will be removed in a future version without replacement.
548      */
549     encode : function(input) {
550         return base64.encode(input);
551     },
552     /**
553      * @deprecated
554      * This method will be removed in a future version without replacement.
555      */
556     decode : function(input) {
557         return base64.decode(input);
558     }
559 };
560 JSZip.compressions = _dereq_('./compressions');
561 module.exports = JSZip;
562 
563 },{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(_dereq_,module,exports){
564 'use strict';
565 var base64 = _dereq_('./base64');
566 var ZipEntries = _dereq_('./zipEntries');
567 module.exports = function(data, options) {
568     var files, zipEntries, i, input;
569     options = options || {};
570     if (options.base64) {
571         data = base64.decode(data);
572     }
573 
574     zipEntries = new ZipEntries(data, options);
575     files = zipEntries.files;
576     for (i = 0; i < files.length; i++) {
577         input = files[i];
578         this.file(input.fileName, input.decompressed, {
579             binary: true,
580             optimizedBinaryString: true,
581             date: input.date,
582             dir: input.dir,
583             comment : input.fileComment.length ? input.fileComment : null,
584             createFolders: options.createFolders
585         });
586     }
587     if (zipEntries.zipComment.length) {
588         this.comment = zipEntries.zipComment;
589     }
590 
591     return this;
592 };
593 
594 },{"./base64":1,"./zipEntries":22}],11:[function(_dereq_,module,exports){
595 (function (Buffer){
596 'use strict';
597 module.exports = function(data, encoding){
598     return new Buffer(data, encoding);
599 };
600 module.exports.test = function(b){
601     return Buffer.isBuffer(b);
602 };
603 }).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined))
604 },{}],12:[function(_dereq_,module,exports){
605 'use strict';
606 var Uint8ArrayReader = _dereq_('./uint8ArrayReader');
607 
608 function NodeBufferReader(data) {
609     this.data = data;
610     this.length = this.data.length;
611     this.index = 0;
612 }
613 NodeBufferReader.prototype = new Uint8ArrayReader();
614 
615 /**
616  * @see DataReader.readData
617  */
618 NodeBufferReader.prototype.readData = function(size) {
619     this.checkOffset(size);
620     var result = this.data.slice(this.index, this.index + size);
621     this.index += size;
622     return result;
623 };
624 module.exports = NodeBufferReader;
625 
626 },{"./uint8ArrayReader":18}],13:[function(_dereq_,module,exports){
627 'use strict';
628 var support = _dereq_('./support');
629 var utils = _dereq_('./utils');
630 var crc32 = _dereq_('./crc32');
631 var signature = _dereq_('./signature');
632 var defaults = _dereq_('./defaults');
633 var base64 = _dereq_('./base64');
634 var compressions = _dereq_('./compressions');
635 var CompressedObject = _dereq_('./compressedObject');
636 var nodeBuffer = _dereq_('./nodeBuffer');
637 var utf8 = _dereq_('./utf8');
638 var StringWriter = _dereq_('./stringWriter');
639 var Uint8ArrayWriter = _dereq_('./uint8ArrayWriter');
640 
641 /**
642  * Returns the raw data of a ZipObject, decompress the content if necessary.
643  * @param {ZipObject} file the file to use.
644  * @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
645  */
646 var getRawData = function(file) {
647     if (file._data instanceof CompressedObject) {
648         file._data = file._data.getContent();
649         file.options.binary = true;
650         file.options.base64 = false;
651 
652         if (utils.getTypeOf(file._data) === "uint8array") {
653             var copy = file._data;
654             // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array.
655             // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file).
656             file._data = new Uint8Array(copy.length);
657             // with an empty Uint8Array, Opera fails with a "Offset larger than array size"
658             if (copy.length !== 0) {
659                 file._data.set(copy, 0);
660             }
661         }
662     }
663     return file._data;
664 };
665 
666 /**
667  * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it.
668  * @param {ZipObject} file the file to use.
669  * @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
670  */
671 var getBinaryData = function(file) {
672     var result = getRawData(file),
673         type = utils.getTypeOf(result);
674     if (type === "string") {
675         if (!file.options.binary) {
676             // unicode text !
677             // unicode string => binary string is a painful process, check if we can avoid it.
678             if (support.nodebuffer) {
679                 return nodeBuffer(result, "utf-8");
680             }
681         }
682         return file.asBinary();
683     }
684     return result;
685 };
686 
687 /**
688  * Transform this._data into a string.
689  * @param {function(!string):!string} filter a function String -> String, applied if not null on the result.
690  * @return {String} the string representing this._data.
691  */
692 var dataToString = function(asUTF8) {
693     var result = getRawData(this);
694     if (result === null || typeof result === "undefined") {
695         return "";
696     }
697     // if the data is a base64 string, we decode it before checking the encoding !
698     if (this.options.base64) {
699         result = base64.decode(result);
700     }
701     if (asUTF8 && this.options.binary) {
702         // JSZip.prototype.utf8decode supports arrays as input
703         // skip to array => string step, utf8decode will do it.
704         result = out.utf8decode(result);
705     }
706     else {
707         // no utf8 transformation, do the array => string step.
708         result = utils.transformTo("string", result);
709     }
710 
711     if (!asUTF8 && !this.options.binary) {
712         result = utils.transformTo("string", out.utf8encode(result));
713     }
714     return result;
715 };
716 /**
717  * A simple object representing a file in the zip file.
718  * @constructor
719  * @param {string} name the name of the file
720  * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data
721  * @param {Object} options the options of the file
722  */
723 var ZipObject = function(name, data, options) {
724     this.name = name;
725     this.dir = options.dir;
726     this.date = options.date;
727     this.comment = options.comment;
728 
729     this._data = data;
730     this.options = options;
731 
732     /*
733      * This object contains initial values for dir and date.
734      * With them, we can check if the user changed the deprecated metadata in
735      * `ZipObject#options` or not.
736      */
737     this._initialMetadata = {
738       dir : options.dir,
739       date : options.date
740     };
741 };
742 
743 ZipObject.prototype = {
744     /**
745      * Return the content as UTF8 string.
746      * @return {string} the UTF8 string.
747      */
748     asText: function() {
749         return dataToString.call(this, true);
750     },
751     /**
752      * Returns the binary content.
753      * @return {string} the content as binary.
754      */
755     asBinary: function() {
756         return dataToString.call(this, false);
757     },
758     /**
759      * Returns the content as a nodejs Buffer.
760      * @return {Buffer} the content as a Buffer.
761      */
762     asNodeBuffer: function() {
763         var result = getBinaryData(this);
764         return utils.transformTo("nodebuffer", result);
765     },
766     /**
767      * Returns the content as an Uint8Array.
768      * @return {Uint8Array} the content as an Uint8Array.
769      */
770     asUint8Array: function() {
771         var result = getBinaryData(this);
772         return utils.transformTo("uint8array", result);
773     },
774     /**
775      * Returns the content as an ArrayBuffer.
776      * @return {ArrayBuffer} the content as an ArrayBufer.
777      */
778     asArrayBuffer: function() {
779         return this.asUint8Array().buffer;
780     }
781 };
782 
783 /**
784  * Transform an integer into a string in hexadecimal.
785  * @private
786  * @param {number} dec the number to convert.
787  * @param {number} bytes the number of bytes to generate.
788  * @returns {string} the result.
789  */
790 var decToHex = function(dec, bytes) {
791     var hex = "",
792         i;
793     for (i = 0; i < bytes; i++) {
794         hex += String.fromCharCode(dec & 0xff);
795         dec = dec >>> 8;
796     }
797     return hex;
798 };
799 
800 /**
801  * Merge the objects passed as parameters into a new one.
802  * @private
803  * @param {...Object} var_args All objects to merge.
804  * @return {Object} a new object with the data of the others.
805  */
806 var extend = function() {
807     var result = {}, i, attr;
808     for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers
809         for (attr in arguments[i]) {
810             if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") {
811                 result[attr] = arguments[i][attr];
812             }
813         }
814     }
815     return result;
816 };
817 
818 /**
819  * Transforms the (incomplete) options from the user into the complete
820  * set of options to create a file.
821  * @private
822  * @param {Object} o the options from the user.
823  * @return {Object} the complete set of options.
824  */
825 var prepareFileAttrs = function(o) {
826     o = o || {};
827     if (o.base64 === true && (o.binary === null || o.binary === undefined)) {
828         o.binary = true;
829     }
830     o = extend(o, defaults);
831     o.date = o.date || new Date();
832     if (o.compression !== null) o.compression = o.compression.toUpperCase();
833 
834     return o;
835 };
836 
837 /**
838  * Add a file in the current folder.
839  * @private
840  * @param {string} name the name of the file
841  * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file
842  * @param {Object} o the options of the file
843  * @return {Object} the new file.
844  */
845 var fileAdd = function(name, data, o) {
846     // be sure sub folders exist
847     var dataType = utils.getTypeOf(data),
848         parent;
849 
850     o = prepareFileAttrs(o);
851 
852     if (o.createFolders && (parent = parentFolder(name))) {
853         folderAdd.call(this, parent, true);
854     }
855 
856     if (o.dir || data === null || typeof data === "undefined") {
857         o.base64 = false;
858         o.binary = false;
859         data = null;
860     }
861     else if (dataType === "string") {
862         if (o.binary && !o.base64) {
863             // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask
864             if (o.optimizedBinaryString !== true) {
865                 // this is a string, not in a base64 format.
866                 // Be sure that this is a correct "binary string"
867                 data = utils.string2binary(data);
868             }
869         }
870     }
871     else { // arraybuffer, uint8array, ...
872         o.base64 = false;
873         o.binary = true;
874 
875         if (!dataType && !(data instanceof CompressedObject)) {
876             throw new Error("The data of '" + name + "' is in an unsupported format !");
877         }
878 
879         // special case : it's way easier to work with Uint8Array than with ArrayBuffer
880         if (dataType === "arraybuffer") {
881             data = utils.transformTo("uint8array", data);
882         }
883     }
884 
885     var object = new ZipObject(name, data, o);
886     this.files[name] = object;
887     return object;
888 };
889 
890 /**
891  * Find the parent folder of the path.
892  * @private
893  * @param {string} path the path to use
894  * @return {string} the parent folder, or ""
895  */
896 var parentFolder = function (path) {
897     if (path.slice(-1) == '/') {
898         path = path.substring(0, path.length - 1);
899     }
900     var lastSlash = path.lastIndexOf('/');
901     return (lastSlash > 0) ? path.substring(0, lastSlash) : "";
902 };
903 
904 /**
905  * Add a (sub) folder in the current folder.
906  * @private
907  * @param {string} name the folder's name
908  * @param {boolean=} [createFolders] If true, automatically create sub
909  *  folders. Defaults to false.
910  * @return {Object} the new folder.
911  */
912 var folderAdd = function(name, createFolders) {
913     // Check the name ends with a /
914     if (name.slice(-1) != "/") {
915         name += "/"; // IE doesn't like substr(-1)
916     }
917 
918     createFolders = (typeof createFolders !== 'undefined') ? createFolders : false;
919 
920     // Does this folder already exist?
921     if (!this.files[name]) {
922         fileAdd.call(this, name, null, {
923             dir: true,
924             createFolders: createFolders
925         });
926     }
927     return this.files[name];
928 };
929 
930 /**
931  * Generate a JSZip.CompressedObject for a given zipOject.
932  * @param {ZipObject} file the object to read.
933  * @param {JSZip.compression} compression the compression to use.
934  * @return {JSZip.CompressedObject} the compressed result.
935  */
936 var generateCompressedObjectFrom = function(file, compression) {
937     var result = new CompressedObject(),
938         content;
939 
940     // the data has not been decompressed, we might reuse things !
941     if (file._data instanceof CompressedObject) {
942         result.uncompressedSize = file._data.uncompressedSize;
943         result.crc32 = file._data.crc32;
944 
945         if (result.uncompressedSize === 0 || file.dir) {
946             compression = compressions['STORE'];
947             result.compressedContent = "";
948             result.crc32 = 0;
949         }
950         else if (file._data.compressionMethod === compression.magic) {
951             result.compressedContent = file._data.getCompressedContent();
952         }
953         else {
954             content = file._data.getContent();
955             // need to decompress / recompress
956             result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content));
957         }
958     }
959     else {
960         // have uncompressed data
961         content = getBinaryData(file);
962         if (!content || content.length === 0 || file.dir) {
963             compression = compressions['STORE'];
964             content = "";
965         }
966         result.uncompressedSize = content.length;
967         result.crc32 = crc32(content);
968         result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content));
969     }
970 
971     result.compressedSize = result.compressedContent.length;
972     result.compressionMethod = compression.magic;
973 
974     return result;
975 };
976 
977 /**
978  * Generate the various parts used in the construction of the final zip file.
979  * @param {string} name the file name.
980  * @param {ZipObject} file the file content.
981  * @param {JSZip.CompressedObject} compressedObject the compressed object.
982  * @param {number} offset the current offset from the start of the zip file.
983  * @return {object} the zip parts.
984  */
985 var generateZipParts = function(name, file, compressedObject, offset) {
986     var data = compressedObject.compressedContent,
987         utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)),
988         comment = file.comment || "",
989         utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)),
990         useUTF8ForFileName = utfEncodedFileName.length !== file.name.length,
991         useUTF8ForComment = utfEncodedComment.length !== comment.length,
992         o = file.options,
993         dosTime,
994         dosDate,
995         extraFields = "",
996         unicodePathExtraField = "",
997         unicodeCommentExtraField = "",
998         dir, date;
999 
1000 
1001     // handle the deprecated options.dir
1002     if (file._initialMetadata.dir !== file.dir) {
1003         dir = file.dir;
1004     } else {
1005         dir = o.dir;
1006     }
1007 
1008     // handle the deprecated options.date
1009     if(file._initialMetadata.date !== file.date) {
1010         date = file.date;
1011     } else {
1012         date = o.date;
1013     }
1014 
1015     // date
1016     // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html
1017     // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
1018     // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
1019 
1020     dosTime = date.getHours();
1021     dosTime = dosTime << 6;
1022     dosTime = dosTime | date.getMinutes();
1023     dosTime = dosTime << 5;
1024     dosTime = dosTime | date.getSeconds() / 2;
1025 
1026     dosDate = date.getFullYear() - 1980;
1027     dosDate = dosDate << 4;
1028     dosDate = dosDate | (date.getMonth() + 1);
1029     dosDate = dosDate << 5;
1030     dosDate = dosDate | date.getDate();
1031 
1032     if (useUTF8ForFileName) {
1033         // set the unicode path extra field. unzip needs at least one extra
1034         // field to correctly handle unicode path, so using the path is as good
1035         // as any other information. This could improve the situation with
1036         // other archive managers too.
1037         // This field is usually used without the utf8 flag, with a non
1038         // unicode path in the header (winrar, winzip). This helps (a bit)
1039         // with the messy Windows' default compressed folders feature but
1040         // breaks on p7zip which doesn't seek the unicode path extra field.
1041         // So for now, UTF-8 everywhere !
1042         unicodePathExtraField =
1043             // Version
1044             decToHex(1, 1) +
1045             // NameCRC32
1046             decToHex(crc32(utfEncodedFileName), 4) +
1047             // UnicodeName
1048             utfEncodedFileName;
1049 
1050         extraFields +=
1051             // Info-ZIP Unicode Path Extra Field
1052             "\x75\x70" +
1053             // size
1054             decToHex(unicodePathExtraField.length, 2) +
1055             // content
1056             unicodePathExtraField;
1057     }
1058 
1059     if(useUTF8ForComment) {
1060 
1061         unicodeCommentExtraField =
1062             // Version
1063             decToHex(1, 1) +
1064             // CommentCRC32
1065             decToHex(this.crc32(utfEncodedComment), 4) +
1066             // UnicodeName
1067             utfEncodedComment;
1068 
1069         extraFields +=
1070             // Info-ZIP Unicode Path Extra Field
1071             "\x75\x63" +
1072             // size
1073             decToHex(unicodeCommentExtraField.length, 2) +
1074             // content
1075             unicodeCommentExtraField;
1076     }
1077 
1078     var header = "";
1079 
1080     // version needed to extract
1081     header += "\x0A\x00";
1082     // general purpose bit flag
1083     // set bit 11 if utf8
1084     header += (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00";
1085     // compression method
1086     header += compressedObject.compressionMethod;
1087     // last mod file time
1088     header += decToHex(dosTime, 2);
1089     // last mod file date
1090     header += decToHex(dosDate, 2);
1091     // crc-32
1092     header += decToHex(compressedObject.crc32, 4);
1093     // compressed size
1094     header += decToHex(compressedObject.compressedSize, 4);
1095     // uncompressed size
1096     header += decToHex(compressedObject.uncompressedSize, 4);
1097     // file name length
1098     header += decToHex(utfEncodedFileName.length, 2);
1099     // extra field length
1100     header += decToHex(extraFields.length, 2);
1101 
1102 
1103     var fileRecord = signature.LOCAL_FILE_HEADER + header + utfEncodedFileName + extraFields;
1104 
1105     var dirRecord = signature.CENTRAL_FILE_HEADER +
1106     // version made by (00: DOS)
1107     "\x14\x00" +
1108     // file header (common to file and central directory)
1109     header +
1110     // file comment length
1111     decToHex(utfEncodedComment.length, 2) +
1112     // disk number start
1113     "\x00\x00" +
1114     // internal file attributes TODO
1115     "\x00\x00" +
1116     // external file attributes
1117     (dir === true ? "\x10\x00\x00\x00" : "\x00\x00\x00\x00") +
1118     // relative offset of local header
1119     decToHex(offset, 4) +
1120     // file name
1121     utfEncodedFileName +
1122     // extra field
1123     extraFields +
1124     // file comment
1125     utfEncodedComment;
1126 
1127     return {
1128         fileRecord: fileRecord,
1129         dirRecord: dirRecord,
1130         compressedObject: compressedObject
1131     };
1132 };
1133 
1134 
1135 // return the actual prototype of JSZip
1136 var out = {
1137     /**
1138      * Read an existing zip and merge the data in the current JSZip object.
1139      * The implementation is in jszip-load.js, don't forget to include it.
1140      * @param {String|ArrayBuffer|Uint8Array|Buffer} stream  The stream to load
1141      * @param {Object} options Options for loading the stream.
1142      *  options.base64 : is the stream in base64 ? default : false
1143      * @return {JSZip} the current JSZip object
1144      */
1145     load: function(stream, options) {
1146         throw new Error("Load method is not defined. Is the file jszip-load.js included ?");
1147     },
1148 
1149     /**
1150      * Filter nested files/folders with the specified function.
1151      * @param {Function} search the predicate to use :
1152      * function (relativePath, file) {...}
1153      * It takes 2 arguments : the relative path and the file.
1154      * @return {Array} An array of matching elements.
1155      */
1156     filter: function(search) {
1157         var result = [],
1158             filename, relativePath, file, fileClone;
1159         for (filename in this.files) {
1160             if (!this.files.hasOwnProperty(filename)) {
1161                 continue;
1162             }
1163             file = this.files[filename];
1164             // return a new object, don't let the user mess with our internal objects :)
1165             fileClone = new ZipObject(file.name, file._data, extend(file.options));
1166             relativePath = filename.slice(this.root.length, filename.length);
1167             if (filename.slice(0, this.root.length) === this.root && // the file is in the current root
1168             search(relativePath, fileClone)) { // and the file matches the function
1169                 result.push(fileClone);
1170             }
1171         }
1172         return result;
1173     },
1174 
1175     /**
1176      * Add a file to the zip file, or search a file.
1177      * @param   {string|RegExp} name The name of the file to add (if data is defined),
1178      * the name of the file to find (if no data) or a regex to match files.
1179      * @param   {String|ArrayBuffer|Uint8Array|Buffer} data  The file data, either raw or base64 encoded
1180      * @param   {Object} o     File options
1181      * @return  {JSZip|Object|Array} this JSZip object (when adding a file),
1182      * a file (when searching by string) or an array of files (when searching by regex).
1183      */
1184     file: function(name, data, o) {
1185         if (arguments.length === 1) {
1186             if (utils.isRegExp(name)) {
1187                 var regexp = name;
1188                 return this.filter(function(relativePath, file) {
1189                     return !file.dir && regexp.test(relativePath);
1190                 });
1191             }
1192             else { // text
1193                 return this.filter(function(relativePath, file) {
1194                     return !file.dir && relativePath === name;
1195                 })[0] || null;
1196             }
1197         }
1198         else { // more than one argument : we have data !
1199             name = this.root + name;
1200             fileAdd.call(this, name, data, o);
1201         }
1202         return this;
1203     },
1204 
1205     /**
1206      * Add a directory to the zip file, or search.
1207      * @param   {String|RegExp} arg The name of the directory to add, or a regex to search folders.
1208      * @return  {JSZip} an object with the new directory as the root, or an array containing matching folders.
1209      */
1210     folder: function(arg) {
1211         if (!arg) {
1212             return this;
1213         }
1214 
1215         if (utils.isRegExp(arg)) {
1216             return this.filter(function(relativePath, file) {
1217                 return file.dir && arg.test(relativePath);
1218             });
1219         }
1220 
1221         // else, name is a new folder
1222         var name = this.root + arg;
1223         var newFolder = folderAdd.call(this, name);
1224 
1225         // Allow chaining by returning a new object with this folder as the root
1226         var ret = this.clone();
1227         ret.root = newFolder.name;
1228         return ret;
1229     },
1230 
1231     /**
1232      * Delete a file, or a directory and all sub-files, from the zip
1233      * @param {string} name the name of the file to delete
1234      * @return {JSZip} this JSZip object
1235      */
1236     remove: function(name) {
1237         name = this.root + name;
1238         var file = this.files[name];
1239         if (!file) {
1240             // Look for any folders
1241             if (name.slice(-1) != "/") {
1242                 name += "/";
1243             }
1244             file = this.files[name];
1245         }
1246 
1247         if (file && !file.dir) {
1248             // file
1249             delete this.files[name];
1250         } else {
1251             // maybe a folder, delete recursively
1252             var kids = this.filter(function(relativePath, file) {
1253                 return file.name.slice(0, name.length) === name;
1254             });
1255             for (var i = 0; i < kids.length; i++) {
1256                 delete this.files[kids[i].name];
1257             }
1258         }
1259 
1260         return this;
1261     },
1262 
1263     /**
1264      * Generate the complete zip file
1265      * @param {Object} options the options to generate the zip file :
1266      * - base64, (deprecated, use type instead) true to generate base64.
1267      * - compression, "STORE" by default.
1268      * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
1269      * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
1270      */
1271     generate: function(options) {
1272         options = extend(options || {}, {
1273             base64: true,
1274             compression: "STORE",
1275             type: "base64",
1276             comment: null
1277         });
1278 
1279         utils.checkSupport(options.type);
1280 
1281         var zipData = [],
1282             localDirLength = 0,
1283             centralDirLength = 0,
1284             writer, i,
1285             utfEncodedComment = utils.transformTo("string", this.utf8encode(options.comment || this.comment || ""));
1286 
1287         // first, generate all the zip parts.
1288         for (var name in this.files) {
1289             if (!this.files.hasOwnProperty(name)) {
1290                 continue;
1291             }
1292             var file = this.files[name];
1293 
1294             var compressionName = file.options.compression || options.compression.toUpperCase();
1295             var compression = compressions[compressionName];
1296             if (!compression) {
1297                 throw new Error(compressionName + " is not a valid compression method !");
1298             }
1299 
1300             var compressedObject = generateCompressedObjectFrom.call(this, file, compression);
1301 
1302             var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength);
1303             localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize;
1304             centralDirLength += zipPart.dirRecord.length;
1305             zipData.push(zipPart);
1306         }
1307 
1308         var dirEnd = "";
1309 
1310         // end of central dir signature
1311         dirEnd = signature.CENTRAL_DIRECTORY_END +
1312         // number of this disk
1313         "\x00\x00" +
1314         // number of the disk with the start of the central directory
1315         "\x00\x00" +
1316         // total number of entries in the central directory on this disk
1317         decToHex(zipData.length, 2) +
1318         // total number of entries in the central directory
1319         decToHex(zipData.length, 2) +
1320         // size of the central directory   4 bytes
1321         decToHex(centralDirLength, 4) +
1322         // offset of start of central directory with respect to the starting disk number
1323         decToHex(localDirLength, 4) +
1324         // .ZIP file comment length
1325         decToHex(utfEncodedComment.length, 2) +
1326         // .ZIP file comment
1327         utfEncodedComment;
1328 
1329 
1330         // we have all the parts (and the total length)
1331         // time to create a writer !
1332         var typeName = options.type.toLowerCase();
1333         if(typeName==="uint8array"||typeName==="arraybuffer"||typeName==="blob"||typeName==="nodebuffer") {
1334             writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length);
1335         }else{
1336             writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length);
1337         }
1338 
1339         for (i = 0; i < zipData.length; i++) {
1340             writer.append(zipData[i].fileRecord);
1341             writer.append(zipData[i].compressedObject.compressedContent);
1342         }
1343         for (i = 0; i < zipData.length; i++) {
1344             writer.append(zipData[i].dirRecord);
1345         }
1346 
1347         writer.append(dirEnd);
1348 
1349         var zip = writer.finalize();
1350 
1351 
1352 
1353         switch(options.type.toLowerCase()) {
1354             // case "zip is an Uint8Array"
1355             case "uint8array" :
1356             case "arraybuffer" :
1357             case "nodebuffer" :
1358                return utils.transformTo(options.type.toLowerCase(), zip);
1359             case "blob" :
1360                return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip));
1361             // case "zip is a string"
1362             case "base64" :
1363                return (options.base64) ? base64.encode(zip) : zip;
1364             default : // case "string" :
1365                return zip;
1366          }
1367 
1368     },
1369 
1370     /**
1371      * @deprecated
1372      * This method will be removed in a future version without replacement.
1373      */
1374     crc32: function (input, crc) {
1375         return crc32(input, crc);
1376     },
1377 
1378     /**
1379      * @deprecated
1380      * This method will be removed in a future version without replacement.
1381      */
1382     utf8encode: function (string) {
1383         return utils.transformTo("string", utf8.utf8encode(string));
1384     },
1385 
1386     /**
1387      * @deprecated
1388      * This method will be removed in a future version without replacement.
1389      */
1390     utf8decode: function (input) {
1391         return utf8.utf8decode(input);
1392     }
1393 };
1394 module.exports = out;
1395 
1396 },{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(_dereq_,module,exports){
1397 'use strict';
1398 exports.LOCAL_FILE_HEADER = "PK\x03\x04";
1399 exports.CENTRAL_FILE_HEADER = "PK\x01\x02";
1400 exports.CENTRAL_DIRECTORY_END = "PK\x05\x06";
1401 exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07";
1402 exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06";
1403 exports.DATA_DESCRIPTOR = "PK\x07\x08";
1404 
1405 },{}],15:[function(_dereq_,module,exports){
1406 'use strict';
1407 var DataReader = _dereq_('./dataReader');
1408 var utils = _dereq_('./utils');
1409 
1410 function StringReader(data, optimizedBinaryString) {
1411     this.data = data;
1412     if (!optimizedBinaryString) {
1413         this.data = utils.string2binary(this.data);
1414     }
1415     this.length = this.data.length;
1416     this.index = 0;
1417 }
1418 StringReader.prototype = new DataReader();
1419 /**
1420  * @see DataReader.byteAt
1421  */
1422 StringReader.prototype.byteAt = function(i) {
1423     return this.data.charCodeAt(i);
1424 };
1425 /**
1426  * @see DataReader.lastIndexOfSignature
1427  */
1428 StringReader.prototype.lastIndexOfSignature = function(sig) {
1429     return this.data.lastIndexOf(sig);
1430 };
1431 /**
1432  * @see DataReader.readData
1433  */
1434 StringReader.prototype.readData = function(size) {
1435     this.checkOffset(size);
1436     // this will work because the constructor applied the "& 0xff" mask.
1437     var result = this.data.slice(this.index, this.index + size);
1438     this.index += size;
1439     return result;
1440 };
1441 module.exports = StringReader;
1442 
1443 },{"./dataReader":5,"./utils":21}],16:[function(_dereq_,module,exports){
1444 'use strict';
1445 
1446 var utils = _dereq_('./utils');
1447 
1448 /**
1449  * An object to write any content to a string.
1450  * @constructor
1451  */
1452 var StringWriter = function() {
1453     this.data = [];
1454 };
1455 StringWriter.prototype = {
1456     /**
1457      * Append any content to the current string.
1458      * @param {Object} input the content to add.
1459      */
1460     append: function(input) {
1461         input = utils.transformTo("string", input);
1462         this.data.push(input);
1463     },
1464     /**
1465      * Finalize the construction an return the result.
1466      * @return {string} the generated string.
1467      */
1468     finalize: function() {
1469         return this.data.join("");
1470     }
1471 };
1472 
1473 module.exports = StringWriter;
1474 
1475 },{"./utils":21}],17:[function(_dereq_,module,exports){
1476 (function (Buffer){
1477 'use strict';
1478 exports.base64 = true;
1479 exports.array = true;
1480 exports.string = true;
1481 exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
1482 // contains true if JSZip can read/generate nodejs Buffer, false otherwise.
1483 // Browserify will provide a Buffer implementation for browsers, which is
1484 // an augmented Uint8Array (i.e., can be used as either Buffer or U8).
1485 exports.nodebuffer = typeof Buffer !== "undefined";
1486 // contains true if JSZip can read/generate Uint8Array, false otherwise.
1487 exports.uint8array = typeof Uint8Array !== "undefined";
1488 
1489 if (typeof ArrayBuffer === "undefined") {
1490     exports.blob = false;
1491 }
1492 else {
1493     var buffer = new ArrayBuffer(0);
1494     try {
1495         exports.blob = new Blob([buffer], {
1496             type: "application/zip"
1497         }).size === 0;
1498     }
1499     catch (e) {
1500         try {
1501             var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
1502             var builder = new Builder();
1503             builder.append(buffer);
1504             exports.blob = builder.getBlob('application/zip').size === 0;
1505         }
1506         catch (e) {
1507             exports.blob = false;
1508         }
1509     }
1510 }
1511 
1512 }).call(this,(typeof Buffer !== "undefined" ? Buffer : undefined))
1513 },{}],18:[function(_dereq_,module,exports){
1514 'use strict';
1515 var DataReader = _dereq_('./dataReader');
1516 
1517 function Uint8ArrayReader(data) {
1518     if (data) {
1519         this.data = data;
1520         this.length = this.data.length;
1521         this.index = 0;
1522     }
1523 }
1524 Uint8ArrayReader.prototype = new DataReader();
1525 /**
1526  * @see DataReader.byteAt
1527  */
1528 Uint8ArrayReader.prototype.byteAt = function(i) {
1529     return this.data[i];
1530 };
1531 /**
1532  * @see DataReader.lastIndexOfSignature
1533  */
1534 Uint8ArrayReader.prototype.lastIndexOfSignature = function(sig) {
1535     var sig0 = sig.charCodeAt(0),
1536         sig1 = sig.charCodeAt(1),
1537         sig2 = sig.charCodeAt(2),
1538         sig3 = sig.charCodeAt(3);
1539     for (var i = this.length - 4; i >= 0; --i) {
1540         if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) {
1541             return i;
1542         }
1543     }
1544 
1545     return -1;
1546 };
1547 /**
1548  * @see DataReader.readData
1549  */
1550 Uint8ArrayReader.prototype.readData = function(size) {
1551     this.checkOffset(size);
1552     if(size === 0) {
1553         // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of [].
1554         return new Uint8Array(0);
1555     }
1556     var result = this.data.subarray(this.index, this.index + size);
1557     this.index += size;
1558     return result;
1559 };
1560 module.exports = Uint8ArrayReader;
1561 
1562 },{"./dataReader":5}],19:[function(_dereq_,module,exports){
1563 'use strict';
1564 
1565 var utils = _dereq_('./utils');
1566 
1567 /**
1568  * An object to write any content to an Uint8Array.
1569  * @constructor
1570  * @param {number} length The length of the array.
1571  */
1572 var Uint8ArrayWriter = function(length) {
1573     this.data = new Uint8Array(length);
1574     this.index = 0;
1575 };
1576 Uint8ArrayWriter.prototype = {
1577     /**
1578      * Append any content to the current array.
1579      * @param {Object} input the content to add.
1580      */
1581     append: function(input) {
1582         if (input.length !== 0) {
1583             // with an empty Uint8Array, Opera fails with a "Offset larger than array size"
1584             input = utils.transformTo("uint8array", input);
1585             this.data.set(input, this.index);
1586             this.index += input.length;
1587         }
1588     },
1589     /**
1590      * Finalize the construction an return the result.
1591      * @return {Uint8Array} the generated array.
1592      */
1593     finalize: function() {
1594         return this.data;
1595     }
1596 };
1597 
1598 module.exports = Uint8ArrayWriter;
1599 
1600 },{"./utils":21}],20:[function(_dereq_,module,exports){
1601 'use strict';
1602 
1603 var utils = _dereq_('./utils');
1604 var support = _dereq_('./support');
1605 var nodeBuffer = _dereq_('./nodeBuffer');
1606 
1607 /**
1608  * The following functions come from pako, from pako/lib/utils/strings
1609  * released under the MIT license, see pako https://github.com/nodeca/pako/
1610  */
1611 
1612 // Table with utf8 lengths (calculated by first byte of sequence)
1613 // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
1614 // because max possible codepoint is 0x10ffff
1615 var _utf8len = new Array(256);
1616 for (var i=0; i<256; i++) {
1617   _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1);
1618 }
1619 _utf8len[254]=_utf8len[254]=1; // Invalid sequence start
1620 
1621 // convert string to array (typed, when possible)
1622 var string2buf = function (str) {
1623     var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
1624 
1625     // count binary size
1626     for (m_pos = 0; m_pos < str_len; m_pos++) {
1627         c = str.charCodeAt(m_pos);
1628         if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
1629             c2 = str.charCodeAt(m_pos+1);
1630             if ((c2 & 0xfc00) === 0xdc00) {
1631                 c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
1632                 m_pos++;
1633             }
1634         }
1635         buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
1636     }
1637 
1638     // allocate buffer
1639     if (support.uint8array) {
1640         buf = new Uint8Array(buf_len);
1641     } else {
1642         buf = new Array(buf_len);
1643     }
1644 
1645     // convert
1646     for (i=0, m_pos = 0; i < buf_len; m_pos++) {
1647         c = str.charCodeAt(m_pos);
1648         if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
1649             c2 = str.charCodeAt(m_pos+1);
1650             if ((c2 & 0xfc00) === 0xdc00) {
1651                 c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
1652                 m_pos++;
1653             }
1654         }
1655         if (c < 0x80) {
1656             /* one byte */
1657             buf[i++] = c;
1658         } else if (c < 0x800) {
1659             /* two bytes */
1660             buf[i++] = 0xC0 | (c >>> 6);
1661             buf[i++] = 0x80 | (c & 0x3f);
1662         } else if (c < 0x10000) {
1663             /* three bytes */
1664             buf[i++] = 0xE0 | (c >>> 12);
1665             buf[i++] = 0x80 | (c >>> 6 & 0x3f);
1666             buf[i++] = 0x80 | (c & 0x3f);
1667         } else {
1668             /* four bytes */
1669             buf[i++] = 0xf0 | (c >>> 18);
1670             buf[i++] = 0x80 | (c >>> 12 & 0x3f);
1671             buf[i++] = 0x80 | (c >>> 6 & 0x3f);
1672             buf[i++] = 0x80 | (c & 0x3f);
1673         }
1674     }
1675 
1676     return buf;
1677 };
1678 
1679 // Calculate max possible position in utf8 buffer,
1680 // that will not break sequence. If that's not possible
1681 // - (very small limits) return max size as is.
1682 //
1683 // buf[] - utf8 bytes array
1684 // max   - length limit (mandatory);
1685 var utf8border = function(buf, max) {
1686     var pos;
1687 
1688     max = max || buf.length;
1689     if (max > buf.length) { max = buf.length; }
1690 
1691     // go back from last position, until start of sequence found
1692     pos = max-1;
1693     while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
1694 
1695     // Fuckup - very small and broken sequence,
1696     // return max, because we should return something anyway.
1697     if (pos < 0) { return max; }
1698 
1699     // If we came to start of buffer - that means vuffer is too small,
1700     // return max too.
1701     if (pos === 0) { return max; }
1702 
1703     return (pos + _utf8len[buf[pos]] > max) ? pos : max;
1704 };
1705 
1706 // convert array to string
1707 var buf2string = function (buf) {
1708     var str, i, out, c, c_len;
1709     var len = buf.length;
1710 
1711     // Reserve max possible length (2 words per char)
1712     // NB: by unknown reasons, Array is significantly faster for
1713     //     String.fromCharCode.apply than Uint16Array.
1714     var utf16buf = new Array(len*2);
1715 
1716     for (out=0, i=0; i<len;) {
1717         c = buf[i++];
1718         // quick process ascii
1719         if (c < 0x80) { utf16buf[out++] = c; continue; }
1720 
1721         c_len = _utf8len[c];
1722         // skip 5 & 6 byte codes
1723         if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; }
1724 
1725         // apply mask on first byte
1726         c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
1727         // join the rest
1728         while (c_len > 1 && i < len) {
1729             c = (c << 6) | (buf[i++] & 0x3f);
1730             c_len--;
1731         }
1732 
1733         // terminated by end of string?
1734         if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
1735 
1736         if (c < 0x10000) {
1737             utf16buf[out++] = c;
1738         } else {
1739             c -= 0x10000;
1740             utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
1741             utf16buf[out++] = 0xdc00 | (c & 0x3ff);
1742         }
1743     }
1744 
1745     // shrinkBuf(utf16buf, out)
1746     if (utf16buf.length !== out) {
1747         if(utf16buf.subarray) {
1748             utf16buf = utf16buf.subarray(0, out);
1749         } else {
1750             utf16buf.length = out;
1751         }
1752     }
1753 
1754     // return String.fromCharCode.apply(null, utf16buf);
1755     return utils.applyFromCharCode(utf16buf);
1756 };
1757 
1758 
1759 // That's all for the pako functions.
1760 
1761 
1762 /**
1763  * Transform a javascript string into an array (typed if possible) of bytes,
1764  * UTF-8 encoded.
1765  * @param {String} str the string to encode
1766  * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string.
1767  */
1768 exports.utf8encode = function utf8encode(str) {
1769     if (support.nodebuffer) {
1770         return nodeBuffer(str, "utf-8");
1771     }
1772 
1773     return string2buf(str);
1774 };
1775 
1776 
1777 /**
1778  * Transform a bytes array (or a representation) representing an UTF-8 encoded
1779  * string into a javascript string.
1780  * @param {Array|Uint8Array|Buffer} buf the data de decode
1781  * @return {String} the decoded string.
1782  */
1783 exports.utf8decode = function utf8decode(buf) {
1784     if (support.nodebuffer) {
1785         return utils.transformTo("nodebuffer", buf).toString("utf-8");
1786     }
1787 
1788     buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf);
1789 
1790     // return buf2string(buf);
1791     // Chrome prefers to work with "small" chunks of data
1792     // for the method buf2string.
1793     // Firefox and Chrome has their own shortcut, IE doesn't seem to really care.
1794     var result = [], k = 0, len = buf.length, chunk = 65536;
1795     while (k < len) {
1796         var nextBoundary = utf8border(buf, Math.min(k + chunk, len));
1797         if (support.uint8array) {
1798             result.push(buf2string(buf.subarray(k, nextBoundary)));
1799         } else {
1800             result.push(buf2string(buf.slice(k, nextBoundary)));
1801         }
1802         k = nextBoundary;
1803     }
1804     return result.join("");
1805 
1806 };
1807 // vim: set shiftwidth=4 softtabstop=4:
1808 
1809 },{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(_dereq_,module,exports){
1810 'use strict';
1811 var support = _dereq_('./support');
1812 var compressions = _dereq_('./compressions');
1813 var nodeBuffer = _dereq_('./nodeBuffer');
1814 /**
1815  * Convert a string to a "binary string" : a string containing only char codes between 0 and 255.
1816  * @param {string} str the string to transform.
1817  * @return {String} the binary string.
1818  */
1819 exports.string2binary = function(str) {
1820     var result = "";
1821     for (var i = 0; i < str.length; i++) {
1822         result += String.fromCharCode(str.charCodeAt(i) & 0xff);
1823     }
1824     return result;
1825 };
1826 exports.arrayBuffer2Blob = function(buffer) {
1827     exports.checkSupport("blob");
1828 
1829     try {
1830         // Blob constructor
1831         return new Blob([buffer], {
1832             type: "application/zip"
1833         });
1834     }
1835     catch (e) {
1836 
1837         try {
1838             // deprecated, browser only, old way
1839             var Builder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
1840             var builder = new Builder();
1841             builder.append(buffer);
1842             return builder.getBlob('application/zip');
1843         }
1844         catch (e) {
1845 
1846             // well, fuck ?!
1847             throw new Error("Bug : can't construct the Blob.");
1848         }
1849     }
1850 
1851 
1852 };
1853 /**
1854  * The identity function.
1855  * @param {Object} input the input.
1856  * @return {Object} the same input.
1857  */
1858 function identity(input) {
1859     return input;
1860 }
1861 
1862 /**
1863  * Fill in an array with a string.
1864  * @param {String} str the string to use.
1865  * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated).
1866  * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array.
1867  */
1868 function stringToArrayLike(str, array) {
1869     for (var i = 0; i < str.length; ++i) {
1870         array[i] = str.charCodeAt(i) & 0xFF;
1871     }
1872     return array;
1873 }
1874 
1875 /**
1876  * Transform an array-like object to a string.
1877  * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform.
1878  * @return {String} the result.
1879  */
1880 function arrayLikeToString(array) {
1881     // Performances notes :
1882     // --------------------
1883     // String.fromCharCode.apply(null, array) is the fastest, see
1884     // see http://jsperf.com/converting-a-uint8array-to-a-string/2
1885     // but the stack is limited (and we can get huge arrays !).
1886     //
1887     // result += String.fromCharCode(array[i]); generate too many strings !
1888     //
1889     // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2
1890     var chunk = 65536;
1891     var result = [],
1892         len = array.length,
1893         type = exports.getTypeOf(array),
1894         k = 0,
1895         canUseApply = true;
1896       try {
1897          switch(type) {
1898             case "uint8array":
1899                String.fromCharCode.apply(null, new Uint8Array(0));
1900                break;
1901             case "nodebuffer":
1902                String.fromCharCode.apply(null, nodeBuffer(0));
1903                break;
1904          }
1905       } catch(e) {
1906          canUseApply = false;
1907       }
1908 
1909       // no apply : slow and painful algorithm
1910       // default browser on android 4.*
1911       if (!canUseApply) {
1912          var resultStr = "";
1913          for(var i = 0; i < array.length;i++) {
1914             resultStr += String.fromCharCode(array[i]);
1915          }
1916     return resultStr;
1917     }
1918     while (k < len && chunk > 1) {
1919         try {
1920             if (type === "array" || type === "nodebuffer") {
1921                 result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len))));
1922             }
1923             else {
1924                 result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len))));
1925             }
1926             k += chunk;
1927         }
1928         catch (e) {
1929             chunk = Math.floor(chunk / 2);
1930         }
1931     }
1932     return result.join("");
1933 }
1934 
1935 exports.applyFromCharCode = arrayLikeToString;
1936 
1937 
1938 /**
1939  * Copy the data from an array-like to an other array-like.
1940  * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array.
1941  * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated.
1942  * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array.
1943  */
1944 function arrayLikeToArrayLike(arrayFrom, arrayTo) {
1945     for (var i = 0; i < arrayFrom.length; i++) {
1946         arrayTo[i] = arrayFrom[i];
1947     }
1948     return arrayTo;
1949 }
1950 
1951 // a matrix containing functions to transform everything into everything.
1952 var transform = {};
1953 
1954 // string to ?
1955 transform["string"] = {
1956     "string": identity,
1957     "array": function(input) {
1958         return stringToArrayLike(input, new Array(input.length));
1959     },
1960     "arraybuffer": function(input) {
1961         return transform["string"]["uint8array"](input).buffer;
1962     },
1963     "uint8array": function(input) {
1964         return stringToArrayLike(input, new Uint8Array(input.length));
1965     },
1966     "nodebuffer": function(input) {
1967         return stringToArrayLike(input, nodeBuffer(input.length));
1968     }
1969 };
1970 
1971 // array to ?
1972 transform["array"] = {
1973     "string": arrayLikeToString,
1974     "array": identity,
1975     "arraybuffer": function(input) {
1976         return (new Uint8Array(input)).buffer;
1977     },
1978     "uint8array": function(input) {
1979         return new Uint8Array(input);
1980     },
1981     "nodebuffer": function(input) {
1982         return nodeBuffer(input);
1983     }
1984 };
1985 
1986 // arraybuffer to ?
1987 transform["arraybuffer"] = {
1988     "string": function(input) {
1989         return arrayLikeToString(new Uint8Array(input));
1990     },
1991     "array": function(input) {
1992         return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength));
1993     },
1994     "arraybuffer": identity,
1995     "uint8array": function(input) {
1996         return new Uint8Array(input);
1997     },
1998     "nodebuffer": function(input) {
1999         return nodeBuffer(new Uint8Array(input));
2000     }
2001 };
2002 
2003 // uint8array to ?
2004 transform["uint8array"] = {
2005     "string": arrayLikeToString,
2006     "array": function(input) {
2007         return arrayLikeToArrayLike(input, new Array(input.length));
2008     },
2009     "arraybuffer": function(input) {
2010         return input.buffer;
2011     },
2012     "uint8array": identity,
2013     "nodebuffer": function(input) {
2014         return nodeBuffer(input);
2015     }
2016 };
2017 
2018 // nodebuffer to ?
2019 transform["nodebuffer"] = {
2020     "string": arrayLikeToString,
2021     "array": function(input) {
2022         return arrayLikeToArrayLike(input, new Array(input.length));
2023     },
2024     "arraybuffer": function(input) {
2025         return transform["nodebuffer"]["uint8array"](input).buffer;
2026     },
2027     "uint8array": function(input) {
2028         return arrayLikeToArrayLike(input, new Uint8Array(input.length));
2029     },
2030     "nodebuffer": identity
2031 };
2032 
2033 /**
2034  * Transform an input into any type.
2035  * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer.
2036  * If no output type is specified, the unmodified input will be returned.
2037  * @param {String} outputType the output type.
2038  * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert.
2039  * @throws {Error} an Error if the browser doesn't support the requested output type.
2040  */
2041 exports.transformTo = function(outputType, input) {
2042     if (!input) {
2043         // undefined, null, etc
2044         // an empty string won't harm.
2045         input = "";
2046     }
2047     if (!outputType) {
2048         return input;
2049     }
2050     exports.checkSupport(outputType);
2051     var inputType = exports.getTypeOf(input);
2052     var result = transform[inputType][outputType](input);
2053     return result;
2054 };
2055 
2056 /**
2057  * Return the type of the input.
2058  * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer.
2059  * @param {Object} input the input to identify.
2060  * @return {String} the (lowercase) type of the input.
2061  */
2062 exports.getTypeOf = function(input) {
2063     if (typeof input === "string") {
2064         return "string";
2065     }
2066     if (Object.prototype.toString.call(input) === "[object Array]") {
2067         return "array";
2068     }
2069     if (support.nodebuffer && nodeBuffer.test(input)) {
2070         return "nodebuffer";
2071     }
2072     if (support.uint8array && input instanceof Uint8Array) {
2073         return "uint8array";
2074     }
2075     if (support.arraybuffer && input instanceof ArrayBuffer) {
2076         return "arraybuffer";
2077     }
2078 };
2079 
2080 /**
2081  * Throw an exception if the type is not supported.
2082  * @param {String} type the type to check.
2083  * @throws {Error} an Error if the browser doesn't support the requested type.
2084  */
2085 exports.checkSupport = function(type) {
2086     var supported = support[type.toLowerCase()];
2087     if (!supported) {
2088         throw new Error(type + " is not supported by this browser");
2089     }
2090 };
2091 exports.MAX_VALUE_16BITS = 65535;
2092 exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1
2093 
2094 /**
2095  * Prettify a string read as binary.
2096  * @param {string} str the string to prettify.
2097  * @return {string} a pretty string.
2098  */
2099 exports.pretty = function(str) {
2100     var res = '',
2101         code, i;
2102     for (i = 0; i < (str || "").length; i++) {
2103         code = str.charCodeAt(i);
2104         res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
2105     }
2106     return res;
2107 };
2108 
2109 /**
2110  * Find a compression registered in JSZip.
2111  * @param {string} compressionMethod the method magic to find.
2112  * @return {Object|null} the JSZip compression object, null if none found.
2113  */
2114 exports.findCompression = function(compressionMethod) {
2115     for (var method in compressions) {
2116         if (!compressions.hasOwnProperty(method)) {
2117             continue;
2118         }
2119         if (compressions[method].magic === compressionMethod) {
2120             return compressions[method];
2121         }
2122     }
2123     return null;
2124 };
2125 /**
2126 * Cross-window, cross-Node-context regular expression detection
2127 * @param  {Object}  object Anything
2128 * @return {Boolean}        true if the object is a regular expression,
2129 * false otherwise
2130 */
2131 exports.isRegExp = function (object) {
2132     return Object.prototype.toString.call(object) === "[object RegExp]";
2133 };
2134 
2135 
2136 },{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(_dereq_,module,exports){
2137 'use strict';
2138 var StringReader = _dereq_('./stringReader');
2139 var NodeBufferReader = _dereq_('./nodeBufferReader');
2140 var Uint8ArrayReader = _dereq_('./uint8ArrayReader');
2141 var utils = _dereq_('./utils');
2142 var sig = _dereq_('./signature');
2143 var ZipEntry = _dereq_('./zipEntry');
2144 var support = _dereq_('./support');
2145 var jszipProto = _dereq_('./object');
2146 //  class ZipEntries {{{
2147 /**
2148  * All the entries in the zip file.
2149  * @constructor
2150  * @param {String|ArrayBuffer|Uint8Array} data the binary stream to load.
2151  * @param {Object} loadOptions Options for loading the stream.
2152  */
2153 function ZipEntries(data, loadOptions) {
2154     this.files = [];
2155     this.loadOptions = loadOptions;
2156     if (data) {
2157         this.load(data);
2158     }
2159 }
2160 ZipEntries.prototype = {
2161     /**
2162      * Check that the reader is on the speficied signature.
2163      * @param {string} expectedSignature the expected signature.
2164      * @throws {Error} if it is an other signature.
2165      */
2166     checkSignature: function(expectedSignature) {
2167         var signature = this.reader.readString(4);
2168         if (signature !== expectedSignature) {
2169             throw new Error("Corrupted zip or bug : unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")");
2170         }
2171     },
2172     /**
2173      * Read the end of the central directory.
2174      */
2175     readBlockEndOfCentral: function() {
2176         this.diskNumber = this.reader.readInt(2);
2177         this.diskWithCentralDirStart = this.reader.readInt(2);
2178         this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
2179         this.centralDirRecords = this.reader.readInt(2);
2180         this.centralDirSize = this.reader.readInt(4);
2181         this.centralDirOffset = this.reader.readInt(4);
2182 
2183         this.zipCommentLength = this.reader.readInt(2);
2184         // warning : the encoding depends of the system locale
2185         // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded.
2186         // On a windows machine, this field is encoded with the localized windows code page.
2187         this.zipComment = this.reader.readString(this.zipCommentLength);
2188         // To get consistent behavior with the generation part, we will assume that
2189         // this is utf8 encoded.
2190         this.zipComment = jszipProto.utf8decode(this.zipComment);
2191     },
2192     /**
2193      * Read the end of the Zip 64 central directory.
2194      * Not merged with the method readEndOfCentral :
2195      * The end of central can coexist with its Zip64 brother,
2196      * I don't want to read the wrong number of bytes !
2197      */
2198     readBlockZip64EndOfCentral: function() {
2199         this.zip64EndOfCentralSize = this.reader.readInt(8);
2200         this.versionMadeBy = this.reader.readString(2);
2201         this.versionNeeded = this.reader.readInt(2);
2202         this.diskNumber = this.reader.readInt(4);
2203         this.diskWithCentralDirStart = this.reader.readInt(4);
2204         this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
2205         this.centralDirRecords = this.reader.readInt(8);
2206         this.centralDirSize = this.reader.readInt(8);
2207         this.centralDirOffset = this.reader.readInt(8);
2208 
2209         this.zip64ExtensibleData = {};
2210         var extraDataSize = this.zip64EndOfCentralSize - 44,
2211             index = 0,
2212             extraFieldId,
2213             extraFieldLength,
2214             extraFieldValue;
2215         while (index < extraDataSize) {
2216             extraFieldId = this.reader.readInt(2);
2217             extraFieldLength = this.reader.readInt(4);
2218             extraFieldValue = this.reader.readString(extraFieldLength);
2219             this.zip64ExtensibleData[extraFieldId] = {
2220                 id: extraFieldId,
2221                 length: extraFieldLength,
2222                 value: extraFieldValue
2223             };
2224         }
2225     },
2226     /**
2227      * Read the end of the Zip 64 central directory locator.
2228      */
2229     readBlockZip64EndOfCentralLocator: function() {
2230         this.diskWithZip64CentralDirStart = this.reader.readInt(4);
2231         this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
2232         this.disksCount = this.reader.readInt(4);
2233         if (this.disksCount > 1) {
2234             throw new Error("Multi-volumes zip are not supported");
2235         }
2236     },
2237     /**
2238      * Read the local files, based on the offset read in the central part.
2239      */
2240     readLocalFiles: function() {
2241         var i, file;
2242         for (i = 0; i < this.files.length; i++) {
2243             file = this.files[i];
2244             this.reader.setIndex(file.localHeaderOffset);
2245             this.checkSignature(sig.LOCAL_FILE_HEADER);
2246             file.readLocalPart(this.reader);
2247             file.handleUTF8();
2248         }
2249     },
2250     /**
2251      * Read the central directory.
2252      */
2253     readCentralDir: function() {
2254         var file;
2255 
2256         this.reader.setIndex(this.centralDirOffset);
2257         while (this.reader.readString(4) === sig.CENTRAL_FILE_HEADER) {
2258             file = new ZipEntry({
2259                 zip64: this.zip64
2260             }, this.loadOptions);
2261             file.readCentralPart(this.reader);
2262             this.files.push(file);
2263         }
2264     },
2265     /**
2266      * Read the end of central directory.
2267      */
2268     readEndOfCentral: function() {
2269         var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END);
2270         if (offset === -1) {
2271             throw new Error("Corrupted zip : can't find end of central directory");
2272         }
2273         this.reader.setIndex(offset);
2274         this.checkSignature(sig.CENTRAL_DIRECTORY_END);
2275         this.readBlockEndOfCentral();
2276 
2277 
2278         /* extract from the zip spec :
2279             4)  If one of the fields in the end of central directory
2280                 record is too small to hold required data, the field
2281                 should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
2282                 ZIP64 format record should be created.
2283             5)  The end of central directory record and the
2284                 Zip64 end of central directory locator record must
2285                 reside on the same disk when splitting or spanning
2286                 an archive.
2287          */
2288         if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) {
2289             this.zip64 = true;
2290 
2291             /*
2292             Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
2293             the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents
2294             all numbers as 64-bit double precision IEEE 754 floating point numbers.
2295             So, we have 53bits for integers and bitwise operations treat everything as 32bits.
2296             see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
2297             and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
2298             */
2299 
2300             // should look for a zip64 EOCD locator
2301             offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
2302             if (offset === -1) {
2303                 throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");
2304             }
2305             this.reader.setIndex(offset);
2306             this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
2307             this.readBlockZip64EndOfCentralLocator();
2308 
2309             // now the zip64 EOCD record
2310             this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
2311             this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END);
2312             this.readBlockZip64EndOfCentral();
2313         }
2314     },
2315     prepareReader: function(data) {
2316         var type = utils.getTypeOf(data);
2317         if (type === "string" && !support.uint8array) {
2318             this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString);
2319         }
2320         else if (type === "nodebuffer") {
2321             this.reader = new NodeBufferReader(data);
2322         }
2323         else {
2324             this.reader = new Uint8ArrayReader(utils.transformTo("uint8array", data));
2325         }
2326     },
2327     /**
2328      * Read a zip file and create ZipEntries.
2329      * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.
2330      */
2331     load: function(data) {
2332         this.prepareReader(data);
2333         this.readEndOfCentral();
2334         this.readCentralDir();
2335         this.readLocalFiles();
2336     }
2337 };
2338 // }}} end of ZipEntries
2339 module.exports = ZipEntries;
2340 
2341 },{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(_dereq_,module,exports){
2342 'use strict';
2343 var StringReader = _dereq_('./stringReader');
2344 var utils = _dereq_('./utils');
2345 var CompressedObject = _dereq_('./compressedObject');
2346 var jszipProto = _dereq_('./object');
2347 // class ZipEntry {{{
2348 /**
2349  * An entry in the zip file.
2350  * @constructor
2351  * @param {Object} options Options of the current file.
2352  * @param {Object} loadOptions Options for loading the stream.
2353  */
2354 function ZipEntry(options, loadOptions) {
2355     this.options = options;
2356     this.loadOptions = loadOptions;
2357 }
2358 ZipEntry.prototype = {
2359     /**
2360      * say if the file is encrypted.
2361      * @return {boolean} true if the file is encrypted, false otherwise.
2362      */
2363     isEncrypted: function() {
2364         // bit 1 is set
2365         return (this.bitFlag & 0x0001) === 0x0001;
2366     },
2367     /**
2368      * say if the file has utf-8 filename/comment.
2369      * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
2370      */
2371     useUTF8: function() {
2372         // bit 11 is set
2373         return (this.bitFlag & 0x0800) === 0x0800;
2374     },
2375     /**
2376      * Prepare the function used to generate the compressed content from this ZipFile.
2377      * @param {DataReader} reader the reader to use.
2378      * @param {number} from the offset from where we should read the data.
2379      * @param {number} length the length of the data to read.
2380      * @return {Function} the callback to get the compressed content (the type depends of the DataReader class).
2381      */
2382     prepareCompressedContent: function(reader, from, length) {
2383         return function() {
2384             var previousIndex = reader.index;
2385             reader.setIndex(from);
2386             var compressedFileData = reader.readData(length);
2387             reader.setIndex(previousIndex);
2388 
2389             return compressedFileData;
2390         };
2391     },
2392     /**
2393      * Prepare the function used to generate the uncompressed content from this ZipFile.
2394      * @param {DataReader} reader the reader to use.
2395      * @param {number} from the offset from where we should read the data.
2396      * @param {number} length the length of the data to read.
2397      * @param {JSZip.compression} compression the compression used on this file.
2398      * @param {number} uncompressedSize the uncompressed size to expect.
2399      * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class).
2400      */
2401     prepareContent: function(reader, from, length, compression, uncompressedSize) {
2402         return function() {
2403 
2404             var compressedFileData = utils.transformTo(compression.uncompressInputType, this.getCompressedContent());
2405             var uncompressedFileData = compression.uncompress(compressedFileData);
2406 
2407             if (uncompressedFileData.length !== uncompressedSize) {
2408                 throw new Error("Bug : uncompressed data size mismatch");
2409             }
2410 
2411             return uncompressedFileData;
2412         };
2413     },
2414     /**
2415      * Read the local part of a zip file and add the info in this object.
2416      * @param {DataReader} reader the reader to use.
2417      */
2418     readLocalPart: function(reader) {
2419         var compression, localExtraFieldsLength;
2420 
2421         // we already know everything from the central dir !
2422         // If the central dir data are false, we are doomed.
2423         // On the bright side, the local part is scary  : zip64, data descriptors, both, etc.
2424         // The less data we get here, the more reliable this should be.
2425         // Let's skip the whole header and dash to the data !
2426         reader.skip(22);
2427         // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
2428         // Strangely, the filename here is OK.
2429         // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
2430         // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
2431         // Search "unzip mismatching "local" filename continuing with "central" filename version" on
2432         // the internet.
2433         //
2434         // I think I see the logic here : the central directory is used to display
2435         // content and the local directory is used to extract the files. Mixing / and \
2436         // may be used to display \ to windows users and use / when extracting the files.
2437         // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
2438         this.fileNameLength = reader.readInt(2);
2439         localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
2440         this.fileName = reader.readString(this.fileNameLength);
2441         reader.skip(localExtraFieldsLength);
2442 
2443         if (this.compressedSize == -1 || this.uncompressedSize == -1) {
2444             throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " + "(compressedSize == -1 || uncompressedSize == -1)");
2445         }
2446 
2447         compression = utils.findCompression(this.compressionMethod);
2448         if (compression === null) { // no compression found
2449             throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")");
2450         }
2451         this.decompressed = new CompressedObject();
2452         this.decompressed.compressedSize = this.compressedSize;
2453         this.decompressed.uncompressedSize = this.uncompressedSize;
2454         this.decompressed.crc32 = this.crc32;
2455         this.decompressed.compressionMethod = this.compressionMethod;
2456         this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression);
2457         this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize);
2458 
2459         // we need to compute the crc32...
2460         if (this.loadOptions.checkCRC32) {
2461             this.decompressed = utils.transformTo("string", this.decompressed.getContent());
2462             if (jszipProto.crc32(this.decompressed) !== this.crc32) {
2463                 throw new Error("Corrupted zip : CRC32 mismatch");
2464             }
2465         }
2466     },
2467 
2468     /**
2469      * Read the central part of a zip file and add the info in this object.
2470      * @param {DataReader} reader the reader to use.
2471      */
2472     readCentralPart: function(reader) {
2473         this.versionMadeBy = reader.readString(2);
2474         this.versionNeeded = reader.readInt(2);
2475         this.bitFlag = reader.readInt(2);
2476         this.compressionMethod = reader.readString(2);
2477         this.date = reader.readDate();
2478         this.crc32 = reader.readInt(4);
2479         this.compressedSize = reader.readInt(4);
2480         this.uncompressedSize = reader.readInt(4);
2481         this.fileNameLength = reader.readInt(2);
2482         this.extraFieldsLength = reader.readInt(2);
2483         this.fileCommentLength = reader.readInt(2);
2484         this.diskNumberStart = reader.readInt(2);
2485         this.internalFileAttributes = reader.readInt(2);
2486         this.externalFileAttributes = reader.readInt(4);
2487         this.localHeaderOffset = reader.readInt(4);
2488 
2489         if (this.isEncrypted()) {
2490             throw new Error("Encrypted zip are not supported");
2491         }
2492 
2493         this.fileName = reader.readString(this.fileNameLength);
2494         this.readExtraFields(reader);
2495         this.parseZIP64ExtraField(reader);
2496         this.fileComment = reader.readString(this.fileCommentLength);
2497 
2498         // warning, this is true only for zip with madeBy == DOS (plateform dependent feature)
2499         this.dir = this.externalFileAttributes & 0x00000010 ? true : false;
2500     },
2501     /**
2502      * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
2503      * @param {DataReader} reader the reader to use.
2504      */
2505     parseZIP64ExtraField: function(reader) {
2506 
2507         if (!this.extraFields[0x0001]) {
2508             return;
2509         }
2510 
2511         // should be something, preparing the extra reader
2512         var extraReader = new StringReader(this.extraFields[0x0001].value);
2513 
2514         // I really hope that these 64bits integer can fit in 32 bits integer, because js
2515         // won't let us have more.
2516         if (this.uncompressedSize === utils.MAX_VALUE_32BITS) {
2517             this.uncompressedSize = extraReader.readInt(8);
2518         }
2519         if (this.compressedSize === utils.MAX_VALUE_32BITS) {
2520             this.compressedSize = extraReader.readInt(8);
2521         }
2522         if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) {
2523             this.localHeaderOffset = extraReader.readInt(8);
2524         }
2525         if (this.diskNumberStart === utils.MAX_VALUE_32BITS) {
2526             this.diskNumberStart = extraReader.readInt(4);
2527         }
2528     },
2529     /**
2530      * Read the central part of a zip file and add the info in this object.
2531      * @param {DataReader} reader the reader to use.
2532      */
2533     readExtraFields: function(reader) {
2534         var start = reader.index,
2535             extraFieldId,
2536             extraFieldLength,
2537             extraFieldValue;
2538 
2539         this.extraFields = this.extraFields || {};
2540 
2541         while (reader.index < start + this.extraFieldsLength) {
2542             extraFieldId = reader.readInt(2);
2543             extraFieldLength = reader.readInt(2);
2544             extraFieldValue = reader.readString(extraFieldLength);
2545 
2546             this.extraFields[extraFieldId] = {
2547                 id: extraFieldId,
2548                 length: extraFieldLength,
2549                 value: extraFieldValue
2550             };
2551         }
2552     },
2553     /**
2554      * Apply an UTF8 transformation if needed.
2555      */
2556     handleUTF8: function() {
2557         if (this.useUTF8()) {
2558             this.fileName = jszipProto.utf8decode(this.fileName);
2559             this.fileComment = jszipProto.utf8decode(this.fileComment);
2560         } else {
2561             var upath = this.findExtraFieldUnicodePath();
2562             if (upath !== null) {
2563                 this.fileName = upath;
2564             }
2565             var ucomment = this.findExtraFieldUnicodeComment();
2566             if (ucomment !== null) {
2567                 this.fileComment = ucomment;
2568             }
2569         }
2570     },
2571 
2572     /**
2573      * Find the unicode path declared in the extra field, if any.
2574      * @return {String} the unicode path, null otherwise.
2575      */
2576     findExtraFieldUnicodePath: function() {
2577         var upathField = this.extraFields[0x7075];
2578         if (upathField) {
2579             var extraReader = new StringReader(upathField.value);
2580 
2581             // wrong version
2582             if (extraReader.readInt(1) !== 1) {
2583                 return null;
2584             }
2585 
2586             // the crc of the filename changed, this field is out of date.
2587             if (jszipProto.crc32(this.fileName) !== extraReader.readInt(4)) {
2588                 return null;
2589             }
2590 
2591             return jszipProto.utf8decode(extraReader.readString(upathField.length - 5));
2592         }
2593         return null;
2594     },
2595 
2596     /**
2597      * Find the unicode comment declared in the extra field, if any.
2598      * @return {String} the unicode comment, null otherwise.
2599      */
2600     findExtraFieldUnicodeComment: function() {
2601         var ucommentField = this.extraFields[0x6375];
2602         if (ucommentField) {
2603             var extraReader = new StringReader(ucommentField.value);
2604 
2605             // wrong version
2606             if (extraReader.readInt(1) !== 1) {
2607                 return null;
2608             }
2609 
2610             // the crc of the comment changed, this field is out of date.
2611             if (jszipProto.crc32(this.fileComment) !== extraReader.readInt(4)) {
2612                 return null;
2613             }
2614 
2615             return jszipProto.utf8decode(extraReader.readString(ucommentField.length - 5));
2616         }
2617         return null;
2618     }
2619 };
2620 module.exports = ZipEntry;
2621 
2622 },{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(_dereq_,module,exports){
2623 // Top level file is just a mixin of submodules & constants
2624 'use strict';
2625 
2626 var assign    = _dereq_('./lib/utils/common').assign;
2627 
2628 var deflate   = _dereq_('./lib/deflate');
2629 var inflate   = _dereq_('./lib/inflate');
2630 var constants = _dereq_('./lib/zlib/constants');
2631 
2632 var pako = {};
2633 
2634 assign(pako, deflate, inflate, constants);
2635 
2636 module.exports = pako;
2637 },{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(_dereq_,module,exports){
2638 'use strict';
2639 
2640 
2641 var zlib_deflate = _dereq_('./zlib/deflate.js');
2642 var utils = _dereq_('./utils/common');
2643 var strings = _dereq_('./utils/strings');
2644 var msg = _dereq_('./zlib/messages');
2645 var zstream = _dereq_('./zlib/zstream');
2646 
2647 
2648 /* Public constants ==========================================================*/
2649 /* ===========================================================================*/
2650 
2651 var Z_NO_FLUSH      = 0;
2652 var Z_FINISH        = 4;
2653 
2654 var Z_OK            = 0;
2655 var Z_STREAM_END    = 1;
2656 
2657 var Z_DEFAULT_COMPRESSION = -1;
2658 
2659 var Z_DEFAULT_STRATEGY    = 0;
2660 
2661 var Z_DEFLATED  = 8;
2662 
2663 /* ===========================================================================*/
2664 
2665 
2666 /**
2667  * class Deflate
2668  *
2669  * Generic JS-style wrapper for zlib calls. If you don't need
2670  * streaming behaviour - use more simple functions: [[deflate]],
2671  * [[deflateRaw]] and [[gzip]].
2672  **/
2673 
2674 /* internal
2675  * Deflate.chunks -> Array
2676  *
2677  * Chunks of output data, if [[Deflate#onData]] not overriden.
2678  **/
2679 
2680 /**
2681  * Deflate.result -> Uint8Array|Array
2682  *
2683  * Compressed result, generated by default [[Deflate#onData]]
2684  * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
2685  * (call [[Deflate#push]] with `Z_FINISH` / `true` param).
2686  **/
2687 
2688 /**
2689  * Deflate.err -> Number
2690  *
2691  * Error code after deflate finished. 0 (Z_OK) on success.
2692  * You will not need it in real life, because deflate errors
2693  * are possible only on wrong options or bad `onData` / `onEnd`
2694  * custom handlers.
2695  **/
2696 
2697 /**
2698  * Deflate.msg -> String
2699  *
2700  * Error message, if [[Deflate.err]] != 0
2701  **/
2702 
2703 
2704 /**
2705  * new Deflate(options)
2706  * - options (Object): zlib deflate options.
2707  *
2708  * Creates new deflator instance with specified params. Throws exception
2709  * on bad params. Supported options:
2710  *
2711  * - `level`
2712  * - `windowBits`
2713  * - `memLevel`
2714  * - `strategy`
2715  *
2716  * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
2717  * for more information on these.
2718  *
2719  * Additional options, for internal needs:
2720  *
2721  * - `chunkSize` - size of generated data chunks (16K by default)
2722  * - `raw` (Boolean) - do raw deflate
2723  * - `gzip` (Boolean) - create gzip wrapper
2724  * - `to` (String) - if equal to 'string', then result will be "binary string"
2725  *    (each char code [0..255])
2726  * - `header` (Object) - custom header for gzip
2727  *   - `text` (Boolean) - true if compressed data believed to be text
2728  *   - `time` (Number) - modification time, unix timestamp
2729  *   - `os` (Number) - operation system code
2730  *   - `extra` (Array) - array of bytes with extra data (max 65536)
2731  *   - `name` (String) - file name (binary string)
2732  *   - `comment` (String) - comment (binary string)
2733  *   - `hcrc` (Boolean) - true if header crc should be added
2734  *
2735  * ##### Example:
2736  *
2737  * ```javascript
2738  * var pako = require('pako')
2739  *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
2740  *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
2741  *
2742  * var deflate = new pako.Deflate({ level: 3});
2743  *
2744  * deflate.push(chunk1, false);
2745  * deflate.push(chunk2, true);  // true -> last chunk
2746  *
2747  * if (deflate.err) { throw new Error(deflate.err); }
2748  *
2749  * console.log(deflate.result);
2750  * ```
2751  **/
2752 var Deflate = function(options) {
2753 
2754   this.options = utils.assign({
2755     level: Z_DEFAULT_COMPRESSION,
2756     method: Z_DEFLATED,
2757     chunkSize: 16384,
2758     windowBits: 15,
2759     memLevel: 8,
2760     strategy: Z_DEFAULT_STRATEGY,
2761     to: ''
2762   }, options || {});
2763 
2764   var opt = this.options;
2765 
2766   if (opt.raw && (opt.windowBits > 0)) {
2767     opt.windowBits = -opt.windowBits;
2768   }
2769 
2770   else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
2771     opt.windowBits += 16;
2772   }
2773 
2774   this.err    = 0;      // error code, if happens (0 = Z_OK)
2775   this.msg    = '';     // error message
2776   this.ended  = false;  // used to avoid multiple onEnd() calls
2777   this.chunks = [];     // chunks of compressed data
2778 
2779   this.strm = new zstream();
2780   this.strm.avail_out = 0;
2781 
2782   var status = zlib_deflate.deflateInit2(
2783     this.strm,
2784     opt.level,
2785     opt.method,
2786     opt.windowBits,
2787     opt.memLevel,
2788     opt.strategy
2789   );
2790 
2791   if (status !== Z_OK) {
2792     throw new Error(msg[status]);
2793   }
2794 
2795   if (opt.header) {
2796     zlib_deflate.deflateSetHeader(this.strm, opt.header);
2797   }
2798 };
2799 
2800 /**
2801  * Deflate#push(data[, mode]) -> Boolean
2802  * - data (Uint8Array|Array|String): input data. Strings will be converted to
2803  *   utf8 byte sequence.
2804  * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
2805  *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH.
2806  *
2807  * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
2808  * new compressed chunks. Returns `true` on success. The last data block must have
2809  * mode Z_FINISH (or `true`). That flush internal pending buffers and call
2810  * [[Deflate#onEnd]].
2811  *
2812  * On fail call [[Deflate#onEnd]] with error code and return false.
2813  *
2814  * We strongly recommend to use `Uint8Array` on input for best speed (output
2815  * array format is detected automatically). Also, don't skip last param and always
2816  * use the same type in your code (boolean or number). That will improve JS speed.
2817  *
2818  * For regular `Array`-s make sure all elements are [0..255].
2819  *
2820  * ##### Example
2821  *
2822  * ```javascript
2823  * push(chunk, false); // push one of data chunks
2824  * ...
2825  * push(chunk, true);  // push last chunk
2826  * ```
2827  **/
2828 Deflate.prototype.push = function(data, mode) {
2829   var strm = this.strm;
2830   var chunkSize = this.options.chunkSize;
2831   var status, _mode;
2832 
2833   if (this.ended) { return false; }
2834 
2835   _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
2836 
2837   // Convert data if needed
2838   if (typeof data === 'string') {
2839     // If we need to compress text, change encoding to utf8.
2840     strm.input = strings.string2buf(data);
2841   } else {
2842     strm.input = data;
2843   }
2844 
2845   strm.next_in = 0;
2846   strm.avail_in = strm.input.length;
2847 
2848   do {
2849     if (strm.avail_out === 0) {
2850       strm.output = new utils.Buf8(chunkSize);
2851       strm.next_out = 0;
2852       strm.avail_out = chunkSize;
2853     }
2854     status = zlib_deflate.deflate(strm, _mode);    /* no bad return value */
2855 
2856     if (status !== Z_STREAM_END && status !== Z_OK) {
2857       this.onEnd(status);
2858       this.ended = true;
2859       return false;
2860     }
2861     if (strm.avail_out === 0 || (strm.avail_in === 0 && _mode === Z_FINISH)) {
2862       if (this.options.to === 'string') {
2863         this.onData(strings.buf2binstring(utils.shrinkBuf(strm.output, strm.next_out)));
2864       } else {
2865         this.onData(utils.shrinkBuf(strm.output, strm.next_out));
2866       }
2867     }
2868   } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
2869 
2870   // Finalize on the last chunk.
2871   if (_mode === Z_FINISH) {
2872     status = zlib_deflate.deflateEnd(this.strm);
2873     this.onEnd(status);
2874     this.ended = true;
2875     return status === Z_OK;
2876   }
2877 
2878   return true;
2879 };
2880 
2881 
2882 /**
2883  * Deflate#onData(chunk) -> Void
2884  * - chunk (Uint8Array|Array|String): ouput data. Type of array depends
2885  *   on js engine support. When string output requested, each chunk
2886  *   will be string.
2887  *
2888  * By default, stores data blocks in `chunks[]` property and glue
2889  * those in `onEnd`. Override this handler, if you need another behaviour.
2890  **/
2891 Deflate.prototype.onData = function(chunk) {
2892   this.chunks.push(chunk);
2893 };
2894 
2895 
2896 /**
2897  * Deflate#onEnd(status) -> Void
2898  * - status (Number): deflate status. 0 (Z_OK) on success,
2899  *   other if not.
2900  *
2901  * Called once after you tell deflate that input stream complete
2902  * or error happenned. By default - join collected chunks,
2903  * free memory and fill `results` / `err` properties.
2904  **/
2905 Deflate.prototype.onEnd = function(status) {
2906   // On success - join
2907   if (status === Z_OK) {
2908     if (this.options.to === 'string') {
2909       this.result = this.chunks.join('');
2910     } else {
2911       this.result = utils.flattenChunks(this.chunks);
2912     }
2913   }
2914   this.chunks = [];
2915   this.err = status;
2916   this.msg = this.strm.msg;
2917 };
2918 
2919 
2920 /**
2921  * deflate(data[, options]) -> Uint8Array|Array|String
2922  * - data (Uint8Array|Array|String): input data to compress.
2923  * - options (Object): zlib deflate options.
2924  *
2925  * Compress `data` with deflate alrorythm and `options`.
2926  *
2927  * Supported options are:
2928  *
2929  * - level
2930  * - windowBits
2931  * - memLevel
2932  * - strategy
2933  *
2934  * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
2935  * for more information on these.
2936  *
2937  * Sugar (options):
2938  *
2939  * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
2940  *   negative windowBits implicitly.
2941  * - `to` (String) - if equal to 'string', then result will be "binary string"
2942  *    (each char code [0..255])
2943  *
2944  * ##### Example:
2945  *
2946  * ```javascript
2947  * var pako = require('pako')
2948  *   , data = Uint8Array([1,2,3,4,5,6,7,8,9]);
2949  *
2950  * console.log(pako.deflate(data));
2951  * ```
2952  **/
2953 function deflate(input, options) {
2954   var deflator = new Deflate(options);
2955 
2956   deflator.push(input, true);
2957 
2958   // That will never happens, if you don't cheat with options :)
2959   if (deflator.err) { throw deflator.msg; }
2960 
2961   return deflator.result;
2962 }
2963 
2964 
2965 /**
2966  * deflateRaw(data[, options]) -> Uint8Array|Array|String
2967  * - data (Uint8Array|Array|String): input data to compress.
2968  * - options (Object): zlib deflate options.
2969  *
2970  * The same as [[deflate]], but creates raw data, without wrapper
2971  * (header and adler32 crc).
2972  **/
2973 function deflateRaw(input, options) {
2974   options = options || {};
2975   options.raw = true;
2976   return deflate(input, options);
2977 }
2978 
2979 
2980 /**
2981  * gzip(data[, options]) -> Uint8Array|Array|String
2982  * - data (Uint8Array|Array|String): input data to compress.
2983  * - options (Object): zlib deflate options.
2984  *
2985  * The same as [[deflate]], but create gzip wrapper instead of
2986  * deflate one.
2987  **/
2988 function gzip(input, options) {
2989   options = options || {};
2990   options.gzip = true;
2991   return deflate(input, options);
2992 }
2993 
2994 
2995 exports.Deflate = Deflate;
2996 exports.deflate = deflate;
2997 exports.deflateRaw = deflateRaw;
2998 exports.gzip = gzip;
2999 },{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(_dereq_,module,exports){
3000 'use strict';
3001 
3002 
3003 var zlib_inflate = _dereq_('./zlib/inflate.js');
3004 var utils = _dereq_('./utils/common');
3005 var strings = _dereq_('./utils/strings');
3006 var c = _dereq_('./zlib/constants');
3007 var msg = _dereq_('./zlib/messages');
3008 var zstream = _dereq_('./zlib/zstream');
3009 var gzheader = _dereq_('./zlib/gzheader');
3010 
3011 
3012 /**
3013  * class Inflate
3014  *
3015  * Generic JS-style wrapper for zlib calls. If you don't need
3016  * streaming behaviour - use more simple functions: [[inflate]]
3017  * and [[inflateRaw]].
3018  **/
3019 
3020 /* internal
3021  * inflate.chunks -> Array
3022  *
3023  * Chunks of output data, if [[Inflate#onData]] not overriden.
3024  **/
3025 
3026 /**
3027  * Inflate.result -> Uint8Array|Array|String
3028  *
3029  * Uncompressed result, generated by default [[Inflate#onData]]
3030  * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
3031  * (call [[Inflate#push]] with `Z_FINISH` / `true` param).
3032  **/
3033 
3034 /**
3035  * Inflate.err -> Number
3036  *
3037  * Error code after inflate finished. 0 (Z_OK) on success.
3038  * Should be checked if broken data possible.
3039  **/
3040 
3041 /**
3042  * Inflate.msg -> String
3043  *
3044  * Error message, if [[Inflate.err]] != 0
3045  **/
3046 
3047 
3048 /**
3049  * new Inflate(options)
3050  * - options (Object): zlib inflate options.
3051  *
3052  * Creates new inflator instance with specified params. Throws exception
3053  * on bad params. Supported options:
3054  *
3055  * - `windowBits`
3056  *
3057  * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
3058  * for more information on these.
3059  *
3060  * Additional options, for internal needs:
3061  *
3062  * - `chunkSize` - size of generated data chunks (16K by default)
3063  * - `raw` (Boolean) - do raw inflate
3064  * - `to` (String) - if equal to 'string', then result will be converted
3065  *   from utf8 to utf16 (javascript) string. When string output requested,
3066  *   chunk length can differ from `chunkSize`, depending on content.
3067  *
3068  * By default, when no options set, autodetect deflate/gzip data format via
3069  * wrapper header.
3070  *
3071  * ##### Example:
3072  *
3073  * ```javascript
3074  * var pako = require('pako')
3075  *   , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
3076  *   , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
3077  *
3078  * var inflate = new pako.Inflate({ level: 3});
3079  *
3080  * inflate.push(chunk1, false);
3081  * inflate.push(chunk2, true);  // true -> last chunk
3082  *
3083  * if (inflate.err) { throw new Error(inflate.err); }
3084  *
3085  * console.log(inflate.result);
3086  * ```
3087  **/
3088 var Inflate = function(options) {
3089 
3090   this.options = utils.assign({
3091     chunkSize: 16384,
3092     windowBits: 0,
3093     to: ''
3094   }, options || {});
3095 
3096   var opt = this.options;
3097 
3098   // Force window size for `raw` data, if not set directly,
3099   // because we have no header for autodetect.
3100   if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
3101     opt.windowBits = -opt.windowBits;
3102     if (opt.windowBits === 0) { opt.windowBits = -15; }
3103   }
3104 
3105   // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
3106   if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
3107       !(options && options.windowBits)) {
3108     opt.windowBits += 32;
3109   }
3110 
3111   // Gzip header has no info about windows size, we can do autodetect only
3112   // for deflate. So, if window size not set, force it to max when gzip possible
3113   if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
3114     // bit 3 (16) -> gzipped data
3115     // bit 4 (32) -> autodetect gzip/deflate
3116     if ((opt.windowBits & 15) === 0) {
3117       opt.windowBits |= 15;
3118     }
3119   }
3120 
3121   this.err    = 0;      // error code, if happens (0 = Z_OK)
3122   this.msg    = '';     // error message
3123   this.ended  = false;  // used to avoid multiple onEnd() calls
3124   this.chunks = [];     // chunks of compressed data
3125 
3126   this.strm   = new zstream();
3127   this.strm.avail_out = 0;
3128 
3129   var status  = zlib_inflate.inflateInit2(
3130     this.strm,
3131     opt.windowBits
3132   );
3133 
3134   if (status !== c.Z_OK) {
3135     throw new Error(msg[status]);
3136   }
3137 
3138   this.header = new gzheader();
3139 
3140   zlib_inflate.inflateGetHeader(this.strm, this.header);
3141 };
3142 
3143 /**
3144  * Inflate#push(data[, mode]) -> Boolean
3145  * - data (Uint8Array|Array|String): input data
3146  * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
3147  *   See constants. Skipped or `false` means Z_NO_FLUSH, `true` meansh Z_FINISH.
3148  *
3149  * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
3150  * new output chunks. Returns `true` on success. The last data block must have
3151  * mode Z_FINISH (or `true`). That flush internal pending buffers and call
3152  * [[Inflate#onEnd]].
3153  *
3154  * On fail call [[Inflate#onEnd]] with error code and return false.
3155  *
3156  * We strongly recommend to use `Uint8Array` on input for best speed (output
3157  * format is detected automatically). Also, don't skip last param and always
3158  * use the same type in your code (boolean or number). That will improve JS speed.
3159  *
3160  * For regular `Array`-s make sure all elements are [0..255].
3161  *
3162  * ##### Example
3163  *
3164  * ```javascript
3165  * push(chunk, false); // push one of data chunks
3166  * ...
3167  * push(chunk, true);  // push last chunk
3168  * ```
3169  **/
3170 Inflate.prototype.push = function(data, mode) {
3171   var strm = this.strm;
3172   var chunkSize = this.options.chunkSize;
3173   var status, _mode;
3174   var next_out_utf8, tail, utf8str;
3175 
3176   if (this.ended) { return false; }
3177   _mode = (mode === ~~mode) ? mode : ((mode === true) ? c.Z_FINISH : c.Z_NO_FLUSH);
3178 
3179   // Convert data if needed
3180   if (typeof data === 'string') {
3181     // Only binary strings can be decompressed on practice
3182     strm.input = strings.binstring2buf(data);
3183   } else {
3184     strm.input = data;
3185   }
3186 
3187   strm.next_in = 0;
3188   strm.avail_in = strm.input.length;
3189 
3190   do {
3191     if (strm.avail_out === 0) {
3192       strm.output = new utils.Buf8(chunkSize);
3193       strm.next_out = 0;
3194       strm.avail_out = chunkSize;
3195     }
3196 
3197     status = zlib_inflate.inflate(strm, c.Z_NO_FLUSH);    /* no bad return value */
3198 
3199     if (status !== c.Z_STREAM_END && status !== c.Z_OK) {
3200       this.onEnd(status);
3201       this.ended = true;
3202       return false;
3203     }
3204 
3205     if (strm.next_out) {
3206       if (strm.avail_out === 0 || status === c.Z_STREAM_END || (strm.avail_in === 0 && _mode === c.Z_FINISH)) {
3207 
3208         if (this.options.to === 'string') {
3209 
3210           next_out_utf8 = strings.utf8border(strm.output, strm.next_out);
3211 
3212           tail = strm.next_out - next_out_utf8;
3213           utf8str = strings.buf2string(strm.output, next_out_utf8);
3214 
3215           // move tail
3216           strm.next_out = tail;
3217           strm.avail_out = chunkSize - tail;
3218           if (tail) { utils.arraySet(strm.output, strm.output, next_out_utf8, tail, 0); }
3219 
3220           this.onData(utf8str);
3221 
3222         } else {
3223           this.onData(utils.shrinkBuf(strm.output, strm.next_out));
3224         }
3225       }
3226     }
3227   } while ((strm.avail_in > 0) && status !== c.Z_STREAM_END);
3228 
3229   if (status === c.Z_STREAM_END) {
3230     _mode = c.Z_FINISH;
3231   }
3232   // Finalize on the last chunk.
3233   if (_mode === c.Z_FINISH) {
3234     status = zlib_inflate.inflateEnd(this.strm);
3235     this.onEnd(status);
3236     this.ended = true;
3237     return status === c.Z_OK;
3238   }
3239 
3240   return true;
3241 };
3242 
3243 
3244 /**
3245  * Inflate#onData(chunk) -> Void
3246  * - chunk (Uint8Array|Array|String): ouput data. Type of array depends
3247  *   on js engine support. When string output requested, each chunk
3248  *   will be string.
3249  *
3250  * By default, stores data blocks in `chunks[]` property and glue
3251  * those in `onEnd`. Override this handler, if you need another behaviour.
3252  **/
3253 Inflate.prototype.onData = function(chunk) {
3254   this.chunks.push(chunk);
3255 };
3256 
3257 
3258 /**
3259  * Inflate#onEnd(status) -> Void
3260  * - status (Number): inflate status. 0 (Z_OK) on success,
3261  *   other if not.
3262  *
3263  * Called once after you tell inflate that input stream complete
3264  * or error happenned. By default - join collected chunks,
3265  * free memory and fill `results` / `err` properties.
3266  **/
3267 Inflate.prototype.onEnd = function(status) {
3268   // On success - join
3269   if (status === c.Z_OK) {
3270     if (this.options.to === 'string') {
3271       // Glue & convert here, until we teach pako to send
3272       // utf8 alligned strings to onData
3273       this.result = this.chunks.join('');
3274     } else {
3275       this.result = utils.flattenChunks(this.chunks);
3276     }
3277   }
3278   this.chunks = [];
3279   this.err = status;
3280   this.msg = this.strm.msg;
3281 };
3282 
3283 
3284 /**
3285  * inflate(data[, options]) -> Uint8Array|Array|String
3286  * - data (Uint8Array|Array|String): input data to decompress.
3287  * - options (Object): zlib inflate options.
3288  *
3289  * Decompress `data` with inflate/ungzip and `options`. Autodetect
3290  * format via wrapper header by default. That's why we don't provide
3291  * separate `ungzip` method.
3292  *
3293  * Supported options are:
3294  *
3295  * - windowBits
3296  *
3297  * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
3298  * for more information.
3299  *
3300  * Sugar (options):
3301  *
3302  * - `raw` (Boolean) - say that we work with raw stream, if you don't wish to specify
3303  *   negative windowBits implicitly.
3304  * - `to` (String) - if equal to 'string', then result will be converted
3305  *   from utf8 to utf16 (javascript) string. When string output requested,
3306  *   chunk length can differ from `chunkSize`, depending on content.
3307  *
3308  *
3309  * ##### Example:
3310  *
3311  * ```javascript
3312  * var pako = require('pako')
3313  *   , input = pako.deflate([1,2,3,4,5,6,7,8,9])
3314  *   , output;
3315  *
3316  * try {
3317  *   output = pako.inflate(input);
3318  * } catch (err)
3319  *   console.log(err);
3320  * }
3321  * ```
3322  **/
3323 function inflate(input, options) {
3324   var inflator = new Inflate(options);
3325 
3326   inflator.push(input, true);
3327 
3328   // That will never happens, if you don't cheat with options :)
3329   if (inflator.err) { throw inflator.msg; }
3330 
3331   return inflator.result;
3332 }
3333 
3334 
3335 /**
3336  * inflateRaw(data[, options]) -> Uint8Array|Array|String
3337  * - data (Uint8Array|Array|String): input data to decompress.
3338  * - options (Object): zlib inflate options.
3339  *
3340  * The same as [[inflate]], but creates raw data, without wrapper
3341  * (header and adler32 crc).
3342  **/
3343 function inflateRaw(input, options) {
3344   options = options || {};
3345   options.raw = true;
3346   return inflate(input, options);
3347 }
3348 
3349 
3350 /**
3351  * ungzip(data[, options]) -> Uint8Array|Array|String
3352  * - data (Uint8Array|Array|String): input data to decompress.
3353  * - options (Object): zlib inflate options.
3354  *
3355  * Just shortcut to [[inflate]], because it autodetects format
3356  * by header.content. Done for convenience.
3357  **/
3358 
3359 
3360 exports.Inflate = Inflate;
3361 exports.inflate = inflate;
3362 exports.inflateRaw = inflateRaw;
3363 exports.ungzip  = inflate;
3364 
3365 },{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(_dereq_,module,exports){
3366 'use strict';
3367 
3368 
3369 var TYPED_OK =  (typeof Uint8Array !== 'undefined') &&
3370                 (typeof Uint16Array !== 'undefined') &&
3371                 (typeof Int32Array !== 'undefined');
3372 
3373 
3374 exports.assign = function (obj /*from1, from2, from3, ...*/) {
3375   var sources = Array.prototype.slice.call(arguments, 1);
3376   while (sources.length) {
3377     var source = sources.shift();
3378     if (!source) { continue; }
3379 
3380     if (typeof(source) !== 'object') {
3381       throw new TypeError(source + 'must be non-object');
3382     }
3383 
3384     for (var p in source) {
3385       if (source.hasOwnProperty(p)) {
3386         obj[p] = source[p];
3387       }
3388     }
3389   }
3390 
3391   return obj;
3392 };
3393 
3394 
3395 // reduce buffer size, avoiding mem copy
3396 exports.shrinkBuf = function (buf, size) {
3397   if (buf.length === size) { return buf; }
3398   if (buf.subarray) { return buf.subarray(0, size); }
3399   buf.length = size;
3400   return buf;
3401 };
3402 
3403 
3404 var fnTyped = {
3405   arraySet: function (dest, src, src_offs, len, dest_offs) {
3406     if (src.subarray && dest.subarray) {
3407       dest.set(src.subarray(src_offs, src_offs+len), dest_offs);
3408       return;
3409     }
3410     // Fallback to ordinary array
3411     for(var i=0; i<len; i++) {
3412       dest[dest_offs + i] = src[src_offs + i];
3413     }
3414   },
3415   // Join array of chunks to single array.
3416   flattenChunks: function(chunks) {
3417     var i, l, len, pos, chunk, result;
3418 
3419     // calculate data length
3420     len = 0;
3421     for (i=0, l=chunks.length; i<l; i++) {
3422       len += chunks[i].length;
3423     }
3424 
3425     // join chunks
3426     result = new Uint8Array(len);
3427     pos = 0;
3428     for (i=0, l=chunks.length; i<l; i++) {
3429       chunk = chunks[i];
3430       result.set(chunk, pos);
3431       pos += chunk.length;
3432     }
3433 
3434     return result;
3435   }
3436 };
3437 
3438 var fnUntyped = {
3439   arraySet: function (dest, src, src_offs, len, dest_offs) {
3440     for(var i=0; i<len; i++) {
3441       dest[dest_offs + i] = src[src_offs + i];
3442     }
3443   },
3444   // Join array of chunks to single array.
3445   flattenChunks: function(chunks) {
3446     return [].concat.apply([], chunks);
3447   }
3448 };
3449 
3450 
3451 // Enable/Disable typed arrays use, for testing
3452 //
3453 exports.setTyped = function (on) {
3454   if (on) {
3455     exports.Buf8  = Uint8Array;
3456     exports.Buf16 = Uint16Array;
3457     exports.Buf32 = Int32Array;
3458     exports.assign(exports, fnTyped);
3459   } else {
3460     exports.Buf8  = Array;
3461     exports.Buf16 = Array;
3462     exports.Buf32 = Array;
3463     exports.assign(exports, fnUntyped);
3464   }
3465 };
3466 
3467 exports.setTyped(TYPED_OK);
3468 },{}],28:[function(_dereq_,module,exports){
3469 // String encode/decode helpers
3470 'use strict';
3471 
3472 
3473 var utils = _dereq_('./common');
3474 
3475 
3476 // Quick check if we can use fast array to bin string conversion
3477 //
3478 // - apply(Array) can fail on Android 2.2
3479 // - apply(Uint8Array) can fail on iOS 5.1 Safary
3480 //
3481 var STR_APPLY_OK = true;
3482 var STR_APPLY_UIA_OK = true;
3483 
3484 try { String.fromCharCode.apply(null, [0]); } catch(__) { STR_APPLY_OK = false; }
3485 try { String.fromCharCode.apply(null, new Uint8Array(1)); } catch(__) { STR_APPLY_UIA_OK = false; }
3486 
3487 
3488 // Table with utf8 lengths (calculated by first byte of sequence)
3489 // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
3490 // because max possible codepoint is 0x10ffff
3491 var _utf8len = new utils.Buf8(256);
3492 for (var i=0; i<256; i++) {
3493   _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1);
3494 }
3495 _utf8len[254]=_utf8len[254]=1; // Invalid sequence start
3496 
3497 
3498 // convert string to array (typed, when possible)
3499 exports.string2buf = function (str) {
3500   var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0;
3501 
3502   // count binary size
3503   for (m_pos = 0; m_pos < str_len; m_pos++) {
3504     c = str.charCodeAt(m_pos);
3505     if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
3506       c2 = str.charCodeAt(m_pos+1);
3507       if ((c2 & 0xfc00) === 0xdc00) {
3508         c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
3509         m_pos++;
3510       }
3511     }
3512     buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
3513   }
3514 
3515   // allocate buffer
3516   buf = new utils.Buf8(buf_len);
3517 
3518   // convert
3519   for (i=0, m_pos = 0; i < buf_len; m_pos++) {
3520     c = str.charCodeAt(m_pos);
3521     if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) {
3522       c2 = str.charCodeAt(m_pos+1);
3523       if ((c2 & 0xfc00) === 0xdc00) {
3524         c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00);
3525         m_pos++;
3526       }
3527     }
3528     if (c < 0x80) {
3529       /* one byte */
3530       buf[i++] = c;
3531     } else if (c < 0x800) {
3532       /* two bytes */
3533       buf[i++] = 0xC0 | (c >>> 6);
3534       buf[i++] = 0x80 | (c & 0x3f);
3535     } else if (c < 0x10000) {
3536       /* three bytes */
3537       buf[i++] = 0xE0 | (c >>> 12);
3538       buf[i++] = 0x80 | (c >>> 6 & 0x3f);
3539       buf[i++] = 0x80 | (c & 0x3f);
3540     } else {
3541       /* four bytes */
3542       buf[i++] = 0xf0 | (c >>> 18);
3543       buf[i++] = 0x80 | (c >>> 12 & 0x3f);
3544       buf[i++] = 0x80 | (c >>> 6 & 0x3f);
3545       buf[i++] = 0x80 | (c & 0x3f);
3546     }
3547   }
3548 
3549   return buf;
3550 };
3551 
3552 // Helper (used in 2 places)
3553 function buf2binstring(buf, len) {
3554   // use fallback for big arrays to avoid stack overflow
3555   if (len < 65537) {
3556     if ((buf.subarray && STR_APPLY_UIA_OK) || (!buf.subarray && STR_APPLY_OK)) {
3557       return String.fromCharCode.apply(null, utils.shrinkBuf(buf, len));
3558     }
3559   }
3560 
3561   var result = '';
3562   for(var i=0; i < len; i++) {
3563     result += String.fromCharCode(buf[i]);
3564   }
3565   return result;
3566 }
3567 
3568 
3569 // Convert byte array to binary string
3570 exports.buf2binstring = function(buf) {
3571   return buf2binstring(buf, buf.length);
3572 };
3573 
3574 
3575 // Convert binary string (typed, when possible)
3576 exports.binstring2buf = function(str) {
3577   var buf = new utils.Buf8(str.length);
3578   for(var i=0, len=buf.length; i < len; i++) {
3579     buf[i] = str.charCodeAt(i);
3580   }
3581   return buf;
3582 };
3583 
3584 
3585 // convert array to string
3586 exports.buf2string = function (buf, max) {
3587   var i, out, c, c_len;
3588   var len = max || buf.length;
3589 
3590   // Reserve max possible length (2 words per char)
3591   // NB: by unknown reasons, Array is significantly faster for
3592   //     String.fromCharCode.apply than Uint16Array.
3593   var utf16buf = new Array(len*2);
3594 
3595   for (out=0, i=0; i<len;) {
3596     c = buf[i++];
3597     // quick process ascii
3598     if (c < 0x80) { utf16buf[out++] = c; continue; }
3599 
3600     c_len = _utf8len[c];
3601     // skip 5 & 6 byte codes
3602     if (c_len > 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; }
3603 
3604     // apply mask on first byte
3605     c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07;
3606     // join the rest
3607     while (c_len > 1 && i < len) {
3608       c = (c << 6) | (buf[i++] & 0x3f);
3609       c_len--;
3610     }
3611 
3612     // terminated by end of string?
3613     if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; }
3614 
3615     if (c < 0x10000) {
3616       utf16buf[out++] = c;
3617     } else {
3618       c -= 0x10000;
3619       utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff);
3620       utf16buf[out++] = 0xdc00 | (c & 0x3ff);
3621     }
3622   }
3623 
3624   return buf2binstring(utf16buf, out);
3625 };
3626 
3627 
3628 // Calculate max possible position in utf8 buffer,
3629 // that will not break sequence. If that's not possible
3630 // - (very small limits) return max size as is.
3631 //
3632 // buf[] - utf8 bytes array
3633 // max   - length limit (mandatory);
3634 exports.utf8border = function(buf, max) {
3635   var pos;
3636 
3637   max = max || buf.length;
3638   if (max > buf.length) { max = buf.length; }
3639 
3640   // go back from last position, until start of sequence found
3641   pos = max-1;
3642   while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; }
3643 
3644   // Fuckup - very small and broken sequence,
3645   // return max, because we should return something anyway.
3646   if (pos < 0) { return max; }
3647 
3648   // If we came to start of buffer - that means vuffer is too small,
3649   // return max too.
3650   if (pos === 0) { return max; }
3651 
3652   return (pos + _utf8len[buf[pos]] > max) ? pos : max;
3653 };
3654 
3655 },{"./common":27}],29:[function(_dereq_,module,exports){
3656 'use strict';
3657 
3658 // Note: adler32 takes 12% for level 0 and 2% for level 6.
3659 // It doesn't worth to make additional optimizationa as in original.
3660 // Small size is preferable.
3661 
3662 function adler32(adler, buf, len, pos) {
3663   var s1 = (adler & 0xffff) |0
3664     , s2 = ((adler >>> 16) & 0xffff) |0
3665     , n = 0;
3666 
3667   while (len !== 0) {
3668     // Set limit ~ twice less than 5552, to keep
3669     // s2 in 31-bits, because we force signed ints.
3670     // in other case %= will fail.
3671     n = len > 2000 ? 2000 : len;
3672     len -= n;
3673 
3674     do {
3675       s1 = (s1 + buf[pos++]) |0;
3676       s2 = (s2 + s1) |0;
3677     } while (--n);
3678 
3679     s1 %= 65521;
3680     s2 %= 65521;
3681   }
3682 
3683   return (s1 | (s2 << 16)) |0;
3684 }
3685 
3686 
3687 module.exports = adler32;
3688 },{}],30:[function(_dereq_,module,exports){
3689 module.exports = {
3690 
3691   /* Allowed flush values; see deflate() and inflate() below for details */
3692   Z_NO_FLUSH:         0,
3693   Z_PARTIAL_FLUSH:    1,
3694   Z_SYNC_FLUSH:       2,
3695   Z_FULL_FLUSH:       3,
3696   Z_FINISH:           4,
3697   Z_BLOCK:            5,
3698   Z_TREES:            6,
3699 
3700   /* Return codes for the compression/decompression functions. Negative values
3701   * are errors, positive values are used for special but normal events.
3702   */
3703   Z_OK:               0,
3704   Z_STREAM_END:       1,
3705   Z_NEED_DICT:        2,
3706   Z_ERRNO:           -1,
3707   Z_STREAM_ERROR:    -2,
3708   Z_DATA_ERROR:      -3,
3709   //Z_MEM_ERROR:     -4,
3710   Z_BUF_ERROR:       -5,
3711   //Z_VERSION_ERROR: -6,
3712 
3713   /* compression levels */
3714   Z_NO_COMPRESSION:         0,
3715   Z_BEST_SPEED:             1,
3716   Z_BEST_COMPRESSION:       9,
3717   Z_DEFAULT_COMPRESSION:   -1,
3718 
3719 
3720   Z_FILTERED:               1,
3721   Z_HUFFMAN_ONLY:           2,
3722   Z_RLE:                    3,
3723   Z_FIXED:                  4,
3724   Z_DEFAULT_STRATEGY:       0,
3725 
3726   /* Possible values of the data_type field (though see inflate()) */
3727   Z_BINARY:                 0,
3728   Z_TEXT:                   1,
3729   //Z_ASCII:                1, // = Z_TEXT (deprecated)
3730   Z_UNKNOWN:                2,
3731 
3732   /* The deflate compression method */
3733   Z_DEFLATED:               8
3734   //Z_NULL:                 null // Use -1 or null inline, depending on var type
3735 };
3736 },{}],31:[function(_dereq_,module,exports){
3737 'use strict';
3738 
3739 // Note: we can't get significant speed boost here.
3740 // So write code to minimize size - no pregenerated tables
3741 // and array tools dependencies.
3742 
3743 
3744 // Use ordinary array, since untyped makes no boost here
3745 function makeTable() {
3746   var c, table = [];
3747 
3748   for(var n =0; n < 256; n++){
3749     c = n;
3750     for(var k =0; k < 8; k++){
3751       c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
3752     }
3753     table[n] = c;
3754   }
3755 
3756   return table;
3757 }
3758 
3759 // Create table on load. Just 255 signed longs. Not a problem.
3760 var crcTable = makeTable();
3761 
3762 
3763 function crc32(crc, buf, len, pos) {
3764   var t = crcTable
3765     , end = pos + len;
3766 
3767   crc = crc ^ (-1);
3768 
3769   for (var i = pos; i < end; i++ ) {
3770     crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
3771   }
3772 
3773   return (crc ^ (-1)); // >>> 0;
3774 }
3775 
3776 
3777 module.exports = crc32;
3778 },{}],32:[function(_dereq_,module,exports){
3779 'use strict';
3780 
3781 var utils   = _dereq_('../utils/common');
3782 var trees   = _dereq_('./trees');
3783 var adler32 = _dereq_('./adler32');
3784 var crc32   = _dereq_('./crc32');
3785 var msg   = _dereq_('./messages');
3786 
3787 /* Public constants ==========================================================*/
3788 /* ===========================================================================*/
3789 
3790 
3791 /* Allowed flush values; see deflate() and inflate() below for details */
3792 var Z_NO_FLUSH      = 0;
3793 var Z_PARTIAL_FLUSH = 1;
3794 //var Z_SYNC_FLUSH    = 2;
3795 var Z_FULL_FLUSH    = 3;
3796 var Z_FINISH        = 4;
3797 var Z_BLOCK         = 5;
3798 //var Z_TREES         = 6;
3799 
3800 
3801 /* Return codes for the compression/decompression functions. Negative values
3802  * are errors, positive values are used for special but normal events.
3803  */
3804 var Z_OK            = 0;
3805 var Z_STREAM_END    = 1;
3806 //var Z_NEED_DICT     = 2;
3807 //var Z_ERRNO         = -1;
3808 var Z_STREAM_ERROR  = -2;
3809 var Z_DATA_ERROR    = -3;
3810 //var Z_MEM_ERROR     = -4;
3811 var Z_BUF_ERROR     = -5;
3812 //var Z_VERSION_ERROR = -6;
3813 
3814 
3815 /* compression levels */
3816 //var Z_NO_COMPRESSION      = 0;
3817 //var Z_BEST_SPEED          = 1;
3818 //var Z_BEST_COMPRESSION    = 9;
3819 var Z_DEFAULT_COMPRESSION = -1;
3820 
3821 
3822 var Z_FILTERED            = 1;
3823 var Z_HUFFMAN_ONLY        = 2;
3824 var Z_RLE                 = 3;
3825 var Z_FIXED               = 4;
3826 var Z_DEFAULT_STRATEGY    = 0;
3827 
3828 /* Possible values of the data_type field (though see inflate()) */
3829 //var Z_BINARY              = 0;
3830 //var Z_TEXT                = 1;
3831 //var Z_ASCII               = 1; // = Z_TEXT
3832 var Z_UNKNOWN             = 2;
3833 
3834 
3835 /* The deflate compression method */
3836 var Z_DEFLATED  = 8;
3837 
3838 /*============================================================================*/
3839 
3840 
3841 var MAX_MEM_LEVEL = 9;
3842 /* Maximum value for memLevel in deflateInit2 */
3843 var MAX_WBITS = 15;
3844 /* 32K LZ77 window */
3845 var DEF_MEM_LEVEL = 8;
3846 
3847 
3848 var LENGTH_CODES  = 29;
3849 /* number of length codes, not counting the special END_BLOCK code */
3850 var LITERALS      = 256;
3851 /* number of literal bytes 0..255 */
3852 var L_CODES       = LITERALS + 1 + LENGTH_CODES;
3853 /* number of Literal or Length codes, including the END_BLOCK code */
3854 var D_CODES       = 30;
3855 /* number of distance codes */
3856 var BL_CODES      = 19;
3857 /* number of codes used to transfer the bit lengths */
3858 var HEAP_SIZE     = 2*L_CODES + 1;
3859 /* maximum heap size */
3860 var MAX_BITS  = 15;
3861 /* All codes must not exceed MAX_BITS bits */
3862 
3863 var MIN_MATCH = 3;
3864 var MAX_MATCH = 258;
3865 var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
3866 
3867 var PRESET_DICT = 0x20;
3868 
3869 var INIT_STATE = 42;
3870 var EXTRA_STATE = 69;
3871 var NAME_STATE = 73;
3872 var COMMENT_STATE = 91;
3873 var HCRC_STATE = 103;
3874 var BUSY_STATE = 113;
3875 var FINISH_STATE = 666;
3876 
3877 var BS_NEED_MORE      = 1; /* block not completed, need more input or more output */
3878 var BS_BLOCK_DONE     = 2; /* block flush performed */
3879 var BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
3880 var BS_FINISH_DONE    = 4; /* finish done, accept no more input or output */
3881 
3882 var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
3883 
3884 function err(strm, errorCode) {
3885   strm.msg = msg[errorCode];
3886   return errorCode;
3887 }
3888 
3889 function rank(f) {
3890   return ((f) << 1) - ((f) > 4 ? 9 : 0);
3891 }
3892 
3893 function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
3894 
3895 
3896 /* =========================================================================
3897  * Flush as much pending output as possible. All deflate() output goes
3898  * through this function so some applications may wish to modify it
3899  * to avoid allocating a large strm->output buffer and copying into it.
3900  * (See also read_buf()).
3901  */
3902 function flush_pending(strm) {
3903   var s = strm.state;
3904 
3905   //_tr_flush_bits(s);
3906   var len = s.pending;
3907   if (len > strm.avail_out) {
3908     len = strm.avail_out;
3909   }
3910   if (len === 0) { return; }
3911 
3912   utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
3913   strm.next_out += len;
3914   s.pending_out += len;
3915   strm.total_out += len;
3916   strm.avail_out -= len;
3917   s.pending -= len;
3918   if (s.pending === 0) {
3919     s.pending_out = 0;
3920   }
3921 }
3922 
3923 
3924 function flush_block_only (s, last) {
3925   trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
3926   s.block_start = s.strstart;
3927   flush_pending(s.strm);
3928 }
3929 
3930 
3931 function put_byte(s, b) {
3932   s.pending_buf[s.pending++] = b;
3933 }
3934 
3935 
3936 /* =========================================================================
3937  * Put a short in the pending buffer. The 16-bit value is put in MSB order.
3938  * IN assertion: the stream state is correct and there is enough room in
3939  * pending_buf.
3940  */
3941 function putShortMSB(s, b) {
3942 //  put_byte(s, (Byte)(b >> 8));
3943 //  put_byte(s, (Byte)(b & 0xff));
3944   s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
3945   s.pending_buf[s.pending++] = b & 0xff;
3946 }
3947 
3948 
3949 /* ===========================================================================
3950  * Read a new buffer from the current input stream, update the adler32
3951  * and total number of bytes read.  All deflate() input goes through
3952  * this function so some applications may wish to modify it to avoid
3953  * allocating a large strm->input buffer and copying from it.
3954  * (See also flush_pending()).
3955  */
3956 function read_buf(strm, buf, start, size) {
3957   var len = strm.avail_in;
3958 
3959   if (len > size) { len = size; }
3960   if (len === 0) { return 0; }
3961 
3962   strm.avail_in -= len;
3963 
3964   utils.arraySet(buf, strm.input, strm.next_in, len, start);
3965   if (strm.state.wrap === 1) {
3966     strm.adler = adler32(strm.adler, buf, len, start);
3967   }
3968 
3969   else if (strm.state.wrap === 2) {
3970     strm.adler = crc32(strm.adler, buf, len, start);
3971   }
3972 
3973   strm.next_in += len;
3974   strm.total_in += len;
3975 
3976   return len;
3977 }
3978 
3979 
3980 /* ===========================================================================
3981  * Set match_start to the longest match starting at the given string and
3982  * return its length. Matches shorter or equal to prev_length are discarded,
3983  * in which case the result is equal to prev_length and match_start is
3984  * garbage.
3985  * IN assertions: cur_match is the head of the hash chain for the current
3986  *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
3987  * OUT assertion: the match length is not greater than s->lookahead.
3988  */
3989 function longest_match(s, cur_match) {
3990   var chain_length = s.max_chain_length;      /* max hash chain length */
3991   var scan = s.strstart; /* current string */
3992   var match;                       /* matched string */
3993   var len;                           /* length of current match */
3994   var best_len = s.prev_length;              /* best match length so far */
3995   var nice_match = s.nice_match;             /* stop if match long enough */
3996   var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
3997       s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
3998 
3999   var _win = s.window; // shortcut
4000 
4001   var wmask = s.w_mask;
4002   var prev  = s.prev;
4003 
4004   /* Stop when cur_match becomes <= limit. To simplify the code,
4005    * we prevent matches with the string of window index 0.
4006    */
4007 
4008   var strend = s.strstart + MAX_MATCH;
4009   var scan_end1  = _win[scan + best_len - 1];
4010   var scan_end   = _win[scan + best_len];
4011 
4012   /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
4013    * It is easy to get rid of this optimization if necessary.
4014    */
4015   // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
4016 
4017   /* Do not waste too much time if we already have a good match: */
4018   if (s.prev_length >= s.good_match) {
4019     chain_length >>= 2;
4020   }
4021   /* Do not look for matches beyond the end of the input. This is necessary
4022    * to make deflate deterministic.
4023    */
4024   if (nice_match > s.lookahead) { nice_match = s.lookahead; }
4025 
4026   // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
4027 
4028   do {
4029     // Assert(cur_match < s->strstart, "no future");
4030     match = cur_match;
4031 
4032     /* Skip to next match if the match length cannot increase
4033      * or if the match length is less than 2.  Note that the checks below
4034      * for insufficient lookahead only occur occasionally for performance
4035      * reasons.  Therefore uninitialized memory will be accessed, and
4036      * conditional jumps will be made that depend on those values.
4037      * However the length of the match is limited to the lookahead, so
4038      * the output of deflate is not affected by the uninitialized values.
4039      */
4040 
4041     if (_win[match + best_len]     !== scan_end  ||
4042         _win[match + best_len - 1] !== scan_end1 ||
4043         _win[match]                !== _win[scan] ||
4044         _win[++match]              !== _win[scan + 1]) {
4045       continue;
4046     }
4047 
4048     /* The check at best_len-1 can be removed because it will be made
4049      * again later. (This heuristic is not always a win.)
4050      * It is not necessary to compare scan[2] and match[2] since they
4051      * are always equal when the other bytes match, given that
4052      * the hash keys are equal and that HASH_BITS >= 8.
4053      */
4054     scan += 2;
4055     match++;
4056     // Assert(*scan == *match, "match[2]?");
4057 
4058     /* We check for insufficient lookahead only every 8th comparison;
4059      * the 256th check will be made at strstart+258.
4060      */
4061     do {
4062       /*jshint noempty:false*/
4063     } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
4064              _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
4065              _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
4066              _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
4067              scan < strend);
4068 
4069     // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
4070 
4071     len = MAX_MATCH - (strend - scan);
4072     scan = strend - MAX_MATCH;
4073 
4074     if (len > best_len) {
4075       s.match_start = cur_match;
4076       best_len = len;
4077       if (len >= nice_match) {
4078         break;
4079       }
4080       scan_end1  = _win[scan + best_len - 1];
4081       scan_end   = _win[scan + best_len];
4082     }
4083   } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
4084 
4085   if (best_len <= s.lookahead) {
4086     return best_len;
4087   }
4088   return s.lookahead;
4089 }
4090 
4091 
4092 /* ===========================================================================
4093  * Fill the window when the lookahead becomes insufficient.
4094  * Updates strstart and lookahead.
4095  *
4096  * IN assertion: lookahead < MIN_LOOKAHEAD
4097  * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
4098  *    At least one byte has been read, or avail_in == 0; reads are
4099  *    performed for at least two bytes (required for the zip translate_eol
4100  *    option -- not supported here).
4101  */
4102 function fill_window(s) {
4103   var _w_size = s.w_size;
4104   var p, n, m, more, str;
4105 
4106   //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
4107 
4108   do {
4109     more = s.window_size - s.lookahead - s.strstart;
4110 
4111     // JS ints have 32 bit, block below not needed
4112     /* Deal with !@#$% 64K limit: */
4113     //if (sizeof(int) <= 2) {
4114     //    if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
4115     //        more = wsize;
4116     //
4117     //  } else if (more == (unsigned)(-1)) {
4118     //        /* Very unlikely, but possible on 16 bit machine if
4119     //         * strstart == 0 && lookahead == 1 (input done a byte at time)
4120     //         */
4121     //        more--;
4122     //    }
4123     //}
4124 
4125 
4126     /* If the window is almost full and there is insufficient lookahead,
4127      * move the upper half to the lower one to make room in the upper half.
4128      */
4129     if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
4130 
4131       utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
4132       s.match_start -= _w_size;
4133       s.strstart -= _w_size;
4134       /* we now have strstart >= MAX_DIST */
4135       s.block_start -= _w_size;
4136 
4137       /* Slide the hash table (could be avoided with 32 bit values
4138        at the expense of memory usage). We slide even when level == 0
4139        to keep the hash table consistent if we switch back to level > 0
4140        later. (Using level 0 permanently is not an optimal usage of
4141        zlib, so we don't care about this pathological case.)
4142        */
4143 
4144       n = s.hash_size;
4145       p = n;
4146       do {
4147         m = s.head[--p];
4148         s.head[p] = (m >= _w_size ? m - _w_size : 0);
4149       } while (--n);
4150 
4151       n = _w_size;
4152       p = n;
4153       do {
4154         m = s.prev[--p];
4155         s.prev[p] = (m >= _w_size ? m - _w_size : 0);
4156         /* If n is not on any hash chain, prev[n] is garbage but
4157          * its value will never be used.
4158          */
4159       } while (--n);
4160 
4161       more += _w_size;
4162     }
4163     if (s.strm.avail_in === 0) {
4164       break;
4165     }
4166 
4167     /* If there was no sliding:
4168      *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
4169      *    more == window_size - lookahead - strstart
4170      * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
4171      * => more >= window_size - 2*WSIZE + 2
4172      * In the BIG_MEM or MMAP case (not yet supported),
4173      *   window_size == input_size + MIN_LOOKAHEAD  &&
4174      *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
4175      * Otherwise, window_size == 2*WSIZE so more >= 2.
4176      * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
4177      */
4178     //Assert(more >= 2, "more < 2");
4179     n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
4180     s.lookahead += n;
4181 
4182     /* Initialize the hash value now that we have some input: */
4183     if (s.lookahead + s.insert >= MIN_MATCH) {
4184       str = s.strstart - s.insert;
4185       s.ins_h = s.window[str];
4186 
4187       /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
4188       s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
4189 //#if MIN_MATCH != 3
4190 //        Call update_hash() MIN_MATCH-3 more times
4191 //#endif
4192       while (s.insert) {
4193         /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
4194         s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH-1]) & s.hash_mask;
4195 
4196         s.prev[str & s.w_mask] = s.head[s.ins_h];
4197         s.head[s.ins_h] = str;
4198         str++;
4199         s.insert--;
4200         if (s.lookahead + s.insert < MIN_MATCH) {
4201           break;
4202         }
4203       }
4204     }
4205     /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
4206      * but this is not important since only literal bytes will be emitted.
4207      */
4208 
4209   } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
4210 
4211   /* If the WIN_INIT bytes after the end of the current data have never been
4212    * written, then zero those bytes in order to avoid memory check reports of
4213    * the use of uninitialized (or uninitialised as Julian writes) bytes by
4214    * the longest match routines.  Update the high water mark for the next
4215    * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
4216    * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
4217    */
4218 //  if (s.high_water < s.window_size) {
4219 //    var curr = s.strstart + s.lookahead;
4220 //    var init = 0;
4221 //
4222 //    if (s.high_water < curr) {
4223 //      /* Previous high water mark below current data -- zero WIN_INIT
4224 //       * bytes or up to end of window, whichever is less.
4225 //       */
4226 //      init = s.window_size - curr;
4227 //      if (init > WIN_INIT)
4228 //        init = WIN_INIT;
4229 //      zmemzero(s->window + curr, (unsigned)init);
4230 //      s->high_water = curr + init;
4231 //    }
4232 //    else if (s->high_water < (ulg)curr + WIN_INIT) {
4233 //      /* High water mark at or above current data, but below current data
4234 //       * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
4235 //       * to end of window, whichever is less.
4236 //       */
4237 //      init = (ulg)curr + WIN_INIT - s->high_water;
4238 //      if (init > s->window_size - s->high_water)
4239 //        init = s->window_size - s->high_water;
4240 //      zmemzero(s->window + s->high_water, (unsigned)init);
4241 //      s->high_water += init;
4242 //    }
4243 //  }
4244 //
4245 //  Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
4246 //    "not enough room for search");
4247 }
4248 
4249 /* ===========================================================================
4250  * Copy without compression as much as possible from the input stream, return
4251  * the current block state.
4252  * This function does not insert new strings in the dictionary since
4253  * uncompressible data is probably not useful. This function is used
4254  * only for the level=0 compression option.
4255  * NOTE: this function should be optimized to avoid extra copying from
4256  * window to pending_buf.
4257  */
4258 function deflate_stored(s, flush) {
4259   /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
4260    * to pending_buf_size, and each stored block has a 5 byte header:
4261    */
4262   var max_block_size = 0xffff;
4263 
4264   if (max_block_size > s.pending_buf_size - 5) {
4265     max_block_size = s.pending_buf_size - 5;
4266   }
4267 
4268   /* Copy as much as possible from input to output: */
4269   for (;;) {
4270     /* Fill the window as much as possible: */
4271     if (s.lookahead <= 1) {
4272 
4273       //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
4274       //  s->block_start >= (long)s->w_size, "slide too late");
4275 //      if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
4276 //        s.block_start >= s.w_size)) {
4277 //        throw  new Error("slide too late");
4278 //      }
4279 
4280       fill_window(s);
4281       if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
4282         return BS_NEED_MORE;
4283       }
4284 
4285       if (s.lookahead === 0) {
4286         break;
4287       }
4288       /* flush the current block */
4289     }
4290     //Assert(s->block_start >= 0L, "block gone");
4291 //    if (s.block_start < 0) throw new Error("block gone");
4292 
4293     s.strstart += s.lookahead;
4294     s.lookahead = 0;
4295 
4296     /* Emit a stored block if pending_buf will be full: */
4297     var max_start = s.block_start + max_block_size;
4298 
4299     if (s.strstart === 0 || s.strstart >= max_start) {
4300       /* strstart == 0 is possible when wraparound on 16-bit machine */
4301       s.lookahead = s.strstart - max_start;
4302       s.strstart = max_start;
4303       /*** FLUSH_BLOCK(s, 0); ***/
4304       flush_block_only(s, false);
4305       if (s.strm.avail_out === 0) {
4306         return BS_NEED_MORE;
4307       }
4308       /***/
4309 
4310 
4311     }
4312     /* Flush if we may have to slide, otherwise block_start may become
4313      * negative and the data will be gone:
4314      */
4315     if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
4316       /*** FLUSH_BLOCK(s, 0); ***/
4317       flush_block_only(s, false);
4318       if (s.strm.avail_out === 0) {
4319         return BS_NEED_MORE;
4320       }
4321       /***/
4322     }
4323   }
4324 
4325   s.insert = 0;
4326 
4327   if (flush === Z_FINISH) {
4328     /*** FLUSH_BLOCK(s, 1); ***/
4329     flush_block_only(s, true);
4330     if (s.strm.avail_out === 0) {
4331       return BS_FINISH_STARTED;
4332     }
4333     /***/
4334     return BS_FINISH_DONE;
4335   }
4336 
4337   if (s.strstart > s.block_start) {
4338     /*** FLUSH_BLOCK(s, 0); ***/
4339     flush_block_only(s, false);
4340     if (s.strm.avail_out === 0) {
4341       return BS_NEED_MORE;
4342     }
4343     /***/
4344   }
4345 
4346   return BS_NEED_MORE;
4347 }
4348 
4349 /* ===========================================================================
4350  * Compress as much as possible from the input stream, return the current
4351  * block state.
4352  * This function does not perform lazy evaluation of matches and inserts
4353  * new strings in the dictionary only for unmatched strings or for short
4354  * matches. It is used only for the fast compression options.
4355  */
4356 function deflate_fast(s, flush) {
4357   var hash_head;        /* head of the hash chain */
4358   var bflush;           /* set if current block must be flushed */
4359 
4360   for (;;) {
4361     /* Make sure that we always have enough lookahead, except
4362      * at the end of the input file. We need MAX_MATCH bytes
4363      * for the next match, plus MIN_MATCH bytes to insert the
4364      * string following the next match.
4365      */
4366     if (s.lookahead < MIN_LOOKAHEAD) {
4367       fill_window(s);
4368       if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
4369         return BS_NEED_MORE;
4370       }
4371       if (s.lookahead === 0) {
4372         break; /* flush the current block */
4373       }
4374     }
4375 
4376     /* Insert the string window[strstart .. strstart+2] in the
4377      * dictionary, and set hash_head to the head of the hash chain:
4378      */
4379     hash_head = 0/*NIL*/;
4380     if (s.lookahead >= MIN_MATCH) {
4381       /*** INSERT_STRING(s, s.strstart, hash_head); ***/
4382       s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
4383       hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
4384       s.head[s.ins_h] = s.strstart;
4385       /***/
4386     }
4387 
4388     /* Find the longest match, discarding those <= prev_length.
4389      * At this point we have always match_length < MIN_MATCH
4390      */
4391     if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
4392       /* To simplify the code, we prevent matches with the string
4393        * of window index 0 (in particular we have to avoid a match
4394        * of the string with itself at the start of the input file).
4395        */
4396       s.match_length = longest_match(s, hash_head);
4397       /* longest_match() sets match_start */
4398     }
4399     if (s.match_length >= MIN_MATCH) {
4400       // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
4401 
4402       /*** _tr_tally_dist(s, s.strstart - s.match_start,
4403                      s.match_length - MIN_MATCH, bflush); ***/
4404       bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
4405 
4406       s.lookahead -= s.match_length;
4407 
4408       /* Insert new strings in the hash table only if the match length
4409        * is not too large. This saves time but degrades compression.
4410        */
4411       if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH) {
4412         s.match_length--; /* string at strstart already in table */
4413         do {
4414           s.strstart++;
4415           /*** INSERT_STRING(s, s.strstart, hash_head); ***/
4416           s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
4417           hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
4418           s.head[s.ins_h] = s.strstart;
4419           /***/
4420           /* strstart never exceeds WSIZE-MAX_MATCH, so there are
4421            * always MIN_MATCH bytes ahead.
4422            */
4423         } while (--s.match_length !== 0);
4424         s.strstart++;
4425       } else
4426       {
4427         s.strstart += s.match_length;
4428         s.match_length = 0;
4429         s.ins_h = s.window[s.strstart];
4430         /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
4431         s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
4432 
4433 //#if MIN_MATCH != 3
4434 //                Call UPDATE_HASH() MIN_MATCH-3 more times
4435 //#endif
4436         /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
4437          * matter since it will be recomputed at next deflate call.
4438          */
4439       }
4440     } else {
4441       /* No match, output a literal byte */
4442       //Tracevv((stderr,"%c", s.window[s.strstart]));
4443       /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
4444       bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
4445 
4446       s.lookahead--;
4447       s.strstart++;
4448     }
4449     if (bflush) {
4450       /*** FLUSH_BLOCK(s, 0); ***/
4451       flush_block_only(s, false);
4452       if (s.strm.avail_out === 0) {
4453         return BS_NEED_MORE;
4454       }
4455       /***/
4456     }
4457   }
4458   s.insert = ((s.strstart < (MIN_MATCH-1)) ? s.strstart : MIN_MATCH-1);
4459   if (flush === Z_FINISH) {
4460     /*** FLUSH_BLOCK(s, 1); ***/
4461     flush_block_only(s, true);
4462     if (s.strm.avail_out === 0) {
4463       return BS_FINISH_STARTED;
4464     }
4465     /***/
4466     return BS_FINISH_DONE;
4467   }
4468   if (s.last_lit) {
4469     /*** FLUSH_BLOCK(s, 0); ***/
4470     flush_block_only(s, false);
4471     if (s.strm.avail_out === 0) {
4472       return BS_NEED_MORE;
4473     }
4474     /***/
4475   }
4476   return BS_BLOCK_DONE;
4477 }
4478 
4479 /* ===========================================================================
4480  * Same as above, but achieves better compression. We use a lazy
4481  * evaluation for matches: a match is finally adopted only if there is
4482  * no better match at the next window position.
4483  */
4484 function deflate_slow(s, flush) {
4485   var hash_head;          /* head of hash chain */
4486   var bflush;              /* set if current block must be flushed */
4487 
4488   var max_insert;
4489 
4490   /* Process the input block. */
4491   for (;;) {
4492     /* Make sure that we always have enough lookahead, except
4493      * at the end of the input file. We need MAX_MATCH bytes
4494      * for the next match, plus MIN_MATCH bytes to insert the
4495      * string following the next match.
4496      */
4497     if (s.lookahead < MIN_LOOKAHEAD) {
4498       fill_window(s);
4499       if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
4500         return BS_NEED_MORE;
4501       }
4502       if (s.lookahead === 0) { break; } /* flush the current block */
4503     }
4504 
4505     /* Insert the string window[strstart .. strstart+2] in the
4506      * dictionary, and set hash_head to the head of the hash chain:
4507      */
4508     hash_head = 0/*NIL*/;
4509     if (s.lookahead >= MIN_MATCH) {
4510       /*** INSERT_STRING(s, s.strstart, hash_head); ***/
4511       s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
4512       hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
4513       s.head[s.ins_h] = s.strstart;
4514       /***/
4515     }
4516 
4517     /* Find the longest match, discarding those <= prev_length.
4518      */
4519     s.prev_length = s.match_length;
4520     s.prev_match = s.match_start;
4521     s.match_length = MIN_MATCH-1;
4522 
4523     if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
4524         s.strstart - hash_head <= (s.w_size-MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
4525       /* To simplify the code, we prevent matches with the string
4526        * of window index 0 (in particular we have to avoid a match
4527        * of the string with itself at the start of the input file).
4528        */
4529       s.match_length = longest_match(s, hash_head);
4530       /* longest_match() sets match_start */
4531 
4532       if (s.match_length <= 5 &&
4533          (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
4534 
4535         /* If prev_match is also MIN_MATCH, match_start is garbage
4536          * but we will ignore the current match anyway.
4537          */
4538         s.match_length = MIN_MATCH-1;
4539       }
4540     }
4541     /* If there was a match at the previous step and the current
4542      * match is not better, output the previous match:
4543      */
4544     if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
4545       max_insert = s.strstart + s.lookahead - MIN_MATCH;
4546       /* Do not insert strings in hash table beyond this. */
4547 
4548       //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
4549 
4550       /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
4551                      s.prev_length - MIN_MATCH, bflush);***/
4552       bflush = trees._tr_tally(s, s.strstart - 1- s.prev_match, s.prev_length - MIN_MATCH);
4553       /* Insert in hash table all strings up to the end of the match.
4554        * strstart-1 and strstart are already inserted. If there is not
4555        * enough lookahead, the last two strings are not inserted in
4556        * the hash table.
4557        */
4558       s.lookahead -= s.prev_length-1;
4559       s.prev_length -= 2;
4560       do {
4561         if (++s.strstart <= max_insert) {
4562           /*** INSERT_STRING(s, s.strstart, hash_head); ***/
4563           s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
4564           hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
4565           s.head[s.ins_h] = s.strstart;
4566           /***/
4567         }
4568       } while (--s.prev_length !== 0);
4569       s.match_available = 0;
4570       s.match_length = MIN_MATCH-1;
4571       s.strstart++;
4572 
4573       if (bflush) {
4574         /*** FLUSH_BLOCK(s, 0); ***/
4575         flush_block_only(s, false);
4576         if (s.strm.avail_out === 0) {
4577           return BS_NEED_MORE;
4578         }
4579         /***/
4580       }
4581 
4582     } else if (s.match_available) {
4583       /* If there was no match at the previous position, output a
4584        * single literal. If there was a match but the current match
4585        * is longer, truncate the previous match to a single literal.
4586        */
4587       //Tracevv((stderr,"%c", s->window[s->strstart-1]));
4588       /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
4589       bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]);
4590 
4591       if (bflush) {
4592         /*** FLUSH_BLOCK_ONLY(s, 0) ***/
4593         flush_block_only(s, false);
4594         /***/
4595       }
4596       s.strstart++;
4597       s.lookahead--;
4598       if (s.strm.avail_out === 0) {
4599         return BS_NEED_MORE;
4600       }
4601     } else {
4602       /* There is no previous match to compare with, wait for
4603        * the next step to decide.
4604        */
4605       s.match_available = 1;
4606       s.strstart++;
4607       s.lookahead--;
4608     }
4609   }
4610   //Assert (flush != Z_NO_FLUSH, "no flush?");
4611   if (s.match_available) {
4612     //Tracevv((stderr,"%c", s->window[s->strstart-1]));
4613     /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
4614     bflush = trees._tr_tally(s, 0, s.window[s.strstart-1]);
4615 
4616     s.match_available = 0;
4617   }
4618   s.insert = s.strstart < MIN_MATCH-1 ? s.strstart : MIN_MATCH-1;
4619   if (flush === Z_FINISH) {
4620     /*** FLUSH_BLOCK(s, 1); ***/
4621     flush_block_only(s, true);
4622     if (s.strm.avail_out === 0) {
4623       return BS_FINISH_STARTED;
4624     }
4625     /***/
4626     return BS_FINISH_DONE;
4627   }
4628   if (s.last_lit) {
4629     /*** FLUSH_BLOCK(s, 0); ***/
4630     flush_block_only(s, false);
4631     if (s.strm.avail_out === 0) {
4632       return BS_NEED_MORE;
4633     }
4634     /***/
4635   }
4636 
4637   return BS_BLOCK_DONE;
4638 }
4639 
4640 
4641 /* ===========================================================================
4642  * For Z_RLE, simply look for runs of bytes, generate matches only of distance
4643  * one.  Do not maintain a hash table.  (It will be regenerated if this run of
4644  * deflate switches away from Z_RLE.)
4645  */
4646 function deflate_rle(s, flush) {
4647   var bflush;            /* set if current block must be flushed */
4648   var prev;              /* byte at distance one to match */
4649   var scan, strend;      /* scan goes up to strend for length of run */
4650 
4651   var _win = s.window;
4652 
4653   for (;;) {
4654     /* Make sure that we always have enough lookahead, except
4655      * at the end of the input file. We need MAX_MATCH bytes
4656      * for the longest run, plus one for the unrolled loop.
4657      */
4658     if (s.lookahead <= MAX_MATCH) {
4659       fill_window(s);
4660       if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
4661         return BS_NEED_MORE;
4662       }
4663       if (s.lookahead ===