=A?(E[D++]=17,E[D++]=A-3,H[17]++):(E[D++]=18,E[D++]=A-11,H[18]++),s-=A;else if(E[D++]=F[r],H[F[r]]++,s--,3>s)for(;0s?s:6,A>s-3&&Ay;y++)ia[y]=ea[Ia[y]];for(P=19;4=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,
+a-31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:throw"invalid length: "+a;}}var d=[],c,f;for(c=3;258>=c;c++)f=e(c),d[c]=f[2]<<24|
+f[1]<<16|f[0];return d}(),Ga=C?new Uint32Array(Fa):Fa;
+function na(e,d){function c(a,c){var b=a.g,d=[],f=0,e;e=Ga[a.length];d[f++]=e&65535;d[f++]=e>>16&255;d[f++]=e>>24;var g;switch(u){case 1===b:g=[0,b-1,0];break;case 2===b:g=[1,b-2,0];break;case 3===b:g=[2,b-3,0];break;case 4===b:g=[3,b-4,0];break;case 6>=b:g=[4,b-5,1];break;case 8>=b:g=[5,b-7,1];break;case 12>=b:g=[6,b-9,2];break;case 16>=b:g=[7,b-13,2];break;case 24>=b:g=[8,b-17,3];break;case 32>=b:g=[9,b-25,3];break;case 48>=b:g=[10,b-33,4];break;case 64>=b:g=[11,b-49,4];break;case 96>=b:g=[12,b-
+65,5];break;case 128>=b:g=[13,b-97,5];break;case 192>=b:g=[14,b-129,6];break;case 256>=b:g=[15,b-193,6];break;case 384>=b:g=[16,b-257,7];break;case 512>=b:g=[17,b-385,7];break;case 768>=b:g=[18,b-513,8];break;case 1024>=b:g=[19,b-769,8];break;case 1536>=b:g=[20,b-1025,9];break;case 2048>=b:g=[21,b-1537,9];break;case 3072>=b:g=[22,b-2049,10];break;case 4096>=b:g=[23,b-3073,10];break;case 6144>=b:g=[24,b-4097,11];break;case 8192>=b:g=[25,b-6145,11];break;case 12288>=b:g=[26,b-8193,12];break;case 16384>=
+b:g=[27,b-12289,12];break;case 24576>=b:g=[28,b-16385,13];break;case 32768>=b:g=[29,b-24577,13];break;default:throw"invalid distance";}e=g;d[f++]=e[0];d[f++]=e[1];d[f++]=e[2];var k,m;k=0;for(m=d.length;k=b;)t[b++]=0;for(b=0;29>=b;)w[b++]=0}t[256]=1;f=0;for(a=d.length;f=a){x&&c(x,-1);b=0;for(k=a-f;bk&&d+kb&&(a=f,b=k);if(258===k)break}return new qa(b,d-a)}
+function oa(e,d){var c=e.length,f=new ja(572),a=new (C?Uint8Array:Array)(c),b,k,m,g,p;if(!C)for(g=0;g2*a[h-1]+b[h]&&(a[h]=2*a[h-1]+b[h]),m[h]=Array(a[h]),g[h]=Array(a[h]);for(l=0;le[l]?(m[h][q]=t,g[h][q]=d,w+=2):(m[h][q]=e[l],g[h][q]=l,++l);p[h]=0;1===b[h]&&f(h)}return k}
+function pa(e){var d=new (C?Uint16Array:Array)(e.length),c=[],f=[],a=0,b,k,m,g;b=0;for(k=e.length;b>>=1}return d};ba("Zlib.RawDeflate",ka);ba("Zlib.RawDeflate.prototype.compress",ka.prototype.h);var Ka={NONE:0,FIXED:1,DYNAMIC:ma},V,La,$,Ma;if(Object.keys)V=Object.keys(Ka);else for(La in V=[],$=0,Ka)V[$++]=La;$=0;for(Ma=V.length;$a&&(a=c[n]),c[n]>=1;for(t=m;t>>=1;switch(c){case 0:var d=this.input,a=this.d,b=this.b,e=this.a,f=l,g=l,h=l,k=b.length,m=l;this.c=this.f=0;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: LEN (first byte)");g=f;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: LEN (second byte)");g|=f<<8;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: NLEN (first byte)");h=f;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: NLEN (second byte)");h|=
+f<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw Error("input buffer is broken");switch(this.i){case x:for(;e+g>b.length;){m=k-e;g-=m;if(r)b.set(d.subarray(a,a+m),e),e+=m,a+=m;else for(;m--;)b[e++]=d[a++];this.a=e;b=this.e();e=this.a}break;case w:for(;e+g>b.length;)b=this.e({o:2});break;default:throw Error("invalid inflate mode");}if(r)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else for(;g--;)b[e++]=d[a++];this.d=a;this.a=e;this.b=b;break;case 1:this.j(z,
+A);break;case 2:B(this);break;default:throw Error("unknown BTYPE: "+c);}}return this.m()};
+var C=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=r?new Uint16Array(C):C,E=[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,258,258],F=r?new Uint16Array(E):E,G=[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,0,0],H=r?new Uint8Array(G):G,I=[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],J=r?new Uint16Array(I):I,K=[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],L=r?new Uint8Array(K):K,M=new (r?Uint8Array:Array)(288),N,O;N=0;for(O=M.length;N=N?8:255>=N?9:279>=N?7:8;var z=u(M),P=new (r?Uint8Array:Array)(30),Q,R;Q=0;for(R=P.length;Q>>d;c.c=b-d;c.d=f;return g}
+function S(c,d){for(var a=c.f,b=c.c,e=c.input,f=c.d,g=d[0],h=d[1],k,m,s;b>>16;c.f=a>>s;c.c=b-s;c.d=f;return m&65535}
+function B(c){function d(a,c,b){var d,f,e,g;for(g=0;gf)b>=e&&(this.a=b,a=this.e(),b=this.a),a[b++]=f;else{g=f-257;k=F[g];0=e&&(this.a=b,a=this.e(),b=this.a);for(;k--;)a[b]=a[b++-h]}for(;8<=this.c;)this.c-=8,this.d--;this.a=b};
+v.prototype.s=function(c,d){var a=this.b,b=this.a;this.n=c;for(var e=a.length,f,g,h,k;256!==(f=S(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=F[g];0e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.c;)this.c-=8,this.d--;this.a=b};
+v.prototype.e=function(){var c=new (r?Uint8Array:Array)(this.a-32768),d=this.a-32768,a,b,e=this.b;if(r)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;aa;++a)e[a]=e[d+a];this.a=32768;return e};
+v.prototype.u=function(c){var d,a=this.input.length/this.d+1|0,b,e,f,g=this.input,h=this.b;c&&("number"===typeof c.o&&(a=c.o),"number"===typeof c.q&&(a+=c.q));2>a?(b=(g.length-this.d)/this.n[2],f=258*(b/2)|0,e=fd&&(this.b.length=d),c=this.b);return this.buffer=c};q("Zlib.RawInflate",v);q("Zlib.RawInflate.prototype.decompress",v.prototype.t);var T={ADAPTIVE:w,BLOCK:x},U,V,W,X;if(Object.keys)U=Object.keys(T);else for(V in U=[],W=0,T)U[W++]=V;W=0;for(X=U.length;W
+
+(c) 2011 David Duponchel
+Dual licenced under the MIT license or GPLv3. See LICENSE.markdown.
+
+**/
+/*global JSZip */
+(function (root) {
+ "use strict";
+
+ var MAX_VALUE_16BITS = 65535;
+ var MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1
+
+ /**
+ * Prettify a string read as binary.
+ * @param {string} str the string to prettify.
+ * @return {string} a pretty string.
+ */
+ var pretty = function (str) {
+ var res = '', code, i;
+ for (i = 0; i < (str||"").length; i++) {
+ code = str.charCodeAt(i);
+ res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase();
+ }
+ return res;
+ };
+
+ /**
+ * Find a compression registered in JSZip.
+ * @param {string} compressionMethod the method magic to find.
+ * @return {Object|null} the JSZip compression object, null if none found.
+ */
+ var findCompression = function (compressionMethod) {
+ for (var method in JSZip.compressions) {
+ if( !JSZip.compressions.hasOwnProperty(method) ) { continue; }
+ if (JSZip.compressions[method].magic === compressionMethod) {
+ return JSZip.compressions[method];
+ }
+ }
+ return null;
+ };
+
+ // class DataReader {{{
+ /**
+ * Read bytes from a source.
+ * Developer tip : when debugging, a watch on pretty(this.reader.data.slice(this.reader.index))
+ * is very useful :)
+ * @constructor
+ * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read.
+ */
+ function DataReader(data) {
+ this.data = null; // type : see implementation
+ this.length = 0;
+ this.index = 0;
+ }
+ DataReader.prototype = {
+ /**
+ * Check that the offset will not go too far.
+ * @param {string} offset the additional offset to check.
+ * @throws {Error} an Error if the offset is out of bounds.
+ */
+ checkOffset : function (offset) {
+ this.checkIndex(this.index + offset);
+ },
+ /**
+ * Check that the specifed index will not be too far.
+ * @param {string} newIndex the index to check.
+ * @throws {Error} an Error if the index is out of bounds.
+ */
+ checkIndex : function (newIndex) {
+ if (this.length < newIndex || newIndex < 0) {
+ throw new Error("End of data reached (data length = " +
+ this.length + ", asked index = " +
+ (newIndex) + "). Corrupted zip ?");
+ }
+ },
+ /**
+ * Change the index.
+ * @param {number} newIndex The new index.
+ * @throws {Error} if the new index is out of the data.
+ */
+ setIndex : function (newIndex) {
+ this.checkIndex(newIndex);
+ this.index = newIndex;
+ },
+ /**
+ * Skip the next n bytes.
+ * @param {number} n the number of bytes to skip.
+ * @throws {Error} if the new index is out of the data.
+ */
+ skip : function (n) {
+ this.setIndex(this.index + n);
+ },
+ /**
+ * Get the byte at the specified index.
+ * @param {number} i the index to use.
+ * @return {number} a byte.
+ */
+ byteAt : function(i) {
+ // see implementations
+ },
+ /**
+ * Get the next number with a given byte size.
+ * @param {number} size the number of bytes to read.
+ * @return {number} the corresponding number.
+ */
+ readInt : function (size) {
+ var result = 0, i;
+ this.checkOffset(size);
+ for(i = this.index + size - 1; i >= this.index; i--) {
+ result = (result << 8) + this.byteAt(i);
+ }
+ this.index += size;
+ return result;
+ },
+ /**
+ * Get the next string with a given byte size.
+ * @param {number} size the number of bytes to read.
+ * @return {string} the corresponding string.
+ */
+ readString : function (size) {
+ return JSZip.utils.transformTo("string", this.readData(size));
+ },
+ /**
+ * Get raw data without conversion, bytes.
+ * @param {number} size the number of bytes to read.
+ * @return {Object} the raw data, implementation specific.
+ */
+ readData : function (size) {
+ // see implementations
+ },
+ /**
+ * Find the last occurence of a zip signature (4 bytes).
+ * @param {string} sig the signature to find.
+ * @return {number} the index of the last occurence, -1 if not found.
+ */
+ lastIndexOfSignature : function (sig) {
+ // see implementations
+ },
+ /**
+ * Get the next date.
+ * @return {Date} the date.
+ */
+ readDate : function () {
+ var dostime = this.readInt(4);
+ return new Date(
+ ((dostime >> 25) & 0x7f) + 1980, // year
+ ((dostime >> 21) & 0x0f) - 1, // month
+ (dostime >> 16) & 0x1f, // day
+ (dostime >> 11) & 0x1f, // hour
+ (dostime >> 5) & 0x3f, // minute
+ (dostime & 0x1f) << 1); // second
+ }
+ };
+
+
+ /**
+ * Read bytes from a string.
+ * @constructor
+ * @param {String} data the data to read.
+ */
+ function StringReader(data, optimizedBinaryString) {
+ this.data = data;
+ if (!optimizedBinaryString) {
+ this.data = JSZip.utils.string2binary(this.data);
+ }
+ this.length = this.data.length;
+ this.index = 0;
+ }
+ StringReader.prototype = new DataReader();
+ /**
+ * @see DataReader.byteAt
+ */
+ StringReader.prototype.byteAt = function(i) {
+ return this.data.charCodeAt(i);
+ };
+ /**
+ * @see DataReader.lastIndexOfSignature
+ */
+ StringReader.prototype.lastIndexOfSignature = function (sig) {
+ return this.data.lastIndexOf(sig);
+ };
+ /**
+ * @see DataReader.readData
+ */
+ StringReader.prototype.readData = function (size) {
+ this.checkOffset(size);
+ // this will work because the constructor applied the "& 0xff" mask.
+ var result = this.data.slice(this.index, this.index + size);
+ this.index += size;
+ return result;
+ };
+
+
+ /**
+ * Read bytes from an Uin8Array.
+ * @constructor
+ * @param {Uint8Array} data the data to read.
+ */
+ function Uint8ArrayReader(data) {
+ if (data) {
+ this.data = data;
+ this.length = this.data.length;
+ this.index = 0;
+ }
+ }
+ Uint8ArrayReader.prototype = new DataReader();
+ /**
+ * @see DataReader.byteAt
+ */
+ Uint8ArrayReader.prototype.byteAt = function(i) {
+ return this.data[i];
+ };
+ /**
+ * @see DataReader.lastIndexOfSignature
+ */
+ Uint8ArrayReader.prototype.lastIndexOfSignature = function (sig) {
+ var sig0 = sig.charCodeAt(0),
+ sig1 = sig.charCodeAt(1),
+ sig2 = sig.charCodeAt(2),
+ sig3 = sig.charCodeAt(3);
+ for(var i = this.length - 4;i >= 0;--i) {
+ if (this.data[i] === sig0 && this.data[i+1] === sig1 && this.data[i+2] === sig2 && this.data[i+3] === sig3) {
+ return i;
+ }
+ }
+
+ return -1;
+ };
+ /**
+ * @see DataReader.readData
+ */
+ Uint8ArrayReader.prototype.readData = function (size) {
+ this.checkOffset(size);
+ var result = this.data.subarray(this.index, this.index + size);
+ this.index += size;
+ return result;
+ };
+
+ /**
+ * Read bytes from a Buffer.
+ * @constructor
+ * @param {Buffer} data the data to read.
+ */
+ function NodeBufferReader(data) {
+ this.data = data;
+ this.length = this.data.length;
+ this.index = 0;
+ }
+ NodeBufferReader.prototype = new Uint8ArrayReader();
+
+ /**
+ * @see DataReader.readData
+ */
+ NodeBufferReader.prototype.readData = function (size) {
+ this.checkOffset(size);
+ var result = this.data.slice(this.index, this.index + size);
+ this.index += size;
+ return result;
+ };
+ // }}} end of DataReader
+
+ // class ZipEntry {{{
+ /**
+ * An entry in the zip file.
+ * @constructor
+ * @param {Object} options Options of the current file.
+ * @param {Object} loadOptions Options for loading the data.
+ */
+ function ZipEntry(options, loadOptions) {
+ this.options = options;
+ this.loadOptions = loadOptions;
+ }
+ ZipEntry.prototype = {
+ /**
+ * say if the file is encrypted.
+ * @return {boolean} true if the file is encrypted, false otherwise.
+ */
+ isEncrypted : function () {
+ // bit 1 is set
+ return (this.bitFlag & 0x0001) === 0x0001;
+ },
+ /**
+ * say if the file has utf-8 filename/comment.
+ * @return {boolean} true if the filename/comment is in utf-8, false otherwise.
+ */
+ useUTF8 : function () {
+ // bit 11 is set
+ return (this.bitFlag & 0x0800) === 0x0800;
+ },
+ /**
+ * Prepare the function used to generate the compressed content from this ZipFile.
+ * @param {DataReader} reader the reader to use.
+ * @param {number} from the offset from where we should read the data.
+ * @param {number} length the length of the data to read.
+ * @return {Function} the callback to get the compressed content (the type depends of the DataReader class).
+ */
+ prepareCompressedContent : function (reader, from, length) {
+ return function () {
+ var previousIndex = reader.index;
+ reader.setIndex(from);
+ var compressedFileData = reader.readData(length);
+ reader.setIndex(previousIndex);
+
+ return compressedFileData;
+ };
+ },
+ /**
+ * Prepare the function used to generate the uncompressed content from this ZipFile.
+ * @param {DataReader} reader the reader to use.
+ * @param {number} from the offset from where we should read the data.
+ * @param {number} length the length of the data to read.
+ * @param {JSZip.compression} compression the compression used on this file.
+ * @param {number} uncompressedSize the uncompressed size to expect.
+ * @return {Function} the callback to get the uncompressed content (the type depends of the DataReader class).
+ */
+ prepareContent : function (reader, from, length, compression, uncompressedSize) {
+ return function () {
+
+ var compressedFileData = JSZip.utils.transformTo(compression.uncompressInputType, this.getCompressedContent());
+ var uncompressedFileData = compression.uncompress(compressedFileData);
+
+ if (uncompressedFileData.length !== uncompressedSize) {
+ throw new Error("Bug : uncompressed data size mismatch");
+ }
+
+ return uncompressedFileData;
+ };
+ },
+ /**
+ * Read the local part of a zip file and add the info in this object.
+ * @param {DataReader} reader the reader to use.
+ */
+ readLocalPart : function(reader) {
+ var compression, localExtraFieldsLength;
+
+ // we already know everything from the central dir !
+ // If the central dir data are false, we are doomed.
+ // On the bright side, the local part is scary : zip64, data descriptors, both, etc.
+ // The less data we get here, the more reliable this should be.
+ // Let's skip the whole header and dash to the data !
+ reader.skip(22);
+ // in some zip created on windows, the filename stored in the central dir contains \ instead of /.
+ // Strangely, the filename here is OK.
+ // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes
+ // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators...
+ // Search "unzip mismatching "local" filename continuing with "central" filename version" on
+ // the internet.
+ //
+ // I think I see the logic here : the central directory is used to display
+ // content and the local directory is used to extract the files. Mixing / and \
+ // may be used to display \ to windows users and use / when extracting the files.
+ // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394
+ this.fileNameLength = reader.readInt(2);
+ localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir
+ this.fileName = reader.readString(this.fileNameLength);
+ reader.skip(localExtraFieldsLength);
+
+ if (this.compressedSize == -1 || this.uncompressedSize == -1) {
+ throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory " +
+ "(compressedSize == -1 || uncompressedSize == -1)");
+ }
+
+ compression = findCompression(this.compressionMethod);
+ if (compression === null) { // no compression found
+ throw new Error("Corrupted zip : compression " + pretty(this.compressionMethod) +
+ " unknown (inner file : " + this.fileName + ")");
+ }
+ this.decompressed = new JSZip.CompressedObject();
+ this.decompressed.compressedSize = this.compressedSize;
+ this.decompressed.uncompressedSize = this.uncompressedSize;
+ this.decompressed.crc32 = this.crc32;
+ this.decompressed.compressionMethod = this.compressionMethod;
+ this.decompressed.getCompressedContent = this.prepareCompressedContent(reader, reader.index, this.compressedSize, compression);
+ this.decompressed.getContent = this.prepareContent(reader, reader.index, this.compressedSize, compression, this.uncompressedSize);
+
+ // we need to compute the crc32...
+ if (this.loadOptions.checkCRC32) {
+ this.decompressed = JSZip.utils.transformTo("string", this.decompressed.getContent());
+ if (JSZip.prototype.crc32(this.decompressed) !== this.crc32) {
+ throw new Error("Corrupted zip : CRC32 mismatch");
+ }
+ }
+ },
+
+ /**
+ * Read the central part of a zip file and add the info in this object.
+ * @param {DataReader} reader the reader to use.
+ */
+ readCentralPart : function(reader) {
+ this.versionMadeBy = reader.readString(2);
+ this.versionNeeded = reader.readInt(2);
+ this.bitFlag = reader.readInt(2);
+ this.compressionMethod = reader.readString(2);
+ this.date = reader.readDate();
+ this.crc32 = reader.readInt(4);
+ this.compressedSize = reader.readInt(4);
+ this.uncompressedSize = reader.readInt(4);
+ this.fileNameLength = reader.readInt(2);
+ this.extraFieldsLength = reader.readInt(2);
+ this.fileCommentLength = reader.readInt(2);
+ this.diskNumberStart = reader.readInt(2);
+ this.internalFileAttributes = reader.readInt(2);
+ this.externalFileAttributes = reader.readInt(4);
+ this.localHeaderOffset = reader.readInt(4);
+
+ if (this.isEncrypted()) {
+ throw new Error("Encrypted zip are not supported");
+ }
+
+ this.fileName = reader.readString(this.fileNameLength);
+ this.readExtraFields(reader);
+ this.parseZIP64ExtraField(reader);
+ this.fileComment = reader.readString(this.fileCommentLength);
+
+ // warning, this is true only for zip with madeBy == DOS (plateform dependent feature)
+ this.dir = this.externalFileAttributes & 0x00000010 ? true : false;
+ },
+ /**
+ * Parse the ZIP64 extra field and merge the info in the current ZipEntry.
+ * @param {DataReader} reader the reader to use.
+ */
+ parseZIP64ExtraField : function(reader) {
+
+ if(!this.extraFields[0x0001]) {
return;
- }
- zip_eofile = false;
- while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) zip_fill_window();
- zip_ins_h = 0;
- for (j = 0; j < zip_MIN_MATCH - 1; j++) {
- zip_ins_h = (zip_ins_h << zip_H_SHIFT ^ zip_window[j] & 255) & zip_HASH_MASK;
- }
- };
- var zip_longest_match = function(cur_match) {
- var chain_length = zip_max_chain_length;
- var scanp = zip_strstart;
- var matchp;
- var len;
- var best_len = zip_prev_length;
- var limit = zip_strstart > zip_MAX_DIST ? zip_strstart - zip_MAX_DIST : zip_NIL;
- var strendp = zip_strstart + zip_MAX_MATCH;
- var scan_end1 = zip_window[scanp + best_len - 1];
- var scan_end = zip_window[scanp + best_len];
- if (zip_prev_length >= zip_good_match) chain_length >>= 2;
- do {
- matchp = cur_match;
- if (zip_window[matchp + best_len] != scan_end || zip_window[matchp + best_len - 1] != scan_end1 || zip_window[matchp] != zip_window[scanp] || zip_window[++matchp] != zip_window[scanp + 1]) {
- continue;
- }
- scanp += 2;
- matchp++;
- do {} while (zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && zip_window[++scanp] == zip_window[++matchp] && scanp < strendp);
- len = zip_MAX_MATCH - (strendp - scanp);
- scanp = strendp - zip_MAX_MATCH;
- if (len > best_len) {
- zip_match_start = cur_match;
- best_len = len;
- if (zip_FULL_SEARCH) {
- if (len >= zip_MAX_MATCH) break;
- } else {
- if (len >= zip_nice_match) break;
- }
- scan_end1 = zip_window[scanp + best_len - 1];
- scan_end = zip_window[scanp + best_len];
- }
- } while ((cur_match = zip_prev[cur_match & zip_WMASK]) > limit && --chain_length != 0);
- return best_len;
- };
- var zip_fill_window = function() {
- var n, m;
- var more = zip_window_size - zip_lookahead - zip_strstart;
- if (more == -1) {
- more--;
- } else if (zip_strstart >= zip_WSIZE + zip_MAX_DIST) {
- for (n = 0; n < zip_WSIZE; n++) zip_window[n] = zip_window[n + zip_WSIZE];
- zip_match_start -= zip_WSIZE;
- zip_strstart -= zip_WSIZE;
- zip_block_start -= zip_WSIZE;
- for (n = 0; n < zip_HASH_SIZE; n++) {
- m = zip_head1(n);
- zip_head2(n, m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL);
- }
- for (n = 0; n < zip_WSIZE; n++) {
- m = zip_prev[n];
- zip_prev[n] = m >= zip_WSIZE ? m - zip_WSIZE : zip_NIL;
- }
- more += zip_WSIZE;
- }
- if (!zip_eofile) {
- n = zip_read_buff(zip_window, zip_strstart + zip_lookahead, more);
- if (n <= 0) zip_eofile = true; else zip_lookahead += n;
- }
- };
- var zip_deflate_fast = function() {
- while (zip_lookahead != 0 && zip_qhead == null) {
- var flush;
- zip_INSERT_STRING();
- if (zip_hash_head != zip_NIL && zip_strstart - zip_hash_head <= zip_MAX_DIST) {
- zip_match_length = zip_longest_match(zip_hash_head);
- if (zip_match_length > zip_lookahead) zip_match_length = zip_lookahead;
- }
- if (zip_match_length >= zip_MIN_MATCH) {
- flush = zip_ct_tally(zip_strstart - zip_match_start, zip_match_length - zip_MIN_MATCH);
- zip_lookahead -= zip_match_length;
- if (zip_match_length <= zip_max_lazy_match) {
- zip_match_length--;
- do {
- zip_strstart++;
- zip_INSERT_STRING();
- } while (--zip_match_length != 0);
- zip_strstart++;
- } else {
- zip_strstart += zip_match_length;
- zip_match_length = 0;
- zip_ins_h = zip_window[zip_strstart] & 255;
- zip_ins_h = (zip_ins_h << zip_H_SHIFT ^ zip_window[zip_strstart + 1] & 255) & zip_HASH_MASK;
- }
- } else {
- flush = zip_ct_tally(0, zip_window[zip_strstart] & 255);
- zip_lookahead--;
- zip_strstart++;
- }
- if (flush) {
- zip_flush_block(0);
- zip_block_start = zip_strstart;
- }
- while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) zip_fill_window();
- }
- };
- var zip_deflate_better = function() {
- while (zip_lookahead != 0 && zip_qhead == null) {
- zip_INSERT_STRING();
- zip_prev_length = zip_match_length;
- zip_prev_match = zip_match_start;
- zip_match_length = zip_MIN_MATCH - 1;
- if (zip_hash_head != zip_NIL && zip_prev_length < zip_max_lazy_match && zip_strstart - zip_hash_head <= zip_MAX_DIST) {
- zip_match_length = zip_longest_match(zip_hash_head);
- if (zip_match_length > zip_lookahead) zip_match_length = zip_lookahead;
- if (zip_match_length == zip_MIN_MATCH && zip_strstart - zip_match_start > zip_TOO_FAR) {
- zip_match_length--;
- }
- }
- if (zip_prev_length >= zip_MIN_MATCH && zip_match_length <= zip_prev_length) {
- var flush;
- flush = zip_ct_tally(zip_strstart - 1 - zip_prev_match, zip_prev_length - zip_MIN_MATCH);
- zip_lookahead -= zip_prev_length - 1;
- zip_prev_length -= 2;
- do {
- zip_strstart++;
- zip_INSERT_STRING();
- } while (--zip_prev_length != 0);
- zip_match_available = 0;
- zip_match_length = zip_MIN_MATCH - 1;
- zip_strstart++;
- if (flush) {
- zip_flush_block(0);
- zip_block_start = zip_strstart;
- }
- } else if (zip_match_available != 0) {
- if (zip_ct_tally(0, zip_window[zip_strstart - 1] & 255)) {
- zip_flush_block(0);
- zip_block_start = zip_strstart;
- }
- zip_strstart++;
- zip_lookahead--;
- } else {
- zip_match_available = 1;
- zip_strstart++;
- zip_lookahead--;
- }
- while (zip_lookahead < zip_MIN_LOOKAHEAD && !zip_eofile) zip_fill_window();
- }
- };
- var zip_init_deflate = function() {
- if (zip_eofile) return;
- zip_bi_buf = 0;
- zip_bi_valid = 0;
- zip_ct_init();
- zip_lm_init();
- zip_qhead = null;
- zip_outcnt = 0;
- zip_outoff = 0;
- if (zip_compr_level <= 3) {
- zip_prev_length = zip_MIN_MATCH - 1;
- zip_match_length = 0;
- } else {
- zip_match_length = zip_MIN_MATCH - 1;
- zip_match_available = 0;
- }
- zip_complete = false;
- };
- var zip_deflate_internal = function(buff, off, buff_size) {
- var n;
- if (!zip_initflag) {
- zip_init_deflate();
- zip_initflag = true;
- if (zip_lookahead == 0) {
- zip_complete = true;
- return 0;
- }
- }
- if ((n = zip_qcopy(buff, off, buff_size)) == buff_size) return buff_size;
- if (zip_complete) return n;
- if (zip_compr_level <= 3) zip_deflate_fast(); else zip_deflate_better();
- if (zip_lookahead == 0) {
- if (zip_match_available != 0) zip_ct_tally(0, zip_window[zip_strstart - 1] & 255);
- zip_flush_block(1);
- zip_complete = true;
- }
- return n + zip_qcopy(buff, n + off, buff_size - n);
- };
- var zip_qcopy = function(buff, off, buff_size) {
- var n, i, j;
- n = 0;
- while (zip_qhead != null && n < buff_size) {
- i = buff_size - n;
- if (i > zip_qhead.len) i = zip_qhead.len;
- for (j = 0; j < i; j++) buff[off + n + j] = zip_qhead.ptr[zip_qhead.off + j];
- zip_qhead.off += i;
- zip_qhead.len -= i;
- n += i;
- if (zip_qhead.len == 0) {
- var p;
- p = zip_qhead;
- zip_qhead = zip_qhead.next;
- zip_reuse_queue(p);
- }
- }
- if (n == buff_size) return n;
- if (zip_outoff < zip_outcnt) {
- i = buff_size - n;
- if (i > zip_outcnt - zip_outoff) i = zip_outcnt - zip_outoff;
- for (j = 0; j < i; j++) buff[off + n + j] = zip_outbuf[zip_outoff + j];
- zip_outoff += i;
- n += i;
- if (zip_outcnt == zip_outoff) zip_outcnt = zip_outoff = 0;
- }
- return n;
- };
- var zip_ct_init = function() {
- var n;
- var bits;
- var length;
- var code;
- var dist;
- if (zip_static_dtree[0].dl != 0) return;
- zip_l_desc.dyn_tree = zip_dyn_ltree;
- zip_l_desc.static_tree = zip_static_ltree;
- zip_l_desc.extra_bits = zip_extra_lbits;
- zip_l_desc.extra_base = zip_LITERALS + 1;
- zip_l_desc.elems = zip_L_CODES;
- zip_l_desc.max_length = zip_MAX_BITS;
- zip_l_desc.max_code = 0;
- zip_d_desc.dyn_tree = zip_dyn_dtree;
- zip_d_desc.static_tree = zip_static_dtree;
- zip_d_desc.extra_bits = zip_extra_dbits;
- zip_d_desc.extra_base = 0;
- zip_d_desc.elems = zip_D_CODES;
- zip_d_desc.max_length = zip_MAX_BITS;
- zip_d_desc.max_code = 0;
- zip_bl_desc.dyn_tree = zip_bl_tree;
- zip_bl_desc.static_tree = null;
- zip_bl_desc.extra_bits = zip_extra_blbits;
- zip_bl_desc.extra_base = 0;
- zip_bl_desc.elems = zip_BL_CODES;
- zip_bl_desc.max_length = zip_MAX_BL_BITS;
- zip_bl_desc.max_code = 0;
- length = 0;
- for (code = 0; code < zip_LENGTH_CODES - 1; code++) {
- zip_base_length[code] = length;
- for (n = 0; n < 1 << zip_extra_lbits[code]; n++) zip_length_code[length++] = code;
- }
- zip_length_code[length - 1] = code;
- dist = 0;
- for (code = 0; code < 16; code++) {
- zip_base_dist[code] = dist;
- for (n = 0; n < 1 << zip_extra_dbits[code]; n++) {
- zip_dist_code[dist++] = code;
- }
- }
- dist >>= 7;
- for (;code < zip_D_CODES; code++) {
- zip_base_dist[code] = dist << 7;
- for (n = 0; n < 1 << zip_extra_dbits[code] - 7; n++) zip_dist_code[256 + dist++] = code;
- }
- for (bits = 0; bits <= zip_MAX_BITS; bits++) zip_bl_count[bits] = 0;
- n = 0;
- while (n <= 143) {
- zip_static_ltree[n++].dl = 8;
- zip_bl_count[8]++;
- }
- while (n <= 255) {
- zip_static_ltree[n++].dl = 9;
- zip_bl_count[9]++;
- }
- while (n <= 279) {
- zip_static_ltree[n++].dl = 7;
- zip_bl_count[7]++;
- }
- while (n <= 287) {
- zip_static_ltree[n++].dl = 8;
- zip_bl_count[8]++;
- }
- zip_gen_codes(zip_static_ltree, zip_L_CODES + 1);
- for (n = 0; n < zip_D_CODES; n++) {
- zip_static_dtree[n].dl = 5;
- zip_static_dtree[n].fc = zip_bi_reverse(n, 5);
- }
- zip_init_block();
- };
- var zip_init_block = function() {
- var n;
- for (n = 0; n < zip_L_CODES; n++) zip_dyn_ltree[n].fc = 0;
- for (n = 0; n < zip_D_CODES; n++) zip_dyn_dtree[n].fc = 0;
- for (n = 0; n < zip_BL_CODES; n++) zip_bl_tree[n].fc = 0;
- zip_dyn_ltree[zip_END_BLOCK].fc = 1;
- zip_opt_len = zip_static_len = 0;
- zip_last_lit = zip_last_dist = zip_last_flags = 0;
- zip_flags = 0;
- zip_flag_bit = 1;
- };
- var zip_pqdownheap = function(tree, k) {
- var v = zip_heap[k];
- var j = k << 1;
- while (j <= zip_heap_len) {
- if (j < zip_heap_len && zip_SMALLER(tree, zip_heap[j + 1], zip_heap[j])) j++;
- if (zip_SMALLER(tree, v, zip_heap[j])) break;
- zip_heap[k] = zip_heap[j];
- k = j;
- j <<= 1;
- }
- zip_heap[k] = v;
- };
- var zip_gen_bitlen = function(desc) {
- var tree = desc.dyn_tree;
- var extra = desc.extra_bits;
- var base = desc.extra_base;
- var max_code = desc.max_code;
- var max_length = desc.max_length;
- var stree = desc.static_tree;
- var h;
- var n, m;
- var bits;
- var xbits;
- var f;
- var overflow = 0;
- for (bits = 0; bits <= zip_MAX_BITS; bits++) zip_bl_count[bits] = 0;
- tree[zip_heap[zip_heap_max]].dl = 0;
- for (h = zip_heap_max + 1; h < zip_HEAP_SIZE; h++) {
- n = zip_heap[h];
- bits = tree[tree[n].dl].dl + 1;
- if (bits > max_length) {
- bits = max_length;
- overflow++;
- }
- tree[n].dl = bits;
- if (n > max_code) continue;
- zip_bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n - base];
- f = tree[n].fc;
- zip_opt_len += f * (bits + xbits);
- if (stree != null) zip_static_len += f * (stree[n].dl + xbits);
- }
- if (overflow == 0) return;
- do {
- bits = max_length - 1;
- while (zip_bl_count[bits] == 0) bits--;
- zip_bl_count[bits]--;
- zip_bl_count[bits + 1] += 2;
- zip_bl_count[max_length]--;
- overflow -= 2;
- } while (overflow > 0);
- for (bits = max_length; bits != 0; bits--) {
- n = zip_bl_count[bits];
- while (n != 0) {
- m = zip_heap[--h];
- if (m > max_code) continue;
- if (tree[m].dl != bits) {
- zip_opt_len += (bits - tree[m].dl) * tree[m].fc;
- tree[m].fc = bits;
- }
- n--;
- }
- }
- };
- var zip_gen_codes = function(tree, max_code) {
- var next_code = new Array(zip_MAX_BITS + 1);
- var code = 0;
- var bits;
- var n;
- for (bits = 1; bits <= zip_MAX_BITS; bits++) {
- code = code + zip_bl_count[bits - 1] << 1;
- next_code[bits] = code;
- }
- for (n = 0; n <= max_code; n++) {
- var len = tree[n].dl;
- if (len == 0) continue;
- tree[n].fc = zip_bi_reverse(next_code[len]++, len);
- }
- };
- var zip_build_tree = function(desc) {
- var tree = desc.dyn_tree;
- var stree = desc.static_tree;
- var elems = desc.elems;
- var n, m;
- var max_code = -1;
- var node = elems;
- zip_heap_len = 0;
- zip_heap_max = zip_HEAP_SIZE;
- for (n = 0; n < elems; n++) {
- if (tree[n].fc != 0) {
- zip_heap[++zip_heap_len] = max_code = n;
- zip_depth[n] = 0;
- } else tree[n].dl = 0;
- }
- while (zip_heap_len < 2) {
- var xnew = zip_heap[++zip_heap_len] = max_code < 2 ? ++max_code : 0;
- tree[xnew].fc = 1;
- zip_depth[xnew] = 0;
- zip_opt_len--;
- if (stree != null) zip_static_len -= stree[xnew].dl;
- }
- desc.max_code = max_code;
- for (n = zip_heap_len >> 1; n >= 1; n--) zip_pqdownheap(tree, n);
- do {
- n = zip_heap[zip_SMALLEST];
- zip_heap[zip_SMALLEST] = zip_heap[zip_heap_len--];
- zip_pqdownheap(tree, zip_SMALLEST);
- m = zip_heap[zip_SMALLEST];
- zip_heap[--zip_heap_max] = n;
- zip_heap[--zip_heap_max] = m;
- tree[node].fc = tree[n].fc + tree[m].fc;
- if (zip_depth[n] > zip_depth[m] + 1) zip_depth[node] = zip_depth[n]; else zip_depth[node] = zip_depth[m] + 1;
- tree[n].dl = tree[m].dl = node;
- zip_heap[zip_SMALLEST] = node++;
- zip_pqdownheap(tree, zip_SMALLEST);
- } while (zip_heap_len >= 2);
- zip_heap[--zip_heap_max] = zip_heap[zip_SMALLEST];
- zip_gen_bitlen(desc);
- zip_gen_codes(tree, max_code);
- };
- var zip_scan_tree = function(tree, max_code) {
- var n;
- var prevlen = -1;
- var curlen;
- var nextlen = tree[0].dl;
- var count = 0;
- var max_count = 7;
- var min_count = 4;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- }
- tree[max_code + 1].dl = 65535;
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen;
- nextlen = tree[n + 1].dl;
- if (++count < max_count && curlen == nextlen) continue; else if (count < min_count) zip_bl_tree[curlen].fc += count; else if (curlen != 0) {
- if (curlen != prevlen) zip_bl_tree[curlen].fc++;
- zip_bl_tree[zip_REP_3_6].fc++;
- } else if (count <= 10) zip_bl_tree[zip_REPZ_3_10].fc++; else zip_bl_tree[zip_REPZ_11_138].fc++;
- count = 0;
- prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6;
- min_count = 3;
- } else {
- max_count = 7;
- min_count = 4;
- }
- }
- };
- var zip_send_tree = function(tree, max_code) {
- var n;
- var prevlen = -1;
- var curlen;
- var nextlen = tree[0].dl;
- var count = 0;
- var max_count = 7;
- var min_count = 4;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- }
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen;
- nextlen = tree[n + 1].dl;
- if (++count < max_count && curlen == nextlen) {
- continue;
- } else if (count < min_count) {
- do {
- zip_SEND_CODE(curlen, zip_bl_tree);
- } while (--count != 0);
- } else if (curlen != 0) {
- if (curlen != prevlen) {
- zip_SEND_CODE(curlen, zip_bl_tree);
- count--;
- }
- zip_SEND_CODE(zip_REP_3_6, zip_bl_tree);
- zip_send_bits(count - 3, 2);
- } else if (count <= 10) {
- zip_SEND_CODE(zip_REPZ_3_10, zip_bl_tree);
- zip_send_bits(count - 3, 3);
- } else {
- zip_SEND_CODE(zip_REPZ_11_138, zip_bl_tree);
- zip_send_bits(count - 11, 7);
- }
- count = 0;
- prevlen = curlen;
- if (nextlen == 0) {
- max_count = 138;
- min_count = 3;
- } else if (curlen == nextlen) {
- max_count = 6;
- min_count = 3;
- } else {
- max_count = 7;
- min_count = 4;
- }
- }
- };
- var zip_build_bl_tree = function() {
- var max_blindex;
- zip_scan_tree(zip_dyn_ltree, zip_l_desc.max_code);
- zip_scan_tree(zip_dyn_dtree, zip_d_desc.max_code);
- zip_build_tree(zip_bl_desc);
- for (max_blindex = zip_BL_CODES - 1; max_blindex >= 3; max_blindex--) {
- if (zip_bl_tree[zip_bl_order[max_blindex]].dl != 0) break;
- }
- zip_opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
- return max_blindex;
- };
- var zip_send_all_trees = function(lcodes, dcodes, blcodes) {
- var rank;
- zip_send_bits(lcodes - 257, 5);
- zip_send_bits(dcodes - 1, 5);
- zip_send_bits(blcodes - 4, 4);
- for (rank = 0; rank < blcodes; rank++) {
- zip_send_bits(zip_bl_tree[zip_bl_order[rank]].dl, 3);
- }
- zip_send_tree(zip_dyn_ltree, lcodes - 1);
- zip_send_tree(zip_dyn_dtree, dcodes - 1);
- };
- var zip_flush_block = function(eof) {
- var opt_lenb, static_lenb;
- var max_blindex;
- var stored_len;
- stored_len = zip_strstart - zip_block_start;
- zip_flag_buf[zip_last_flags] = zip_flags;
- zip_build_tree(zip_l_desc);
- zip_build_tree(zip_d_desc);
- max_blindex = zip_build_bl_tree();
- opt_lenb = zip_opt_len + 3 + 7 >> 3;
- static_lenb = zip_static_len + 3 + 7 >> 3;
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
- if (stored_len + 4 <= opt_lenb && zip_block_start >= 0) {
- var i;
- zip_send_bits((zip_STORED_BLOCK << 1) + eof, 3);
- zip_bi_windup();
- zip_put_short(stored_len);
- zip_put_short(~stored_len);
- for (i = 0; i < stored_len; i++) zip_put_byte(zip_window[zip_block_start + i]);
- } else if (static_lenb == opt_lenb) {
- zip_send_bits((zip_STATIC_TREES << 1) + eof, 3);
- zip_compress_block(zip_static_ltree, zip_static_dtree);
- } else {
- zip_send_bits((zip_DYN_TREES << 1) + eof, 3);
- zip_send_all_trees(zip_l_desc.max_code + 1, zip_d_desc.max_code + 1, max_blindex + 1);
- zip_compress_block(zip_dyn_ltree, zip_dyn_dtree);
- }
- zip_init_block();
- if (eof != 0) zip_bi_windup();
- };
- var zip_ct_tally = function(dist, lc) {
- zip_l_buf[zip_last_lit++] = lc;
- if (dist == 0) {
- zip_dyn_ltree[lc].fc++;
- } else {
- dist--;
- zip_dyn_ltree[zip_length_code[lc] + zip_LITERALS + 1].fc++;
- zip_dyn_dtree[zip_D_CODE(dist)].fc++;
- zip_d_buf[zip_last_dist++] = dist;
- zip_flags |= zip_flag_bit;
- }
- zip_flag_bit <<= 1;
- if ((zip_last_lit & 7) == 0) {
- zip_flag_buf[zip_last_flags++] = zip_flags;
- zip_flags = 0;
- zip_flag_bit = 1;
- }
- if (zip_compr_level > 2 && (zip_last_lit & 4095) == 0) {
- var out_length = zip_last_lit * 8;
- var in_length = zip_strstart - zip_block_start;
- var dcode;
- for (dcode = 0; dcode < zip_D_CODES; dcode++) {
- out_length += zip_dyn_dtree[dcode].fc * (5 + zip_extra_dbits[dcode]);
- }
- out_length >>= 3;
- if (zip_last_dist < parseInt(zip_last_lit / 2) && out_length < parseInt(in_length / 2)) return true;
- }
- return zip_last_lit == zip_LIT_BUFSIZE - 1 || zip_last_dist == zip_DIST_BUFSIZE;
- };
- var zip_compress_block = function(ltree, dtree) {
- var dist;
- var lc;
- var lx = 0;
- var dx = 0;
- var fx = 0;
- var flag = 0;
- var code;
- var extra;
- if (zip_last_lit != 0) do {
- if ((lx & 7) == 0) flag = zip_flag_buf[fx++];
- lc = zip_l_buf[lx++] & 255;
- if ((flag & 1) == 0) {
- zip_SEND_CODE(lc, ltree);
- } else {
- code = zip_length_code[lc];
- zip_SEND_CODE(code + zip_LITERALS + 1, ltree);
- extra = zip_extra_lbits[code];
- if (extra != 0) {
- lc -= zip_base_length[code];
- zip_send_bits(lc, extra);
- }
- dist = zip_d_buf[dx++];
- code = zip_D_CODE(dist);
- zip_SEND_CODE(code, dtree);
- extra = zip_extra_dbits[code];
- if (extra != 0) {
- dist -= zip_base_dist[code];
- zip_send_bits(dist, extra);
- }
- }
- flag >>= 1;
- } while (lx < zip_last_lit);
- zip_SEND_CODE(zip_END_BLOCK, ltree);
- };
- var zip_Buf_size = 16;
- var zip_send_bits = function(value, length) {
- if (zip_bi_valid > zip_Buf_size - length) {
- zip_bi_buf |= value << zip_bi_valid;
- zip_put_short(zip_bi_buf);
- zip_bi_buf = value >> zip_Buf_size - zip_bi_valid;
- zip_bi_valid += length - zip_Buf_size;
- } else {
- zip_bi_buf |= value << zip_bi_valid;
- zip_bi_valid += length;
- }
- };
- var zip_bi_reverse = function(code, len) {
- var res = 0;
- do {
- res |= code & 1;
- code >>= 1;
- res <<= 1;
- } while (--len > 0);
- return res >> 1;
- };
- var zip_bi_windup = function() {
- if (zip_bi_valid > 8) {
- zip_put_short(zip_bi_buf);
- } else if (zip_bi_valid > 0) {
- zip_put_byte(zip_bi_buf);
- }
- zip_bi_buf = 0;
- zip_bi_valid = 0;
- };
- var zip_qoutbuf = function() {
- if (zip_outcnt != 0) {
- var q, i;
- q = zip_new_queue();
- if (zip_qhead == null) zip_qhead = zip_qtail = q; else zip_qtail = zip_qtail.next = q;
- q.len = zip_outcnt - zip_outoff;
- for (i = 0; i < q.len; i++) q.ptr[i] = zip_outbuf[zip_outoff + i];
- zip_outcnt = zip_outoff = 0;
- }
- };
- var zip_deflate = function(str, level) {
- var i, j;
- zip_deflate_data = str;
- zip_deflate_pos = 0;
- if (typeof level == "undefined") level = zip_DEFAULT_LEVEL;
- zip_deflate_start(level);
- var buff = new Array(1024);
- var aout = [];
- while ((i = zip_deflate_internal(buff, 0, buff.length)) > 0) {
- var cbuf = new Array(i);
- for (j = 0; j < i; j++) {
- cbuf[j] = String.fromCharCode(buff[j]);
- }
- aout[aout.length] = cbuf.join("");
- }
- zip_deflate_data = null;
- return aout.join("");
- };
- if (!JSZip.compressions["DEFLATE"]) {
- JSZip.compressions["DEFLATE"] = {
- magic: "\b\0",
- compress: zip_deflate
- };
- } else {
- JSZip.compressions["DEFLATE"].compress = zip_deflate;
- }
-})();
+ }
-if (!JSZip) {
- throw "JSZip not defined";
-}
+ // should be something, preparing the extra reader
+ var extraReader = new StringReader(this.extraFields[0x0001].value);
-(function() {
- var zip_fixed_bd;
- var zip_WSIZE = 32768;
- var zip_STORED_BLOCK = 0;
- var zip_STATIC_TREES = 1;
- var zip_DYN_TREES = 2;
- var zip_lbits = 9;
- var zip_dbits = 6;
- var zip_INBUFSIZ = 32768;
- var zip_INBUF_EXTRA = 64;
- var zip_slide;
- var zip_wp;
- var zip_fixed_tl = null;
- var zip_fixed_td;
- var zip_fixed_bl, fixed_bd;
- var zip_bit_buf;
- var zip_bit_len;
- var zip_method;
- var zip_eof;
- var zip_copy_leng;
- var zip_copy_dist;
- var zip_tl, zip_td;
- var zip_bl, zip_bd;
- var zip_inflate_data;
- var zip_inflate_pos;
- var zip_MASK_BITS = new Array(0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535);
- var zip_cplens = new Array(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);
- var zip_cplext = new Array(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, 99, 99);
- var zip_cpdist = new Array(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 zip_cpdext = new Array(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);
- var zip_border = new Array(16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
- function zip_HuftList() {
- this.next = null;
- this.list = null;
- }
- function zip_HuftNode() {
- this.e = 0;
- this.b = 0;
- this.n = 0;
- this.t = null;
- }
- function zip_HuftBuild(b, n, s, d, e, mm) {
- this.BMAX = 16;
- this.N_MAX = 288;
- this.status = 0;
- this.root = null;
- this.m = 0;
- {
- var a;
- var c = new Array(this.BMAX + 1);
- var el;
- var f;
- var g;
- var h;
- var i;
- var j;
- var k;
- var lx = new Array(this.BMAX + 1);
- var p;
- var pidx;
- var q;
- var r = new zip_HuftNode();
- var u = new Array(this.BMAX);
- var v = new Array(this.N_MAX);
- var w;
- var x = new Array(this.BMAX + 1);
- var xp;
- var y;
- var z;
- var o;
- var tail;
- tail = this.root = null;
- for (i = 0; i < c.length; i++) c[i] = 0;
- for (i = 0; i < lx.length; i++) lx[i] = 0;
- for (i = 0; i < u.length; i++) u[i] = null;
- for (i = 0; i < v.length; i++) v[i] = 0;
- for (i = 0; i < x.length; i++) x[i] = 0;
- el = n > 256 ? b[256] : this.BMAX;
- p = b;
- pidx = 0;
- i = n;
- do {
- c[p[pidx]]++;
- pidx++;
- } while (--i > 0);
- if (c[0] == n) {
- this.root = null;
- this.m = 0;
- this.status = 0;
- return;
- }
- for (j = 1; j <= this.BMAX; j++) if (c[j] != 0) break;
- k = j;
- if (mm < j) mm = j;
- for (i = this.BMAX; i != 0; i--) if (c[i] != 0) break;
- g = i;
- if (mm > i) mm = i;
- for (y = 1 << j; j < i; j++, y <<= 1) if ((y -= c[j]) < 0) {
- this.status = 2;
- this.m = mm;
- return;
- }
- if ((y -= c[i]) < 0) {
- this.status = 2;
- this.m = mm;
- return;
- }
- c[i] += y;
- x[1] = j = 0;
- p = c;
- pidx = 1;
- xp = 2;
- while (--i > 0) x[xp++] = j += p[pidx++];
- p = b;
- pidx = 0;
- i = 0;
- do {
- if ((j = p[pidx++]) != 0) v[x[j]++] = i;
- } while (++i < n);
- n = x[g];
- x[0] = i = 0;
- p = v;
- pidx = 0;
- h = -1;
- w = lx[0] = 0;
- q = null;
- z = 0;
- for (;k <= g; k++) {
- a = c[k];
- while (a-- > 0) {
- while (k > w + lx[1 + h]) {
- w += lx[1 + h];
- h++;
- z = (z = g - w) > mm ? mm : z;
- if ((f = 1 << (j = k - w)) > a + 1) {
- f -= a + 1;
- xp = k;
- while (++j < z) {
- if ((f <<= 1) <= c[++xp]) break;
- f -= c[xp];
- }
- }
- if (w + j > el && w < el) j = el - w;
- z = 1 << j;
- lx[1 + h] = j;
- q = new Array(z);
- for (o = 0; o < z; o++) {
- q[o] = new zip_HuftNode();
- }
- if (tail == null) tail = this.root = new zip_HuftList(); else tail = tail.next = new zip_HuftList();
- tail.next = null;
- tail.list = q;
- u[h] = q;
- if (h > 0) {
- x[h] = i;
- r.b = lx[h];
- r.e = 16 + j;
- r.t = q;
- j = (i & (1 << w) - 1) >> w - lx[h];
- u[h - 1][j].e = r.e;
- u[h - 1][j].b = r.b;
- u[h - 1][j].n = r.n;
- u[h - 1][j].t = r.t;
- }
- }
- r.b = k - w;
- if (pidx >= n) r.e = 99; else if (p[pidx] < s) {
- r.e = p[pidx] < 256 ? 16 : 15;
- r.n = p[pidx++];
- } else {
- r.e = e[p[pidx] - s];
- r.n = d[p[pidx++] - s];
- }
- f = 1 << k - w;
- for (j = i >> w; j < z; j += f) {
- q[j].e = r.e;
- q[j].b = r.b;
- q[j].n = r.n;
- q[j].t = r.t;
- }
- for (j = 1 << k - 1; (i & j) != 0; j >>= 1) i ^= j;
- i ^= j;
- while ((i & (1 << w) - 1) != x[h]) {
- w -= lx[h];
- h--;
- }
- }
- }
- this.m = lx[1];
- this.status = y != 0 && g != 1 ? 1 : 0;
- }
- }
- function zip_GET_BYTE() {
- if (zip_inflate_data.length == zip_inflate_pos) return -1;
- return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 255;
- }
- function zip_NEEDBITS(n) {
- while (zip_bit_len < n) {
- zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
- zip_bit_len += 8;
- }
- }
- function zip_GETBITS(n) {
- return zip_bit_buf & zip_MASK_BITS[n];
- }
- function zip_DUMPBITS(n) {
- zip_bit_buf >>= n;
- zip_bit_len -= n;
- }
- function zip_inflate_codes(buff, off, size) {
- var e;
- var t;
- var n;
- if (size == 0) return 0;
- n = 0;
- for (;;) {
- zip_NEEDBITS(zip_bl);
- t = zip_tl.list[zip_GETBITS(zip_bl)];
- e = t.e;
- while (e > 16) {
- if (e == 99) return -1;
- zip_DUMPBITS(t.b);
- e -= 16;
- zip_NEEDBITS(e);
- t = t.t[zip_GETBITS(e)];
- e = t.e;
- }
- zip_DUMPBITS(t.b);
- if (e == 16) {
- zip_wp &= zip_WSIZE - 1;
- buff[off + n++] = zip_slide[zip_wp++] = t.n;
- if (n == size) return size;
- continue;
- }
- if (e == 15) break;
- zip_NEEDBITS(e);
- zip_copy_leng = t.n + zip_GETBITS(e);
- zip_DUMPBITS(e);
- zip_NEEDBITS(zip_bd);
- t = zip_td.list[zip_GETBITS(zip_bd)];
- e = t.e;
- while (e > 16) {
- if (e == 99) return -1;
- zip_DUMPBITS(t.b);
- e -= 16;
- zip_NEEDBITS(e);
- t = t.t[zip_GETBITS(e)];
- e = t.e;
- }
- zip_DUMPBITS(t.b);
- zip_NEEDBITS(e);
- zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
- zip_DUMPBITS(e);
- while (zip_copy_leng > 0 && n < size) {
- zip_copy_leng--;
- zip_copy_dist &= zip_WSIZE - 1;
- zip_wp &= zip_WSIZE - 1;
- buff[off + n++] = zip_slide[zip_wp++] = zip_slide[zip_copy_dist++];
- }
- if (n == size) return size;
- }
- zip_method = -1;
- return n;
- }
- function zip_inflate_stored(buff, off, size) {
- var n;
- n = zip_bit_len & 7;
- zip_DUMPBITS(n);
- zip_NEEDBITS(16);
- n = zip_GETBITS(16);
- zip_DUMPBITS(16);
- zip_NEEDBITS(16);
- if (n != (~zip_bit_buf & 65535)) return -1;
- zip_DUMPBITS(16);
- zip_copy_leng = n;
- n = 0;
- while (zip_copy_leng > 0 && n < size) {
- zip_copy_leng--;
- zip_wp &= zip_WSIZE - 1;
- zip_NEEDBITS(8);
- buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
- zip_DUMPBITS(8);
- }
- if (zip_copy_leng == 0) zip_method = -1;
- return n;
- }
- function zip_inflate_fixed(buff, off, size) {
- if (zip_fixed_tl == null) {
- var i;
- var l = new Array(288);
- var h;
- for (i = 0; i < 144; i++) l[i] = 8;
- for (;i < 256; i++) l[i] = 9;
- for (;i < 280; i++) l[i] = 7;
- for (;i < 288; i++) l[i] = 8;
- zip_fixed_bl = 7;
- h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext, zip_fixed_bl);
- if (h.status != 0) {
- alert("HufBuild error: " + h.status);
- return -1;
- }
- zip_fixed_tl = h.root;
- zip_fixed_bl = h.m;
- for (i = 0; i < 30; i++) l[i] = 5;
- zip_fixed_bd = 5;
- h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
- if (h.status > 1) {
- zip_fixed_tl = null;
- alert("HufBuild error: " + h.status);
- return -1;
- }
- zip_fixed_td = h.root;
- zip_fixed_bd = h.m;
- }
- zip_tl = zip_fixed_tl;
- zip_td = zip_fixed_td;
- zip_bl = zip_fixed_bl;
- zip_bd = zip_fixed_bd;
- return zip_inflate_codes(buff, off, size);
- }
- function zip_inflate_dynamic(buff, off, size) {
- var i;
- var j;
- var l;
- var n;
- var t;
- var nb;
- var nl;
- var nd;
- var ll = new Array(286 + 30);
- var h;
- for (i = 0; i < ll.length; i++) ll[i] = 0;
- zip_NEEDBITS(5);
- nl = 257 + zip_GETBITS(5);
- zip_DUMPBITS(5);
- zip_NEEDBITS(5);
- nd = 1 + zip_GETBITS(5);
- zip_DUMPBITS(5);
- zip_NEEDBITS(4);
- nb = 4 + zip_GETBITS(4);
- zip_DUMPBITS(4);
- if (nl > 286 || nd > 30) return -1;
- for (j = 0; j < nb; j++) {
- zip_NEEDBITS(3);
- ll[zip_border[j]] = zip_GETBITS(3);
- zip_DUMPBITS(3);
- }
- for (;j < 19; j++) ll[zip_border[j]] = 0;
- zip_bl = 7;
- h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
- if (h.status != 0) return -1;
- zip_tl = h.root;
- zip_bl = h.m;
- n = nl + nd;
- i = l = 0;
- while (i < n) {
- zip_NEEDBITS(zip_bl);
- t = zip_tl.list[zip_GETBITS(zip_bl)];
- j = t.b;
- zip_DUMPBITS(j);
- j = t.n;
- if (j < 16) ll[i++] = l = j; else if (j == 16) {
- zip_NEEDBITS(2);
- j = 3 + zip_GETBITS(2);
- zip_DUMPBITS(2);
- if (i + j > n) return -1;
- while (j-- > 0) ll[i++] = l;
- } else if (j == 17) {
- zip_NEEDBITS(3);
- j = 3 + zip_GETBITS(3);
- zip_DUMPBITS(3);
- if (i + j > n) return -1;
- while (j-- > 0) ll[i++] = 0;
- l = 0;
- } else {
- zip_NEEDBITS(7);
- j = 11 + zip_GETBITS(7);
- zip_DUMPBITS(7);
- if (i + j > n) return -1;
- while (j-- > 0) ll[i++] = 0;
- l = 0;
- }
- }
- zip_bl = zip_lbits;
- h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
- if (zip_bl == 0) h.status = 1;
- if (h.status != 0) {
- if (h.status == 1) ;
- return -1;
- }
- zip_tl = h.root;
- zip_bl = h.m;
- for (i = 0; i < nd; i++) ll[i] = ll[i + nl];
- zip_bd = zip_dbits;
- h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
- zip_td = h.root;
- zip_bd = h.m;
- if (zip_bd == 0 && nl > 257) {
- return -1;
- }
- if (h.status == 1) {
- }
- if (h.status != 0) return -1;
- return zip_inflate_codes(buff, off, size);
- }
- function zip_inflate_start() {
- var i;
- if (zip_slide == null) zip_slide = new Array(2 * zip_WSIZE);
- zip_wp = 0;
- zip_bit_buf = 0;
- zip_bit_len = 0;
- zip_method = -1;
- zip_eof = false;
- zip_copy_leng = zip_copy_dist = 0;
- zip_tl = null;
- }
- function zip_inflate_internal(buff, off, size) {
- var n, i;
- n = 0;
- while (n < size) {
- if (zip_eof && zip_method == -1) return n;
- if (zip_copy_leng > 0) {
- if (zip_method != zip_STORED_BLOCK) {
- while (zip_copy_leng > 0 && n < size) {
- zip_copy_leng--;
- zip_copy_dist &= zip_WSIZE - 1;
- zip_wp &= zip_WSIZE - 1;
- buff[off + n++] = zip_slide[zip_wp++] = zip_slide[zip_copy_dist++];
- }
- } else {
- while (zip_copy_leng > 0 && n < size) {
- zip_copy_leng--;
- zip_wp &= zip_WSIZE - 1;
- zip_NEEDBITS(8);
- buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
- zip_DUMPBITS(8);
- }
- if (zip_copy_leng == 0) zip_method = -1;
- }
- if (n == size) return n;
- }
- if (zip_method == -1) {
- if (zip_eof) break;
- zip_NEEDBITS(1);
- if (zip_GETBITS(1) != 0) zip_eof = true;
- zip_DUMPBITS(1);
- zip_NEEDBITS(2);
- zip_method = zip_GETBITS(2);
- zip_DUMPBITS(2);
- zip_tl = null;
- zip_copy_leng = 0;
- }
- switch (zip_method) {
- case 0:
- i = zip_inflate_stored(buff, off + n, size - n);
- break;
+ // I really hope that these 64bits integer can fit in 32 bits integer, because js
+ // won't let us have more.
+ if(this.uncompressedSize === MAX_VALUE_32BITS) {
+ this.uncompressedSize = extraReader.readInt(8);
+ }
+ if(this.compressedSize === MAX_VALUE_32BITS) {
+ this.compressedSize = extraReader.readInt(8);
+ }
+ if(this.localHeaderOffset === MAX_VALUE_32BITS) {
+ this.localHeaderOffset = extraReader.readInt(8);
+ }
+ if(this.diskNumberStart === MAX_VALUE_32BITS) {
+ this.diskNumberStart = extraReader.readInt(4);
+ }
+ },
+ /**
+ * Read the central part of a zip file and add the info in this object.
+ * @param {DataReader} reader the reader to use.
+ */
+ readExtraFields : function(reader) {
+ var start = reader.index,
+ extraFieldId,
+ extraFieldLength,
+ extraFieldValue;
- case 1:
- if (zip_tl != null) i = zip_inflate_codes(buff, off + n, size - n); else i = zip_inflate_fixed(buff, off + n, size - n);
- break;
+ this.extraFields = this.extraFields || {};
- case 2:
- if (zip_tl != null) i = zip_inflate_codes(buff, off + n, size - n); else i = zip_inflate_dynamic(buff, off + n, size - n);
- break;
+ while (reader.index < start + this.extraFieldsLength) {
+ extraFieldId = reader.readInt(2);
+ extraFieldLength = reader.readInt(2);
+ extraFieldValue = reader.readString(extraFieldLength);
- default:
- i = -1;
- break;
- }
- if (i == -1) {
- if (zip_eof) return 0;
- return -1;
- }
- n += i;
- }
- return n;
- }
- function zip_inflate(str) {
- var out, buff;
- var i, j;
- zip_inflate_start();
- zip_inflate_data = str;
- zip_inflate_pos = 0;
- buff = new Array(1024);
- out = "";
- while ((i = zip_inflate_internal(buff, 0, buff.length)) > 0) {
- for (j = 0; j < i; j++) out += String.fromCharCode(buff[j]);
- }
- zip_inflate_data = null;
- return out;
- }
- if (!JSZip.compressions["DEFLATE"]) {
- JSZip.compressions["DEFLATE"] = {
- magic: "\b\0",
- uncompress: zip_inflate
- };
- } else {
- JSZip.compressions["DEFLATE"].uncompress = zip_inflate;
- }
-})();
+ this.extraFields[extraFieldId] = {
+ id: extraFieldId,
+ length: extraFieldLength,
+ value: extraFieldValue
+ };
+ }
+ },
+ /**
+ * Apply an UTF8 transformation if needed.
+ */
+ handleUTF8 : function() {
+ if (this.useUTF8()) {
+ this.fileName = JSZip.prototype.utf8decode(this.fileName);
+ this.fileComment = JSZip.prototype.utf8decode(this.fileComment);
+ }
+ }
+ };
+ // }}} end of ZipEntry
-(function() {
- var pretty = function(str) {
- var res = "", code, i;
- for (i = 0; i < str.length; i++) {
- code = str.charCodeAt(i);
- res += "\\x" + (code < 10 ? "0" : "") + code.toString(16);
- }
- return res;
- };
- var findCompression = function(compressionMethod) {
- for (var method in JSZip.compressions) {
- if (JSZip.compressions[method].magic === compressionMethod) {
- return JSZip.compressions[method];
- }
- }
- return null;
- };
- function StreamReader(stream) {
- this.stream = stream;
- this.index = 0;
- }
- StreamReader.prototype = {
- checkOffset: function(offset) {
- this.checkIndex(this.index + offset);
- },
- checkIndex: function(newIndex) {
- if (this.stream.length < newIndex || newIndex < 0) {
- throw new Error("End of stream reached (stream length = " + this.stream.length + ", asked index = " + newIndex + "). Corrupted zip ?");
- }
- },
- setIndex: function(newIndex) {
- this.checkIndex(newIndex);
- this.index = newIndex;
- },
- eof: function() {
- return this.index >= this.stream.length;
- },
- byteAt: function(i) {
- return this.stream.charCodeAt(i) & 255;
- },
- readByte: function() {
- this.checkOffset(1);
- return this.byteAt(1 + this.index++);
- },
- readInt: function(size) {
- var result = 0, i;
- this.checkOffset(size);
- for (i = size - 1; i >= 0; i--) {
- result = (result << 8) + this.byteAt(this.index + i);
- }
- this.index += size;
- return result;
- },
- readString: function(size) {
- var result = "", i, code;
- this.checkOffset(size);
- for (i = 0; i < size; i++) {
- code = this.byteAt(this.index + i);
- result += String.fromCharCode(code);
- }
- this.index += size;
- return result;
- },
- readDate: function() {
- var dostime = this.readInt(4);
- return new Date((dostime >> 25 & 127) + 1980, (dostime >> 21 & 15) - 1, dostime >> 16 & 31, dostime >> 11 & 31, dostime >> 5 & 63, (dostime & 31) << 1);
- }
- };
- function ZipEntry(options, loadOptions) {
- this.options = options;
- this.loadOptions = loadOptions;
- }
- ZipEntry.prototype = {
- isEncrypted: function() {
- return (this.bitFlag & 1) === 1;
- },
- hasDataDescriptor: function() {
- return (this.bitFlag & 8) === 8;
- },
- useUTF8: function() {
- return (this.bitFlag & 2048) === 2048;
- },
- isZIP64: function() {
- return this.options.zip64;
- },
- readLocalPartHeader: function(reader) {
- this.versionNeeded = reader.readInt(2);
- this.bitFlag = reader.readInt(2);
- this.compressionMethod = reader.readString(2);
- this.date = reader.readDate();
- this.crc32 = reader.readInt(4);
- this.compressedSize = reader.readInt(4);
- this.uncompressedSize = reader.readInt(4);
- this.fileNameLength = reader.readInt(2);
- this.extraFieldsLength = reader.readInt(2);
- if (this.isEncrypted()) {
- throw new Error("Encrypted zip are not supported");
- }
- },
- readLocalPart: function(reader) {
- var compression;
- this.readLocalPartHeader(reader);
- this.fileName = reader.readString(this.fileNameLength);
- this.readExtraFields(reader);
- if (!this.hasDataDescriptor()) {
- this.compressedFileData = reader.readString(this.compressedSize);
- } else {
- this.compressedFileData = this.findDataUntilDataDescriptor(reader);
- this.crc32 = reader.readInt(4);
- this.compressedSize = reader.readInt(this.isZIP64() ? 8 : 4);
- this.uncompressedSize = reader.readInt(this.isZIP64() ? 8 : 4);
- if (this.compressedFileData.length !== this.compressedSize) {
- throw new Error("Bug : data descriptor incorrectly read (size mismatch)");
- }
- }
- this.uncompressedFileData = null;
- compression = findCompression(this.compressionMethod);
- if (compression === null) {
- throw new Error("Corrupted zip : compression " + pretty(this.compressionMethod) + " unknown (inner file : " + this.fileName + ")");
- }
- this.uncompressedFileData = compression.uncompress(this.compressedFileData);
- if (this.loadOptions.checkCRC32 && JSZip.prototype.crc32(this.uncompressedFileData) !== this.crc32) {
- throw new Error("Corrupted zip : CRC32 mismatch");
- }
- if (this.useUTF8()) {
- this.fileName = JSZip.prototype.utf8decode(this.fileName);
- }
- },
- findDataUntilDataDescriptor: function(reader) {
- var data = "", buffer = reader.readString(4), aByte;
- while (buffer !== JSZip.signature.DATA_DESCRIPTOR) {
- aByte = reader.readString(1);
- data += buffer.slice(0, 1);
- buffer = (buffer + aByte).slice(-4);
- }
- return data;
- },
- readCentralPart: function(reader) {
- this.versionMadeBy = reader.readString(2);
- this.readLocalPartHeader(reader);
- this.fileCommentLength = reader.readInt(2);
- this.diskNumberStart = reader.readInt(2);
- this.internalFileAttributes = reader.readInt(2);
- this.externalFileAttributes = reader.readInt(4);
- this.localHeaderOffset = reader.readInt(4);
- this.fileName = reader.readString(this.fileNameLength);
- this.readExtraFields(reader);
- this.fileComment = reader.readString(this.fileCommentLength);
- if (this.useUTF8()) {
- this.fileName = JSZip.prototype.utf8decode(this.fileName);
- this.fileComment = JSZip.prototype.utf8decode(this.fileComment);
- }
- this.dir = this.externalFileAttributes & 16 ? true : false;
- },
- parseZIP64ExtraField: function(reader) {
- var extraReader = new StreamReader(this.extraFields[1].value);
- if (this.uncompressedSize === -1) {
- this.uncompressedSize = extraReader.readInt(8);
- }
- if (this.compressedSize === -1) {
- this.compressedSize = extraReader.readInt(8);
- }
- if (this.localHeaderOffset === -1) {
- this.localHeaderOffset = extraReader.readInt(8);
- }
- if (this.diskNumberStart === -1) {
- this.diskNumberStart = extraReader.readInt(4);
- }
- },
- readExtraFields: function(reader) {
- var start = reader.index, extraFieldId, extraFieldLength, extraFieldValue;
- this.extraFields = this.extraFields || {};
- while (reader.index < start + this.extraFieldsLength) {
- extraFieldId = reader.readInt(2);
- extraFieldLength = reader.readInt(2);
- extraFieldValue = reader.readString(extraFieldLength);
- this.extraFields[extraFieldId] = {
- id: extraFieldId,
- length: extraFieldLength,
- value: extraFieldValue
- };
- }
- if (this.isZIP64() && this.extraFields[1]) {
- this.parseZIP64ExtraField(reader);
- }
- }
- };
- function ZipEntries(data, loadOptions) {
- this.files = [];
- this.loadOptions = loadOptions;
- if (data) {
- this.load(data);
- }
- }
- ZipEntries.prototype = {
- checkSignature: function(expectedSignature) {
- var signature = this.reader.readString(4);
- if (signature !== expectedSignature) {
- throw new Error("Corrupted zip or bug : unexpected signature " + "(" + pretty(signature) + ", expected " + pretty(expectedSignature) + ")");
- }
- },
- readBlockEndOfCentral: function() {
- this.diskNumber = this.reader.readInt(2);
- this.diskWithCentralDirStart = this.reader.readInt(2);
- this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
- this.centralDirRecords = this.reader.readInt(2);
- this.centralDirSize = this.reader.readInt(4);
- this.centralDirOffset = this.reader.readInt(4);
- this.zipCommentLength = this.reader.readInt(2);
- this.zipComment = this.reader.readString(this.zipCommentLength);
- },
- readBlockZip64EndOfCentral: function() {
- this.zip64EndOfCentralSize = this.reader.readInt(8);
- this.versionMadeBy = this.reader.readString(2);
- this.versionNeeded = this.reader.readInt(2);
- this.diskNumber = this.reader.readInt(4);
- this.diskWithCentralDirStart = this.reader.readInt(4);
- this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
- this.centralDirRecords = this.reader.readInt(8);
- this.centralDirSize = this.reader.readInt(8);
- this.centralDirOffset = this.reader.readInt(8);
- this.zip64ExtensibleData = {};
- var extraDataSize = this.zip64EndOfCentralSize - 44, index = 0, extraFieldId, extraFieldLength, extraFieldValue;
- while (index < extraDataSize) {
- extraFieldId = this.reader.readInt(2);
- extraFieldLength = this.reader.readInt(4);
- extraFieldValue = this.reader.readString(extraFieldLength);
- this.zip64ExtensibleData[extraFieldId] = {
- id: extraFieldId,
- length: extraFieldLength,
- value: extraFieldValue
- };
- }
- },
- readBlockZip64EndOfCentralLocator: function() {
- this.diskWithZip64CentralDirStart = this.reader.readInt(4);
- this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
- this.disksCount = this.reader.readInt(4);
- if (this.disksCount > 1) {
- throw new Error("Multi-volumes zip are not supported");
- }
- },
- readLocalFiles: function() {
- var i, file;
- for (i = 0; i < this.files.length; i++) {
- file = this.files[i];
- this.reader.setIndex(file.localHeaderOffset);
- this.checkSignature(JSZip.signature.LOCAL_FILE_HEADER);
- file.readLocalPart(this.reader);
- }
- },
- readCentralDir: function() {
- var file;
- this.reader.setIndex(this.centralDirOffset);
- while (this.reader.readString(4) === JSZip.signature.CENTRAL_FILE_HEADER) {
- file = new ZipEntry({
- zip64: this.zip64
- }, this.loadOptions);
- file.readCentralPart(this.reader);
- this.files.push(file);
- }
- },
- readEndOfCentral: function() {
- var offset = this.reader.stream.lastIndexOf(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
+ // class ZipEntries {{{
+ /**
+ * All the entries in the zip file.
+ * @constructor
+ * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary data to load.
+ * @param {Object} loadOptions Options for loading the data.
+ */
+ function ZipEntries(data, loadOptions) {
+ this.files = [];
+ this.loadOptions = loadOptions;
+ if (data) {
+ this.load(data);
+ }
+ }
+ ZipEntries.prototype = {
+ /**
+ * Check that the reader is on the speficied signature.
+ * @param {string} expectedSignature the expected signature.
+ * @throws {Error} if it is an other signature.
+ */
+ checkSignature : function(expectedSignature) {
+ var signature = this.reader.readString(4);
+ if (signature !== expectedSignature) {
+ throw new Error("Corrupted zip or bug : unexpected signature " +
+ "(" + pretty(signature) + ", expected " + pretty(expectedSignature) + ")");
+ }
+ },
+ /**
+ * Read the end of the central directory.
+ */
+ readBlockEndOfCentral : function () {
+ this.diskNumber = this.reader.readInt(2);
+ this.diskWithCentralDirStart = this.reader.readInt(2);
+ this.centralDirRecordsOnThisDisk = this.reader.readInt(2);
+ this.centralDirRecords = this.reader.readInt(2);
+ this.centralDirSize = this.reader.readInt(4);
+ this.centralDirOffset = this.reader.readInt(4);
+
+ this.zipCommentLength = this.reader.readInt(2);
+ this.zipComment = this.reader.readString(this.zipCommentLength);
+ },
+ /**
+ * Read the end of the Zip 64 central directory.
+ * Not merged with the method readEndOfCentral :
+ * The end of central can coexist with its Zip64 brother,
+ * I don't want to read the wrong number of bytes !
+ */
+ readBlockZip64EndOfCentral : function () {
+ this.zip64EndOfCentralSize = this.reader.readInt(8);
+ this.versionMadeBy = this.reader.readString(2);
+ this.versionNeeded = this.reader.readInt(2);
+ this.diskNumber = this.reader.readInt(4);
+ this.diskWithCentralDirStart = this.reader.readInt(4);
+ this.centralDirRecordsOnThisDisk = this.reader.readInt(8);
+ this.centralDirRecords = this.reader.readInt(8);
+ this.centralDirSize = this.reader.readInt(8);
+ this.centralDirOffset = this.reader.readInt(8);
+
+ this.zip64ExtensibleData = {};
+ var extraDataSize = this.zip64EndOfCentralSize - 44,
+ index = 0,
+ extraFieldId,
+ extraFieldLength,
+ extraFieldValue;
+ while(index < extraDataSize) {
+ extraFieldId = this.reader.readInt(2);
+ extraFieldLength = this.reader.readInt(4);
+ extraFieldValue = this.reader.readString(extraFieldLength);
+ this.zip64ExtensibleData[extraFieldId] = {
+ id: extraFieldId,
+ length: extraFieldLength,
+ value: extraFieldValue
+ };
+ }
+ },
+ /**
+ * Read the end of the Zip 64 central directory locator.
+ */
+ readBlockZip64EndOfCentralLocator : function () {
+ this.diskWithZip64CentralDirStart = this.reader.readInt(4);
+ this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8);
+ this.disksCount = this.reader.readInt(4);
+ if (this.disksCount > 1) {
+ throw new Error("Multi-volumes zip are not supported");
+ }
+ },
+ /**
+ * Read the local files, based on the offset read in the central part.
+ */
+ readLocalFiles : function() {
+ var i, file;
+ for(i = 0; i < this.files.length; i++) {
+ file = this.files[i];
+ this.reader.setIndex(file.localHeaderOffset);
+ this.checkSignature(JSZip.signature.LOCAL_FILE_HEADER);
+ file.readLocalPart(this.reader);
+ file.handleUTF8();
+ }
+ },
+ /**
+ * Read the central directory.
+ */
+ readCentralDir : function() {
+ var file;
+
+ this.reader.setIndex(this.centralDirOffset);
+ while(this.reader.readString(4) === JSZip.signature.CENTRAL_FILE_HEADER) {
+ file = new ZipEntry({
+ zip64: this.zip64
+ }, this.loadOptions);
+ file.readCentralPart(this.reader);
+ this.files.push(file);
+ }
+ },
+ /**
+ * Read the end of central directory.
+ */
+ readEndOfCentral : function() {
+ var offset = this.reader.lastIndexOfSignature(JSZip.signature.CENTRAL_DIRECTORY_END);
+ if (offset === -1) {
+ throw new Error("Corrupted zip : can't find end of central directory");
+ }
+ this.reader.setIndex(offset);
+ this.checkSignature(JSZip.signature.CENTRAL_DIRECTORY_END);
+ this.readBlockEndOfCentral();
+
+
+ /* extract from the zip spec :
+ 4) If one of the fields in the end of central directory
+ record is too small to hold required data, the field
+ should be set to -1 (0xFFFF or 0xFFFFFFFF) and the
+ ZIP64 format record should be created.
+ 5) The end of central directory record and the
+ Zip64 end of central directory locator record must
+ reside on the same disk when splitting or spanning
+ an archive.
+ */
+ if (this.diskNumber === MAX_VALUE_16BITS ||
+ this.diskWithCentralDirStart === MAX_VALUE_16BITS ||
+ this.centralDirRecordsOnThisDisk === MAX_VALUE_16BITS ||
+ this.centralDirRecords === MAX_VALUE_16BITS ||
+ this.centralDirSize === MAX_VALUE_32BITS ||
+ this.centralDirOffset === MAX_VALUE_32BITS
+ ) {
+ this.zip64 = true;
+
+ /*
+ Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from
+ the zip file can fit into a 32bits integer. This cannot be solved : Javascript represents
+ all numbers as 64-bit double precision IEEE 754 floating point numbers.
+ So, we have 53bits for integers and bitwise operations treat everything as 32bits.
+ see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
+ and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5
+ */
+
+ // should look for a zip64 EOCD locator
+ offset = this.reader.lastIndexOfSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
if (offset === -1) {
- this.zip64 = false;
- offset = this.reader.stream.lastIndexOf(JSZip.signature.CENTRAL_DIRECTORY_END);
- if (offset === -1) {
- throw new Error("Corrupted zip : can't find end of central directory");
- }
- this.reader.setIndex(offset);
- this.checkSignature(JSZip.signature.CENTRAL_DIRECTORY_END);
- this.readBlockEndOfCentral();
- } else {
- this.zip64 = true;
- this.reader.setIndex(offset);
- this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
- this.readBlockZip64EndOfCentralLocator();
- this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
- this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_END);
- this.readBlockZip64EndOfCentral();
+ throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");
}
- },
- load: function(data) {
- this.reader = new StreamReader(data);
- this.readEndOfCentral();
- this.readCentralDir();
- this.readLocalFiles();
- }
- };
- JSZip.prototype.load = function(data, options) {
- var files, zipEntries, i, input;
- options = options || {};
- if (options.base64) {
- data = JSZipBase64.decode(data);
- }
- zipEntries = new ZipEntries(data, options);
- files = zipEntries.files;
- for (i in files) {
- input = files[i];
- this.file(input.fileName, input.uncompressedFileData, {
- binary: true,
- date: input.date,
- dir: input.dir
- });
- }
- return this;
- };
-})();
+ this.reader.setIndex(offset);
+ this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_LOCATOR);
+ this.readBlockZip64EndOfCentralLocator();
+
+ // now the zip64 EOCD record
+ this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir);
+ this.checkSignature(JSZip.signature.ZIP64_CENTRAL_DIRECTORY_END);
+ this.readBlockZip64EndOfCentral();
+ }
+ },
+ prepareReader : function (data) {
+ var type = JSZip.utils.getTypeOf(data);
+ if (type === "string" && !JSZip.support.uint8array) {
+ this.reader = new StringReader(data, this.loadOptions.optimizedBinaryString);
+ } else if (type === "nodebuffer") {
+ this.reader = new NodeBufferReader(data);
+ } else {
+ this.reader = new Uint8ArrayReader(JSZip.utils.transformTo("uint8array", data));
+ }
+ },
+ /**
+ * Read a zip file and create ZipEntries.
+ * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file.
+ */
+ load : function(data) {
+ this.prepareReader(data);
+ this.readEndOfCentral();
+ this.readCentralDir();
+ this.readLocalFiles();
+ }
+ };
+ // }}} end of ZipEntries
+
+ /**
+ * Implementation of the load method of JSZip.
+ * It uses the above classes to decode a zip file, and load every files.
+ * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to load.
+ * @param {Object} options Options for loading the data.
+ * options.base64 : is the data in base64 ? default : false
+ */
+ JSZip.prototype.load = function(data, options) {
+ var files, zipEntries, i, input;
+ options = options || {};
+ if(options.base64) {
+ data = JSZip.base64.decode(data);
+ }
+
+ zipEntries = new ZipEntries(data, options);
+ files = zipEntries.files;
+ for (i = 0; i < files.length; i++) {
+ input = files[i];
+ this.file(input.fileName, input.decompressed, {
+ binary:true,
+ optimizedBinaryString:true,
+ date:input.date,
+ dir:input.dir
+ });
+ }
+
+ return this;
+ };
+
+}(this));
if (typeof exports !== 'undefined') exports.JSZip = JSZip;
+// enforcing Stuk's coding style
+// vim: set shiftwidth=3 softtabstop=3 foldmethod=marker:
diff --git a/package.json b/package.json
index 381c064..ca0a087 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "xlsx",
- "version": "0.3.1",
- "author": "Niggler",
+ "version": "0.3.2",
+ "author": "sheetjs",
"description": "(one day) a full-featured XLSX parser and writer. For now, primitive parser",
"keywords": [
"xlsx", "office", "excel", "spreadsheet"
@@ -20,14 +20,14 @@
},
"repository": {
"type":"git",
- "url": "git://github.com/Niggler/js-xlsx.git"
+ "url": "git://github.com/SheetJS/js-xlsx.git"
},
"scripts": {
"pretest": "git submodule init && git submodule update",
"test": "make mocha",
"test-jasmine": "jasmine-node --verbose tests/"
},
- "bugs": { "url": "https://github.com/Niggler/js-xlsx/issues" },
+ "bugs": { "url": "https://github.com/SheetJS/js-xlsx/issues" },
"license": "Apache-2.0",
"engines": { "node": ">=0.6" }
}
diff --git a/xlsx.js b/xlsx.js
index c05d6bb..f2fd59c 100644
--- a/xlsx.js
+++ b/xlsx.js
@@ -228,7 +228,7 @@ function parsexmltag(tag) {
var words = tag.split(/\s+/);
var z = {'0': words[0]};
if(words.length === 1) return z;
- tag.match(/(\w+)="([^"]*)"/g).map(
+ (tag.match(/(\w+)="([^"]*)"/g) || []).map(
function(x){var y=x.match(/(\w+)="([^"]*)"/); z[y[1]] = y[2]; });
return z;
}
@@ -279,7 +279,7 @@ function matchtag(f,g) {return new RegExp('<'+f+'(?: xml:space="preserve")?>([^\
function parseVector(data) {
var h = parsexmltag(data);
- var matches = data.match(new RegExp("(.*?)", 'g'));
+ var matches = data.match(new RegExp("(.*?)", 'g'))||[];
if(matches.length != h.size) throw "unexpected vector length " + matches.length + " != " + h.size;
var res = [];
matches.forEach(function(x) {
@@ -298,7 +298,7 @@ var parse_sst = (function(){
/* 18.4.7 rPr CT_RPrElt */
var parse_rpr = function(rpr, intro, outro) {
var font = {};
- rpr.match(/<[^>]*>/g).forEach(function(x) {
+ (rpr.match(/<[^>]*>/g)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
/* 18.8.12 condense CT_BooleanProperty */
@@ -422,7 +422,7 @@ var parse_sst = (function(){
var s = [];
/* 18.4.9 sst CT_Sst */
var sst = data.match(new RegExp("]*)>([\\s\\S]*)<\/sst>","m"));
- if(sst) {
+ if(isval(sst)) {
s = sst[2].replace(//g,"").split(/<\/si>/).map(parse_si);
sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
}
@@ -653,7 +653,7 @@ function parseProps(data) {
function parseDeps(data) {
var d = [];
var l = 0, i = 1;
- data.match(/<[^>]*>/g).forEach(function(x) {
+ (data.match(/<[^>]*>/g)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(y[0]) {
case '