commit b532159fb23e1a08309302fd7b9155a8d09fa07b Author: SheetJS Date: Mon Dec 3 14:47:44 2012 -0500 initial diff --git a/index.html b/index.html new file mode 100644 index 0000000..63418f4 --- /dev/null +++ b/index.html @@ -0,0 +1,168 @@ + + + + +JS-XLSX Live Demo + + + +JS-XLSX Live Demo
+Github Repo
+Issues? Something look weird? Click here and report an issue
+ CSV
+ JSON
+ FORMULAE
+ +
Drop an XLSX file here to see sheet data.
+ + +

+
+ + + + + + + diff --git a/jszip.js b/jszip.js new file mode 100644 index 0000000..3418fb7 --- /dev/null +++ b/jszip.js @@ -0,0 +1,2128 @@ +var JSZip = function(data, options) { + this.files = {}; + this.root = ""; + if (data) { + this.load(data, options); + } +}; + +JSZip.signature = { + LOCAL_FILE_HEADER: "PK", + CENTRAL_FILE_HEADER: "PK", + CENTRAL_DIRECTORY_END: "PK", + ZIP64_CENTRAL_DIRECTORY_LOCATOR: "PK", + ZIP64_CENTRAL_DIRECTORY_END: "PK", + DATA_DESCRIPTOR: "PK\b" +}; + +JSZip.defaults = { + base64: false, + binary: false, + dir: false, + date: null +}; + +JSZip.prototype = function() { + var ZipObject = function(name, data, options) { + this.name = name; + this.data = data; + this.options = options; + }; + ZipObject.prototype = { + asText: function() { + return this.options.binary ? JSZip.prototype.utf8decode(this.data) : this.data; + }, + asBinary: function() { + return this.options.binary ? this.data : JSZip.prototype.utf8encode(this.data); + } + }; + var decToHex = function(dec, bytes) { + var hex = "", i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 255); + dec = dec >>> 8; + } + return hex; + }; + var extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { + for (attr in arguments[i]) { + if (typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; + }; + var prepareFileAttrs = function(o) { + o = o || {}; + if (o.base64 === true && o.binary == null) { + o.binary = true; + } + o = extend(o, JSZip.defaults); + o.date = o.date || new Date(); + return o; + }; + var fileAdd = function(name, data, o) { + var parent = parentFolder(name); + if (parent) { + folderAdd.call(this, parent); + } + o = prepareFileAttrs(o); + return this.files[name] = { + name: name, + data: data, + options: o + }; + }; + var parentFolder = function(path) { + if (path.slice(-1) == "/") { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf("/"); + return lastSlash > 0 ? path.substring(0, lastSlash) : ""; + }; + var folderAdd = function(name) { + if (name.slice(-1) != "/") { + name += "/"; + } + if (!this.files[name]) { + var parent = parentFolder(name); + if (parent) { + folderAdd.call(this, parent); + } + fileAdd.call(this, name, "", { + dir: true + }); + } + return this.files[name]; + }; + var prepareLocalHeaderData = function(file, utfEncodedFileName, compressionType) { + var useUTF8 = utfEncodedFileName !== file.name, data = file.data, o = file.options, dosTime, dosDate; + dosTime = o.date.getHours(); + dosTime = dosTime << 6; + dosTime = dosTime | o.date.getMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | o.date.getSeconds() / 2; + dosDate = o.date.getFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | o.date.getMonth() + 1; + dosDate = dosDate << 5; + dosDate = dosDate | o.date.getDate(); + if (o.base64 === true) { + data = JSZipBase64.decode(data); + } + if (o.binary === false) { + data = this.utf8encode(data); + } + var compression = JSZip.compressions[compressionType]; + var compressedData = compression.compress(data); + var header = ""; + header += "\n\0"; + header += useUTF8 ? "\0\b" : "\0\0"; + header += compression.magic; + header += decToHex(dosTime, 2); + header += decToHex(dosDate, 2); + header += decToHex(this.crc32(data), 4); + header += decToHex(compressedData.length, 4); + header += decToHex(data.length, 4); + header += decToHex(utfEncodedFileName.length, 2); + header += "\0\0"; + return { + header: header, + compressedData: compressedData + }; + }; + return { + load: function(stream, options) { + throw new Error("Load method is not defined. Is the file jszip-load.js included ?"); + }, + filter: function(search) { + var result = [], filename, relativePath, file, fileClone; + for (filename in this.files) { + file = this.files[filename]; + fileClone = new ZipObject(file.name, file.data, extend(file.options)); + relativePath = filename.slice(this.root.length, filename.length); + if (filename.slice(0, this.root.length) === this.root && search(relativePath, fileClone)) { + result.push(fileClone); + } + } + return result; + }, + file: function(name, data, o) { + if (arguments.length === 1) { + if (name instanceof RegExp) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.options.dir && regexp.test(relativePath); + }); + } else { + return this.filter(function(relativePath, file) { + return !file.options.dir && relativePath === name; + })[0] || null; + } + } else { + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + folder: function(arg) { + if (!arg) { + throw new Error("folder : wrong argument"); + } + if (arg instanceof RegExp) { + return this.filter(function(relativePath, file) { + return file.options.dir && arg.test(relativePath); + }); + } + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + if (name.slice(-1) != "/") { + name += "/"; + } + file = this.files[name]; + } + if (file) { + if (!file.options.dir) { + delete this.files[name]; + } else { + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + } + return this; + }, + generate: function(options) { + options = extend(options || {}, { + base64: true, + compression: "STORE" + }); + var compression = options.compression.toUpperCase(); + var directory = [], files = [], fileOffset = 0; + if (!JSZip.compressions[compression]) { + throw compression + " is not a valid compression method !"; + } + for (var name in this.files) { + if (!this.files.hasOwnProperty(name)) { + continue; + } + var file = this.files[name]; + var utfEncodedFileName = this.utf8encode(file.name); + var fileRecord = "", dirRecord = "", data = prepareLocalHeaderData.call(this, file, utfEncodedFileName, compression); + fileRecord = JSZip.signature.LOCAL_FILE_HEADER + data.header + utfEncodedFileName + data.compressedData; + dirRecord = JSZip.signature.CENTRAL_FILE_HEADER + "\0" + data.header + "\0\0" + "\0\0" + "\0\0" + (this.files[name].dir === true ? "\0\0\0" : "\0\0\0\0") + decToHex(fileOffset, 4) + utfEncodedFileName; + fileOffset += fileRecord.length; + files.push(fileRecord); + directory.push(dirRecord); + } + var fileData = files.join(""); + var dirData = directory.join(""); + var dirEnd = ""; + dirEnd = JSZip.signature.CENTRAL_DIRECTORY_END + "\0\0" + "\0\0" + decToHex(files.length, 2) + decToHex(files.length, 2) + decToHex(dirData.length, 4) + decToHex(fileData.length, 4) + "\0\0"; + var zip = fileData + dirData + dirEnd; + return options.base64 ? JSZipBase64.encode(zip) : zip; + }, + crc32: function(str, crc) { + if (str === "" || typeof str === "undefined") { + return 0; + } + var table = [ 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035, 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049, 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639, 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317, 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443, 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665, 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303, 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565, 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059, 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297, 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223, 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405, 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995, 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649, 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015, 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989, 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523, 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377, 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879, 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637, 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859, 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161, 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815, 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221, 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371, 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881, 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567, 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701, 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035, 2932959818, 3654703836, 1088359270, 936918e3, 2847714899, 3736837829, 1202900863, 817233897, 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431, 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117 ]; + if (typeof crc == "undefined") { + crc = 0; + } + var x = 0; + var y = 0; + crc = crc ^ -1; + for (var i = 0, iTop = str.length; i < iTop; i++) { + y = (crc ^ str.charCodeAt(i)) & 255; + x = table[y]; + crc = crc >>> 8 ^ x; + } + return crc ^ -1; + }, + clone: function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }, + utf8encode: function(string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } else if (c > 127 && c < 2048) { + utftext += String.fromCharCode(c >> 6 | 192); + utftext += String.fromCharCode(c & 63 | 128); + } else { + utftext += String.fromCharCode(c >> 12 | 224); + utftext += String.fromCharCode(c >> 6 & 63 | 128); + utftext += String.fromCharCode(c & 63 | 128); + } + } + return utftext; + }, + utf8decode: function(utftext) { + var string = ""; + var i = 0; + var c = 0, c1 = 0, c2 = 0, c3 = 0; + while (i < utftext.length) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } else if (c > 191 && c < 224) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode((c & 31) << 6 | c2 & 63); + i += 2; + } else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63); + i += 3; + } + } + return string; + } + }; +}(); + +JSZip.compressions = { + STORE: { + magic: "\0\0", + compress: function(content) { + return content; + }, + uncompress: function(content) { + return content; + } + } +}; + +var JSZipBase64 = function() { + var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + return { + encode: function(input, utf8) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = (chr1 & 3) << 4 | chr2 >> 4; + enc3 = (chr2 & 15) << 2 | chr3 >> 6; + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4); + } + return output; + }, + decode: function(input, utf8) { + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + while (i < input.length) { + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + chr1 = enc1 << 2 | enc2 >> 4; + chr2 = (enc2 & 15) << 4 | enc3 >> 2; + chr3 = (enc3 & 3) << 6 | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + } + return output; + } + }; +}(); + +if (!JSZip) { + throw "JSZip not defined"; +} + +(function() { + var zip_WSIZE = 32768; + var zip_STORED_BLOCK = 0; + var zip_STATIC_TREES = 1; + var zip_DYN_TREES = 2; + var zip_DEFAULT_LEVEL = 6; + var zip_FULL_SEARCH = true; + var zip_INBUFSIZ = 32768; + var zip_INBUF_EXTRA = 64; + var zip_OUTBUFSIZ = 1024 * 8; + var zip_window_size = 2 * zip_WSIZE; + var zip_MIN_MATCH = 3; + var zip_MAX_MATCH = 258; + var zip_BITS = 16; + var zip_LIT_BUFSIZE = 8192; + var zip_HASH_BITS = 13; + if (zip_LIT_BUFSIZE > zip_INBUFSIZ) alert("error: zip_INBUFSIZ is too small"); + if (zip_WSIZE << 1 > 1 << zip_BITS) alert("error: zip_WSIZE is too large"); + if (zip_HASH_BITS > zip_BITS - 1) alert("error: zip_HASH_BITS is too large"); + if (zip_HASH_BITS < 8 || zip_MAX_MATCH != 258) alert("error: Code too clever"); + var zip_DIST_BUFSIZE = zip_LIT_BUFSIZE; + var zip_HASH_SIZE = 1 << zip_HASH_BITS; + var zip_HASH_MASK = zip_HASH_SIZE - 1; + var zip_WMASK = zip_WSIZE - 1; + var zip_NIL = 0; + var zip_TOO_FAR = 4096; + var zip_MIN_LOOKAHEAD = zip_MAX_MATCH + zip_MIN_MATCH + 1; + var zip_MAX_DIST = zip_WSIZE - zip_MIN_LOOKAHEAD; + var zip_SMALLEST = 1; + var zip_MAX_BITS = 15; + var zip_MAX_BL_BITS = 7; + var zip_LENGTH_CODES = 29; + var zip_LITERALS = 256; + var zip_END_BLOCK = 256; + var zip_L_CODES = zip_LITERALS + 1 + zip_LENGTH_CODES; + var zip_D_CODES = 30; + var zip_BL_CODES = 19; + var zip_REP_3_6 = 16; + var zip_REPZ_3_10 = 17; + var zip_REPZ_11_138 = 18; + var zip_HEAP_SIZE = 2 * zip_L_CODES + 1; + var zip_H_SHIFT = parseInt((zip_HASH_BITS + zip_MIN_MATCH - 1) / zip_MIN_MATCH); + var zip_free_queue; + var zip_qhead, zip_qtail; + var zip_initflag; + var zip_outbuf = null; + var zip_outcnt, zip_outoff; + var zip_complete; + var zip_window; + var zip_d_buf; + var zip_l_buf; + var zip_prev; + var zip_bi_buf; + var zip_bi_valid; + var zip_block_start; + var zip_ins_h; + var zip_hash_head; + var zip_prev_match; + var zip_match_available; + var zip_match_length; + var zip_prev_length; + var zip_strstart; + var zip_match_start; + var zip_eofile; + var zip_lookahead; + var zip_max_chain_length; + var zip_max_lazy_match; + var zip_compr_level; + var zip_good_match; + var zip_nice_match; + var zip_dyn_ltree; + var zip_dyn_dtree; + var zip_static_ltree; + var zip_static_dtree; + var zip_bl_tree; + var zip_l_desc; + var zip_d_desc; + var zip_bl_desc; + var zip_bl_count; + var zip_heap; + var zip_heap_len; + var zip_heap_max; + var zip_depth; + var zip_length_code; + var zip_dist_code; + var zip_base_length; + var zip_base_dist; + var zip_flag_buf; + var zip_last_lit; + var zip_last_dist; + var zip_last_flags; + var zip_flags; + var zip_flag_bit; + var zip_opt_len; + var zip_static_len; + var zip_deflate_data; + var zip_deflate_pos; + var zip_DeflateCT = function() { + this.fc = 0; + this.dl = 0; + }; + var zip_DeflateTreeDesc = function() { + this.dyn_tree = null; + this.static_tree = null; + this.extra_bits = null; + this.extra_base = 0; + this.elems = 0; + this.max_length = 0; + this.max_code = 0; + }; + var zip_DeflateConfiguration = function(a, b, c, d) { + this.good_length = a; + this.max_lazy = b; + this.nice_length = c; + this.max_chain = d; + }; + var zip_DeflateBuffer = function() { + this.next = null; + this.len = 0; + this.ptr = new Array(zip_OUTBUFSIZ); + this.off = 0; + }; + var zip_extra_lbits = 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); + var zip_extra_dbits = 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_extra_blbits = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7); + var zip_bl_order = new Array(16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15); + var zip_configuration_table = new Array(new zip_DeflateConfiguration(0, 0, 0, 0), new zip_DeflateConfiguration(4, 4, 8, 4), new zip_DeflateConfiguration(4, 5, 16, 8), new zip_DeflateConfiguration(4, 6, 32, 32), new zip_DeflateConfiguration(4, 4, 16, 16), new zip_DeflateConfiguration(8, 16, 32, 32), new zip_DeflateConfiguration(8, 16, 128, 128), new zip_DeflateConfiguration(8, 32, 128, 256), new zip_DeflateConfiguration(32, 128, 258, 1024), new zip_DeflateConfiguration(32, 258, 258, 4096)); + var zip_deflate_start = function(level) { + var i; + if (!level) level = zip_DEFAULT_LEVEL; else if (level < 1) level = 1; else if (level > 9) level = 9; + zip_compr_level = level; + zip_initflag = false; + zip_eofile = false; + if (zip_outbuf != null) return; + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = new Array(zip_OUTBUFSIZ); + zip_window = new Array(zip_window_size); + zip_d_buf = new Array(zip_DIST_BUFSIZE); + zip_l_buf = new Array(zip_INBUFSIZ + zip_INBUF_EXTRA); + zip_prev = new Array(1 << zip_BITS); + zip_dyn_ltree = new Array(zip_HEAP_SIZE); + for (i = 0; i < zip_HEAP_SIZE; i++) zip_dyn_ltree[i] = new zip_DeflateCT(); + zip_dyn_dtree = new Array(2 * zip_D_CODES + 1); + for (i = 0; i < 2 * zip_D_CODES + 1; i++) zip_dyn_dtree[i] = new zip_DeflateCT(); + zip_static_ltree = new Array(zip_L_CODES + 2); + for (i = 0; i < zip_L_CODES + 2; i++) zip_static_ltree[i] = new zip_DeflateCT(); + zip_static_dtree = new Array(zip_D_CODES); + for (i = 0; i < zip_D_CODES; i++) zip_static_dtree[i] = new zip_DeflateCT(); + zip_bl_tree = new Array(2 * zip_BL_CODES + 1); + for (i = 0; i < 2 * zip_BL_CODES + 1; i++) zip_bl_tree[i] = new zip_DeflateCT(); + zip_l_desc = new zip_DeflateTreeDesc(); + zip_d_desc = new zip_DeflateTreeDesc(); + zip_bl_desc = new zip_DeflateTreeDesc(); + zip_bl_count = new Array(zip_MAX_BITS + 1); + zip_heap = new Array(2 * zip_L_CODES + 1); + zip_depth = new Array(2 * zip_L_CODES + 1); + zip_length_code = new Array(zip_MAX_MATCH - zip_MIN_MATCH + 1); + zip_dist_code = new Array(512); + zip_base_length = new Array(zip_LENGTH_CODES); + zip_base_dist = new Array(zip_D_CODES); + zip_flag_buf = new Array(parseInt(zip_LIT_BUFSIZE / 8)); + }; + var zip_deflate_end = function() { + zip_free_queue = zip_qhead = zip_qtail = null; + zip_outbuf = null; + zip_window = null; + zip_d_buf = null; + zip_l_buf = null; + zip_prev = null; + zip_dyn_ltree = null; + zip_dyn_dtree = null; + zip_static_ltree = null; + zip_static_dtree = null; + zip_bl_tree = null; + zip_l_desc = null; + zip_d_desc = null; + zip_bl_desc = null; + zip_bl_count = null; + zip_heap = null; + zip_depth = null; + zip_length_code = null; + zip_dist_code = null; + zip_base_length = null; + zip_base_dist = null; + zip_flag_buf = null; + }; + var zip_reuse_queue = function(p) { + p.next = zip_free_queue; + zip_free_queue = p; + }; + var zip_new_queue = function() { + var p; + if (zip_free_queue != null) { + p = zip_free_queue; + zip_free_queue = zip_free_queue.next; + } else p = new zip_DeflateBuffer(); + p.next = null; + p.len = p.off = 0; + return p; + }; + var zip_head1 = function(i) { + return zip_prev[zip_WSIZE + i]; + }; + var zip_head2 = function(i, val) { + return zip_prev[zip_WSIZE + i] = val; + }; + var zip_put_byte = function(c) { + zip_outbuf[zip_outoff + zip_outcnt++] = c; + if (zip_outoff + zip_outcnt == zip_OUTBUFSIZ) zip_qoutbuf(); + }; + var zip_put_short = function(w) { + w &= 65535; + if (zip_outoff + zip_outcnt < zip_OUTBUFSIZ - 2) { + zip_outbuf[zip_outoff + zip_outcnt++] = w & 255; + zip_outbuf[zip_outoff + zip_outcnt++] = w >>> 8; + } else { + zip_put_byte(w & 255); + zip_put_byte(w >>> 8); + } + }; + var zip_INSERT_STRING = function() { + zip_ins_h = (zip_ins_h << zip_H_SHIFT ^ zip_window[zip_strstart + zip_MIN_MATCH - 1] & 255) & zip_HASH_MASK; + zip_hash_head = zip_head1(zip_ins_h); + zip_prev[zip_strstart & zip_WMASK] = zip_hash_head; + zip_head2(zip_ins_h, zip_strstart); + }; + var zip_SEND_CODE = function(c, tree) { + zip_send_bits(tree[c].fc, tree[c].dl); + }; + var zip_D_CODE = function(dist) { + return (dist < 256 ? zip_dist_code[dist] : zip_dist_code[256 + (dist >> 7)]) & 255; + }; + var zip_SMALLER = function(tree, n, m) { + return tree[n].fc < tree[m].fc || tree[n].fc == tree[m].fc && zip_depth[n] <= zip_depth[m]; + }; + var zip_read_buff = function(buff, offset, n) { + var i; + for (i = 0; i < n && zip_deflate_pos < zip_deflate_data.length; i++) buff[offset + i] = zip_deflate_data.charCodeAt(zip_deflate_pos++) & 255; + return i; + }; + var zip_lm_init = function() { + var j; + for (j = 0; j < zip_HASH_SIZE; j++) zip_prev[zip_WSIZE + j] = 0; + zip_max_lazy_match = zip_configuration_table[zip_compr_level].max_lazy; + zip_good_match = zip_configuration_table[zip_compr_level].good_length; + if (!zip_FULL_SEARCH) zip_nice_match = zip_configuration_table[zip_compr_level].nice_length; + zip_max_chain_length = zip_configuration_table[zip_compr_level].max_chain; + zip_strstart = 0; + zip_block_start = 0; + zip_lookahead = zip_read_buff(zip_window, 0, 2 * zip_WSIZE); + if (zip_lookahead <= 0) { + zip_eofile = true; + zip_lookahead = 0; + 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"; +} + +(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; + + 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; + + 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; + + 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; + } +})(); + +(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); + 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(); + } + }, + 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; + }; +})(); +if (typeof exports !== 'undefined') exports.JSZip = JSZip; diff --git a/shim.js b/shim.js new file mode 100644 index 0000000..93264f4 --- /dev/null +++ b/shim.js @@ -0,0 +1,145 @@ +if (!Object.keys) { + Object.keys = (function () { + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length; + + return function (obj) { + if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object'); + + var result = []; + + for (var prop in obj) { + if (hasOwnProperty.call(obj, prop)) result.push(prop); + } + + if (hasDontEnumBug) { + for (var i=0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]); + } + } + return result; + }; + })(); +} + +if (!Array.prototype.filter) +{ + Array.prototype.filter = function(fun /*, thisp */) + { + "use strict"; + + if (this == null) + throw new TypeError(); + + var t = Object(this); + var len = t.length >>> 0; + if (typeof fun != "function") + throw new TypeError(); + + var res = []; + var thisp = arguments[1]; + for (var i = 0; i < len; i++) + { + if (i in t) + { + var val = t[i]; // in case fun mutates this + if (fun.call(thisp, val, i, t)) + res.push(val); + } + } + + return res; + }; +} + +if ( !Array.prototype.forEach ) { + Array.prototype.forEach = function(fn, scope) { + for(var i = 0, len = this.length; i < len; ++i) { + fn.call(scope, this[i], i, this); + } + }; +} + +// Production steps of ECMA-262, Edition 5, 15.4.4.19 +// Reference: http://es5.github.com/#x15.4.4.19 +if (!Array.prototype.map) { + Array.prototype.map = function(callback, thisArg) { + + var T, A, k; + + if (this == null) { + throw new TypeError(" this is null or not defined"); + } + + // 1. Let O be the result of calling ToObject passing the |this| value as the argument. + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if (typeof callback !== "function") { + throw new TypeError(callback + " is not a function"); + } + + // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (thisArg) { + T = thisArg; + } + + // 6. Let A be a new array created as if by the expression new Array(len) where Array is + // the standard built-in constructor with that name and len is the value of len. + A = new Array(len); + + // 7. Let k be 0 + k = 0; + + // 8. Repeat, while k < len + while(k < len) { + + var kValue, mappedValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if (k in O) { + + // i. Let kValue be the result of calling the Get internal method of O with argument Pk. + kValue = O[ k ]; + + // ii. Let mappedValue be the result of calling the Call internal method of callback + // with T as the this value and argument list containing kValue, k, and O. + mappedValue = callback.call(T, kValue, k, O); + + // iii. Call the DefineOwnProperty internal method of A with arguments + // Pk, Property Descriptor {Value: mappedValue, : true, Enumerable: true, Configurable: true}, + // and false. + + // In browsers that support Object.defineProperty, use the following: + // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); + + // For best browser support, use the following: + A[ k ] = mappedValue; + } + // d. Increase k by 1. + k++; + } + + // 9. return A + return A; + }; +} diff --git a/xlsx.js b/xlsx.js new file mode 100644 index 0000000..5134635 --- /dev/null +++ b/xlsx.js @@ -0,0 +1,1112 @@ +/* xlsx.js (C) 2013 SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*jshint eqnull:true */ +/* Spreadsheet Format -- jump to XLSX for the XLSX code */ +if(typeof require !== "undefined") SSF = require('ssf'); +var SSF = (function() { + var SSF = {}; +String.prototype.reverse=function(){return this.split("").reverse().join("");}; +var _strrev = function(x) { return String(x).reverse(); }; +function fill(c,l) { return new Array(l+1).join(c); } +function pad(v,d){var t=String(v);return t.length>=d?t:(fill(0,d-t.length)+t);} +/* Options */ +var opts_fmt = {}; +function fixopts(o){for(var y in opts_fmt) if(o[y]===undefined) o[y]=opts_fmt[y];} +SSF.opts = opts_fmt; +opts_fmt.date1904 = 0; +opts_fmt.output = ""; +opts_fmt.mode = ""; +var table_fmt = { + 1: '0', + 2: '0.00', + 3: '#,##0', + 4: '#,##0.00', + 9: '0%', + 10: '0.00%', + 11: '0.00E+00', + 12: '# ?/?', + 13: '# ??/??', + 14: 'mm/dd/yy', + 15: 'd-mmm-yy', + 16: 'd-mmm', + 17: 'mmm-yy', + 18: 'h:mm AM/PM', + 19: 'h:mm:ss AM/PM', + 20: 'h:mm', + 21: 'h:mm:ss', + 22: 'm/d/yy h:mm', + 37: '#,##0 ;(#,##0)', + 38: '#,##0 ;[Red](#,##0)', + 39: '#,##0.00;(#,##0.00)', + 40: '#,##0.00;[Red](#,##0.00)', + 45: 'mm:ss', + 46: '[h]:mm:ss', + 47: 'mmss.0', + 48: '##0.0E+0', + 49: '@' +}; +var days = [ + ['Sun', 'Sunday'], + ['Mon', 'Monday'], + ['Tue', 'Tuesday'], + ['Wed', 'Wednesday'], + ['Thu', 'Thursday'], + ['Fri', 'Friday'], + ['Sat', 'Saturday'] +]; +var months = [ + ['J', 'Jan', 'January'], + ['F', 'Feb', 'February'], + ['M', 'Mar', 'March'], + ['A', 'Apr', 'April'], + ['M', 'May', 'May'], + ['J', 'Jun', 'June'], + ['J', 'Jul', 'July'], + ['A', 'Aug', 'August'], + ['S', 'Sep', 'September'], + ['O', 'Oct', 'October'], + ['N', 'Nov', 'November'], + ['D', 'Dec', 'December'] +]; +var general_fmt = function(v) { + if(typeof v === 'boolean') return v ? "TRUE" : "FALSE"; +}; +SSF._general = general_fmt; +var parse_date_code = function parse_date_code(v,opts) { + var date = Math.floor(v), time = Math.round(86400 * (v - date)), dow=0; + var dout=[], out={D:date, T:time}; fixopts(opts = (opts||{})); + if(opts.date1904) date += 1462; + if(date === 60) {dout = [1900,2,29]; dow=3;} + else { + if(date > 60) --date; + /* 1 = Jan 1 1900 */ + var d = new Date(1900,0,1); + d.setDate(d.getDate() + date - 1); + dout = [d.getFullYear(), d.getMonth()+1,d.getDate()]; + dow = d.getDay(); + if(opts.mode === 'excel' && date < 60) dow = (dow + 6) % 7; + } + out.y = dout[0]; out.m = dout[1]; out.d = dout[2]; + out.S = time % 60; time = Math.floor(time / 60); + out.M = time % 60; time = Math.floor(time / 60); + out.H = time; + out.q = dow; + return out; +}; +SSF.parse_date_code = parse_date_code; +var write_date = function(type, fmt, val) { + switch(type) { + case 'y': switch(fmt) { /* year */ + case 'y': case 'yy': return pad(val.y % 100,2); + default: return val.y; + } break; + case 'm': switch(fmt) { /* month */ + case 'm': return val.m; + case 'mm': return pad(val.m,2); + case 'mmm': return months[val.m-1][1]; + case 'mmmm': return months[val.m-1][2]; + case 'mmmmm': return months[val.m-1][0]; + default: throw 'bad month format: ' + fmt; + } break; + case 'd': switch(fmt) { /* day */ + case 'd': return val.d; + case 'dd': return pad(val.d,2); + case 'ddd': return days[val.q][0]; + case 'dddd': return days[val.q][1]; + default: throw 'bad day format: ' + fmt; + } break; + case 'h': switch(fmt) { /* 12-hour */ + case 'h': return 1+(val.H+11)%12; + case 'hh': return pad(1+(val.H+11)%12, 2); + default: throw 'bad hour format: ' + fmt; + } break; + case 'H': switch(fmt) { /* 24-hour */ + case 'h': return val.H; + case 'hh': return pad(val.H, 2); + default: throw 'bad hour format: ' + fmt; + } break; + case 'M': switch(fmt) { /* minutes */ + case 'm': return val.M; + case 'mm': return pad(val.M, 2); + default: throw 'bad minute format: ' + fmt; + } break; + case 's': switch(fmt) { /* seconds */ + case 's': return val.S; + case 'ss': return pad(val.S, 2); + default: throw 'bad second format: ' + fmt; + } break; + /* TODO: handle the ECMA spec format ee -> yy */ + case 'e': { return val.y; } break; + case 'A': return (val.h>=12 ? 'P' : 'A') + fmt.substr(1); + default: throw 'bad format type ' + type + ' in ' + fmt; + } +}; +function split_fmt(fmt) { + return fmt.reverse().split(/;(?!\\)/).reverse().map(_strrev); +} +SSF._split = split_fmt; +function eval_fmt(fmt, v, opts) { + var out = [], o = "", i = 0, c = "", lst='t', q = {}, dt; + fixopts(opts = (opts || {})); + var hr='H'; + /* Tokenize */ + while(i < fmt.length) { + switch((c = fmt[i])) { + case '"': /* Literal text */ + for(o="";fmt[++i] !== '"';) o += fmt[(fmt[i] === '\\' ? ++i : i)]; + out.push({t:'t', v:o}); break; + case '\\': out.push({t:'t', v:fmt[++i]}); ++i; break; + case '@': /* Text Placeholder */ + out.push({t:'T', v:v}); ++i; break; + /* Dates */ + case 'm': case 'd': case 'y': case 'h': case 's': case 'e': + if(!dt) dt = parse_date_code(v, opts); + o = fmt[i]; while(fmt[++i] === c) o+=c; + if(c === 'm' && lst.toLowerCase() === 'h') c = 'M'; /* m = minute */ + if(c === 'h') c = hr; + q={t:c, v:o}; out.push(q); lst = c; break; + case 'A': + if(!dt) dt = parse_date_code(v, opts); + q={t:c,v:"A"}; + if(fmt.substr(i, 3) === "A/P") {q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} + else if(fmt.substr(i,5) === "AM/PM") { q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } + else q.t = "t"; + out.push(q); lst = c; break; + case '[': /* TODO: Fix this -- ignore all conditionals and formatting */ + while(fmt[i++] !== ']'); break; + default: + if("$-+/():!^&'~{}<>= ".indexOf(c) === -1) + throw 'unrecognized character ' + fmt[i] + ' in ' + fmt; + out.push({t:'t', v:c}); ++i; break; + } + } + /* walk backwards */ + for(i=out.length-1, lst='t'; i >= 0; --i) { + switch(out[i].t) { + case 'h': case 'H': out[i].t = hr; lst='h'; break; + case 'd': case 'y': case 's': case 'M': case 'e': lst=out[i].t; break; + case 'm': if(lst === 's') out[i].t = 'M'; break; + } + } + + /* replace fields */ + for(i=0; i < out.length; ++i) { + switch(out[i].t) { + case 't': case 'T': break; + case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'A': case 'e': + out[i].v = write_date(out[i].t, out[i].v, dt); + out[i].t = 't'; break; + default: throw "unrecognized type " + out[i].t; + } + } + + return out.map(function(x){return x.v;}).join(""); +} +SSF._eval = eval_fmt; +function choose_fmt(fmt, v) { + if(typeof fmt === "string") fmt = split_fmt(fmt); + if(typeof v !== "number") return fmt[3]; + return v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2]; +} + +var format = function format(fmt,v,o) { + fixopts(o = (o||{})); + if(fmt === 0) return general_fmt(v, o); + if(typeof fmt === 'number') fmt = table_fmt[fmt]; + var f = choose_fmt(fmt, v, o); + return eval_fmt(f, v, o); +}; + +SSF._choose = choose_fmt; +SSF._table = table_fmt; +SSF.load = function(fmt, idx) { table_fmt[idx] = fmt; }; +SSF.format = format; + return SSF; +})(); +var XLSX = {}; +(function(XLSX){ +function parsexmltag(tag) { + var words = tag.split(/\s+/); + var z = {'0': words[0]}; + if(words.length === 1) return z; + (tag.match(/(\w+)="([^"]*)"/g) || []).map( + function(x){var y=x.match(/(\w+)="([^"]*)"/); z[y[1]] = y[2]; }); + return z; +} + +var encodings = { + '"': '"', + ''': "'", + '>': '>', + '<': '<', + '&': '&' +}; + +// TODO: CP remap (need to read file version to determine OS) +function unescapexml(text){ + var s = text + ''; + for(var y in encodings) s = s.replace(new RegExp(y,'g'), encodings[y]); + return s.replace(/_x([0-9a-fA-F]*)_/g,function(m,c) {return _chr(parseInt(c,16));}); +} + +function parsexmlbool(value, tag) { + switch(value) { + case '0': case 0: case 'false': case 'FALSE': return false; + case '1': case 1: case 'true': case 'TRUE': return true; + default: throw "bad boolean value " + value + " in "+(tag||"?"); + } +} + +var utf8read = function(orig) { + var out = "", i = 0, c = 0, c1 = 0, c2 = 0, c3 = 0; + while (i < orig.length) { + c = orig.charCodeAt(i++); + if (c < 128) out += _chr(c); + else { + c2 = orig.charCodeAt(i++); + if (c>191 && c<224) out += _chr((c & 31) << 6 | c2 & 63); + else { + c3 = orig.charCodeAt(i++); + out += _chr((c & 15) << 12 | (c2 & 63) << 6 | c3 & 63); + } + } + } + return out; +}; + +// matches ... extracts content +function matchtag(f,g) {return new RegExp('<'+f+'(?: xml:space="preserve")?>([^\u2603]*)',(g||"")+"m");} + +function parseVector(data) { + var h = parsexmltag(data); + + 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) { + var v = x.replace(/<[/]?vt:variant>/g,"").match(/]*)>(.*) tags */ + var parse_rs = (function() { + /* 18.4.7 rPr CT_RPrElt */ + var parse_rpr = function(rpr, intro, outro) { + var font = {}; + (rpr.match(/<[^>]*>/g)||[]).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + /* 18.8.12 condense CT_BooleanProperty */ + /* ** not required . */ + case '': font.strike = 1; break; + case '': break; + + /* 18.4.13 u CT_UnderlineProperty */ + case '': font.u = 1; break; + case '': break; + + /* 18.8.2 b */ + case '': font.b = 1; break; + case '': break; + + /* 18.8.26 i */ + case '': font.i = 1; break; + case '': break; + + /* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */ + case ''); + outro.push(""); + }; + + /* 18.4.4 r CT_RElt */ + function parse_r(r) { + var terms = [[],"",[]]; + /* 18.4.12 t ST_Xstring */ + var t = r.match(tregex); + if(!isval(t)) return ""; + terms[1] = t[1]; + + var rpr = r.match(rpregex); + if(isval(rpr)) parse_rpr(rpr[1], terms[0], terms[2]); + return terms[0].join("") + terms[1].replace(/\r\n/g,'
') + terms[2].join(""); + } + return function(rs) { + return rs.replace(//g,"").split(/<\/r>/).map(parse_r).join(""); + }; + })(); + + /* 18.4.8 si CT_Rst */ + var parse_si = function(x) { + var z = {}; + if(!x) return z; + var y; + /* 18.4.12 t ST_Xstring (Plaintext String) */ + if(x[1] === 't') { + z.t = utf8read(unescapexml(x.replace(/<[^>]*>/g,""))); + z.raw = x; + z.r = z.t; + } + /* 18.4.4 r CT_RElt (Rich Text Run) */ + else if((y = x.match(//))) { + z.raw = x; + /* TODO: properly parse (note: no other valid child can have body text) */ + z.t = utf8read(unescapexml(x.replace(/<[^>]*>/gm,""))); + z.r = parse_rs(x); + } + /* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */ + /* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */ + return z; + }; + + + return function(data) { + var s = []; + /* 18.4.9 sst CT_Sst */ + var sst = data.match(new RegExp("]*)>([\\s\\S]*)<\/sst>","m")); + 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; + } + return s; + }; +})(); + +var ct2type = { + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks", + "application/vnd.openxmlformats-package.core-properties+xml": "coreprops", + "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops", + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains", + "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":"sheets", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml": "strs", + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":"styles", + "application/vnd.openxmlformats-officedocument.theme+xml":"themes", + "foo": "bar" +}; + +/* 18.2.28 (CT_WorkbookProtection) Defaults */ +var WBPropsDef = { + allowRefreshQuery: '0', + autoCompressPictures: '1', + backupFile: '0', + checkCompatibility: '0', + codeName: '', + date1904: '0', + dateCompatibility: '1', + //defaultThemeVersion: '0', + filterPrivacy: '0', + hidePivotFieldList: '0', + promptedSolutions: '0', + publishItems: '0', + refreshAllConnections: false, + saveExternalLinkValues: '1', + showBorderUnselectedTables: '1', + showInkAnnotation: '1', + showObjects: 'all', + showPivotChartFilter: '0' + //updateLinks: 'userSet' +}; + +/* 18.2.30 (CT_BookView) Defaults */ +var WBViewDef = { + activeTab: '0', + autoFilterDateGrouping: '1', + firstSheet: '0', + minimized: '0', + showHorizontalScroll: '1', + showSheetTabs: '1', + showVerticalScroll: '1', + tabRatio: '600', + visibility: 'visible' + //window{Height,Width}, {x,y}Window +}; + +/* 18.2.19 (CT_Sheet) Defaults */ +var SheetDef = { + state: 'visible' +}; + +/* 18.2.2 (CT_CalcPr) Defaults */ +var CalcPrDef = { + calcCompleted: 'true', + calcMode: 'auto', + calcOnSave: 'true', + concurrentCalc: 'true', + fullCalcOnLoad: 'false', + fullPrecision: 'true', + iterate: 'false', + iterateCount: '100', + iterateDelta: '0.001', + refMode: 'A1' +}; + +/* 18.2.3 (CT_CustomWorkbookView) Defaults */ +var CustomWBViewDef = { + autoUpdate: 'false', + changesSavedWin: 'false', + includeHiddenRowCol: 'true', + includePrintSettings: 'true', + maximized: 'false', + minimized: 'false', + onlySync: 'false', + personalView: 'false', + showComments: 'commIndicator', + showFormulaBar: 'true', + showHorizontalScroll: 'true', + showObjects: 'all', + showSheetTabs: 'true', + showStatusbar: 'true', + showVerticalScroll: 'true', + tabRatio: '600', + xWindow: '0', + yWindow: '0' +}; + +var XMLNS_CT = 'http://schemas.openxmlformats.org/package/2006/content-types'; +var XMLNS_WB = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'; + +var strs = {}; // shared strings +var styles = {}; // shared styles +var _ssfopts = {}; // spreadsheet formatting options + +/* 18.3 Worksheets */ +function parseSheet(data) { + if(!data) return data; + /* 18.3.1.99 worksheet CT_Worksheet */ + var s = {}; + + /* 18.3.1.35 dimension CT_SheetDimension ? */ + var ref = data.match(//); + if(ref && ref.length == 2 && ref[1].indexOf(":") !== -1) s["!ref"] = ref[1]; + + var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} }; + var q = ["v","f"]; + var sidx = 0; + /* 18.3.1.80 sheetData CT_SheetData ? */ + if(!data.match(//)) + data.match(/([^\u2603]*)<\/sheetData>/m)[1].split("").forEach(function(x) { + if(x === "" || x.trim() === "") return; + + /* 18.3.1.73 row CT_Row */ + var row = parsexmltag(x.match(/]*>/)[0]); + if(refguess.s.r > row.r - 1) refguess.s.r = row.r - 1; + if(refguess.e.r < row.r - 1) refguess.e.r = row.r - 1; + + /* 18.3.1.4 c CT_Cell */ + var cells = x.substr(x.indexOf('>')+1).split(/ idx) refguess.s.c = idx; + if(refguess.e.c < idx) refguess.e.c = idx; + var cell = parsexmltag((c.match(/]*>/)||[c])[0]); delete cell[0]; + var d = c.substr(c.indexOf('>')+1); + var p = {}; + q.forEach(function(f){var x=d.match(matchtag(f));if(x)p[f]=unescapexml(x[1]);}); + + /* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */ + if(cell.t === undefined && p.v === undefined) { p.t = "str"; p.v = undefined; } + else p.t = (cell.t ? cell.t : "n"); // default is "n" in schema + switch(p.t) { + case 'n': p.v = parseFloat(p.v); break; + case 's': { + sidx = parseInt(p.v, 10); + p.v = strs[sidx].t; + p.r = strs[sidx].r; + } break; + case 'str': if(p.v) p.v = utf8read(p.v); break; // normal string + case 'inlineStr': + p.t = 'str'; p.v = unescapexml((d.match(matchtag('t'))||["",""])[1]); + break; // inline string + case 'b': + switch(p.v) { + case '0': case 'FALSE': case "false": case false: p.v=false; break; + case '1': case 'TRUE': case "true": case true: p.v=true; break; + default: throw "Unrecognized boolean: " + p.v; + } break; + /* in case of error, stick value in .raw */ + case 'e': p.raw = p.v; p.v = undefined; break; + default: throw "Unrecognized cell type: " + p.t; + } + + /* formatting */ + if(cell.s && styles.CellXf) { /* TODO: second check is a hacked guard */ + var cf = styles.CellXf[cell.s]; + if(cf && cf.numFmtId && cf.numFmtId !== 0) { + p.raw = p.v; + p.rawt = p.t; + try { + p.v = SSF.format(cf.numFmtId,p.v,_ssfopts); + p.t = 'str'; + } catch(e) { p.v = p.raw; } + } + } + + s[cell.r] = p; + }); + }); + if(!s["!ref"]) s["!ref"] = encode_range(refguess); + return s; +} + +function parseProps(data) { + var p = { Company:'' }, q = {}; + var strings = ["Application", "DocSecurity", "Company", "AppVersion"]; + var bools = ["HyperlinksChanged","SharedDoc","LinksUpToDate","ScaleCrop"]; + var xtra = ["HeadingPairs", "TitlesOfParts"]; + var xtracp = ["category", "contentStatus", "lastModifiedBy", "lastPrinted", "revision", "version"]; + var xtradc = ["creator", "description", "identifier", "language", "subject", "title"]; + var xtradcterms = ["created", "modified"]; + xtra = xtra.concat(xtracp.map(function(x) { return "cp:" + x; })); + xtra = xtra.concat(xtradc.map(function(x) { return "dc:" + x; })); + xtra = xtra.concat(xtradcterms.map(function(x) { return "dcterms:" + x; })); + + + strings.forEach(function(f){p[f] = (data.match(matchtag(f))||[])[1];}); + bools.forEach(function(f){p[f] = (data.match(matchtag(f))||[])[1] == "true";}); + xtra.forEach(function(f) { + var cur = data.match(new RegExp("<" + f + "[^>]*>(.*)<\/" + f + ">")); + if(cur && cur.length > 0) q[f] = cur[1]; + }); + + if(q.HeadingPairs && q.TitlesOfParts) { + var v = parseVector(q.HeadingPairs); + var j = 0, widx = 0; + for(var i = 0; i !== v.length; ++i) { + switch(v[i].v) { + case "Worksheets": widx = j; p.Worksheets = +v[++i]; break; + case "Named Ranges": ++i; break; // TODO: Handle Named Ranges + } + } + var parts = parseVector(q.TitlesOfParts).map(utf8read); + p.SheetNames = parts.slice(widx, widx + p.Worksheets); + } + p.Creator = q["dc:creator"]; + p.LastModifiedBy = q["cp:lastModifiedBy"]; + p.CreatedDate = new Date(q["dcterms:created"]); + p.ModifiedDate = new Date(q["dcterms:modified"]); + return p; +} + +/* 18.6 Calculation Chain */ +function parseDeps(data) { + var d = []; + var l = 0, i = 1; + (data.match(/<[^>]*>/g)||[]).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': case '': break; + /* 18.6.1 c CT_CalcCell 1 */ + case ']*>/g)||[]).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case ' 0 ? ct.calcchains[0] : ""; + ct.sst = ct.strs.length > 0 ? ct.strs[0] : ""; + ct.style = ct.styles.length > 0 ? ct.styles[0] : ""; + delete ct.calcchains; + return ct; +} + + +/* 18.2 Workbook */ +function parseWB(data) { + var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; + var pass = false; + data.match(/<[^>]*>/g).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': break; + + /* 18.2.13 fileVersion CT_FileVersion ? */ + case '': break; + + /* 18.2.12 fileSharing CT_FileSharing ? */ + case '': break; + + /* 18.2.28 workbookPr CT_WorkbookPr ? */ + case '': delete y[0]; wb.WBProps = y; break; + + /* 18.2.29 workbookProtection CT_WorkbookProtection ? */ + case '': break; + + /* 18.2.1 bookViews CT_BookViews ? */ + case '': case '': break; + /* 18.2.30 workbookView CT_BookView + */ + case '': case '': break; // aggregate sheet + /* 18.2.19 sheet CT_Sheet + */ + case '': break; + /* 18.2.14 functionGroup CT_FunctionGroup + */ + case '': break; + /* 18.2.8 externalReference CT_ExternalReference + */ + case '': break; + case '': pass=true; break; + case '': pass=false; break; + /* 18.2.5 definedName CT_DefinedName + */ + case '': case '': break; + + /* 18.2.2 calcPr CT_CalcPr ? */ + case '': delete y[0]; wb.CalcPr = y; break; + + /* 18.2.16 oleSize CT_OleSize ? (ref required) */ + case '': case '': case '': break; + + /* 18.2.18 pivotCaches CT_PivotCaches ? */ + case '': case '': case '': break; + + /* 18.2.23 smartTagTypes CT_SmartTagTypes ? */ + case '': case '': break; + /* 18.2.22 smartTagType CT_SmartTagType ? */ + case '': break; + + /* 18.2.11 fileRecoveryPr CT_FileRecoveryPr ? */ + case '': break; + + /* 18.2.26 webPublishObjects CT_WebPublishObjects ? */ + case '': case '': break; + /* 18.2.25 webPublishObject CT_WebPublishObject ? */ + case '': case '': case '': break; + /* 18.2.7 ext CT_Extension + */ + case '': pass=false; break; + + /* Others */ + case '': pass=false; break; + } + }); + if(wb.xmlns !== XMLNS_WB) throw new Error("Unknown Namespace: " + wb.xmlns); + + var z; + /* defaults */ + for(z in WBPropsDef) if(typeof wb.WBProps[z] === 'undefined') wb.WBProps[z] = WBPropsDef[z]; + for(z in CalcPrDef) if(typeof wb.CalcPr[z] === 'undefined') wb.CalcPr[z] = CalcPrDef[z]; + + wb.WBView.forEach(function(w){for(var z in WBViewDef) if(typeof w[z] === 'undefined') w[z]=WBViewDef[z]; }); + wb.Sheets.forEach(function(w){for(var z in SheetDef) if(typeof w[z] === 'undefined') w[z]=SheetDef[z]; }); + + _ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904'); + + return wb; +} + +/* 18.8.31 numFmts CT_NumFmts */ +function parseNumFmts(t) { + styles.NumberFmt = []; + for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y]; + t[0].match(/<[^>]*>/g).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': case '': break; + case ']*>/g).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': case '': break; + + /* 18.8.45 xf CT_Xf */ + case '': break; + + /* 18.8.1 alignment CT_CellAlignment */ + case '': case '': break; + + case '': break; + case ']*)>.*<\/numFmts>/))) parseNumFmts(t); + + /* fonts CT_Fonts ? */ + /* fills CT_Fills ? */ + /* borders CT_Borders ? */ + /* cellStyleXfs CT_CellStyleXfs ? */ + + /* cellXfs CT_CellXfs ? */ + if((t=data.match(/]*)>.*<\/cellXfs>/))) parseCXfs(t); + + /* dxfs CT_Dxfs ? */ + /* tableStyles CT_TableStyles ? */ + /* colors CT_Colors ? */ + /* extLst CT_ExtensionList ? */ + + return styles; +} + +function getdata(data) { + if(!data) return null; + if(data.data) return data.data; + if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent(),0).map(function(x) { return String.fromCharCode(x); }).join(""); + return null; +} + +function getzipfile(zip, file) { + var f = file; if(zip.files[f]) return zip.files[f]; + f = file.toLowerCase(); if(zip.files[f]) return zip.files[f]; + f = f.replace(/\//g,'\\'); if(zip.files[f]) return zip.files[f]; + throw new Error("Cannot find file " + file + " in zip"); +} + +function parseZip(zip) { + var entries = Object.keys(zip.files); + var keys = entries.filter(function(x){return x.substr(-1) != '/';}).sort(); + var dir = parseCT(getdata(getzipfile(zip, '[Content_Types].xml'))); + + strs = {}; + if(dir.sst) strs=parse_sst(getdata(getzipfile(zip, dir.sst.replace(/^\//,'')))); + + styles = {}; + if(dir.style) styles = parseStyles(getdata(getzipfile(zip, dir.style.replace(/^\//,'')))); + + var wb = parseWB(getdata(getzipfile(zip, dir.workbooks[0].replace(/^\//,'')))); + var propdata = dir.coreprops.length !== 0 ? getdata(getzipfile(zip, dir.coreprops[0].replace(/^\//,''))) : ""; + propdata += dir.extprops.length !== 0 ? getdata(getzipfile(zip, dir.extprops[0].replace(/^\//,''))) : ""; + var props = propdata !== "" ? parseProps(propdata) : {}; + var deps = {}; + if(dir.calcchain) deps=parseDeps(getdata(getzipfile(zip, dir.calcchain.replace(/^\//,'')))); + var sheets = {}, i=0; + if(!props.Worksheets) { + /* Google Docs doesn't generate the appropriate metadata, so we impute: */ + var wbsheets = wb.Sheets; + props.Worksheets = wbsheets.length; + props.SheetNames = []; + for(var j = 0; j != wbsheets.length; ++j) { + props.SheetNames[j] = wbsheets[j].name; + } + for(i = 0; i != props.Worksheets; ++i) { + try { /* TODO: remove these guards */ + sheets[props.SheetNames[i]]=parseSheet(getdata(getzipfile(zip, 'xl/worksheets/sheet' + (i+1) + '.xml'))); + } catch(e) {} + } + } + else { + for(i = 0; i != props.Worksheets; ++i) { + try { + sheets[props.SheetNames[i]]=parseSheet(getdata(getzipfile(zip, dir.sheets[i].replace(/^\//,'')))); + } catch(e) {} + } + } + return { + Directory: dir, + Workbook: wb, + Props: props, + Deps: deps, + Sheets: sheets, + SheetNames: props.SheetNames, + Strings: strs, + Styles: styles, + keys: keys, + files: zip.files + }; +} + +var _fs, jszip; +if(typeof JSZip !== 'undefined') jszip = JSZip; +if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + if(typeof jszip === 'undefined') jszip = require('./jszip').JSZip; + _fs = require('fs'); + } +} + +function readSync(data, options) { + var zip, d = data; + var o = options||{}; + switch((o.type||"base64")){ + case "file": d = _fs.readFileSync(data).toString('base64'); + /* falls through */ + case "base64": zip = new jszip(d, { base64:true }); break; + case "binary": zip = new jszip(d, { base64:false }); break; + } + return parseZip(zip); +} + +function readFileSync(data, options) { + var o = options||{}; o.type = 'file'; + return readSync(data, o); +} + +XLSX.read = readSync; +XLSX.readFile = readFileSync; +XLSX.parseZip = parseZip; +return this; + +})(XLSX); + +var _chr = function(c) { return String.fromCharCode(c); }; + +function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = _chr(((col-1)%26) + 65) + s; return s; } +function encode_row(row) { return "" + (row + 1); } +function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); } + +function decode_col(c) { var d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } +function decode_row(rowstr) { return Number(rowstr) - 1; } +function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?[0-9]*)/,"$1,$2").split(","); } +function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } +function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } +function encode_range(range) { return encode_cell(range.s) + ":" + encode_cell(range.e); } +/** + * Convert a sheet into an array of objects where the column headers are keys. + **/ +function sheet_to_row_object_array(sheet){ + var val, rowObject, range, columnHeaders, emptyRow, C; + var outSheet = []; + if (sheet["!ref"]) { + range = decode_range(sheet["!ref"]); + + columnHeaders = {}; + for (C = range.s.c; C <= range.e.c; ++C) { + val = sheet[encode_cell({ + c: C, + r: range.s.r + })]; + if(val){ + switch(val.t) { + case 's': case 'str': columnHeaders[C] = val.v; break; + case 'n': columnHeaders[C] = val.v; break; + } + } + } + + for (var R = range.s.r + 1; R <= range.e.r; ++R) { + emptyRow = true; + //Row number is recorded in the prototype + //so that it doesn't appear when stringified. + rowObject = Object.create({ __rowNum__ : R }); + for (C = range.s.c; C <= range.e.c; ++C) { + val = sheet[encode_cell({ + c: C, + r: R + })]; + if(val !== undefined) switch(val.t){ + case 's': case 'str': case 'b': case 'n': + if(val.v !== undefined) { + rowObject[columnHeaders[C]] = val.v; + emptyRow = false; + } + break; + case 'e': break; /* throw */ + default: throw 'unrecognized type ' + val.t; + } + } + if(!emptyRow) { + outSheet.push(rowObject); + } + } + } + return outSheet; +} + +function sheet_to_csv(sheet) { + var stringify = function stringify(val) { + switch(val.t){ + case 'n': return String(val.v); + case 's': case 'str': + if(typeof val.v === 'undefined') return ""; + return JSON.stringify(val.v); + case 'b': return val.v ? "TRUE" : "FALSE"; + case 'e': return ""; /* throw out value in case of error */ + default: throw 'unrecognized type ' + val.t; + } + }; + var out = ""; + if(sheet["!ref"]) { + var r = XLSX.utils.decode_range(sheet["!ref"]); + for(var R = r.s.r; R <= r.e.r; ++R) { + var row = []; + for(var C = r.s.c; C <= r.e.c; ++C) { + var val = sheet[XLSX.utils.encode_cell({c:C,r:R})]; + row.push(val ? stringify(val).replace(/\\r\\n/g,"\n").replace(/\\t/g,"\t").replace(/\\\\/g,"\\").replace("\\\"","\"\"") : ""); + } + out += row.join(",") + "\n"; + } + } + return out; +} +var make_csv = sheet_to_csv; + +function get_formulae(ws) { + var cmds = []; + for(var y in ws) if(y[0] !=='!' && ws.hasOwnProperty(y)) { + var x = ws[y]; + var val = ""; + if(x.f) val = x.f; + else if(typeof x.v === 'number') val = x.v; + else val = x.v; + cmds.push(y + "=" + val); + } + return cmds; +} + +XLSX.utils = { + encode_col: encode_col, + encode_row: encode_row, + encode_cell: encode_cell, + encode_range: encode_range, + decode_col: decode_col, + decode_row: decode_row, + split_cell: split_cell, + decode_cell: decode_cell, + decode_range: decode_range, + sheet_to_csv: sheet_to_csv, + make_csv: sheet_to_csv, + get_formulae: get_formulae, + sheet_to_row_object_array: sheet_to_row_object_array +}; + +if(typeof require !== 'undefined' && typeof exports !== 'undefined') { + exports.read = XLSX.read; + exports.readFile = XLSX.readFile; + exports.utils = XLSX.utils; + exports.main = function(args) { + var zip = XLSX.read(args[0], {type:'file'}); + console.log(zip.Sheets); + }; +if(typeof module !== 'undefined' && require.main === module) + exports.main(process.argv.slice(2)); +} diff --git a/xlsxworker.js b/xlsxworker.js new file mode 100644 index 0000000..c58d05c --- /dev/null +++ b/xlsxworker.js @@ -0,0 +1,11 @@ +importScripts('jszip.js'); +importScripts('xlsx.js'); +postMessage({t:"ready"}); + +onmessage = function (oEvent) { + var v; + try { + v = XLSX.read(oEvent.data, {type: 'base64'}); + } catch(e) { postMessage({t:"e",d:e.stack}); } + postMessage({t:"xlsx", d:JSON.stringify(v)}); +};