diff --git a/resources/openpgp.js b/resources/openpgp.js
index 32e3836e..5515c8db 100644
--- a/resources/openpgp.js
+++ b/resources/openpgp.js
@@ -219,12 +219,6 @@ function _openpgp () {
 					if (first_packet.tagType == 8) {
 						util.print_error("A directly compressed message is currently not supported");
 						break;
-				} else
-					// Literal Message
-					// TODO: needs to be implemented. From a security perspective: this message is plaintext anyway.
-					if (first_packet.tagType == 11) {
-						util.print_error("A direct literal message is currently not supported.");
-						break;
 				} else
 					// Marker Packet (Obsolete Literal Packet) (Tag 10)
 					// "Such a packet MUST be ignored when received." see http://tools.ietf.org/html/rfc4880#section-5.8
@@ -234,6 +228,12 @@ function _openpgp () {
 						// continue with next packet
 						mypos += first_packet.packetLength + first_packet.headerLength;
 						l -= (first_packet.packetLength + first_packet.headerLength);
+				} else
+					// Literal Message
+					// TODO: needs to be implemented. From a security perspective: this message is plaintext anyway.
+					if (first_packet.tagType == 11) {
+						util.print_error("A direct literal message is currently not supported.");
+						break;
 				}
 			} else {
 				util.print_error('no message found!');
@@ -4700,8 +4700,8 @@ var util = new Util();
  1. Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
 
- 2. Redistributions in binary form must reproduce the above copyright 
- notice, this list of conditions and the following disclaimer in 
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
  the documentation and/or other materials provided with the distribution.
 
  3. The names of the authors may not be used to endorse or promote products
@@ -4719,11 +4719,19 @@ var util = new Util();
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+(function(obj) {
+
+	obj.zip = {
+		useWebWorkers : false
+	};
+
+})(this);
+
+// include inflate.js
+
 /*
- * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
- * JZlib is based on zlib-1.1.3, so all credit should go authors
- * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
- * and contributors of zlib.
+ * zip.js and include.js are merged in one file because of a dependency in the
+ * execution order: zip.Inflater is only defined if inflate.js is executed after zip.js
  */
 
 (function(obj) {
@@ -6860,41 +6868,7 @@ var util = new Util();
 	}
 
 })(this);
-/*
- Copyright (c) 2012 Gildas Lormeau. All rights reserved.
 
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-(function(obj) {
-
-	obj.zip = {
-		useWebWorkers : false
-	};
-
-})(this);
 // GPG4Browsers - An OpenPGP implementation in javascript
 // Copyright (C) 2011 Recurity Labs GmbH
 // 
diff --git a/resources/openpgp.min.js b/resources/openpgp.min.js
index 259f950c..ee92cdda 100644
--- a/resources/openpgp.min.js
+++ b/resources/openpgp.min.js
@@ -7,7 +7,7 @@ a,d);return openpgp_encoding_armor(3,c,null,null)};this.write_encrypted_message=
 g.MPIs,g.publicKeyAlgorithm,openpgp.config.config.encryption_cipher,d)}e=openpgp.config.config.integrity_protect?e+(new openpgp_packet_encryptedintegrityprotecteddata).write_packet(openpgp.config.config.encryption_cipher,d,c):e+(new openpgp_packet_encrypteddata).write_packet(openpgp.config.config.encryption_cipher,d,c);return openpgp_encoding_armor(3,e,null,null)};this.read_message=function(a){var b;try{b=openpgp_encoding_deArmor(a.replace(/\r/g,""))}catch(c){return util.print_error("no message found!"),
 null}for(var a=b.openpgp,d=[],e=0,f=0,g=a.length;f<a.length;){var h=openpgp_packet.read_packet(a,f,g);if(1==h.tagType||2==h.tagType&&16>h.signatureType||3==h.tagType||8==h.tagType||9==h.tagType||10==h.tagType||11==h.tagType||18==h.tagType||19==h.tagType)if(d[d.length]=new openpgp_msg_message,d[e].messagePacket=h,d[e].type=b.type,9==h.tagType||1==h.tagType||3==h.tagType||18==h.tagType)if(9==h.tagType){util.print_error("unexpected openpgp packet");break}else if(1==h.tagType){util.print_debug("session key found:\n "+
 h.toString());var k=!0;d[e].sessionKeys=[];for(var j=0;k;)d[e].sessionKeys[j]=h,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength,h=openpgp_packet.read_packet(a,f,g),1!=h.tagType&&3!=h.tagType&&(k=!1),j++;18==h.tagType||9==h.tagType?(util.print_debug("encrypted data found:\n "+h.toString()),d[e].encryptedData=h,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength,e++):util.print_debug("something is wrong: "+h.tagType)}else{if(18==h.tagType){util.print_debug("symmetric encrypted data");
-break}}else if(2==h.tagType&&3>h.signatureType){d[e].text=b.text;d[e].signature=h;break}else if(8==h.tagType){util.print_error("A directly compressed message is currently not supported");break}else if(11==h.tagType){util.print_error("A direct literal message is currently not supported.");break}else{if(10==h.tagType)d.length=0,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength}else return util.print_error("no message found!"),null}return d};this.read_publicKey=function(a){for(var b=
+break}}else if(2==h.tagType&&3>h.signatureType){d[e].text=b.text;d[e].signature=h;break}else if(8==h.tagType){util.print_error("A directly compressed message is currently not supported");break}else if(10==h.tagType)d.length=0,f+=h.packetLength+h.headerLength,g-=h.packetLength+h.headerLength;else{if(11==h.tagType){util.print_error("A direct literal message is currently not supported.");break}}else return util.print_error("no message found!"),null}return d};this.read_publicKey=function(a){for(var b=
 0,c=[],d=0,a=openpgp_encoding_deArmor(a.replace(/\r/g,"")).openpgp,e=a.length;b!=a.length;){var f=openpgp_packet.read_packet(a,b,e);if(153==a[b].charCodeAt()||6==f.tagType)c[d]=new openpgp_msg_publickey,c[d].header=a.substring(b,b+3),153==a[b].charCodeAt()?(b++,e=a[b++].charCodeAt()<<8|a[b++].charCodeAt(),c[d].publicKeyPacket=new openpgp_packet_keymaterial,c[d].publicKeyPacket.header=c[d].header,c[d].publicKeyPacket.read_tag6(a,b,e),b+=c[d].publicKeyPacket.packetLength,b+=c[d].read_nodes(c[d].publicKeyPacket,
 a,b,a.length-b)):(c[d]=new openpgp_msg_publickey,c[d].publicKeyPacket=f,b+=f.headerLength+f.packetLength,b+=c[d].read_nodes(f,a,b,a.length-b));else return util.print_error("no public key found!"),null;c[d].data=a.substring(0,b);d++}return c};this.read_privateKey=function(a){for(var b=[],c=0,d=0,a=openpgp_encoding_deArmor(a.replace(/\r/g,"")).openpgp,e=a.length;d!=a.length;){var f=openpgp_packet.read_packet(a,d,e);if(5==f.tagType)b[b.length]=new openpgp_msg_privatekey,d+=f.headerLength+f.packetLength,
 d+=b[c].read_nodes(f,a,d,e);else return util.print_error("no block packet found!"),null;b[c].data=a.substring(0,d);c++}return b};this.init=function(){this.config=new openpgp_config;this.config.read();this.keyring=new openpgp_keyring;this.keyring.init()}}var openpgp=new _openpgp;
@@ -138,7 +138,7 @@ function(a){for(var b=new Uint8Array(new ArrayBuffer(a.length)),c=0;c<a.length;c
 a.replace(/\n/g,"<br>")+"</p></tt>"))};this.print_debug_hexstr_dump=function(a,b){openpgp.config.debug&&(a+=this.hexstrdump(b),a=openpgp_encoding_html_encode(a),showMessages('<tt><p style="background-color: #ffffff; width: 652px; word-break: break-word; padding: 5px; border-bottom: 1px solid black;">'+a.replace(/\n/g,"<br>")+"</p></tt>"))};this.print_error=function(a){a=openpgp_encoding_html_encode(a);showMessages('<p style="font-size: 80%; background-color: #FF8888; margin:0; width: 652px; word-break: break-word; padding: 5px; border-bottom: 1px solid black;"><span style="color: #888;"><b>ERROR:</b></span>\t'+
 a.replace(/\n/g,"<br>")+"</p>")};this.print_info=function(a){a=openpgp_encoding_html_encode(a);showMessages('<p style="font-size: 80%; background-color: #88FF88; margin:0; width: 652px; word-break: break-word; padding: 5px; border-bottom: 1px solid black;"><span style="color: #888;"><b>INFO:</b></span>\t'+a.replace(/\n/g,"<br>")+"</p>")};this.print_warning=function(a){a=openpgp_encoding_html_encode(a);showMessages('<p style="font-size: 80%; background-color: #FFAA88; margin:0; width: 652px; word-break: break-word; padding: 5px; border-bottom: 1px solid black;"><span style="color: #888;"><b>WARNING:</b></span>\t'+
 a.replace(/\n/g,"<br>")+"</p>")};this.getLeftNBits=function(a,b){var c=b%8;return 0==c?a.substring(0,b/8):this.shiftRight(a.substring(0,(b-c)/8+1),8-c)};this.shiftRight=function(a,b){var c=util.str2bin(a);if(0!=b%8)for(var d=c.length-1;0<=d;d--)c[d]>>=b%8,0<d&&(c[d]|=c[d-1]<<8-b%8&255);else return a;return util.bin2str(c)};this.get_hashAlgorithmString=function(a){switch(a){case 1:return"MD5";case 2:return"SHA1";case 3:return"RIPEMD160";case 8:return"SHA256";case 9:return"SHA384";case 10:return"SHA512";
-case 11:return"SHA224"}return"unknown"}},util=new Util;
+case 11:return"SHA224"}return"unknown"}},util=new Util;(function(a){a.zip={useWebWorkers:!1}})(this);
 (function(a){function b(){function a(b,c,d,Ea,j,O,t,x,Q,o,p){var l,ga,s,q,u,r,U,z,y,V;U=0;s=d;do e[b[c+U]]++,U++,s--;while(0!==s);if(e[0]==d)return t[0]=-1,x[0]=0,h;r=x[0];for(q=1;q<=W&&!(0!==e[q]);q++);u=q;r<q&&(r=q);for(s=W;0!==s&&!(0!==e[s]);s--);ga=s;r>s&&(r=s);x[0]=r;for(x=1<<q;q<s;q++,x<<=1)if(0>(x-=e[q]))return w;if(0>(x-=e[s]))return w;e[s]+=x;k[1]=q=0;U=1;for(z=2;0!==--s;)k[z]=q+=e[U],z++,U++;U=s=0;do{if(0!==(q=b[c+U]))p[k[q]++]=s;U++}while(++s<d);d=k[ga];U=k[0]=s=0;c=-1;y=-r;for(V=z=g[0]=
 0;u<=ga;u++)for(b=e[u];0!==b--;){for(;u>y+r;){c++;y+=r;V=ga-y;V=V>r?r:V;if((l=1<<(q=u-y))>b+1)if(l-=b+1,z=u,q<V)for(;++q<V&&!((l<<=1)<=e[++z]);)l-=e[z];V=1<<q;if(o[0]+V>ba)return w;g[c]=z=o[0];o[0]+=V;0!==c?(k[c]=s,f[0]=q,f[1]=r,q=s>>>y-r,f[2]=z-g[c-1]-q,Q.set(f,3*(g[c-1]+q))):t[0]=z}f[1]=u-y;U>=d?f[0]=192:p[U]<Ea?(f[0]=256>p[U]?0:96,f[2]=p[U++]):(f[0]=O[p[U]-Ea]+16+64,f[2]=j[p[U++]-Ea]);l=1<<u-y;for(q=s>>>y;q<V;q+=l)Q.set(f,3*(z+q));for(q=1<<u-1;0!==(s&q);q>>>=1)s^=q;s^=q;for(q=(1<<y)-1;(s&q)!=k[c];)c--,
 y-=r,q=(1<<y)-1}return 0!==x&&1!=ga?v:h}function b(a){var h;c||(c=[],d=[],e=new Int32Array(W+1),f=[],g=new Int32Array(W),k=new Int32Array(W+1));d.length<a&&(d=[]);for(h=0;h<a;h++)d[h]=0;for(h=0;h<W+1;h++)e[h]=0;for(h=0;3>h;h++)f[h]=0;g.set(e.subarray(0,W),0);k.set(e.subarray(0,W+1),0)}var c,d,e,f,g,k;this.inflate_trees_bits=function(e,f,h,g,k){b(19);c[0]=0;e=a(e,0,19,19,null,null,h,f,g,c,d);if(e==w)k.msg="oversubscribed dynamic bit lengths tree";else if(e==v||0===f[0])k.msg="incomplete dynamic bit lengths tree",
@@ -183,7 +183,7 @@ j.push(new Uint8Array(c)):j.push(new Uint8Array(c.subarray(0,a.next_out_index)))
 5,1537,85,5,97,93,5,24577,80,5,4,88,5,769,84,5,49,92,5,12289,82,5,13,90,5,3073,86,5,193,192,5,24577],ma=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],la=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,112,112],ia=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],ja=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],W=15;b.inflate_trees_fixed=function(a,b,c,d){a[0]=
 9;b[0]=5;c[0]=D;d[0]=m;return h};var L=0,Z=1,oa=2,ea=3,aa=4,pa=5,O=6,Q=7,ga=8,U=9,ua=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],R=0,na=1,qa=2,Ca=3,Ga=4,T=5,Da=6,z=7,va=8,ha=9,da=32,Ha=8,wa=0,ca=1,xa=2,ya=3,za=4,Aa=5,sa=6,ra=7,Ba=12,ka=13,r=[0,0,255,255];f.prototype={inflateInit:function(a){this.istate=new e;a||(a=15);return this.istate.inflateInit(this,a)},inflate:function(a){return!this.istate?l:this.istate.inflate(this,a)},inflateEnd:function(){if(!this.istate)return l;var a=this.istate.inflateEnd(this);
 this.istate=null;return a},inflateSync:function(){return!this.istate?l:this.istate.inflateSync(this)},inflateSetDictionary:function(a,b){return!this.istate?l:this.istate.inflateSetDictionary(this,a,b)},read_byte:function(a){return this.next_in.subarray(a,a+1)[0]},read_buf:function(a,b){return this.next_in.subarray(a,a+b)}};var ta;a.zip?a.zip.Inflater=g:(ta=new g,a.addEventListener("message",function(b){b=b.data;b.append&&a.postMessage({onappend:!0,data:ta.append(b.data,function(b){a.postMessage({progress:!0,
-current:b})})});b.flush&&(ta.flush(),a.postMessage({onflush:!0}))},!1))})(this);(function(a){a.zip={useWebWorkers:!1}})(this);
+current:b})})});b.flush&&(ta.flush(),a.postMessage({onflush:!0}))},!1))})(this);
 function openpgp_crypto_symmetricEncrypt(a,b,c,d,e){switch(b){case 0:return d;case 2:return openpgp_cfb_encrypt(a,desede,d,8,c,e).substring(0,d.length+10);case 3:return openpgp_cfb_encrypt(a,cast5_encrypt,d,8,c,e).substring(0,d.length+10);case 4:return openpgp_cfb_encrypt(a,BFencrypt,d,8,c,e).substring(0,d.length+10);case 7:case 8:case 9:return openpgp_cfb_encrypt(a,AESencrypt,d,16,keyExpansion(c),e).substring(0,d.length+18);case 10:return openpgp_cfb_encrypt(a,TFencrypt,d,16,c,e).substring(0,d.length+
 18);case 1:return util.print_error("IDEA Algorithm not implemented"),null;default:return null}}
 function openpgp_crypto_symmetricDecrypt(a,b,c,d){util.print_debug_hexstr_dump("openpgp_crypto_symmetricDecrypt:\nalgo:"+a+"\nencrypteddata:",c);var e=0;d||(e=2);switch(a){case 0:return c;case 2:return openpgp_cfb_decrypt(desede,8,b,c,d).substring(e,c.length+e-10);case 3:return openpgp_cfb_decrypt(cast5_encrypt,8,b,c,d).substring(e,c.length+e-10);case 4:return openpgp_cfb_decrypt(BFencrypt,8,b,c,d).substring(e,c.length+e-10);case 7:case 8:case 9:return openpgp_cfb_decrypt(AESencrypt,16,keyExpansion(b),
diff --git a/src/compression/zip/inflate.js b/src/compression/zip/inflate.js
deleted file mode 100644
index 67dfe18d..00000000
--- a/src/compression/zip/inflate.js
+++ /dev/null
@@ -1,2169 +0,0 @@
-/*
- Copyright (c) 2012 Gildas Lormeau. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright 
- notice, this list of conditions and the following disclaimer in 
- the documentation and/or other materials provided with the distribution.
-
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
- * JZlib is based on zlib-1.1.3, so all credit should go authors
- * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
- * and contributors of zlib.
- */
-
-(function(obj) {
-
-	// Global
-	var MAX_BITS = 15;
-
-	var Z_OK = 0;
-	var Z_STREAM_END = 1;
-	var Z_NEED_DICT = 2;
-	var Z_STREAM_ERROR = -2;
-	var Z_DATA_ERROR = -3;
-	var Z_MEM_ERROR = -4;
-	var Z_BUF_ERROR = -5;
-
-	var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff,
-			0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ];
-
-	var MANY = 1440;
-
-	var MAX_WBITS = 15; // 32K LZ77 window
-	var DEF_WBITS = MAX_WBITS;
-
-	// JZlib version : "1.0.2"
-	var Z_NO_FLUSH = 0;
-	var Z_FINISH = 4;
-
-	// InfTree
-	var fixed_bl = 9;
-	var fixed_bd = 5;
-
-	var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0,
-			0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40,
-			0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13,
-			0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60,
-			0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7,
-			35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8,
-			26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80,
-			7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0,
-			8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0,
-			8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97,
-			0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210,
-			81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117,
-			0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154,
-			84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83,
-			0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230,
-			80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139,
-			0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174,
-			0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111,
-			0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9,
-			193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8,
-			120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8,
-			227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8,
-			92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9,
-			249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8,
-			130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9,
-			181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8,
-			102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9,
-			221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0,
-			8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9,
-			147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8,
-			85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9,
-			235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8,
-			141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9,
-			167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8,
-			107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9,
-			207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8,
-			127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ];
-	var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5,
-			8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5,
-			24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ];
-
-	// Tables for deflate from PKZIP's appnote.txt.
-	var cplens = [ // Copy lengths for literal codes 257..285
-	3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ];
-
-	// see note #13 above about 258
-	var cplext = [ // Extra bits for literal codes 257..285
-	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid
-	];
-
-	var cpdist = [ // Copy offsets for distance codes 0..29
-	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];
-
-	var cpdext = [ // Extra bits for distance codes
-	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
-
-	// If BMAX needs to be larger than 16, then h and x[] should be uLong.
-	var BMAX = 15; // maximum bit length of any code
-
-	function InfTree() {
-		var that = this;
-
-		var hn; // hufts used in space
-		var v; // work area for huft_build
-		var c; // bit length count table
-		var r; // table entry for structure assignment
-		var u; // table stack
-		var x; // bit offsets, then code stack
-
-		function huft_build(b, // code lengths in bits (all assumed <=
-		// BMAX)
-		bindex, n, // number of codes (assumed <= 288)
-		s, // number of simple-valued codes (0..s-1)
-		d, // list of base values for non-simple codes
-		e, // list of extra bits for non-simple codes
-		t, // result: starting table
-		m, // maximum lookup bits, returns actual
-		hp,// space for trees
-		hn,// hufts used in space
-		v // working area: values in order of bit length
-		) {
-			// Given a list of code lengths and a maximum table size, make a set of
-			// tables to decode that set of codes. Return Z_OK on success,
-			// Z_BUF_ERROR
-			// if the given code set is incomplete (the tables are still built in
-			// this
-			// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set
-			// of
-			// lengths), or Z_MEM_ERROR if not enough memory.
-
-			var a; // counter for codes of length k
-			var f; // i repeats in table every f entries
-			var g; // maximum code length
-			var h; // table level
-			var i; // counter, current code
-			var j; // counter
-			var k; // number of bits in current code
-			var l; // bits per table (returned in m)
-			var mask; // (1 << w) - 1, to avoid cc -O bug on HP
-			var p; // pointer into c[], b[], or v[]
-			var q; // points to current table
-			var w; // bits before this table == (l * h)
-			var xp; // pointer into x
-			var y; // number of dummy codes added
-			var z; // number of entries in current table
-
-			// Generate counts for each bit length
-
-			p = 0;
-			i = n;
-			do {
-				c[b[bindex + p]]++;
-				p++;
-				i--; // assume all entries <= BMAX
-			} while (i !== 0);
-
-			if (c[0] == n) { // null input--all zero length codes
-				t[0] = -1;
-				m[0] = 0;
-				return Z_OK;
-			}
-
-			// Find minimum and maximum length, bound *m by those
-			l = m[0];
-			for (j = 1; j <= BMAX; j++)
-				if (c[j] !== 0)
-					break;
-			k = j; // minimum code length
-			if (l < j) {
-				l = j;
-			}
-			for (i = BMAX; i !== 0; i--) {
-				if (c[i] !== 0)
-					break;
-			}
-			g = i; // maximum code length
-			if (l > i) {
-				l = i;
-			}
-			m[0] = l;
-
-			// Adjust last length count to fill out codes, if needed
-			for (y = 1 << j; j < i; j++, y <<= 1) {
-				if ((y -= c[j]) < 0) {
-					return Z_DATA_ERROR;
-				}
-			}
-			if ((y -= c[i]) < 0) {
-				return Z_DATA_ERROR;
-			}
-			c[i] += y;
-
-			// Generate starting offsets into the value table for each length
-			x[1] = j = 0;
-			p = 1;
-			xp = 2;
-			while (--i !== 0) { // note that i == g from above
-				x[xp] = (j += c[p]);
-				xp++;
-				p++;
-			}
-
-			// Make a table of values in order of bit lengths
-			i = 0;
-			p = 0;
-			do {
-				if ((j = b[bindex + p]) !== 0) {
-					v[x[j]++] = i;
-				}
-				p++;
-			} while (++i < n);
-			n = x[g]; // set n to length of v
-
-			// Generate the Huffman codes and for each, make the table entries
-			x[0] = i = 0; // first Huffman code is zero
-			p = 0; // grab values in bit order
-			h = -1; // no tables yet--level -1
-			w = -l; // bits decoded == (l * h)
-			u[0] = 0; // just to keep compilers happy
-			q = 0; // ditto
-			z = 0; // ditto
-
-			// go through the bit lengths (k already is bits in shortest code)
-			for (; k <= g; k++) {
-				a = c[k];
-				while (a-- !== 0) {
-					// here i is the Huffman code of length k bits for value *p
-					// make tables up to required level
-					while (k > w + l) {
-						h++;
-						w += l; // previous table always l bits
-						// compute minimum size table less than or equal to l bits
-						z = g - w;
-						z = (z > l) ? l : z; // table size upper limit
-						if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
-							// too few codes for
-							// k-w bit table
-							f -= a + 1; // deduct codes from patterns left
-							xp = k;
-							if (j < z) {
-								while (++j < z) { // try smaller tables up to z bits
-									if ((f <<= 1) <= c[++xp])
-										break; // enough codes to use up j bits
-									f -= c[xp]; // else deduct codes from patterns
-								}
-							}
-						}
-						z = 1 << j; // table entries for j-bit table
-
-						// allocate new table
-						if (hn[0] + z > MANY) { // (note: doesn't matter for fixed)
-							return Z_DATA_ERROR; // overflow of MANY
-						}
-						u[h] = q = /* hp+ */hn[0]; // DEBUG
-						hn[0] += z;
-
-						// connect to last table, if there is one
-						if (h !== 0) {
-							x[h] = i; // save pattern for backing up
-							r[0] = /* (byte) */j; // bits in this table
-							r[1] = /* (byte) */l; // bits to dump before this table
-							j = i >>> (w - l);
-							r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table
-							hp.set(r, (u[h - 1] + j) * 3);
-							// to
-							// last
-							// table
-						} else {
-							t[0] = q; // first table is returned result
-						}
-					}
-
-					// set up table entry in r
-					r[1] = /* (byte) */(k - w);
-					if (p >= n) {
-						r[0] = 128 + 64; // out of values--invalid code
-					} else if (v[p] < s) {
-						r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is
-						// end-of-block
-						r[2] = v[p++]; // simple code is just the value
-					} else {
-						r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look
-						// up in lists
-						r[2] = d[v[p++] - s];
-					}
-
-					// fill code-like entries with r
-					f = 1 << (k - w);
-					for (j = i >>> w; j < z; j += f) {
-						hp.set(r, (q + j) * 3);
-					}
-
-					// backwards increment the k-bit code i
-					for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) {
-						i ^= j;
-					}
-					i ^= j;
-
-					// backup over finished tables
-					mask = (1 << w) - 1; // needed on HP, cc -O bug
-					while ((i & mask) != x[h]) {
-						h--; // don't need to update q
-						w -= l;
-						mask = (1 << w) - 1;
-					}
-				}
-			}
-			// Return Z_BUF_ERROR if we were given an incomplete table
-			return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-		}
-
-		function initWorkArea(vsize) {
-			var i;
-			if (!hn) {
-				hn = []; // []; //new Array(1);
-				v = []; // new Array(vsize);
-				c = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
-				r = []; // new Array(3);
-				u = new Int32Array(BMAX); // new Array(BMAX);
-				x = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
-			}
-			if (v.length < vsize) {
-				v = []; // new Array(vsize);
-			}
-			for (i = 0; i < vsize; i++) {
-				v[i] = 0;
-			}
-			for (i = 0; i < BMAX + 1; i++) {
-				c[i] = 0;
-			}
-			for (i = 0; i < 3; i++) {
-				r[i] = 0;
-			}
-			// for(int i=0; i<BMAX; i++){u[i]=0;}
-			u.set(c.subarray(0, BMAX), 0);
-			// for(int i=0; i<BMAX+1; i++){x[i]=0;}
-			x.set(c.subarray(0, BMAX + 1), 0);
-		}
-
-		that.inflate_trees_bits = function(c, // 19 code lengths
-		bb, // bits tree desired/actual depth
-		tb, // bits tree result
-		hp, // space for trees
-		z // for messages
-		) {
-			var result;
-			initWorkArea(19);
-			hn[0] = 0;
-			result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
-
-			if (result == Z_DATA_ERROR) {
-				z.msg = "oversubscribed dynamic bit lengths tree";
-			} else if (result == Z_BUF_ERROR || bb[0] === 0) {
-				z.msg = "incomplete dynamic bit lengths tree";
-				result = Z_DATA_ERROR;
-			}
-			return result;
-		};
-
-		that.inflate_trees_dynamic = function(nl, // number of literal/length codes
-		nd, // number of distance codes
-		c, // that many (total) code lengths
-		bl, // literal desired/actual bit depth
-		bd, // distance desired/actual bit depth
-		tl, // literal/length tree result
-		td, // distance tree result
-		hp, // space for trees
-		z // for messages
-		) {
-			var result;
-
-			// build literal/length tree
-			initWorkArea(288);
-			hn[0] = 0;
-			result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
-			if (result != Z_OK || bl[0] === 0) {
-				if (result == Z_DATA_ERROR) {
-					z.msg = "oversubscribed literal/length tree";
-				} else if (result != Z_MEM_ERROR) {
-					z.msg = "incomplete literal/length tree";
-					result = Z_DATA_ERROR;
-				}
-				return result;
-			}
-
-			// build distance tree
-			initWorkArea(288);
-			result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
-
-			if (result != Z_OK || (bd[0] === 0 && nl > 257)) {
-				if (result == Z_DATA_ERROR) {
-					z.msg = "oversubscribed distance tree";
-				} else if (result == Z_BUF_ERROR) {
-					z.msg = "incomplete distance tree";
-					result = Z_DATA_ERROR;
-				} else if (result != Z_MEM_ERROR) {
-					z.msg = "empty distance tree with lengths";
-					result = Z_DATA_ERROR;
-				}
-				return result;
-			}
-
-			return Z_OK;
-		};
-
-	}
-
-	InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth
-	bd, // distance desired/actual bit depth
-	tl,// literal/length tree result
-	td,// distance tree result
-	z // for memory allocation
-	) {
-		bl[0] = fixed_bl;
-		bd[0] = fixed_bd;
-		tl[0] = fixed_tl;
-		td[0] = fixed_td;
-		return Z_OK;
-	};
-
-	// InfCodes
-
-	// waiting for "i:"=input,
-	// "o:"=output,
-	// "x:"=nothing
-	var START = 0; // x: set up for LEN
-	var LEN = 1; // i: get length/literal/eob next
-	var LENEXT = 2; // i: getting length extra (have base)
-	var DIST = 3; // i: get distance next
-	var DISTEXT = 4;// i: getting distance extra
-	var COPY = 5; // o: copying bytes in window, waiting
-	// for space
-	var LIT = 6; // o: got literal, waiting for output
-	// space
-	var WASH = 7; // o: got eob, possibly still output
-	// waiting
-	var END = 8; // x: got eob and all data flushed
-	var BADCODE = 9;// x: got error
-
-	function InfCodes() {
-		var that = this;
-
-		var mode; // current inflate_codes mode
-
-		// mode dependent information
-		var len = 0;
-
-		var tree; // pointer into tree
-		var tree_index = 0;
-		var need = 0; // bits needed
-
-		var lit = 0;
-
-		// if EXT or COPY, where and how much
-		var get = 0; // bits to get for extra
-		var dist = 0; // distance back to copy from
-
-		var lbits = 0; // ltree bits decoded per branch
-		var dbits = 0; // dtree bits decoder per branch
-		var ltree; // literal/length/eob tree
-		var ltree_index = 0; // literal/length/eob tree
-		var dtree; // distance tree
-		var dtree_index = 0; // distance tree
-
-		// Called with number of bytes left to write in window at least 258
-		// (the maximum string length) and number of input bytes available
-		// at least ten. The ten bytes are six bytes for the longest length/
-		// distance pair plus four bytes for overloading the bit buffer.
-
-		function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) {
-			var t; // temporary pointer
-			var tp; // temporary pointer
-			var tp_index; // temporary pointer
-			var e; // extra bits or operation
-			var b; // bit buffer
-			var k; // bits in bit buffer
-			var p; // input data pointer
-			var n; // bytes available there
-			var q; // output window write pointer
-			var m; // bytes to end of window or read pointer
-			var ml; // mask for literal/length tree
-			var md; // mask for distance tree
-			var c; // bytes to copy
-			var d; // distance back to copy from
-			var r; // copy source pointer
-
-			var tp_index_t_3; // (tp_index+t)*3
-
-			// load input, output, bit values
-			p = z.next_in_index;
-			n = z.avail_in;
-			b = s.bitb;
-			k = s.bitk;
-			q = s.write;
-			m = q < s.read ? s.read - q - 1 : s.end - q;
-
-			// initialize masks
-			ml = inflate_mask[bl];
-			md = inflate_mask[bd];
-
-			// do until not enough input or output space for fast loop
-			do { // assume called with m >= 258 && n >= 10
-				// get literal/length code
-				while (k < (20)) { // max bits for literal/length code
-					n--;
-					b |= (z.read_byte(p++) & 0xff) << k;
-					k += 8;
-				}
-
-				t = b & ml;
-				tp = tl;
-				tp_index = tl_index;
-				tp_index_t_3 = (tp_index + t) * 3;
-				if ((e = tp[tp_index_t_3]) === 0) {
-					b >>= (tp[tp_index_t_3 + 1]);
-					k -= (tp[tp_index_t_3 + 1]);
-
-					s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
-					m--;
-					continue;
-				}
-				do {
-
-					b >>= (tp[tp_index_t_3 + 1]);
-					k -= (tp[tp_index_t_3 + 1]);
-
-					if ((e & 16) !== 0) {
-						e &= 15;
-						c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]);
-
-						b >>= e;
-						k -= e;
-
-						// decode distance base of block to copy
-						while (k < (15)) { // max bits for distance code
-							n--;
-							b |= (z.read_byte(p++) & 0xff) << k;
-							k += 8;
-						}
-
-						t = b & md;
-						tp = td;
-						tp_index = td_index;
-						tp_index_t_3 = (tp_index + t) * 3;
-						e = tp[tp_index_t_3];
-
-						do {
-
-							b >>= (tp[tp_index_t_3 + 1]);
-							k -= (tp[tp_index_t_3 + 1]);
-
-							if ((e & 16) !== 0) {
-								// get extra bits to add to distance base
-								e &= 15;
-								while (k < (e)) { // get extra bits (up to 13)
-									n--;
-									b |= (z.read_byte(p++) & 0xff) << k;
-									k += 8;
-								}
-
-								d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]);
-
-								b >>= (e);
-								k -= (e);
-
-								// do the copy
-								m -= c;
-								if (q >= d) { // offset before dest
-									// just copy
-									r = q - d;
-									if (q - r > 0 && 2 > (q - r)) {
-										s.window[q++] = s.window[r++]; // minimum
-										// count is
-										// three,
-										s.window[q++] = s.window[r++]; // so unroll
-										// loop a
-										// little
-										c -= 2;
-									} else {
-										s.window.set(s.window.subarray(r, r + 2), q);
-										q += 2;
-										r += 2;
-										c -= 2;
-									}
-								} else { // else offset after destination
-									r = q - d;
-									do {
-										r += s.end; // force pointer in window
-									} while (r < 0); // covers invalid distances
-									e = s.end - r;
-									if (c > e) { // if source crosses,
-										c -= e; // wrapped copy
-										if (q - r > 0 && e > (q - r)) {
-											do {
-												s.window[q++] = s.window[r++];
-											} while (--e !== 0);
-										} else {
-											s.window.set(s.window.subarray(r, r + e), q);
-											q += e;
-											r += e;
-											e = 0;
-										}
-										r = 0; // copy rest from start of window
-									}
-
-								}
-
-								// copy all or what's left
-								if (q - r > 0 && c > (q - r)) {
-									do {
-										s.window[q++] = s.window[r++];
-									} while (--c !== 0);
-								} else {
-									s.window.set(s.window.subarray(r, r + c), q);
-									q += c;
-									r += c;
-									c = 0;
-								}
-								break;
-							} else if ((e & 64) === 0) {
-								t += tp[tp_index_t_3 + 2];
-								t += (b & inflate_mask[e]);
-								tp_index_t_3 = (tp_index + t) * 3;
-								e = tp[tp_index_t_3];
-							} else {
-								z.msg = "invalid distance code";
-
-								c = z.avail_in - n;
-								c = (k >> 3) < c ? k >> 3 : c;
-								n += c;
-								p -= c;
-								k -= c << 3;
-
-								s.bitb = b;
-								s.bitk = k;
-								z.avail_in = n;
-								z.total_in += p - z.next_in_index;
-								z.next_in_index = p;
-								s.write = q;
-
-								return Z_DATA_ERROR;
-							}
-						} while (true);
-						break;
-					}
-
-					if ((e & 64) === 0) {
-						t += tp[tp_index_t_3 + 2];
-						t += (b & inflate_mask[e]);
-						tp_index_t_3 = (tp_index + t) * 3;
-						if ((e = tp[tp_index_t_3]) === 0) {
-
-							b >>= (tp[tp_index_t_3 + 1]);
-							k -= (tp[tp_index_t_3 + 1]);
-
-							s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
-							m--;
-							break;
-						}
-					} else if ((e & 32) !== 0) {
-
-						c = z.avail_in - n;
-						c = (k >> 3) < c ? k >> 3 : c;
-						n += c;
-						p -= c;
-						k -= c << 3;
-
-						s.bitb = b;
-						s.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						s.write = q;
-
-						return Z_STREAM_END;
-					} else {
-						z.msg = "invalid literal/length code";
-
-						c = z.avail_in - n;
-						c = (k >> 3) < c ? k >> 3 : c;
-						n += c;
-						p -= c;
-						k -= c << 3;
-
-						s.bitb = b;
-						s.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						s.write = q;
-
-						return Z_DATA_ERROR;
-					}
-				} while (true);
-			} while (m >= 258 && n >= 10);
-
-			// not enough input or output--restore pointers and return
-			c = z.avail_in - n;
-			c = (k >> 3) < c ? k >> 3 : c;
-			n += c;
-			p -= c;
-			k -= c << 3;
-
-			s.bitb = b;
-			s.bitk = k;
-			z.avail_in = n;
-			z.total_in += p - z.next_in_index;
-			z.next_in_index = p;
-			s.write = q;
-
-			return Z_OK;
-		}
-
-		that.init = function(bl, bd, tl, tl_index, td, td_index, z) {
-			mode = START;
-			lbits = /* (byte) */bl;
-			dbits = /* (byte) */bd;
-			ltree = tl;
-			ltree_index = tl_index;
-			dtree = td;
-			dtree_index = td_index;
-			tree = null;
-		};
-
-		that.proc = function(s, z, r) {
-			var j; // temporary storage
-			var t; // temporary pointer
-			var tindex; // temporary pointer
-			var e; // extra bits or operation
-			var b = 0; // bit buffer
-			var k = 0; // bits in bit buffer
-			var p = 0; // input data pointer
-			var n; // bytes available there
-			var q; // output window write pointer
-			var m; // bytes to end of window or read pointer
-			var f; // pointer to copy strings from
-
-			// copy input/output information to locals (UPDATE macro restores)
-			p = z.next_in_index;
-			n = z.avail_in;
-			b = s.bitb;
-			k = s.bitk;
-			q = s.write;
-			m = q < s.read ? s.read - q - 1 : s.end - q;
-
-			// process input and output based on current state
-			while (true) {
-				switch (mode) {
-				// waiting for "i:"=input, "o:"=output, "x:"=nothing
-				case START: // x: set up for LEN
-					if (m >= 258 && n >= 10) {
-
-						s.bitb = b;
-						s.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						s.write = q;
-						r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z);
-
-						p = z.next_in_index;
-						n = z.avail_in;
-						b = s.bitb;
-						k = s.bitk;
-						q = s.write;
-						m = q < s.read ? s.read - q - 1 : s.end - q;
-
-						if (r != Z_OK) {
-							mode = r == Z_STREAM_END ? WASH : BADCODE;
-							break;
-						}
-					}
-					need = lbits;
-					tree = ltree;
-					tree_index = ltree_index;
-
-					mode = LEN;
-				case LEN: // i: get length/literal/eob next
-					j = need;
-
-					while (k < (j)) {
-						if (n !== 0)
-							r = Z_OK;
-						else {
-
-							s.bitb = b;
-							s.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							s.write = q;
-							return s.inflate_flush(z, r);
-						}
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-
-					tindex = (tree_index + (b & inflate_mask[j])) * 3;
-
-					b >>>= (tree[tindex + 1]);
-					k -= (tree[tindex + 1]);
-
-					e = tree[tindex];
-
-					if (e === 0) { // literal
-						lit = tree[tindex + 2];
-						mode = LIT;
-						break;
-					}
-					if ((e & 16) !== 0) { // length
-						get = e & 15;
-						len = tree[tindex + 2];
-						mode = LENEXT;
-						break;
-					}
-					if ((e & 64) === 0) { // next table
-						need = e;
-						tree_index = tindex / 3 + tree[tindex + 2];
-						break;
-					}
-					if ((e & 32) !== 0) { // end of block
-						mode = WASH;
-						break;
-					}
-					mode = BADCODE; // invalid code
-					z.msg = "invalid literal/length code";
-					r = Z_DATA_ERROR;
-
-					s.bitb = b;
-					s.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					s.write = q;
-					return s.inflate_flush(z, r);
-
-				case LENEXT: // i: getting length extra (have base)
-					j = get;
-
-					while (k < (j)) {
-						if (n !== 0)
-							r = Z_OK;
-						else {
-
-							s.bitb = b;
-							s.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							s.write = q;
-							return s.inflate_flush(z, r);
-						}
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-
-					len += (b & inflate_mask[j]);
-
-					b >>= j;
-					k -= j;
-
-					need = dbits;
-					tree = dtree;
-					tree_index = dtree_index;
-					mode = DIST;
-				case DIST: // i: get distance next
-					j = need;
-
-					while (k < (j)) {
-						if (n !== 0)
-							r = Z_OK;
-						else {
-
-							s.bitb = b;
-							s.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							s.write = q;
-							return s.inflate_flush(z, r);
-						}
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-
-					tindex = (tree_index + (b & inflate_mask[j])) * 3;
-
-					b >>= tree[tindex + 1];
-					k -= tree[tindex + 1];
-
-					e = (tree[tindex]);
-					if ((e & 16) !== 0) { // distance
-						get = e & 15;
-						dist = tree[tindex + 2];
-						mode = DISTEXT;
-						break;
-					}
-					if ((e & 64) === 0) { // next table
-						need = e;
-						tree_index = tindex / 3 + tree[tindex + 2];
-						break;
-					}
-					mode = BADCODE; // invalid code
-					z.msg = "invalid distance code";
-					r = Z_DATA_ERROR;
-
-					s.bitb = b;
-					s.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					s.write = q;
-					return s.inflate_flush(z, r);
-
-				case DISTEXT: // i: getting distance extra
-					j = get;
-
-					while (k < (j)) {
-						if (n !== 0)
-							r = Z_OK;
-						else {
-
-							s.bitb = b;
-							s.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							s.write = q;
-							return s.inflate_flush(z, r);
-						}
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-
-					dist += (b & inflate_mask[j]);
-
-					b >>= j;
-					k -= j;
-
-					mode = COPY;
-				case COPY: // o: copying bytes in window, waiting for space
-					f = q - dist;
-					while (f < 0) { // modulo window size-"while" instead
-						f += s.end; // of "if" handles invalid distances
-					}
-					while (len !== 0) {
-
-						if (m === 0) {
-							if (q == s.end && s.read !== 0) {
-								q = 0;
-								m = q < s.read ? s.read - q - 1 : s.end - q;
-							}
-							if (m === 0) {
-								s.write = q;
-								r = s.inflate_flush(z, r);
-								q = s.write;
-								m = q < s.read ? s.read - q - 1 : s.end - q;
-
-								if (q == s.end && s.read !== 0) {
-									q = 0;
-									m = q < s.read ? s.read - q - 1 : s.end - q;
-								}
-
-								if (m === 0) {
-									s.bitb = b;
-									s.bitk = k;
-									z.avail_in = n;
-									z.total_in += p - z.next_in_index;
-									z.next_in_index = p;
-									s.write = q;
-									return s.inflate_flush(z, r);
-								}
-							}
-						}
-
-						s.window[q++] = s.window[f++];
-						m--;
-
-						if (f == s.end)
-							f = 0;
-						len--;
-					}
-					mode = START;
-					break;
-				case LIT: // o: got literal, waiting for output space
-					if (m === 0) {
-						if (q == s.end && s.read !== 0) {
-							q = 0;
-							m = q < s.read ? s.read - q - 1 : s.end - q;
-						}
-						if (m === 0) {
-							s.write = q;
-							r = s.inflate_flush(z, r);
-							q = s.write;
-							m = q < s.read ? s.read - q - 1 : s.end - q;
-
-							if (q == s.end && s.read !== 0) {
-								q = 0;
-								m = q < s.read ? s.read - q - 1 : s.end - q;
-							}
-							if (m === 0) {
-								s.bitb = b;
-								s.bitk = k;
-								z.avail_in = n;
-								z.total_in += p - z.next_in_index;
-								z.next_in_index = p;
-								s.write = q;
-								return s.inflate_flush(z, r);
-							}
-						}
-					}
-					r = Z_OK;
-
-					s.window[q++] = /* (byte) */lit;
-					m--;
-
-					mode = START;
-					break;
-				case WASH: // o: got eob, possibly more output
-					if (k > 7) { // return unused byte, if any
-						k -= 8;
-						n++;
-						p--; // can always return one
-					}
-
-					s.write = q;
-					r = s.inflate_flush(z, r);
-					q = s.write;
-					m = q < s.read ? s.read - q - 1 : s.end - q;
-
-					if (s.read != s.write) {
-						s.bitb = b;
-						s.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						s.write = q;
-						return s.inflate_flush(z, r);
-					}
-					mode = END;
-				case END:
-					r = Z_STREAM_END;
-					s.bitb = b;
-					s.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					s.write = q;
-					return s.inflate_flush(z, r);
-
-				case BADCODE: // x: got error
-
-					r = Z_DATA_ERROR;
-
-					s.bitb = b;
-					s.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					s.write = q;
-					return s.inflate_flush(z, r);
-
-				default:
-					r = Z_STREAM_ERROR;
-
-					s.bitb = b;
-					s.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					s.write = q;
-					return s.inflate_flush(z, r);
-				}
-			}
-		};
-
-		that.free = function(z) {
-			// ZFREE(z, c);
-		};
-
-	}
-
-	// InfBlocks
-
-	// Table for deflate from PKZIP's appnote.txt.
-	var border = [ // Order of the bit length code lengths
-	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
-
-	var TYPE = 0; // get type bits (3, including end bit)
-	var LENS = 1; // get lengths for stored
-	var STORED = 2;// processing stored block
-	var TABLE = 3; // get table lengths
-	var BTREE = 4; // get bit lengths tree for a dynamic
-	// block
-	var DTREE = 5; // get length, distance trees for a
-	// dynamic block
-	var CODES = 6; // processing fixed or dynamic block
-	var DRY = 7; // output remaining window bytes
-	var DONELOCKS = 8; // finished last block, done
-	var BADBLOCKS = 9; // ot a data error--stuck here
-
-	function InfBlocks(z, w) {
-		var that = this;
-
-		var mode = TYPE; // current inflate_block mode
-
-		var left = 0; // if STORED, bytes left to copy
-
-		var table = 0; // table lengths (14 bits)
-		var index = 0; // index into blens (or border)
-		var blens; // bit lengths of codes
-		var bb = [ 0 ]; // bit length tree depth
-		var tb = [ 0 ]; // bit length decoding tree
-
-		var codes = new InfCodes(); // if CODES, current state
-
-		var last = 0; // true if this block is the last block
-
-		var hufts = new Int32Array(MANY * 3); // single malloc for tree space
-		var check = 0; // check on output
-		var inftree = new InfTree();
-
-		that.bitk = 0; // bits in bit buffer
-		that.bitb = 0; // bit buffer
-		that.window = new Uint8Array(w); // sliding window
-		that.end = w; // one byte after sliding window
-		that.read = 0; // window read pointer
-		that.write = 0; // window write pointer
-
-		that.reset = function(z, c) {
-			if (c)
-				c[0] = check;
-			// if (mode == BTREE || mode == DTREE) {
-			// }
-			if (mode == CODES) {
-				codes.free(z);
-			}
-			mode = TYPE;
-			that.bitk = 0;
-			that.bitb = 0;
-			that.read = that.write = 0;
-		};
-
-		that.reset(z, null);
-
-		// copy as much as possible from the sliding window to the output area
-		that.inflate_flush = function(z, r) {
-			var n;
-			var p;
-			var q;
-
-			// local copies of source and destination pointers
-			p = z.next_out_index;
-			q = that.read;
-
-			// compute number of bytes to copy as far as end of window
-			n = /* (int) */((q <= that.write ? that.write : that.end) - q);
-			if (n > z.avail_out)
-				n = z.avail_out;
-			if (n !== 0 && r == Z_BUF_ERROR)
-				r = Z_OK;
-
-			// update counters
-			z.avail_out -= n;
-			z.total_out += n;
-
-			// copy as far as end of window
-			z.next_out.set(that.window.subarray(q, q + n), p);
-			p += n;
-			q += n;
-
-			// see if more to copy at beginning of window
-			if (q == that.end) {
-				// wrap pointers
-				q = 0;
-				if (that.write == that.end)
-					that.write = 0;
-
-				// compute bytes to copy
-				n = that.write - q;
-				if (n > z.avail_out)
-					n = z.avail_out;
-				if (n !== 0 && r == Z_BUF_ERROR)
-					r = Z_OK;
-
-				// update counters
-				z.avail_out -= n;
-				z.total_out += n;
-
-				// copy
-				z.next_out.set(that.window.subarray(q, q + n), p);
-				p += n;
-				q += n;
-			}
-
-			// update pointers
-			z.next_out_index = p;
-			that.read = q;
-
-			// done
-			return r;
-		};
-
-		that.proc = function(z, r) {
-			var t; // temporary storage
-			var b; // bit buffer
-			var k; // bits in bit buffer
-			var p; // input data pointer
-			var n; // bytes available there
-			var q; // output window write pointer
-			var m; // bytes to end of window or read pointer
-
-			var i;
-
-			// copy input/output information to locals (UPDATE macro restores)
-			// {
-			p = z.next_in_index;
-			n = z.avail_in;
-			b = that.bitb;
-			k = that.bitk;
-			// }
-			// {
-			q = that.write;
-			m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
-			// }
-
-			// process input based on current state
-			// DEBUG dtree
-			while (true) {
-				switch (mode) {
-				case TYPE:
-
-					while (k < (3)) {
-						if (n !== 0) {
-							r = Z_OK;
-						} else {
-							that.bitb = b;
-							that.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							that.write = q;
-							return that.inflate_flush(z, r);
-						}
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-					t = /* (int) */(b & 7);
-					last = t & 1;
-
-					switch (t >>> 1) {
-					case 0: // stored
-						// {
-						b >>>= (3);
-						k -= (3);
-						// }
-						t = k & 7; // go to byte boundary
-
-						// {
-						b >>>= (t);
-						k -= (t);
-						// }
-						mode = LENS; // get length of stored block
-						break;
-					case 1: // fixed
-						// {
-						var bl = []; // new Array(1);
-						var bd = []; // new Array(1);
-						var tl = [ [] ]; // new Array(1);
-						var td = [ [] ]; // new Array(1);
-
-						InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
-						codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z);
-						// }
-
-						// {
-						b >>>= (3);
-						k -= (3);
-						// }
-
-						mode = CODES;
-						break;
-					case 2: // dynamic
-
-						// {
-						b >>>= (3);
-						k -= (3);
-						// }
-
-						mode = TABLE;
-						break;
-					case 3: // illegal
-
-						// {
-						b >>>= (3);
-						k -= (3);
-						// }
-						mode = BADBLOCKS;
-						z.msg = "invalid block type";
-						r = Z_DATA_ERROR;
-
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-					break;
-				case LENS:
-
-					while (k < (32)) {
-						if (n !== 0) {
-							r = Z_OK;
-						} else {
-							that.bitb = b;
-							that.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							that.write = q;
-							return that.inflate_flush(z, r);
-						}
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-
-					if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) {
-						mode = BADBLOCKS;
-						z.msg = "invalid stored block lengths";
-						r = Z_DATA_ERROR;
-
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-					left = (b & 0xffff);
-					b = k = 0; // dump bits
-					mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE);
-					break;
-				case STORED:
-					if (n === 0) {
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-
-					if (m === 0) {
-						if (q == that.end && that.read !== 0) {
-							q = 0;
-							m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
-						}
-						if (m === 0) {
-							that.write = q;
-							r = that.inflate_flush(z, r);
-							q = that.write;
-							m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
-							if (q == that.end && that.read !== 0) {
-								q = 0;
-								m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
-							}
-							if (m === 0) {
-								that.bitb = b;
-								that.bitk = k;
-								z.avail_in = n;
-								z.total_in += p - z.next_in_index;
-								z.next_in_index = p;
-								that.write = q;
-								return that.inflate_flush(z, r);
-							}
-						}
-					}
-					r = Z_OK;
-
-					t = left;
-					if (t > n)
-						t = n;
-					if (t > m)
-						t = m;
-					that.window.set(z.read_buf(p, t), q);
-					p += t;
-					n -= t;
-					q += t;
-					m -= t;
-					if ((left -= t) !== 0)
-						break;
-					mode = last !== 0 ? DRY : TYPE;
-					break;
-				case TABLE:
-
-					while (k < (14)) {
-						if (n !== 0) {
-							r = Z_OK;
-						} else {
-							that.bitb = b;
-							that.bitk = k;
-							z.avail_in = n;
-							z.total_in += p - z.next_in_index;
-							z.next_in_index = p;
-							that.write = q;
-							return that.inflate_flush(z, r);
-						}
-
-						n--;
-						b |= (z.read_byte(p++) & 0xff) << k;
-						k += 8;
-					}
-
-					table = t = (b & 0x3fff);
-					if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
-						mode = BADBLOCKS;
-						z.msg = "too many length or distance symbols";
-						r = Z_DATA_ERROR;
-
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-					t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-					if (!blens || blens.length < t) {
-						blens = []; // new Array(t);
-					} else {
-						for (i = 0; i < t; i++) {
-							blens[i] = 0;
-						}
-					}
-
-					// {
-					b >>>= (14);
-					k -= (14);
-					// }
-
-					index = 0;
-					mode = BTREE;
-				case BTREE:
-					while (index < 4 + (table >>> 10)) {
-						while (k < (3)) {
-							if (n !== 0) {
-								r = Z_OK;
-							} else {
-								that.bitb = b;
-								that.bitk = k;
-								z.avail_in = n;
-								z.total_in += p - z.next_in_index;
-								z.next_in_index = p;
-								that.write = q;
-								return that.inflate_flush(z, r);
-							}
-							n--;
-							b |= (z.read_byte(p++) & 0xff) << k;
-							k += 8;
-						}
-
-						blens[border[index++]] = b & 7;
-
-						// {
-						b >>>= (3);
-						k -= (3);
-						// }
-					}
-
-					while (index < 19) {
-						blens[border[index++]] = 0;
-					}
-
-					bb[0] = 7;
-					t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
-					if (t != Z_OK) {
-						r = t;
-						if (r == Z_DATA_ERROR) {
-							blens = null;
-							mode = BADBLOCKS;
-						}
-
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-
-					index = 0;
-					mode = DTREE;
-				case DTREE:
-					while (true) {
-						t = table;
-						if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
-							break;
-						}
-
-						var h;
-						var j, c;
-
-						t = bb[0];
-
-						while (k < (t)) {
-							if (n !== 0) {
-								r = Z_OK;
-							} else {
-								that.bitb = b;
-								that.bitk = k;
-								z.avail_in = n;
-								z.total_in += p - z.next_in_index;
-								z.next_in_index = p;
-								that.write = q;
-								return that.inflate_flush(z, r);
-							}
-							n--;
-							b |= (z.read_byte(p++) & 0xff) << k;
-							k += 8;
-						}
-
-						// if (tb[0] == -1) {
-						// System.err.println("null...");
-						// }
-
-						t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
-						c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
-
-						if (c < 16) {
-							b >>>= (t);
-							k -= (t);
-							blens[index++] = c;
-						} else { // c == 16..18
-							i = c == 18 ? 7 : c - 14;
-							j = c == 18 ? 11 : 3;
-
-							while (k < (t + i)) {
-								if (n !== 0) {
-									r = Z_OK;
-								} else {
-									that.bitb = b;
-									that.bitk = k;
-									z.avail_in = n;
-									z.total_in += p - z.next_in_index;
-									z.next_in_index = p;
-									that.write = q;
-									return that.inflate_flush(z, r);
-								}
-								n--;
-								b |= (z.read_byte(p++) & 0xff) << k;
-								k += 8;
-							}
-
-							b >>>= (t);
-							k -= (t);
-
-							j += (b & inflate_mask[i]);
-
-							b >>>= (i);
-							k -= (i);
-
-							i = index;
-							t = table;
-							if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) {
-								blens = null;
-								mode = BADBLOCKS;
-								z.msg = "invalid bit length repeat";
-								r = Z_DATA_ERROR;
-
-								that.bitb = b;
-								that.bitk = k;
-								z.avail_in = n;
-								z.total_in += p - z.next_in_index;
-								z.next_in_index = p;
-								that.write = q;
-								return that.inflate_flush(z, r);
-							}
-
-							c = c == 16 ? blens[i - 1] : 0;
-							do {
-								blens[i++] = c;
-							} while (--j !== 0);
-							index = i;
-						}
-					}
-
-					tb[0] = -1;
-					// {
-					var bl_ = []; // new Array(1);
-					var bd_ = []; // new Array(1);
-					var tl_ = []; // new Array(1);
-					var td_ = []; // new Array(1);
-					bl_[0] = 9; // must be <= 9 for lookahead assumptions
-					bd_[0] = 6; // must be <= 9 for lookahead assumptions
-
-					t = table;
-					t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z);
-
-					if (t != Z_OK) {
-						if (t == Z_DATA_ERROR) {
-							blens = null;
-							mode = BADBLOCKS;
-						}
-						r = t;
-
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-					codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0], z);
-					// }
-					mode = CODES;
-				case CODES:
-					that.bitb = b;
-					that.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					that.write = q;
-
-					if ((r = codes.proc(that, z, r)) != Z_STREAM_END) {
-						return that.inflate_flush(z, r);
-					}
-					r = Z_OK;
-					codes.free(z);
-
-					p = z.next_in_index;
-					n = z.avail_in;
-					b = that.bitb;
-					k = that.bitk;
-					q = that.write;
-					m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
-
-					if (last === 0) {
-						mode = TYPE;
-						break;
-					}
-					mode = DRY;
-				case DRY:
-					that.write = q;
-					r = that.inflate_flush(z, r);
-					q = that.write;
-					m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
-					if (that.read != that.write) {
-						that.bitb = b;
-						that.bitk = k;
-						z.avail_in = n;
-						z.total_in += p - z.next_in_index;
-						z.next_in_index = p;
-						that.write = q;
-						return that.inflate_flush(z, r);
-					}
-					mode = DONELOCKS;
-				case DONELOCKS:
-					r = Z_STREAM_END;
-
-					that.bitb = b;
-					that.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					that.write = q;
-					return that.inflate_flush(z, r);
-				case BADBLOCKS:
-					r = Z_DATA_ERROR;
-
-					that.bitb = b;
-					that.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					that.write = q;
-					return that.inflate_flush(z, r);
-
-				default:
-					r = Z_STREAM_ERROR;
-
-					that.bitb = b;
-					that.bitk = k;
-					z.avail_in = n;
-					z.total_in += p - z.next_in_index;
-					z.next_in_index = p;
-					that.write = q;
-					return that.inflate_flush(z, r);
-				}
-			}
-		};
-
-		that.free = function(z) {
-			that.reset(z, null);
-			that.window = null;
-			hufts = null;
-			// ZFREE(z, s);
-		};
-
-		that.set_dictionary = function(d, start, n) {
-			that.window.set(d.subarray(start, start + n), 0);
-			that.read = that.write = n;
-		};
-
-		// Returns true if inflate is currently at the end of a block generated
-		// by Z_SYNC_FLUSH or Z_FULL_FLUSH.
-		that.sync_point = function() {
-			return mode == LENS ? 1 : 0;
-		};
-
-	}
-
-	// Inflate
-
-	// preset dictionary flag in zlib header
-	var PRESET_DICT = 0x20;
-
-	var Z_DEFLATED = 8;
-
-	var METHOD = 0; // waiting for method byte
-	var FLAG = 1; // waiting for flag byte
-	var DICT4 = 2; // four dictionary check bytes to go
-	var DICT3 = 3; // three dictionary check bytes to go
-	var DICT2 = 4; // two dictionary check bytes to go
-	var DICT1 = 5; // one dictionary check byte to go
-	var DICT0 = 6; // waiting for inflateSetDictionary
-	var BLOCKS = 7; // decompressing blocks
-	var DONE = 12; // finished check, done
-	var BAD = 13; // got an error--stay here
-
-	var mark = [ 0, 0, 0xff, 0xff ];
-
-	function Inflate() {
-		var that = this;
-
-		that.mode = 0; // current inflate mode
-
-		// mode dependent information
-		that.method = 0; // if FLAGS, method byte
-
-		// if CHECK, check values to compare
-		that.was = [ 0 ]; // new Array(1); // computed check value
-		that.need = 0; // stream check value
-
-		// if BAD, inflateSync's marker bytes count
-		that.marker = 0;
-
-		// mode independent information
-		that.wbits = 0; // log2(window size) (8..15, defaults to 15)
-
-		// this.blocks; // current inflate_blocks state
-
-		function inflateReset(z) {
-			if (!z || !z.istate)
-				return Z_STREAM_ERROR;
-
-			z.total_in = z.total_out = 0;
-			z.msg = null;
-			z.istate.mode = BLOCKS;
-			z.istate.blocks.reset(z, null);
-			return Z_OK;
-		}
-
-		that.inflateEnd = function(z) {
-			if (that.blocks)
-				that.blocks.free(z);
-			that.blocks = null;
-			// ZFREE(z, z->state);
-			return Z_OK;
-		};
-
-		that.inflateInit = function(z, w) {
-			z.msg = null;
-			that.blocks = null;
-
-			// set window size
-			if (w < 8 || w > 15) {
-				that.inflateEnd(z);
-				return Z_STREAM_ERROR;
-			}
-			that.wbits = w;
-
-			z.istate.blocks = new InfBlocks(z, 1 << w);
-
-			// reset state
-			inflateReset(z);
-			return Z_OK;
-		};
-
-		that.inflate = function(z, f) {
-			var r;
-			var b;
-
-			if (!z || !z.istate || !z.next_in)
-				return Z_STREAM_ERROR;
-			f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
-			r = Z_BUF_ERROR;
-			while (true) {
-				// System.out.println("mode: "+z.istate.mode);
-				switch (z.istate.mode) {
-				case METHOD:
-
-					if (z.avail_in === 0)
-						return r;
-					r = f;
-
-					z.avail_in--;
-					z.total_in++;
-					if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) {
-						z.istate.mode = BAD;
-						z.msg = "unknown compression method";
-						z.istate.marker = 5; // can't try inflateSync
-						break;
-					}
-					if ((z.istate.method >> 4) + 8 > z.istate.wbits) {
-						z.istate.mode = BAD;
-						z.msg = "invalid window size";
-						z.istate.marker = 5; // can't try inflateSync
-						break;
-					}
-					z.istate.mode = FLAG;
-				case FLAG:
-
-					if (z.avail_in === 0)
-						return r;
-					r = f;
-
-					z.avail_in--;
-					z.total_in++;
-					b = (z.read_byte(z.next_in_index++)) & 0xff;
-
-					if ((((z.istate.method << 8) + b) % 31) !== 0) {
-						z.istate.mode = BAD;
-						z.msg = "incorrect header check";
-						z.istate.marker = 5; // can't try inflateSync
-						break;
-					}
-
-					if ((b & PRESET_DICT) === 0) {
-						z.istate.mode = BLOCKS;
-						break;
-					}
-					z.istate.mode = DICT4;
-				case DICT4:
-
-					if (z.avail_in === 0)
-						return r;
-					r = f;
-
-					z.avail_in--;
-					z.total_in++;
-					z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000;
-					z.istate.mode = DICT3;
-				case DICT3:
-
-					if (z.avail_in === 0)
-						return r;
-					r = f;
-
-					z.avail_in--;
-					z.total_in++;
-					z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000;
-					z.istate.mode = DICT2;
-				case DICT2:
-
-					if (z.avail_in === 0)
-						return r;
-					r = f;
-
-					z.avail_in--;
-					z.total_in++;
-					z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00;
-					z.istate.mode = DICT1;
-				case DICT1:
-
-					if (z.avail_in === 0)
-						return r;
-					r = f;
-
-					z.avail_in--;
-					z.total_in++;
-					z.istate.need += (z.read_byte(z.next_in_index++) & 0xff);
-					z.istate.mode = DICT0;
-					return Z_NEED_DICT;
-				case DICT0:
-					z.istate.mode = BAD;
-					z.msg = "need dictionary";
-					z.istate.marker = 0; // can try inflateSync
-					return Z_STREAM_ERROR;
-				case BLOCKS:
-
-					r = z.istate.blocks.proc(z, r);
-					if (r == Z_DATA_ERROR) {
-						z.istate.mode = BAD;
-						z.istate.marker = 0; // can try inflateSync
-						break;
-					}
-					if (r == Z_OK) {
-						r = f;
-					}
-					if (r != Z_STREAM_END) {
-						return r;
-					}
-					r = f;
-					z.istate.blocks.reset(z, z.istate.was);
-					z.istate.mode = DONE;
-				case DONE:
-					return Z_STREAM_END;
-				case BAD:
-					return Z_DATA_ERROR;
-				default:
-					return Z_STREAM_ERROR;
-				}
-			}
-		};
-
-		that.inflateSetDictionary = function(z, dictionary, dictLength) {
-			var index = 0;
-			var length = dictLength;
-			if (!z || !z.istate || z.istate.mode != DICT0)
-				return Z_STREAM_ERROR;
-
-			if (length >= (1 << z.istate.wbits)) {
-				length = (1 << z.istate.wbits) - 1;
-				index = dictLength - length;
-			}
-			z.istate.blocks.set_dictionary(dictionary, index, length);
-			z.istate.mode = BLOCKS;
-			return Z_OK;
-		};
-
-		that.inflateSync = function(z) {
-			var n; // number of bytes to look at
-			var p; // pointer to bytes
-			var m; // number of marker bytes found in a row
-			var r, w; // temporaries to save total_in and total_out
-
-			// set up
-			if (!z || !z.istate)
-				return Z_STREAM_ERROR;
-			if (z.istate.mode != BAD) {
-				z.istate.mode = BAD;
-				z.istate.marker = 0;
-			}
-			if ((n = z.avail_in) === 0)
-				return Z_BUF_ERROR;
-			p = z.next_in_index;
-			m = z.istate.marker;
-
-			// search
-			while (n !== 0 && m < 4) {
-				if (z.read_byte(p) == mark[m]) {
-					m++;
-				} else if (z.read_byte(p) !== 0) {
-					m = 0;
-				} else {
-					m = 4 - m;
-				}
-				p++;
-				n--;
-			}
-
-			// restore
-			z.total_in += p - z.next_in_index;
-			z.next_in_index = p;
-			z.avail_in = n;
-			z.istate.marker = m;
-
-			// return no joy or set up to restart on a new block
-			if (m != 4) {
-				return Z_DATA_ERROR;
-			}
-			r = z.total_in;
-			w = z.total_out;
-			inflateReset(z);
-			z.total_in = r;
-			z.total_out = w;
-			z.istate.mode = BLOCKS;
-			return Z_OK;
-		};
-
-		// Returns true if inflate is currently at the end of a block generated
-		// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
-		// implementation to provide an additional safety check. PPP uses
-		// Z_SYNC_FLUSH
-		// but removes the length bytes of the resulting empty stored block. When
-		// decompressing, PPP checks that at the end of input packet, inflate is
-		// waiting for these length bytes.
-		that.inflateSyncPoint = function(z) {
-			if (!z || !z.istate || !z.istate.blocks)
-				return Z_STREAM_ERROR;
-			return z.istate.blocks.sync_point();
-		};
-	}
-
-	// ZStream
-
-	function ZStream() {
-	}
-
-	ZStream.prototype = {
-		inflateInit : function(bits) {
-			var that = this;
-			that.istate = new Inflate();
-			if (!bits)
-				bits = MAX_BITS;
-			return that.istate.inflateInit(that, bits);
-		},
-
-		inflate : function(f) {
-			var that = this;
-			if (!that.istate)
-				return Z_STREAM_ERROR;
-			return that.istate.inflate(that, f);
-		},
-
-		inflateEnd : function() {
-			var that = this;
-			if (!that.istate)
-				return Z_STREAM_ERROR;
-			var ret = that.istate.inflateEnd(that);
-			that.istate = null;
-			return ret;
-		},
-
-		inflateSync : function() {
-			var that = this;
-			if (!that.istate)
-				return Z_STREAM_ERROR;
-			return that.istate.inflateSync(that);
-		},
-		inflateSetDictionary : function(dictionary, dictLength) {
-			var that = this;
-			if (!that.istate)
-				return Z_STREAM_ERROR;
-			return that.istate.inflateSetDictionary(that, dictionary, dictLength);
-		},
-		read_byte : function(start) {
-			var that = this;
-			return that.next_in.subarray(start, start + 1)[0];
-		},
-		read_buf : function(start, size) {
-			var that = this;
-			return that.next_in.subarray(start, start + size);
-		}
-	};
-
-	// Inflater
-
-	function Inflater() {
-		var that = this;
-		var z = new ZStream();
-		var bufsize = 512;
-		var flush = Z_NO_FLUSH;
-		var buf = new Uint8Array(bufsize);
-		var nomoreinput = false;
-
-		z.inflateInit();
-		z.next_out = buf;
-
-		that.append = function(data, onprogress) {
-			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
-			if (data.length === 0)
-				return;
-			z.next_in_index = 0;
-			z.next_in = data;
-			z.avail_in = data.length;
-			do {
-				z.next_out_index = 0;
-				z.avail_out = bufsize;
-				if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it
-					z.next_in_index = 0;
-					nomoreinput = true;
-				}
-				err = z.inflate(flush);
-				if (nomoreinput && (err == Z_BUF_ERROR))
-					return -1;
-				if (err != Z_OK && err != Z_STREAM_END)
-					throw "inflating: " + z.msg;
-				if ((nomoreinput || err == Z_STREAM_END) && (z.avail_out == data.length))
-					return -1;
-				if (z.next_out_index)
-					if (z.next_out_index == bufsize)
-						buffers.push(new Uint8Array(buf));
-					else
-						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
-				bufferSize += z.next_out_index;
-				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
-					onprogress(z.next_in_index);
-					lastIndex = z.next_in_index;
-				}
-			} while (z.avail_in > 0 || z.avail_out === 0);
-			array = new Uint8Array(bufferSize);
-			buffers.forEach(function(chunk) {
-				array.set(chunk, bufferIndex);
-				bufferIndex += chunk.length;
-			});
-			return array;
-		};
-		that.flush = function() {
-			z.inflateEnd();
-		};
-	}
-
-	var inflater;
-
-	if (obj.zip)
-		obj.zip.Inflater = Inflater;
-	else {
-		inflater = new Inflater();
-		obj.addEventListener("message", function(event) {
-			var message = event.data;
-
-			if (message.append)
-				obj.postMessage({
-					onappend : true,
-					data : inflater.append(message.data, function(current) {
-						obj.postMessage({
-							progress : true,
-							current : current
-						});
-					})
-				});
-			if (message.flush) {
-				inflater.flush();
-				obj.postMessage({
-					onflush : true
-				});
-			}
-		}, false);
-	}
-
-})(this);
diff --git a/src/compression/zip/zip.js b/src/compression/zip/zip.js
index c05e8c83..32d0f9bc 100644
--- a/src/compression/zip/zip.js
+++ b/src/compression/zip/zip.js
@@ -33,3 +33,2146 @@
 	};
 
 })(this);
+
+// include inflate.js
+
+/*
+ * zip.js and include.js are merged in one file because of a dependency in the
+ * execution order: zip.Inflater is only defined if inflate.js is executed after zip.js
+ */
+
+(function(obj) {
+
+	// Global
+	var MAX_BITS = 15;
+
+	var Z_OK = 0;
+	var Z_STREAM_END = 1;
+	var Z_NEED_DICT = 2;
+	var Z_STREAM_ERROR = -2;
+	var Z_DATA_ERROR = -3;
+	var Z_MEM_ERROR = -4;
+	var Z_BUF_ERROR = -5;
+
+	var inflate_mask = [ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff,
+			0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff ];
+
+	var MANY = 1440;
+
+	var MAX_WBITS = 15; // 32K LZ77 window
+	var DEF_WBITS = MAX_WBITS;
+
+	// JZlib version : "1.0.2"
+	var Z_NO_FLUSH = 0;
+	var Z_FINISH = 4;
+
+	// InfTree
+	var fixed_bl = 9;
+	var fixed_bd = 5;
+
+	var fixed_tl = [ 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0,
+			0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40,
+			0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13,
+			0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60,
+			0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7,
+			35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8,
+			26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80,
+			7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0,
+			8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0,
+			8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97,
+			0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210,
+			81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117,
+			0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154,
+			84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83,
+			0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230,
+			80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139,
+			0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174,
+			0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111,
+			0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9,
+			193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8,
+			120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8,
+			227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8,
+			92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9,
+			249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8,
+			130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9,
+			181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8,
+			102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9,
+			221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0,
+			8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9,
+			147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8,
+			85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9,
+			235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8,
+			141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9,
+			167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8,
+			107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9,
+			207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8,
+			127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255 ];
+	var fixed_td = [ 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5,
+			8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5,
+			24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577 ];
+
+	// Tables for deflate from PKZIP's appnote.txt.
+	var cplens = [ // Copy lengths for literal codes 257..285
+	3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 ];
+
+	// see note #13 above about 258
+	var cplext = [ // Extra bits for literal codes 257..285
+	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112 // 112==invalid
+	];
+
+	var cpdist = [ // Copy offsets for distance codes 0..29
+	1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];
+
+	var cpdext = [ // Extra bits for distance codes
+	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
+
+	// If BMAX needs to be larger than 16, then h and x[] should be uLong.
+	var BMAX = 15; // maximum bit length of any code
+
+	function InfTree() {
+		var that = this;
+
+		var hn; // hufts used in space
+		var v; // work area for huft_build
+		var c; // bit length count table
+		var r; // table entry for structure assignment
+		var u; // table stack
+		var x; // bit offsets, then code stack
+
+		function huft_build(b, // code lengths in bits (all assumed <=
+		// BMAX)
+		bindex, n, // number of codes (assumed <= 288)
+		s, // number of simple-valued codes (0..s-1)
+		d, // list of base values for non-simple codes
+		e, // list of extra bits for non-simple codes
+		t, // result: starting table
+		m, // maximum lookup bits, returns actual
+		hp,// space for trees
+		hn,// hufts used in space
+		v // working area: values in order of bit length
+		) {
+			// Given a list of code lengths and a maximum table size, make a set of
+			// tables to decode that set of codes. Return Z_OK on success,
+			// Z_BUF_ERROR
+			// if the given code set is incomplete (the tables are still built in
+			// this
+			// case), Z_DATA_ERROR if the input is invalid (an over-subscribed set
+			// of
+			// lengths), or Z_MEM_ERROR if not enough memory.
+
+			var a; // counter for codes of length k
+			var f; // i repeats in table every f entries
+			var g; // maximum code length
+			var h; // table level
+			var i; // counter, current code
+			var j; // counter
+			var k; // number of bits in current code
+			var l; // bits per table (returned in m)
+			var mask; // (1 << w) - 1, to avoid cc -O bug on HP
+			var p; // pointer into c[], b[], or v[]
+			var q; // points to current table
+			var w; // bits before this table == (l * h)
+			var xp; // pointer into x
+			var y; // number of dummy codes added
+			var z; // number of entries in current table
+
+			// Generate counts for each bit length
+
+			p = 0;
+			i = n;
+			do {
+				c[b[bindex + p]]++;
+				p++;
+				i--; // assume all entries <= BMAX
+			} while (i !== 0);
+
+			if (c[0] == n) { // null input--all zero length codes
+				t[0] = -1;
+				m[0] = 0;
+				return Z_OK;
+			}
+
+			// Find minimum and maximum length, bound *m by those
+			l = m[0];
+			for (j = 1; j <= BMAX; j++)
+				if (c[j] !== 0)
+					break;
+			k = j; // minimum code length
+			if (l < j) {
+				l = j;
+			}
+			for (i = BMAX; i !== 0; i--) {
+				if (c[i] !== 0)
+					break;
+			}
+			g = i; // maximum code length
+			if (l > i) {
+				l = i;
+			}
+			m[0] = l;
+
+			// Adjust last length count to fill out codes, if needed
+			for (y = 1 << j; j < i; j++, y <<= 1) {
+				if ((y -= c[j]) < 0) {
+					return Z_DATA_ERROR;
+				}
+			}
+			if ((y -= c[i]) < 0) {
+				return Z_DATA_ERROR;
+			}
+			c[i] += y;
+
+			// Generate starting offsets into the value table for each length
+			x[1] = j = 0;
+			p = 1;
+			xp = 2;
+			while (--i !== 0) { // note that i == g from above
+				x[xp] = (j += c[p]);
+				xp++;
+				p++;
+			}
+
+			// Make a table of values in order of bit lengths
+			i = 0;
+			p = 0;
+			do {
+				if ((j = b[bindex + p]) !== 0) {
+					v[x[j]++] = i;
+				}
+				p++;
+			} while (++i < n);
+			n = x[g]; // set n to length of v
+
+			// Generate the Huffman codes and for each, make the table entries
+			x[0] = i = 0; // first Huffman code is zero
+			p = 0; // grab values in bit order
+			h = -1; // no tables yet--level -1
+			w = -l; // bits decoded == (l * h)
+			u[0] = 0; // just to keep compilers happy
+			q = 0; // ditto
+			z = 0; // ditto
+
+			// go through the bit lengths (k already is bits in shortest code)
+			for (; k <= g; k++) {
+				a = c[k];
+				while (a-- !== 0) {
+					// here i is the Huffman code of length k bits for value *p
+					// make tables up to required level
+					while (k > w + l) {
+						h++;
+						w += l; // previous table always l bits
+						// compute minimum size table less than or equal to l bits
+						z = g - w;
+						z = (z > l) ? l : z; // table size upper limit
+						if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
+							// too few codes for
+							// k-w bit table
+							f -= a + 1; // deduct codes from patterns left
+							xp = k;
+							if (j < z) {
+								while (++j < z) { // try smaller tables up to z bits
+									if ((f <<= 1) <= c[++xp])
+										break; // enough codes to use up j bits
+									f -= c[xp]; // else deduct codes from patterns
+								}
+							}
+						}
+						z = 1 << j; // table entries for j-bit table
+
+						// allocate new table
+						if (hn[0] + z > MANY) { // (note: doesn't matter for fixed)
+							return Z_DATA_ERROR; // overflow of MANY
+						}
+						u[h] = q = /* hp+ */hn[0]; // DEBUG
+						hn[0] += z;
+
+						// connect to last table, if there is one
+						if (h !== 0) {
+							x[h] = i; // save pattern for backing up
+							r[0] = /* (byte) */j; // bits in this table
+							r[1] = /* (byte) */l; // bits to dump before this table
+							j = i >>> (w - l);
+							r[2] = /* (int) */(q - u[h - 1] - j); // offset to this table
+							hp.set(r, (u[h - 1] + j) * 3);
+							// to
+							// last
+							// table
+						} else {
+							t[0] = q; // first table is returned result
+						}
+					}
+
+					// set up table entry in r
+					r[1] = /* (byte) */(k - w);
+					if (p >= n) {
+						r[0] = 128 + 64; // out of values--invalid code
+					} else if (v[p] < s) {
+						r[0] = /* (byte) */(v[p] < 256 ? 0 : 32 + 64); // 256 is
+						// end-of-block
+						r[2] = v[p++]; // simple code is just the value
+					} else {
+						r[0] = /* (byte) */(e[v[p] - s] + 16 + 64); // non-simple--look
+						// up in lists
+						r[2] = d[v[p++] - s];
+					}
+
+					// fill code-like entries with r
+					f = 1 << (k - w);
+					for (j = i >>> w; j < z; j += f) {
+						hp.set(r, (q + j) * 3);
+					}
+
+					// backwards increment the k-bit code i
+					for (j = 1 << (k - 1); (i & j) !== 0; j >>>= 1) {
+						i ^= j;
+					}
+					i ^= j;
+
+					// backup over finished tables
+					mask = (1 << w) - 1; // needed on HP, cc -O bug
+					while ((i & mask) != x[h]) {
+						h--; // don't need to update q
+						w -= l;
+						mask = (1 << w) - 1;
+					}
+				}
+			}
+			// Return Z_BUF_ERROR if we were given an incomplete table
+			return y !== 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+		}
+
+		function initWorkArea(vsize) {
+			var i;
+			if (!hn) {
+				hn = []; // []; //new Array(1);
+				v = []; // new Array(vsize);
+				c = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
+				r = []; // new Array(3);
+				u = new Int32Array(BMAX); // new Array(BMAX);
+				x = new Int32Array(BMAX + 1); // new Array(BMAX + 1);
+			}
+			if (v.length < vsize) {
+				v = []; // new Array(vsize);
+			}
+			for (i = 0; i < vsize; i++) {
+				v[i] = 0;
+			}
+			for (i = 0; i < BMAX + 1; i++) {
+				c[i] = 0;
+			}
+			for (i = 0; i < 3; i++) {
+				r[i] = 0;
+			}
+			// for(int i=0; i<BMAX; i++){u[i]=0;}
+			u.set(c.subarray(0, BMAX), 0);
+			// for(int i=0; i<BMAX+1; i++){x[i]=0;}
+			x.set(c.subarray(0, BMAX + 1), 0);
+		}
+
+		that.inflate_trees_bits = function(c, // 19 code lengths
+		bb, // bits tree desired/actual depth
+		tb, // bits tree result
+		hp, // space for trees
+		z // for messages
+		) {
+			var result;
+			initWorkArea(19);
+			hn[0] = 0;
+			result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v);
+
+			if (result == Z_DATA_ERROR) {
+				z.msg = "oversubscribed dynamic bit lengths tree";
+			} else if (result == Z_BUF_ERROR || bb[0] === 0) {
+				z.msg = "incomplete dynamic bit lengths tree";
+				result = Z_DATA_ERROR;
+			}
+			return result;
+		};
+
+		that.inflate_trees_dynamic = function(nl, // number of literal/length codes
+		nd, // number of distance codes
+		c, // that many (total) code lengths
+		bl, // literal desired/actual bit depth
+		bd, // distance desired/actual bit depth
+		tl, // literal/length tree result
+		td, // distance tree result
+		hp, // space for trees
+		z // for messages
+		) {
+			var result;
+
+			// build literal/length tree
+			initWorkArea(288);
+			hn[0] = 0;
+			result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v);
+			if (result != Z_OK || bl[0] === 0) {
+				if (result == Z_DATA_ERROR) {
+					z.msg = "oversubscribed literal/length tree";
+				} else if (result != Z_MEM_ERROR) {
+					z.msg = "incomplete literal/length tree";
+					result = Z_DATA_ERROR;
+				}
+				return result;
+			}
+
+			// build distance tree
+			initWorkArea(288);
+			result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v);
+
+			if (result != Z_OK || (bd[0] === 0 && nl > 257)) {
+				if (result == Z_DATA_ERROR) {
+					z.msg = "oversubscribed distance tree";
+				} else if (result == Z_BUF_ERROR) {
+					z.msg = "incomplete distance tree";
+					result = Z_DATA_ERROR;
+				} else if (result != Z_MEM_ERROR) {
+					z.msg = "empty distance tree with lengths";
+					result = Z_DATA_ERROR;
+				}
+				return result;
+			}
+
+			return Z_OK;
+		};
+
+	}
+
+	InfTree.inflate_trees_fixed = function(bl, // literal desired/actual bit depth
+	bd, // distance desired/actual bit depth
+	tl,// literal/length tree result
+	td,// distance tree result
+	z // for memory allocation
+	) {
+		bl[0] = fixed_bl;
+		bd[0] = fixed_bd;
+		tl[0] = fixed_tl;
+		td[0] = fixed_td;
+		return Z_OK;
+	};
+
+	// InfCodes
+
+	// waiting for "i:"=input,
+	// "o:"=output,
+	// "x:"=nothing
+	var START = 0; // x: set up for LEN
+	var LEN = 1; // i: get length/literal/eob next
+	var LENEXT = 2; // i: getting length extra (have base)
+	var DIST = 3; // i: get distance next
+	var DISTEXT = 4;// i: getting distance extra
+	var COPY = 5; // o: copying bytes in window, waiting
+	// for space
+	var LIT = 6; // o: got literal, waiting for output
+	// space
+	var WASH = 7; // o: got eob, possibly still output
+	// waiting
+	var END = 8; // x: got eob and all data flushed
+	var BADCODE = 9;// x: got error
+
+	function InfCodes() {
+		var that = this;
+
+		var mode; // current inflate_codes mode
+
+		// mode dependent information
+		var len = 0;
+
+		var tree; // pointer into tree
+		var tree_index = 0;
+		var need = 0; // bits needed
+
+		var lit = 0;
+
+		// if EXT or COPY, where and how much
+		var get = 0; // bits to get for extra
+		var dist = 0; // distance back to copy from
+
+		var lbits = 0; // ltree bits decoded per branch
+		var dbits = 0; // dtree bits decoder per branch
+		var ltree; // literal/length/eob tree
+		var ltree_index = 0; // literal/length/eob tree
+		var dtree; // distance tree
+		var dtree_index = 0; // distance tree
+
+		// Called with number of bytes left to write in window at least 258
+		// (the maximum string length) and number of input bytes available
+		// at least ten. The ten bytes are six bytes for the longest length/
+		// distance pair plus four bytes for overloading the bit buffer.
+
+		function inflate_fast(bl, bd, tl, tl_index, td, td_index, s, z) {
+			var t; // temporary pointer
+			var tp; // temporary pointer
+			var tp_index; // temporary pointer
+			var e; // extra bits or operation
+			var b; // bit buffer
+			var k; // bits in bit buffer
+			var p; // input data pointer
+			var n; // bytes available there
+			var q; // output window write pointer
+			var m; // bytes to end of window or read pointer
+			var ml; // mask for literal/length tree
+			var md; // mask for distance tree
+			var c; // bytes to copy
+			var d; // distance back to copy from
+			var r; // copy source pointer
+
+			var tp_index_t_3; // (tp_index+t)*3
+
+			// load input, output, bit values
+			p = z.next_in_index;
+			n = z.avail_in;
+			b = s.bitb;
+			k = s.bitk;
+			q = s.write;
+			m = q < s.read ? s.read - q - 1 : s.end - q;
+
+			// initialize masks
+			ml = inflate_mask[bl];
+			md = inflate_mask[bd];
+
+			// do until not enough input or output space for fast loop
+			do { // assume called with m >= 258 && n >= 10
+				// get literal/length code
+				while (k < (20)) { // max bits for literal/length code
+					n--;
+					b |= (z.read_byte(p++) & 0xff) << k;
+					k += 8;
+				}
+
+				t = b & ml;
+				tp = tl;
+				tp_index = tl_index;
+				tp_index_t_3 = (tp_index + t) * 3;
+				if ((e = tp[tp_index_t_3]) === 0) {
+					b >>= (tp[tp_index_t_3 + 1]);
+					k -= (tp[tp_index_t_3 + 1]);
+
+					s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
+					m--;
+					continue;
+				}
+				do {
+
+					b >>= (tp[tp_index_t_3 + 1]);
+					k -= (tp[tp_index_t_3 + 1]);
+
+					if ((e & 16) !== 0) {
+						e &= 15;
+						c = tp[tp_index_t_3 + 2] + (/* (int) */b & inflate_mask[e]);
+
+						b >>= e;
+						k -= e;
+
+						// decode distance base of block to copy
+						while (k < (15)) { // max bits for distance code
+							n--;
+							b |= (z.read_byte(p++) & 0xff) << k;
+							k += 8;
+						}
+
+						t = b & md;
+						tp = td;
+						tp_index = td_index;
+						tp_index_t_3 = (tp_index + t) * 3;
+						e = tp[tp_index_t_3];
+
+						do {
+
+							b >>= (tp[tp_index_t_3 + 1]);
+							k -= (tp[tp_index_t_3 + 1]);
+
+							if ((e & 16) !== 0) {
+								// get extra bits to add to distance base
+								e &= 15;
+								while (k < (e)) { // get extra bits (up to 13)
+									n--;
+									b |= (z.read_byte(p++) & 0xff) << k;
+									k += 8;
+								}
+
+								d = tp[tp_index_t_3 + 2] + (b & inflate_mask[e]);
+
+								b >>= (e);
+								k -= (e);
+
+								// do the copy
+								m -= c;
+								if (q >= d) { // offset before dest
+									// just copy
+									r = q - d;
+									if (q - r > 0 && 2 > (q - r)) {
+										s.window[q++] = s.window[r++]; // minimum
+										// count is
+										// three,
+										s.window[q++] = s.window[r++]; // so unroll
+										// loop a
+										// little
+										c -= 2;
+									} else {
+										s.window.set(s.window.subarray(r, r + 2), q);
+										q += 2;
+										r += 2;
+										c -= 2;
+									}
+								} else { // else offset after destination
+									r = q - d;
+									do {
+										r += s.end; // force pointer in window
+									} while (r < 0); // covers invalid distances
+									e = s.end - r;
+									if (c > e) { // if source crosses,
+										c -= e; // wrapped copy
+										if (q - r > 0 && e > (q - r)) {
+											do {
+												s.window[q++] = s.window[r++];
+											} while (--e !== 0);
+										} else {
+											s.window.set(s.window.subarray(r, r + e), q);
+											q += e;
+											r += e;
+											e = 0;
+										}
+										r = 0; // copy rest from start of window
+									}
+
+								}
+
+								// copy all or what's left
+								if (q - r > 0 && c > (q - r)) {
+									do {
+										s.window[q++] = s.window[r++];
+									} while (--c !== 0);
+								} else {
+									s.window.set(s.window.subarray(r, r + c), q);
+									q += c;
+									r += c;
+									c = 0;
+								}
+								break;
+							} else if ((e & 64) === 0) {
+								t += tp[tp_index_t_3 + 2];
+								t += (b & inflate_mask[e]);
+								tp_index_t_3 = (tp_index + t) * 3;
+								e = tp[tp_index_t_3];
+							} else {
+								z.msg = "invalid distance code";
+
+								c = z.avail_in - n;
+								c = (k >> 3) < c ? k >> 3 : c;
+								n += c;
+								p -= c;
+								k -= c << 3;
+
+								s.bitb = b;
+								s.bitk = k;
+								z.avail_in = n;
+								z.total_in += p - z.next_in_index;
+								z.next_in_index = p;
+								s.write = q;
+
+								return Z_DATA_ERROR;
+							}
+						} while (true);
+						break;
+					}
+
+					if ((e & 64) === 0) {
+						t += tp[tp_index_t_3 + 2];
+						t += (b & inflate_mask[e]);
+						tp_index_t_3 = (tp_index + t) * 3;
+						if ((e = tp[tp_index_t_3]) === 0) {
+
+							b >>= (tp[tp_index_t_3 + 1]);
+							k -= (tp[tp_index_t_3 + 1]);
+
+							s.window[q++] = /* (byte) */tp[tp_index_t_3 + 2];
+							m--;
+							break;
+						}
+					} else if ((e & 32) !== 0) {
+
+						c = z.avail_in - n;
+						c = (k >> 3) < c ? k >> 3 : c;
+						n += c;
+						p -= c;
+						k -= c << 3;
+
+						s.bitb = b;
+						s.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						s.write = q;
+
+						return Z_STREAM_END;
+					} else {
+						z.msg = "invalid literal/length code";
+
+						c = z.avail_in - n;
+						c = (k >> 3) < c ? k >> 3 : c;
+						n += c;
+						p -= c;
+						k -= c << 3;
+
+						s.bitb = b;
+						s.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						s.write = q;
+
+						return Z_DATA_ERROR;
+					}
+				} while (true);
+			} while (m >= 258 && n >= 10);
+
+			// not enough input or output--restore pointers and return
+			c = z.avail_in - n;
+			c = (k >> 3) < c ? k >> 3 : c;
+			n += c;
+			p -= c;
+			k -= c << 3;
+
+			s.bitb = b;
+			s.bitk = k;
+			z.avail_in = n;
+			z.total_in += p - z.next_in_index;
+			z.next_in_index = p;
+			s.write = q;
+
+			return Z_OK;
+		}
+
+		that.init = function(bl, bd, tl, tl_index, td, td_index, z) {
+			mode = START;
+			lbits = /* (byte) */bl;
+			dbits = /* (byte) */bd;
+			ltree = tl;
+			ltree_index = tl_index;
+			dtree = td;
+			dtree_index = td_index;
+			tree = null;
+		};
+
+		that.proc = function(s, z, r) {
+			var j; // temporary storage
+			var t; // temporary pointer
+			var tindex; // temporary pointer
+			var e; // extra bits or operation
+			var b = 0; // bit buffer
+			var k = 0; // bits in bit buffer
+			var p = 0; // input data pointer
+			var n; // bytes available there
+			var q; // output window write pointer
+			var m; // bytes to end of window or read pointer
+			var f; // pointer to copy strings from
+
+			// copy input/output information to locals (UPDATE macro restores)
+			p = z.next_in_index;
+			n = z.avail_in;
+			b = s.bitb;
+			k = s.bitk;
+			q = s.write;
+			m = q < s.read ? s.read - q - 1 : s.end - q;
+
+			// process input and output based on current state
+			while (true) {
+				switch (mode) {
+				// waiting for "i:"=input, "o:"=output, "x:"=nothing
+				case START: // x: set up for LEN
+					if (m >= 258 && n >= 10) {
+
+						s.bitb = b;
+						s.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						s.write = q;
+						r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z);
+
+						p = z.next_in_index;
+						n = z.avail_in;
+						b = s.bitb;
+						k = s.bitk;
+						q = s.write;
+						m = q < s.read ? s.read - q - 1 : s.end - q;
+
+						if (r != Z_OK) {
+							mode = r == Z_STREAM_END ? WASH : BADCODE;
+							break;
+						}
+					}
+					need = lbits;
+					tree = ltree;
+					tree_index = ltree_index;
+
+					mode = LEN;
+				case LEN: // i: get length/literal/eob next
+					j = need;
+
+					while (k < (j)) {
+						if (n !== 0)
+							r = Z_OK;
+						else {
+
+							s.bitb = b;
+							s.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							s.write = q;
+							return s.inflate_flush(z, r);
+						}
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+
+					tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+					b >>>= (tree[tindex + 1]);
+					k -= (tree[tindex + 1]);
+
+					e = tree[tindex];
+
+					if (e === 0) { // literal
+						lit = tree[tindex + 2];
+						mode = LIT;
+						break;
+					}
+					if ((e & 16) !== 0) { // length
+						get = e & 15;
+						len = tree[tindex + 2];
+						mode = LENEXT;
+						break;
+					}
+					if ((e & 64) === 0) { // next table
+						need = e;
+						tree_index = tindex / 3 + tree[tindex + 2];
+						break;
+					}
+					if ((e & 32) !== 0) { // end of block
+						mode = WASH;
+						break;
+					}
+					mode = BADCODE; // invalid code
+					z.msg = "invalid literal/length code";
+					r = Z_DATA_ERROR;
+
+					s.bitb = b;
+					s.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					s.write = q;
+					return s.inflate_flush(z, r);
+
+				case LENEXT: // i: getting length extra (have base)
+					j = get;
+
+					while (k < (j)) {
+						if (n !== 0)
+							r = Z_OK;
+						else {
+
+							s.bitb = b;
+							s.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							s.write = q;
+							return s.inflate_flush(z, r);
+						}
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+
+					len += (b & inflate_mask[j]);
+
+					b >>= j;
+					k -= j;
+
+					need = dbits;
+					tree = dtree;
+					tree_index = dtree_index;
+					mode = DIST;
+				case DIST: // i: get distance next
+					j = need;
+
+					while (k < (j)) {
+						if (n !== 0)
+							r = Z_OK;
+						else {
+
+							s.bitb = b;
+							s.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							s.write = q;
+							return s.inflate_flush(z, r);
+						}
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+
+					tindex = (tree_index + (b & inflate_mask[j])) * 3;
+
+					b >>= tree[tindex + 1];
+					k -= tree[tindex + 1];
+
+					e = (tree[tindex]);
+					if ((e & 16) !== 0) { // distance
+						get = e & 15;
+						dist = tree[tindex + 2];
+						mode = DISTEXT;
+						break;
+					}
+					if ((e & 64) === 0) { // next table
+						need = e;
+						tree_index = tindex / 3 + tree[tindex + 2];
+						break;
+					}
+					mode = BADCODE; // invalid code
+					z.msg = "invalid distance code";
+					r = Z_DATA_ERROR;
+
+					s.bitb = b;
+					s.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					s.write = q;
+					return s.inflate_flush(z, r);
+
+				case DISTEXT: // i: getting distance extra
+					j = get;
+
+					while (k < (j)) {
+						if (n !== 0)
+							r = Z_OK;
+						else {
+
+							s.bitb = b;
+							s.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							s.write = q;
+							return s.inflate_flush(z, r);
+						}
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+
+					dist += (b & inflate_mask[j]);
+
+					b >>= j;
+					k -= j;
+
+					mode = COPY;
+				case COPY: // o: copying bytes in window, waiting for space
+					f = q - dist;
+					while (f < 0) { // modulo window size-"while" instead
+						f += s.end; // of "if" handles invalid distances
+					}
+					while (len !== 0) {
+
+						if (m === 0) {
+							if (q == s.end && s.read !== 0) {
+								q = 0;
+								m = q < s.read ? s.read - q - 1 : s.end - q;
+							}
+							if (m === 0) {
+								s.write = q;
+								r = s.inflate_flush(z, r);
+								q = s.write;
+								m = q < s.read ? s.read - q - 1 : s.end - q;
+
+								if (q == s.end && s.read !== 0) {
+									q = 0;
+									m = q < s.read ? s.read - q - 1 : s.end - q;
+								}
+
+								if (m === 0) {
+									s.bitb = b;
+									s.bitk = k;
+									z.avail_in = n;
+									z.total_in += p - z.next_in_index;
+									z.next_in_index = p;
+									s.write = q;
+									return s.inflate_flush(z, r);
+								}
+							}
+						}
+
+						s.window[q++] = s.window[f++];
+						m--;
+
+						if (f == s.end)
+							f = 0;
+						len--;
+					}
+					mode = START;
+					break;
+				case LIT: // o: got literal, waiting for output space
+					if (m === 0) {
+						if (q == s.end && s.read !== 0) {
+							q = 0;
+							m = q < s.read ? s.read - q - 1 : s.end - q;
+						}
+						if (m === 0) {
+							s.write = q;
+							r = s.inflate_flush(z, r);
+							q = s.write;
+							m = q < s.read ? s.read - q - 1 : s.end - q;
+
+							if (q == s.end && s.read !== 0) {
+								q = 0;
+								m = q < s.read ? s.read - q - 1 : s.end - q;
+							}
+							if (m === 0) {
+								s.bitb = b;
+								s.bitk = k;
+								z.avail_in = n;
+								z.total_in += p - z.next_in_index;
+								z.next_in_index = p;
+								s.write = q;
+								return s.inflate_flush(z, r);
+							}
+						}
+					}
+					r = Z_OK;
+
+					s.window[q++] = /* (byte) */lit;
+					m--;
+
+					mode = START;
+					break;
+				case WASH: // o: got eob, possibly more output
+					if (k > 7) { // return unused byte, if any
+						k -= 8;
+						n++;
+						p--; // can always return one
+					}
+
+					s.write = q;
+					r = s.inflate_flush(z, r);
+					q = s.write;
+					m = q < s.read ? s.read - q - 1 : s.end - q;
+
+					if (s.read != s.write) {
+						s.bitb = b;
+						s.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						s.write = q;
+						return s.inflate_flush(z, r);
+					}
+					mode = END;
+				case END:
+					r = Z_STREAM_END;
+					s.bitb = b;
+					s.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					s.write = q;
+					return s.inflate_flush(z, r);
+
+				case BADCODE: // x: got error
+
+					r = Z_DATA_ERROR;
+
+					s.bitb = b;
+					s.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					s.write = q;
+					return s.inflate_flush(z, r);
+
+				default:
+					r = Z_STREAM_ERROR;
+
+					s.bitb = b;
+					s.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					s.write = q;
+					return s.inflate_flush(z, r);
+				}
+			}
+		};
+
+		that.free = function(z) {
+			// ZFREE(z, c);
+		};
+
+	}
+
+	// InfBlocks
+
+	// Table for deflate from PKZIP's appnote.txt.
+	var border = [ // Order of the bit length code lengths
+	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+	var TYPE = 0; // get type bits (3, including end bit)
+	var LENS = 1; // get lengths for stored
+	var STORED = 2;// processing stored block
+	var TABLE = 3; // get table lengths
+	var BTREE = 4; // get bit lengths tree for a dynamic
+	// block
+	var DTREE = 5; // get length, distance trees for a
+	// dynamic block
+	var CODES = 6; // processing fixed or dynamic block
+	var DRY = 7; // output remaining window bytes
+	var DONELOCKS = 8; // finished last block, done
+	var BADBLOCKS = 9; // ot a data error--stuck here
+
+	function InfBlocks(z, w) {
+		var that = this;
+
+		var mode = TYPE; // current inflate_block mode
+
+		var left = 0; // if STORED, bytes left to copy
+
+		var table = 0; // table lengths (14 bits)
+		var index = 0; // index into blens (or border)
+		var blens; // bit lengths of codes
+		var bb = [ 0 ]; // bit length tree depth
+		var tb = [ 0 ]; // bit length decoding tree
+
+		var codes = new InfCodes(); // if CODES, current state
+
+		var last = 0; // true if this block is the last block
+
+		var hufts = new Int32Array(MANY * 3); // single malloc for tree space
+		var check = 0; // check on output
+		var inftree = new InfTree();
+
+		that.bitk = 0; // bits in bit buffer
+		that.bitb = 0; // bit buffer
+		that.window = new Uint8Array(w); // sliding window
+		that.end = w; // one byte after sliding window
+		that.read = 0; // window read pointer
+		that.write = 0; // window write pointer
+
+		that.reset = function(z, c) {
+			if (c)
+				c[0] = check;
+			// if (mode == BTREE || mode == DTREE) {
+			// }
+			if (mode == CODES) {
+				codes.free(z);
+			}
+			mode = TYPE;
+			that.bitk = 0;
+			that.bitb = 0;
+			that.read = that.write = 0;
+		};
+
+		that.reset(z, null);
+
+		// copy as much as possible from the sliding window to the output area
+		that.inflate_flush = function(z, r) {
+			var n;
+			var p;
+			var q;
+
+			// local copies of source and destination pointers
+			p = z.next_out_index;
+			q = that.read;
+
+			// compute number of bytes to copy as far as end of window
+			n = /* (int) */((q <= that.write ? that.write : that.end) - q);
+			if (n > z.avail_out)
+				n = z.avail_out;
+			if (n !== 0 && r == Z_BUF_ERROR)
+				r = Z_OK;
+
+			// update counters
+			z.avail_out -= n;
+			z.total_out += n;
+
+			// copy as far as end of window
+			z.next_out.set(that.window.subarray(q, q + n), p);
+			p += n;
+			q += n;
+
+			// see if more to copy at beginning of window
+			if (q == that.end) {
+				// wrap pointers
+				q = 0;
+				if (that.write == that.end)
+					that.write = 0;
+
+				// compute bytes to copy
+				n = that.write - q;
+				if (n > z.avail_out)
+					n = z.avail_out;
+				if (n !== 0 && r == Z_BUF_ERROR)
+					r = Z_OK;
+
+				// update counters
+				z.avail_out -= n;
+				z.total_out += n;
+
+				// copy
+				z.next_out.set(that.window.subarray(q, q + n), p);
+				p += n;
+				q += n;
+			}
+
+			// update pointers
+			z.next_out_index = p;
+			that.read = q;
+
+			// done
+			return r;
+		};
+
+		that.proc = function(z, r) {
+			var t; // temporary storage
+			var b; // bit buffer
+			var k; // bits in bit buffer
+			var p; // input data pointer
+			var n; // bytes available there
+			var q; // output window write pointer
+			var m; // bytes to end of window or read pointer
+
+			var i;
+
+			// copy input/output information to locals (UPDATE macro restores)
+			// {
+			p = z.next_in_index;
+			n = z.avail_in;
+			b = that.bitb;
+			k = that.bitk;
+			// }
+			// {
+			q = that.write;
+			m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+			// }
+
+			// process input based on current state
+			// DEBUG dtree
+			while (true) {
+				switch (mode) {
+				case TYPE:
+
+					while (k < (3)) {
+						if (n !== 0) {
+							r = Z_OK;
+						} else {
+							that.bitb = b;
+							that.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							that.write = q;
+							return that.inflate_flush(z, r);
+						}
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+					t = /* (int) */(b & 7);
+					last = t & 1;
+
+					switch (t >>> 1) {
+					case 0: // stored
+						// {
+						b >>>= (3);
+						k -= (3);
+						// }
+						t = k & 7; // go to byte boundary
+
+						// {
+						b >>>= (t);
+						k -= (t);
+						// }
+						mode = LENS; // get length of stored block
+						break;
+					case 1: // fixed
+						// {
+						var bl = []; // new Array(1);
+						var bd = []; // new Array(1);
+						var tl = [ [] ]; // new Array(1);
+						var td = [ [] ]; // new Array(1);
+
+						InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
+						codes.init(bl[0], bd[0], tl[0], 0, td[0], 0, z);
+						// }
+
+						// {
+						b >>>= (3);
+						k -= (3);
+						// }
+
+						mode = CODES;
+						break;
+					case 2: // dynamic
+
+						// {
+						b >>>= (3);
+						k -= (3);
+						// }
+
+						mode = TABLE;
+						break;
+					case 3: // illegal
+
+						// {
+						b >>>= (3);
+						k -= (3);
+						// }
+						mode = BADBLOCKS;
+						z.msg = "invalid block type";
+						r = Z_DATA_ERROR;
+
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+					break;
+				case LENS:
+
+					while (k < (32)) {
+						if (n !== 0) {
+							r = Z_OK;
+						} else {
+							that.bitb = b;
+							that.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							that.write = q;
+							return that.inflate_flush(z, r);
+						}
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+
+					if ((((~b) >>> 16) & 0xffff) != (b & 0xffff)) {
+						mode = BADBLOCKS;
+						z.msg = "invalid stored block lengths";
+						r = Z_DATA_ERROR;
+
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+					left = (b & 0xffff);
+					b = k = 0; // dump bits
+					mode = left !== 0 ? STORED : (last !== 0 ? DRY : TYPE);
+					break;
+				case STORED:
+					if (n === 0) {
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+
+					if (m === 0) {
+						if (q == that.end && that.read !== 0) {
+							q = 0;
+							m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+						}
+						if (m === 0) {
+							that.write = q;
+							r = that.inflate_flush(z, r);
+							q = that.write;
+							m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+							if (q == that.end && that.read !== 0) {
+								q = 0;
+								m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+							}
+							if (m === 0) {
+								that.bitb = b;
+								that.bitk = k;
+								z.avail_in = n;
+								z.total_in += p - z.next_in_index;
+								z.next_in_index = p;
+								that.write = q;
+								return that.inflate_flush(z, r);
+							}
+						}
+					}
+					r = Z_OK;
+
+					t = left;
+					if (t > n)
+						t = n;
+					if (t > m)
+						t = m;
+					that.window.set(z.read_buf(p, t), q);
+					p += t;
+					n -= t;
+					q += t;
+					m -= t;
+					if ((left -= t) !== 0)
+						break;
+					mode = last !== 0 ? DRY : TYPE;
+					break;
+				case TABLE:
+
+					while (k < (14)) {
+						if (n !== 0) {
+							r = Z_OK;
+						} else {
+							that.bitb = b;
+							that.bitk = k;
+							z.avail_in = n;
+							z.total_in += p - z.next_in_index;
+							z.next_in_index = p;
+							that.write = q;
+							return that.inflate_flush(z, r);
+						}
+
+						n--;
+						b |= (z.read_byte(p++) & 0xff) << k;
+						k += 8;
+					}
+
+					table = t = (b & 0x3fff);
+					if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
+						mode = BADBLOCKS;
+						z.msg = "too many length or distance symbols";
+						r = Z_DATA_ERROR;
+
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+					t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+					if (!blens || blens.length < t) {
+						blens = []; // new Array(t);
+					} else {
+						for (i = 0; i < t; i++) {
+							blens[i] = 0;
+						}
+					}
+
+					// {
+					b >>>= (14);
+					k -= (14);
+					// }
+
+					index = 0;
+					mode = BTREE;
+				case BTREE:
+					while (index < 4 + (table >>> 10)) {
+						while (k < (3)) {
+							if (n !== 0) {
+								r = Z_OK;
+							} else {
+								that.bitb = b;
+								that.bitk = k;
+								z.avail_in = n;
+								z.total_in += p - z.next_in_index;
+								z.next_in_index = p;
+								that.write = q;
+								return that.inflate_flush(z, r);
+							}
+							n--;
+							b |= (z.read_byte(p++) & 0xff) << k;
+							k += 8;
+						}
+
+						blens[border[index++]] = b & 7;
+
+						// {
+						b >>>= (3);
+						k -= (3);
+						// }
+					}
+
+					while (index < 19) {
+						blens[border[index++]] = 0;
+					}
+
+					bb[0] = 7;
+					t = inftree.inflate_trees_bits(blens, bb, tb, hufts, z);
+					if (t != Z_OK) {
+						r = t;
+						if (r == Z_DATA_ERROR) {
+							blens = null;
+							mode = BADBLOCKS;
+						}
+
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+
+					index = 0;
+					mode = DTREE;
+				case DTREE:
+					while (true) {
+						t = table;
+						if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
+							break;
+						}
+
+						var h;
+						var j, c;
+
+						t = bb[0];
+
+						while (k < (t)) {
+							if (n !== 0) {
+								r = Z_OK;
+							} else {
+								that.bitb = b;
+								that.bitk = k;
+								z.avail_in = n;
+								z.total_in += p - z.next_in_index;
+								z.next_in_index = p;
+								that.write = q;
+								return that.inflate_flush(z, r);
+							}
+							n--;
+							b |= (z.read_byte(p++) & 0xff) << k;
+							k += 8;
+						}
+
+						// if (tb[0] == -1) {
+						// System.err.println("null...");
+						// }
+
+						t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
+						c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];
+
+						if (c < 16) {
+							b >>>= (t);
+							k -= (t);
+							blens[index++] = c;
+						} else { // c == 16..18
+							i = c == 18 ? 7 : c - 14;
+							j = c == 18 ? 11 : 3;
+
+							while (k < (t + i)) {
+								if (n !== 0) {
+									r = Z_OK;
+								} else {
+									that.bitb = b;
+									that.bitk = k;
+									z.avail_in = n;
+									z.total_in += p - z.next_in_index;
+									z.next_in_index = p;
+									that.write = q;
+									return that.inflate_flush(z, r);
+								}
+								n--;
+								b |= (z.read_byte(p++) & 0xff) << k;
+								k += 8;
+							}
+
+							b >>>= (t);
+							k -= (t);
+
+							j += (b & inflate_mask[i]);
+
+							b >>>= (i);
+							k -= (i);
+
+							i = index;
+							t = table;
+							if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1)) {
+								blens = null;
+								mode = BADBLOCKS;
+								z.msg = "invalid bit length repeat";
+								r = Z_DATA_ERROR;
+
+								that.bitb = b;
+								that.bitk = k;
+								z.avail_in = n;
+								z.total_in += p - z.next_in_index;
+								z.next_in_index = p;
+								that.write = q;
+								return that.inflate_flush(z, r);
+							}
+
+							c = c == 16 ? blens[i - 1] : 0;
+							do {
+								blens[i++] = c;
+							} while (--j !== 0);
+							index = i;
+						}
+					}
+
+					tb[0] = -1;
+					// {
+					var bl_ = []; // new Array(1);
+					var bd_ = []; // new Array(1);
+					var tl_ = []; // new Array(1);
+					var td_ = []; // new Array(1);
+					bl_[0] = 9; // must be <= 9 for lookahead assumptions
+					bd_[0] = 6; // must be <= 9 for lookahead assumptions
+
+					t = table;
+					t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl_, bd_, tl_, td_, hufts, z);
+
+					if (t != Z_OK) {
+						if (t == Z_DATA_ERROR) {
+							blens = null;
+							mode = BADBLOCKS;
+						}
+						r = t;
+
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+					codes.init(bl_[0], bd_[0], hufts, tl_[0], hufts, td_[0], z);
+					// }
+					mode = CODES;
+				case CODES:
+					that.bitb = b;
+					that.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					that.write = q;
+
+					if ((r = codes.proc(that, z, r)) != Z_STREAM_END) {
+						return that.inflate_flush(z, r);
+					}
+					r = Z_OK;
+					codes.free(z);
+
+					p = z.next_in_index;
+					n = z.avail_in;
+					b = that.bitb;
+					k = that.bitk;
+					q = that.write;
+					m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+
+					if (last === 0) {
+						mode = TYPE;
+						break;
+					}
+					mode = DRY;
+				case DRY:
+					that.write = q;
+					r = that.inflate_flush(z, r);
+					q = that.write;
+					m = /* (int) */(q < that.read ? that.read - q - 1 : that.end - q);
+					if (that.read != that.write) {
+						that.bitb = b;
+						that.bitk = k;
+						z.avail_in = n;
+						z.total_in += p - z.next_in_index;
+						z.next_in_index = p;
+						that.write = q;
+						return that.inflate_flush(z, r);
+					}
+					mode = DONELOCKS;
+				case DONELOCKS:
+					r = Z_STREAM_END;
+
+					that.bitb = b;
+					that.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					that.write = q;
+					return that.inflate_flush(z, r);
+				case BADBLOCKS:
+					r = Z_DATA_ERROR;
+
+					that.bitb = b;
+					that.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					that.write = q;
+					return that.inflate_flush(z, r);
+
+				default:
+					r = Z_STREAM_ERROR;
+
+					that.bitb = b;
+					that.bitk = k;
+					z.avail_in = n;
+					z.total_in += p - z.next_in_index;
+					z.next_in_index = p;
+					that.write = q;
+					return that.inflate_flush(z, r);
+				}
+			}
+		};
+
+		that.free = function(z) {
+			that.reset(z, null);
+			that.window = null;
+			hufts = null;
+			// ZFREE(z, s);
+		};
+
+		that.set_dictionary = function(d, start, n) {
+			that.window.set(d.subarray(start, start + n), 0);
+			that.read = that.write = n;
+		};
+
+		// Returns true if inflate is currently at the end of a block generated
+		// by Z_SYNC_FLUSH or Z_FULL_FLUSH.
+		that.sync_point = function() {
+			return mode == LENS ? 1 : 0;
+		};
+
+	}
+
+	// Inflate
+
+	// preset dictionary flag in zlib header
+	var PRESET_DICT = 0x20;
+
+	var Z_DEFLATED = 8;
+
+	var METHOD = 0; // waiting for method byte
+	var FLAG = 1; // waiting for flag byte
+	var DICT4 = 2; // four dictionary check bytes to go
+	var DICT3 = 3; // three dictionary check bytes to go
+	var DICT2 = 4; // two dictionary check bytes to go
+	var DICT1 = 5; // one dictionary check byte to go
+	var DICT0 = 6; // waiting for inflateSetDictionary
+	var BLOCKS = 7; // decompressing blocks
+	var DONE = 12; // finished check, done
+	var BAD = 13; // got an error--stay here
+
+	var mark = [ 0, 0, 0xff, 0xff ];
+
+	function Inflate() {
+		var that = this;
+
+		that.mode = 0; // current inflate mode
+
+		// mode dependent information
+		that.method = 0; // if FLAGS, method byte
+
+		// if CHECK, check values to compare
+		that.was = [ 0 ]; // new Array(1); // computed check value
+		that.need = 0; // stream check value
+
+		// if BAD, inflateSync's marker bytes count
+		that.marker = 0;
+
+		// mode independent information
+		that.wbits = 0; // log2(window size) (8..15, defaults to 15)
+
+		// this.blocks; // current inflate_blocks state
+
+		function inflateReset(z) {
+			if (!z || !z.istate)
+				return Z_STREAM_ERROR;
+
+			z.total_in = z.total_out = 0;
+			z.msg = null;
+			z.istate.mode = BLOCKS;
+			z.istate.blocks.reset(z, null);
+			return Z_OK;
+		}
+
+		that.inflateEnd = function(z) {
+			if (that.blocks)
+				that.blocks.free(z);
+			that.blocks = null;
+			// ZFREE(z, z->state);
+			return Z_OK;
+		};
+
+		that.inflateInit = function(z, w) {
+			z.msg = null;
+			that.blocks = null;
+
+			// set window size
+			if (w < 8 || w > 15) {
+				that.inflateEnd(z);
+				return Z_STREAM_ERROR;
+			}
+			that.wbits = w;
+
+			z.istate.blocks = new InfBlocks(z, 1 << w);
+
+			// reset state
+			inflateReset(z);
+			return Z_OK;
+		};
+
+		that.inflate = function(z, f) {
+			var r;
+			var b;
+
+			if (!z || !z.istate || !z.next_in)
+				return Z_STREAM_ERROR;
+			f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+			r = Z_BUF_ERROR;
+			while (true) {
+				// System.out.println("mode: "+z.istate.mode);
+				switch (z.istate.mode) {
+				case METHOD:
+
+					if (z.avail_in === 0)
+						return r;
+					r = f;
+
+					z.avail_in--;
+					z.total_in++;
+					if (((z.istate.method = z.read_byte(z.next_in_index++)) & 0xf) != Z_DEFLATED) {
+						z.istate.mode = BAD;
+						z.msg = "unknown compression method";
+						z.istate.marker = 5; // can't try inflateSync
+						break;
+					}
+					if ((z.istate.method >> 4) + 8 > z.istate.wbits) {
+						z.istate.mode = BAD;
+						z.msg = "invalid window size";
+						z.istate.marker = 5; // can't try inflateSync
+						break;
+					}
+					z.istate.mode = FLAG;
+				case FLAG:
+
+					if (z.avail_in === 0)
+						return r;
+					r = f;
+
+					z.avail_in--;
+					z.total_in++;
+					b = (z.read_byte(z.next_in_index++)) & 0xff;
+
+					if ((((z.istate.method << 8) + b) % 31) !== 0) {
+						z.istate.mode = BAD;
+						z.msg = "incorrect header check";
+						z.istate.marker = 5; // can't try inflateSync
+						break;
+					}
+
+					if ((b & PRESET_DICT) === 0) {
+						z.istate.mode = BLOCKS;
+						break;
+					}
+					z.istate.mode = DICT4;
+				case DICT4:
+
+					if (z.avail_in === 0)
+						return r;
+					r = f;
+
+					z.avail_in--;
+					z.total_in++;
+					z.istate.need = ((z.read_byte(z.next_in_index++) & 0xff) << 24) & 0xff000000;
+					z.istate.mode = DICT3;
+				case DICT3:
+
+					if (z.avail_in === 0)
+						return r;
+					r = f;
+
+					z.avail_in--;
+					z.total_in++;
+					z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 16) & 0xff0000;
+					z.istate.mode = DICT2;
+				case DICT2:
+
+					if (z.avail_in === 0)
+						return r;
+					r = f;
+
+					z.avail_in--;
+					z.total_in++;
+					z.istate.need += ((z.read_byte(z.next_in_index++) & 0xff) << 8) & 0xff00;
+					z.istate.mode = DICT1;
+				case DICT1:
+
+					if (z.avail_in === 0)
+						return r;
+					r = f;
+
+					z.avail_in--;
+					z.total_in++;
+					z.istate.need += (z.read_byte(z.next_in_index++) & 0xff);
+					z.istate.mode = DICT0;
+					return Z_NEED_DICT;
+				case DICT0:
+					z.istate.mode = BAD;
+					z.msg = "need dictionary";
+					z.istate.marker = 0; // can try inflateSync
+					return Z_STREAM_ERROR;
+				case BLOCKS:
+
+					r = z.istate.blocks.proc(z, r);
+					if (r == Z_DATA_ERROR) {
+						z.istate.mode = BAD;
+						z.istate.marker = 0; // can try inflateSync
+						break;
+					}
+					if (r == Z_OK) {
+						r = f;
+					}
+					if (r != Z_STREAM_END) {
+						return r;
+					}
+					r = f;
+					z.istate.blocks.reset(z, z.istate.was);
+					z.istate.mode = DONE;
+				case DONE:
+					return Z_STREAM_END;
+				case BAD:
+					return Z_DATA_ERROR;
+				default:
+					return Z_STREAM_ERROR;
+				}
+			}
+		};
+
+		that.inflateSetDictionary = function(z, dictionary, dictLength) {
+			var index = 0;
+			var length = dictLength;
+			if (!z || !z.istate || z.istate.mode != DICT0)
+				return Z_STREAM_ERROR;
+
+			if (length >= (1 << z.istate.wbits)) {
+				length = (1 << z.istate.wbits) - 1;
+				index = dictLength - length;
+			}
+			z.istate.blocks.set_dictionary(dictionary, index, length);
+			z.istate.mode = BLOCKS;
+			return Z_OK;
+		};
+
+		that.inflateSync = function(z) {
+			var n; // number of bytes to look at
+			var p; // pointer to bytes
+			var m; // number of marker bytes found in a row
+			var r, w; // temporaries to save total_in and total_out
+
+			// set up
+			if (!z || !z.istate)
+				return Z_STREAM_ERROR;
+			if (z.istate.mode != BAD) {
+				z.istate.mode = BAD;
+				z.istate.marker = 0;
+			}
+			if ((n = z.avail_in) === 0)
+				return Z_BUF_ERROR;
+			p = z.next_in_index;
+			m = z.istate.marker;
+
+			// search
+			while (n !== 0 && m < 4) {
+				if (z.read_byte(p) == mark[m]) {
+					m++;
+				} else if (z.read_byte(p) !== 0) {
+					m = 0;
+				} else {
+					m = 4 - m;
+				}
+				p++;
+				n--;
+			}
+
+			// restore
+			z.total_in += p - z.next_in_index;
+			z.next_in_index = p;
+			z.avail_in = n;
+			z.istate.marker = m;
+
+			// return no joy or set up to restart on a new block
+			if (m != 4) {
+				return Z_DATA_ERROR;
+			}
+			r = z.total_in;
+			w = z.total_out;
+			inflateReset(z);
+			z.total_in = r;
+			z.total_out = w;
+			z.istate.mode = BLOCKS;
+			return Z_OK;
+		};
+
+		// Returns true if inflate is currently at the end of a block generated
+		// by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+		// implementation to provide an additional safety check. PPP uses
+		// Z_SYNC_FLUSH
+		// but removes the length bytes of the resulting empty stored block. When
+		// decompressing, PPP checks that at the end of input packet, inflate is
+		// waiting for these length bytes.
+		that.inflateSyncPoint = function(z) {
+			if (!z || !z.istate || !z.istate.blocks)
+				return Z_STREAM_ERROR;
+			return z.istate.blocks.sync_point();
+		};
+	}
+
+	// ZStream
+
+	function ZStream() {
+	}
+
+	ZStream.prototype = {
+		inflateInit : function(bits) {
+			var that = this;
+			that.istate = new Inflate();
+			if (!bits)
+				bits = MAX_BITS;
+			return that.istate.inflateInit(that, bits);
+		},
+
+		inflate : function(f) {
+			var that = this;
+			if (!that.istate)
+				return Z_STREAM_ERROR;
+			return that.istate.inflate(that, f);
+		},
+
+		inflateEnd : function() {
+			var that = this;
+			if (!that.istate)
+				return Z_STREAM_ERROR;
+			var ret = that.istate.inflateEnd(that);
+			that.istate = null;
+			return ret;
+		},
+
+		inflateSync : function() {
+			var that = this;
+			if (!that.istate)
+				return Z_STREAM_ERROR;
+			return that.istate.inflateSync(that);
+		},
+		inflateSetDictionary : function(dictionary, dictLength) {
+			var that = this;
+			if (!that.istate)
+				return Z_STREAM_ERROR;
+			return that.istate.inflateSetDictionary(that, dictionary, dictLength);
+		},
+		read_byte : function(start) {
+			var that = this;
+			return that.next_in.subarray(start, start + 1)[0];
+		},
+		read_buf : function(start, size) {
+			var that = this;
+			return that.next_in.subarray(start, start + size);
+		}
+	};
+
+	// Inflater
+
+	function Inflater() {
+		var that = this;
+		var z = new ZStream();
+		var bufsize = 512;
+		var flush = Z_NO_FLUSH;
+		var buf = new Uint8Array(bufsize);
+		var nomoreinput = false;
+
+		z.inflateInit();
+		z.next_out = buf;
+
+		that.append = function(data, onprogress) {
+			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
+			if (data.length === 0)
+				return;
+			z.next_in_index = 0;
+			z.next_in = data;
+			z.avail_in = data.length;
+			do {
+				z.next_out_index = 0;
+				z.avail_out = bufsize;
+				if ((z.avail_in === 0) && (!nomoreinput)) { // if buffer is empty and more input is available, refill it
+					z.next_in_index = 0;
+					nomoreinput = true;
+				}
+				err = z.inflate(flush);
+				if (nomoreinput && (err == Z_BUF_ERROR))
+					return -1;
+				if (err != Z_OK && err != Z_STREAM_END)
+					throw "inflating: " + z.msg;
+				if ((nomoreinput || err == Z_STREAM_END) && (z.avail_out == data.length))
+					return -1;
+				if (z.next_out_index)
+					if (z.next_out_index == bufsize)
+						buffers.push(new Uint8Array(buf));
+					else
+						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+				bufferSize += z.next_out_index;
+				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
+					onprogress(z.next_in_index);
+					lastIndex = z.next_in_index;
+				}
+			} while (z.avail_in > 0 || z.avail_out === 0);
+			array = new Uint8Array(bufferSize);
+			buffers.forEach(function(chunk) {
+				array.set(chunk, bufferIndex);
+				bufferIndex += chunk.length;
+			});
+			return array;
+		};
+		that.flush = function() {
+			z.inflateEnd();
+		};
+	}
+
+	var inflater;
+
+	if (obj.zip)
+		obj.zip.Inflater = Inflater;
+	else {
+		inflater = new Inflater();
+		obj.addEventListener("message", function(event) {
+			var message = event.data;
+
+			if (message.append)
+				obj.postMessage({
+					onappend : true,
+					data : inflater.append(message.data, function(current) {
+						obj.postMessage({
+							progress : true,
+							current : current
+						});
+					})
+				});
+			if (message.flush) {
+				inflater.flush();
+				obj.postMessage({
+					onflush : true
+				});
+			}
+		}, false);
+	}
+
+})(this);
+
diff --git a/test/encryption.html b/test/encryption.html
index c8cf2ec0..1247f166 100644
--- a/test/encryption.html
+++ b/test/encryption.html
@@ -25,6 +25,7 @@
 <script type="text/javascript" src="../src/ciphers/openpgp.cfb.js"></script>
 
 <!-- compression -->
+<script type="text/javascript" src="../src/compression/zip/zip.js"></script>
 
 <!-- encoding -->
 <script type="text/javascript" src="../src/encoding/base64.js"></script>