From c78bb5195ec4055ce58bb7a8a65b3c980fa38545 Mon Sep 17 00:00:00 2001 From: zhl Date: Thu, 22 Oct 2020 11:11:55 +0800 Subject: [PATCH] project init --- .gitignore | 3 + README.md | 2 + app/main.js | 57 + app/package.json | 8 + copy.bat | 5 + libs/jszip.js | 2128 +++ libs/xlsx.js | 11656 ++++++++++++++++ src/Defines.ts | 246 + src/MenualCodeHelper.ts | 101 + src/PackageData.ts | 338 + src/PluginErrorType.ts | 14 + src/PluginLoader.ts | 48 + src/SvnCmd.ts | 209 + src/TypeCheckers.ts | 451 + src/asyncFileLoad.ts | 27 + src/indexJava.ts | 1140 ++ src/plugins/MsgCodeParser.ts | 57 + testsample/0.测试数据/CeShiBiao.xlsx | Bin 0 -> 11842 bytes testsample/0.测试数据/CeShiBiao1.xlsx | Bin 0 -> 11753 bytes testsample/0.测试数据/CeShiBiao2.xlsx | Bin 0 -> 11753 bytes testsample/csrc/chuanqi/GConfig.ts | 16 + .../module/gongneng/cfg/GongNengCfg.ts | 78 + .../chuanqi/module/test/cfg/CeShiBiaoCfg.ts | 128 + .../csrc/huaqiangu/test/CeShiBiaoCfg.ts | 103 + testsample/data/client/basic.json | 1 + testsample/data/client/cfgs.json | 1 + testsample/data/client/raw/CeShiBiao.json | 1 + testsample/data/client/running.json | 1 + testsample/data/server/CeShiBiao.json | 1 + testsample/globalConfig.json | 4 + testsample/out/client/CeShiBiao.json | 1 + testsample/out/client/CeShiBiao1.json | 1 + testsample/out/client/CeShiBiao2.json | 1 + testsample/out/server/CeShiBiao.json | 1 + testsample/out/server/CeShiBiao.xml | 15 + testsample/out/server/CeShiBiao1.json | 1 + testsample/out/server/CeShiBiao1.xml | 3 + testsample/out/server/CeShiBiao2.json | 1 + .../huaqiangu/test/CeShiBiaoTemplate.java | 112 + testsample/ssrc/test/CeShiBiaoTemplate.java | 132 + tsconfig.json | 13 + typings/electron.d.ts | 10 + typings/node/node.d.ts | 2340 ++++ typings/tsd.d.ts | 43 + typings/xlsx/xlsx.d.ts | 148 + web.js | 64 + 调试用.bat | 1 + 47 files changed, 19711 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 app/main.js create mode 100644 app/package.json create mode 100644 copy.bat create mode 100644 libs/jszip.js create mode 100644 libs/xlsx.js create mode 100644 src/Defines.ts create mode 100644 src/MenualCodeHelper.ts create mode 100644 src/PackageData.ts create mode 100644 src/PluginErrorType.ts create mode 100644 src/PluginLoader.ts create mode 100644 src/SvnCmd.ts create mode 100644 src/TypeCheckers.ts create mode 100644 src/asyncFileLoad.ts create mode 100644 src/indexJava.ts create mode 100644 src/plugins/MsgCodeParser.ts create mode 100644 testsample/0.测试数据/CeShiBiao.xlsx create mode 100644 testsample/0.测试数据/CeShiBiao1.xlsx create mode 100644 testsample/0.测试数据/CeShiBiao2.xlsx create mode 100644 testsample/csrc/chuanqi/GConfig.ts create mode 100644 testsample/csrc/chuanqi/module/gongneng/cfg/GongNengCfg.ts create mode 100644 testsample/csrc/chuanqi/module/test/cfg/CeShiBiaoCfg.ts create mode 100644 testsample/csrc/huaqiangu/test/CeShiBiaoCfg.ts create mode 100644 testsample/data/client/basic.json create mode 100644 testsample/data/client/cfgs.json create mode 100644 testsample/data/client/raw/CeShiBiao.json create mode 100644 testsample/data/client/running.json create mode 100644 testsample/data/server/CeShiBiao.json create mode 100644 testsample/globalConfig.json create mode 100644 testsample/out/client/CeShiBiao.json create mode 100644 testsample/out/client/CeShiBiao1.json create mode 100644 testsample/out/client/CeShiBiao2.json create mode 100644 testsample/out/server/CeShiBiao.json create mode 100644 testsample/out/server/CeShiBiao.xml create mode 100644 testsample/out/server/CeShiBiao1.json create mode 100644 testsample/out/server/CeShiBiao1.xml create mode 100644 testsample/out/server/CeShiBiao2.json create mode 100644 testsample/ssrc/huaqiangu/test/CeShiBiaoTemplate.java create mode 100644 testsample/ssrc/test/CeShiBiaoTemplate.java create mode 100644 tsconfig.json create mode 100644 typings/electron.d.ts create mode 100644 typings/node/node.d.ts create mode 100644 typings/tsd.d.ts create mode 100644 typings/xlsx/xlsx.d.ts create mode 100644 web.js create mode 100644 调试用.bat diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e0b87bb --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode +dist +tmp diff --git a/README.md b/README.md new file mode 100644 index 0000000..7665108 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +h5工具下载地址: +http://h5tools.client.jy/h5tools.zip \ No newline at end of file diff --git a/app/main.js b/app/main.js new file mode 100644 index 0000000..c0763eb --- /dev/null +++ b/app/main.js @@ -0,0 +1,57 @@ +const electron = require('electron'); +// Module to control application life. +const {app} = electron; +// Module to create native browser window. +const {BrowserWindow} = electron; + +// Keep a global reference of the window object, if you don't, the window will +// be closed automatically when the JavaScript object is garbage collected. +let win; + +function createWindow() { + // Create the browser window. + win = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + nodeIntegration: true + } + }); + + // and load the index.html of the app. + // win.loadURL("http://127.0.0.1:12345/index.html"); + win.loadFile('../dist/index.html') + + // Open the DevTools. + // win.webContents.openDevTools(); + + // Emitted when the window is closed. + win.on('closed', () => { + // Dereference the window object, usually you would store windows + // in an array if your app supports multi windows, this is the time + // when you should delete the corresponding element. + win = null; + }); +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.on('ready', createWindow); + +// Quit when all windows are closed. +app.on('window-all-closed', () => { + // On OS X it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + // On OS X it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (win === null) { + createWindow(); + } +}); diff --git a/app/package.json b/app/package.json new file mode 100644 index 0000000..3509396 --- /dev/null +++ b/app/package.json @@ -0,0 +1,8 @@ +{ + "name": "configtools", + "version": "0.1.0", + "main": "main.js", + "scripts": { + "start": "electron ." + } +} diff --git a/copy.bat b/copy.bat new file mode 100644 index 0000000..78cb74c --- /dev/null +++ b/copy.bat @@ -0,0 +1,5 @@ +echo 开始copy + +robocopy .\dist ..\..\release\dataparse /MIR + +pause \ No newline at end of file diff --git a/libs/jszip.js b/libs/jszip.js new file mode 100644 index 0000000..3418fb7 --- /dev/null +++ b/libs/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/libs/xlsx.js b/libs/xlsx.js new file mode 100644 index 0000000..6b237cf --- /dev/null +++ b/libs/xlsx.js @@ -0,0 +1,11656 @@ +/* xlsx.js (C) 2013-2015 SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*jshint -W041 */ +/*jshint funcscope:true, eqnull:true */ +var XLSX = {}; +(function make_xlsx(XLSX){ +XLSX.version = '0.8.0'; +var current_codepage = 1200, current_cptable; +if(typeof module !== "undefined" && typeof require !== 'undefined') { + if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel'); + current_cptable = cptable[current_codepage]; +} +function reset_cp() { set_cp(1200); } +var set_cp = function(cp) { current_codepage = cp; }; + +function char_codes(data) { var o = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; } +var debom_xml = function(data) { return data; }; + +var _getchar = function _gc1(x) { return String.fromCharCode(x); }; +if(typeof cptable !== 'undefined') { + set_cp = function(cp) { current_codepage = cp; current_cptable = cptable[cp]; }; + debom_xml = function(data) { + if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return cptable.utils.decode(1200, char_codes(data.substr(2))); } + return data; + }; + _getchar = function _gc2(x) { + if(current_codepage === 1200) return String.fromCharCode(x); + return cptable.utils.decode(current_codepage, [x&255,x>>8])[0]; + }; +} +var Base64 = (function make_b64(){ + var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + return { + encode: function(input, utf8) { + var o = ""; + var c1, c2, c3, e1, e2, e3, e4; + for(var i = 0; i < input.length; ) { + c1 = input.charCodeAt(i++); + c2 = input.charCodeAt(i++); + c3 = input.charCodeAt(i++); + e1 = c1 >> 2; + e2 = (c1 & 3) << 4 | c2 >> 4; + e3 = (c2 & 15) << 2 | c3 >> 6; + e4 = c3 & 63; + if (isNaN(c2)) { e3 = e4 = 64; } + else if (isNaN(c3)) { e4 = 64; } + o += map.charAt(e1) + map.charAt(e2) + map.charAt(e3) + map.charAt(e4); + } + return o; + }, + decode: function b64_decode(input, utf8) { + var o = ""; + var c1, c2, c3; + var e1, e2, e3, e4; + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + for(var i = 0; i < input.length;) { + e1 = map.indexOf(input.charAt(i++)); + e2 = map.indexOf(input.charAt(i++)); + e3 = map.indexOf(input.charAt(i++)); + e4 = map.indexOf(input.charAt(i++)); + c1 = e1 << 2 | e2 >> 4; + c2 = (e2 & 15) << 4 | e3 >> 2; + c3 = (e3 & 3) << 6 | e4; + o += String.fromCharCode(c1); + if (e3 != 64) { o += String.fromCharCode(c2); } + if (e4 != 64) { o += String.fromCharCode(c3); } + } + return o; + } + }; +})(); +var has_buf = (typeof Buffer !== 'undefined'); + +function new_raw_buf(len) { + /* jshint -W056 */ + return new (has_buf ? Buffer : Array)(len); + /* jshint +W056 */ +} + +function s2a(s) { + if(has_buf) return new Buffer(s, "binary"); + return s.split("").map(function(x){ return x.charCodeAt(0) & 0xff; }); +} + +var bconcat = function(bufs) { return [].concat.apply([], bufs); }; + +var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/; +/* ssf.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/*jshint -W041 */ +var SSF = {}; +var make_ssf = function make_ssf(SSF){ +SSF.version = '0.8.1'; +function _strrev(x) { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; } +function fill(c,l) { var o = ""; while(o.length < l) o+=c; return o; } +function pad0(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} +function pad_(v,d){var t=""+v;return t.length>=d?t:fill(' ',d-t.length)+t;} +function rpad_(v,d){var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);} +function pad0r1(v,d){var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;} +function pad0r2(v,d){var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;} +var p2_32 = Math.pow(2,32); +function pad0r(v,d){if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); } +function isgeneral(s, i) { return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; } +/* Options */ +var opts_fmt = [ + ["date1904", 0], + ["output", ""], + ["WTF", false] +]; +function fixopts(o){ + for(var y = 0; y != opts_fmt.length; ++y) if(o[opts_fmt[y][0]]===undefined) o[opts_fmt[y][0]]=opts_fmt[y][1]; +} +SSF.opts = opts_fmt; +var table_fmt = { + 0: 'General', + 1: '0', + 2: '0.00', + 3: '#,##0', + 4: '#,##0.00', + 9: '0%', + 10: '0.00%', + 11: '0.00E+00', + 12: '# ?/?', + 13: '# ??/??', + 14: 'm/d/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: '@', + 56: '"上午/下午 "hh"時"mm"分"ss"秒 "', + 65535: 'General' +}; +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'] +]; +function frac(x, D, mixed) { + var sgn = x < 0 ? -1 : 1; + var B = x * sgn; + var P_2 = 0, P_1 = 1, P = 0; + var Q_2 = 1, Q_1 = 0, Q = 0; + var A = Math.floor(B); + while(Q_1 < D) { + A = Math.floor(B); + P = A * P_1 + P_2; + Q = A * Q_1 + Q_2; + if((B - A) < 0.0000000005) break; + B = 1 / (B - A); + P_2 = P_1; P_1 = P; + Q_2 = Q_1; Q_1 = Q; + } + if(Q > D) { Q = Q_1; P = P_1; } + if(Q > D) { Q = Q_2; P = P_2; } + if(!mixed) return [0, sgn * P, Q]; + if(Q===0) throw "Unexpected state: "+P+" "+P_1+" "+P_2+" "+Q+" "+Q_1+" "+Q_2; + var q = Math.floor(sgn * P/Q); + return [q, sgn*P - q*Q, Q]; +} +function general_fmt_int(v, opts) { return ""+v; } +SSF._general_int = general_fmt_int; +var general_fmt_num = (function make_general_fmt_num() { +var gnr1 = /\.(\d*[1-9])0+$/, gnr2 = /\.0*$/, gnr4 = /\.(\d*[1-9])0+/, gnr5 = /\.0*[Ee]/, gnr6 = /(E[+-])(\d)$/; +function gfn2(v) { + var w = (v<0?12:11); + var o = gfn5(v.toFixed(12)); if(o.length <= w) return o; + o = v.toPrecision(10); if(o.length <= w) return o; + return v.toExponential(5); +} +function gfn3(v) { + var o = v.toFixed(11).replace(gnr1,".$1"); + if(o.length > (v<0?12:11)) o = v.toPrecision(6); + return o; +} +function gfn4(o) { + for(var i = 0; i != o.length; ++i) if((o.charCodeAt(i) | 0x20) === 101) return o.replace(gnr4,".$1").replace(gnr5,"E").replace("e","E").replace(gnr6,"$10$2"); + return o; +} +function gfn5(o) { + //for(var i = 0; i != o.length; ++i) if(o.charCodeAt(i) === 46) return o.replace(gnr2,"").replace(gnr1,".$1"); + //return o; + return o.indexOf(".") > -1 ? o.replace(gnr2,"").replace(gnr1,".$1") : o; +} +return function general_fmt_num(v, opts) { + var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o; + if(V >= -4 && V <= -1) o = v.toPrecision(10+V); + else if(Math.abs(V) <= 9) o = gfn2(v); + else if(V === 10) o = v.toFixed(10).substr(0,12); + else o = gfn3(v); + return gfn5(gfn4(o)); +};})(); +SSF._general_num = general_fmt_num; +function general_fmt(v, opts) { + switch(typeof v) { + case 'string': return v; + case 'boolean': return v ? "TRUE" : "FALSE"; + case 'number': return (v|0) === v ? general_fmt_int(v, opts) : general_fmt_num(v, opts); + } + throw new Error("unsupported value in General format: " + v); +} +SSF._general = general_fmt; +function fix_hijri(date, o) { return 0; } +function parse_date_code(v,opts,b2) { + if(v > 2958465 || v < 0) return null; + var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0; + var dout=[]; + var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0}; + if(Math.abs(out.u) < 1e-6) out.u = 0; + fixopts(opts != null ? opts : (opts=[])); + if(opts.date1904) date += 1462; + if(out.u > 0.999) { + out.u = 0; + if(++time == 86400) { time = 0; ++date; } + } + if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;} + else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;} + 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(date < 60) dow = (dow + 6) % 7; + if(b2) dow = fix_hijri(d, dout); + } + 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; +/*jshint -W086 */ +function write_date(type, fmt, val, ss0) { + var o="", ss=0, tt=0, y = val.y, out, outl = 0; + switch(type) { + case 98: /* 'b' buddhist year */ + y = val.y + 543; + /* falls through */ + case 121: /* 'y' year */ + switch(fmt.length) { + case 1: case 2: out = y % 100; outl = 2; break; + default: out = y % 10000; outl = 4; break; + } break; + case 109: /* 'm' month */ + switch(fmt.length) { + case 1: case 2: out = val.m; outl = fmt.length; break; + case 3: return months[val.m-1][1]; + case 5: return months[val.m-1][0]; + default: return months[val.m-1][2]; + } break; + case 100: /* 'd' day */ + switch(fmt.length) { + case 1: case 2: out = val.d; outl = fmt.length; break; + case 3: return days[val.q][0]; + default: return days[val.q][1]; + } break; + case 104: /* 'h' 12-hour */ + switch(fmt.length) { + case 1: case 2: out = 1+(val.H+11)%12; outl = fmt.length; break; + default: throw 'bad hour format: ' + fmt; + } break; + case 72: /* 'H' 24-hour */ + switch(fmt.length) { + case 1: case 2: out = val.H; outl = fmt.length; break; + default: throw 'bad hour format: ' + fmt; + } break; + case 77: /* 'M' minutes */ + switch(fmt.length) { + case 1: case 2: out = val.M; outl = fmt.length; break; + default: throw 'bad minute format: ' + fmt; + } break; + case 115: /* 's' seconds */ + if(val.u === 0) switch(fmt) { + case 's': case 'ss': return pad0(val.S, fmt.length); + case '.0': case '.00': case '.000': + } + switch(fmt) { + case 's': case 'ss': case '.0': case '.00': case '.000': + if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100; + else tt = ss0 === 1 ? 10 : 1; + ss = Math.round((tt)*(val.S + val.u)); + if(ss >= 60*tt) ss = 0; + if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt; + o = pad0(ss,2 + ss0); + if(fmt === 'ss') return o.substr(0,2); + return "." + o.substr(2,fmt.length-1); + default: throw 'bad second format: ' + fmt; + } + case 90: /* 'Z' absolute time */ + switch(fmt) { + case '[h]': case '[hh]': out = val.D*24+val.H; break; + case '[m]': case '[mm]': out = (val.D*24+val.H)*60+val.M; break; + case '[s]': case '[ss]': out = ((val.D*24+val.H)*60+val.M)*60+Math.round(val.S+val.u); break; + default: throw 'bad abstime format: ' + fmt; + } outl = fmt.length === 3 ? 1 : 2; break; + case 101: /* 'e' era */ + out = y; outl = 1; + } + if(outl > 0) return pad0(out, outl); else return ""; +} +/*jshint +W086 */ +function commaify(s) { + if(s.length <= 3) return s; + var j = (s.length % 3), o = s.substr(0,j); + for(; j!=s.length; j+=3) o+=(o.length > 0 ? "," : "") + s.substr(j,3); + return o; +} +var write_num = (function make_write_num(){ +var pct1 = /%/g; +function write_num_pct(type, fmt, val){ + var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length; + return write_num(type, sfmt, val * Math.pow(10,2*mul)) + fill("%",mul); +} +function write_num_cm(type, fmt, val){ + var idx = fmt.length - 1; + while(fmt.charCodeAt(idx-1) === 44) --idx; + return write_num(type, fmt.substr(0,idx), val / Math.pow(10,3*(fmt.length-idx))); +} +function write_num_exp(fmt, val){ + var o; + var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1; + if(fmt.match(/^#+0.0E\+0$/)) { + var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E'); + var ee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E)%period; + if(ee < 0) ee += period; + o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period); + if(o.indexOf("e") === -1) { + var fakee = Math.floor(Math.log(Math.abs(val))*Math.LOG10E); + if(o.indexOf(".") === -1) o = o[0] + "." + o.substr(1) + "E+" + (fakee - o.length+ee); + else o += "E+" + (fakee - ee); + while(o.substr(0,2) === "0.") { + o = o[0] + o.substr(2,period) + "." + o.substr(2+period); + o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0."); + } + o = o.replace(/\+-/,"-"); + } + o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; }); + } else o = val.toExponential(idx); + if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o[o.length-1]; + if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e"); + return o.replace("e","E"); +} +var frac1 = /# (\?+)( ?)\/( ?)(\d+)/; +function write_num_f1(r, aval, sign) { + var den = parseInt(r[4]), rr = Math.round(aval * den), base = Math.floor(rr/den); + var myn = (rr - base*den), myd = den; + return sign + (base === 0 ? "" : ""+base) + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad_(myn,r[1].length) + r[2] + "/" + r[3] + pad0(myd,r[4].length)); +} +function write_num_f2(r, aval, sign) { + return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length); +} +var dec1 = /^#*0*\.(0+)/; +var closeparen = /\).*[0#]/; +var phone = /\(###\) ###\\?-####/; +function hashq(str) { + var o = "", cc; + for(var i = 0; i != str.length; ++i) switch((cc=str.charCodeAt(i))) { + case 35: break; + case 63: o+= " "; break; + case 48: o+= "0"; break; + default: o+= String.fromCharCode(cc); + } + return o; +} +function rnd(val, d) { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } +function dec(val, d) { return Math.round((val-Math.floor(val))*Math.pow(10,d)); } +function flr(val) { if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0)); return ""+Math.floor(val); } +function write_num_flt(type, fmt, val) { + if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) { + var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,""); + if(val >= 0) return write_num_flt('n', ffmt, val); + return '(' + write_num_flt('n', ffmt, -val) + ')'; + } + if(fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm(type, fmt, val); + if(fmt.indexOf('%') !== -1) return write_num_pct(type, fmt, val); + if(fmt.indexOf('E') !== -1) return write_num_exp(fmt, val); + if(fmt.charCodeAt(0) === 36) return "$"+write_num_flt(type,fmt.substr(fmt[1]==' '?2:1),val); + var o, oo; + var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : ""; + if(fmt.match(/^00+$/)) return sign + pad0r(aval,fmt.length); + if(fmt.match(/^[#?]+$/)) { + o = pad0r(val,0); if(o === "0") o = ""; + return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o; + } + if((r = fmt.match(frac1)) !== null) return write_num_f1(r, aval, sign); + if(fmt.match(/^#+0+$/) !== null) return sign + pad0r(aval,fmt.length - fmt.indexOf("0")); + if((r = fmt.match(dec1)) !== null) { + o = rnd(val, r[1].length).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); }); + return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,"."); + } + fmt = fmt.replace(/^#+([0.])/, "$1"); + if((r = fmt.match(/^(0*)\.(#*)$/)) !== null) { + return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":"."); + } + if((r = fmt.match(/^#,##0(\.?)$/)) !== null) return sign + commaify(pad0r(aval,0)); + if((r = fmt.match(/^#,##0\.([#0]*0)$/)) !== null) { + return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(""+(Math.floor(val))) + "." + pad0(dec(val, r[1].length),r[1].length); + } + if((r = fmt.match(/^#,#*,#0/)) !== null) return write_num_flt(type,fmt.replace(/^#,#*,/,""),val); + if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) !== null) { + o = _strrev(write_num_flt(type, fmt.replace(/[\\-]/g,""), val)); + ri = 0; + return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri= 0) return write_num_int('n', ffmt, val); + return '(' + write_num_int('n', ffmt, -val) + ')'; + } + if(fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm2(type, fmt, val); + if(fmt.indexOf('%') !== -1) return write_num_pct2(type, fmt, val); + if(fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val); + if(fmt.charCodeAt(0) === 36) return "$"+write_num_int(type,fmt.substr(fmt[1]==' '?2:1),val); + var o; + var r, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : ""; + if(fmt.match(/^00+$/)) return sign + pad0(aval,fmt.length); + if(fmt.match(/^[#?]+$/)) { + o = (""+val); if(val === 0) o = ""; + return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o; + } + if((r = fmt.match(frac1)) !== null) return write_num_f2(r, aval, sign); + if(fmt.match(/^#+0+$/) !== null) return sign + pad0(aval,fmt.length - fmt.indexOf("0")); + if((r = fmt.match(dec1)) !== null) { + o = (""+val).replace(/^([^\.]+)$/,"$1."+r[1]).replace(/\.$/,"."+r[1]).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", r[1].length-$1.length); }); + return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,"."); + } + fmt = fmt.replace(/^#+([0.])/, "$1"); + if((r = fmt.match(/^(0*)\.(#*)$/)) !== null) { + return sign + (""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":"."); + } + if((r = fmt.match(/^#,##0(\.?)$/)) !== null) return sign + commaify((""+aval)); + if((r = fmt.match(/^#,##0\.([#0]*0)$/)) !== null) { + return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify((""+val)) + "." + fill('0',r[1].length); + } + if((r = fmt.match(/^#,#*,#0/)) !== null) return write_num_int(type,fmt.replace(/^#,#*,/,""),val); + if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) !== null) { + o = _strrev(write_num_int(type, fmt.replace(/[\\-]/g,""), val)); + ri = 0; + return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;} + else if(fmt.substr(i,5) === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; } + else { q.t = "t"; ++i; } + if(dt==null && q.t === 'T') return ""; + out[out.length] = q; lst = c; break; + case '[': + o = c; + while(fmt[i++] !== ']' && i < fmt.length) o += fmt[i]; + if(o.substr(-1) !== ']') throw 'unterminated "[" block: |' + o + '|'; + if(o.match(abstime)) { + if(dt==null) { dt=parse_date_code(v, opts); if(dt==null) return ""; } + out[out.length] = {t:'Z', v:o.toLowerCase()}; + } else { o=""; } + break; + /* Numbers */ + case '.': + if(dt != null) { + o = c; while((c=fmt[++i]) === "0") o += c; + out[out.length] = {t:'s', v:o}; break; + } + /* falls through */ + case '0': case '#': + o = c; while("0#?.,E+-%".indexOf(c=fmt[++i]) > -1 || c=='\\' && fmt[i+1] == "-" && "0#".indexOf(fmt[i+2])>-1) o += c; + out[out.length] = {t:'n', v:o}; break; + case '?': + o = c; while(fmt[++i] === c) o+=c; + q={t:c, v:o}; out[out.length] = q; lst = c; break; + case '*': ++i; if(fmt[i] == ' ' || fmt[i] == '*') ++i; break; // ** + case '(': case ')': out[out.length] = {t:(flen===1?'t':c), v:c}; ++i; break; + case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + o = c; while("0123456789".indexOf(fmt[++i]) > -1) o+=fmt[i]; + out[out.length] = {t:'D', v:o}; break; + case ' ': out[out.length] = {t:c, v:c}; ++i; break; + default: + if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxz".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt); + out[out.length] = {t:'t', v:c}; ++i; break; + } + } + var bt = 0, ss0 = 0, ssm; + for(i=out.length-1, lst='t'; i >= 0; --i) { + switch(out[i].t) { + case 'h': case 'H': out[i].t = hr; lst='h'; if(bt < 1) bt = 1; break; + case 's': + if((ssm=out[i].v.match(/\.0+$/))) ss0=Math.max(ss0,ssm[0].length-1); + if(bt < 3) bt = 3; + /* falls through */ + case 'd': case 'y': case 'M': case 'e': lst=out[i].t; break; + case 'm': if(lst === 's') { out[i].t = 'M'; if(bt < 2) bt = 2; } break; + case 'X': if(out[i].v === "B2"); + break; + case 'Z': + if(bt < 1 && out[i].v.match(/[Hh]/)) bt = 1; + if(bt < 2 && out[i].v.match(/[Mm]/)) bt = 2; + if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3; + } + } + switch(bt) { + case 0: break; + case 1: + if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } + if(dt.S >= 60) { dt.S = 0; ++dt.M; } + if(dt.M >= 60) { dt.M = 0; ++dt.H; } + break; + case 2: + if(dt.u >= 0.5) { dt.u = 0; ++dt.S; } + if(dt.S >= 60) { dt.S = 0; ++dt.M; } + break; + } + /* replace fields */ + var nstr = "", jj; + for(i=0; i < out.length; ++i) { + switch(out[i].t) { + case 't': case 'T': case ' ': case 'D': break; + case 'X': out[i] = undefined; break; + case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z': + out[i].v = write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0); + out[i].t = 't'; break; + case 'n': case '(': case '?': + jj = i+1; + while(out[jj] != null && ( + (c=out[jj].t) === "?" || c === "D" || + (c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/') || + out[i].t === '(' && (c === ' ' || c === 'n' || c === ')') || + c === 't' && (out[jj].v === '/' || '$€'.indexOf(out[jj].v) > -1 || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?') + )) { + out[i].v += out[jj].v; + out[jj] = undefined; ++jj; + } + nstr += out[i].v; + i = jj-1; break; + case 'G': out[i].t = 't'; out[i].v = general_fmt(v,opts); break; + } + } + var vv = "", myv, ostr; + if(nstr.length > 0) { + myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v); /* '-' */ + ostr = write_num(nstr.charCodeAt(0) === 40 ? '(' : 'n', nstr, myv); /* '(' */ + jj=ostr.length-1; + var decpt = out.length; + for(i=0; i < out.length; ++i) if(out[i] != null && out[i].v.indexOf(".") > -1) { decpt = i; break; } + var lasti=out.length; + if(decpt === out.length && ostr.indexOf("E") === -1) { + for(i=out.length-1; i>= 0;--i) { + if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; + if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); } + else if(jj < 0) out[i].v = ""; + else { out[i].v = ostr.substr(0, jj+1); jj = -1; } + out[i].t = 't'; + lasti = i; + } + if(jj>=0 && lasti= 0; --i) { + if(out[i] == null || 'n?('.indexOf(out[i].t) === -1) continue; + j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1; + vv = out[i].v.substr(j+1); + for(; j>=0; --j) { + if(jj>=0 && (out[i].v[j] === "0" || out[i].v[j] === "#")) vv = ostr[jj--] + vv; + } + out[i].v = vv; + out[i].t = 't'; + lasti = i; + } + if(jj>=0 && lasti-1&&i===decpt?out[i].v.indexOf(".")+1:0; + vv = out[i].v.substr(0,j); + for(; j-1) { + myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v); + out[i].v = write_num(out[i].t, out[i].v, myv); + out[i].t = 't'; + } + var retval = ""; + for(i=0; i !== out.length; ++i) if(out[i] != null) retval += out[i].v; + return retval; +} +SSF._eval = eval_fmt; +var cfregex = /\[[=<>]/; +var cfregex2 = /\[([=<>]*)(-?\d+\.?\d*)\]/; +function chkcond(v, rr) { + if(rr == null) return false; + var thresh = parseFloat(rr[2]); + switch(rr[1]) { + case "=": if(v == thresh) return true; break; + case ">": if(v > thresh) return true; break; + case "<": if(v < thresh) return true; break; + case "<>": if(v != thresh) return true; break; + case ">=": if(v >= thresh) return true; break; + case "<=": if(v <= thresh) return true; break; + } + return false; +} +function choose_fmt(f, v) { + var fmt = split_fmt(f); + var l = fmt.length, lat = fmt[l-1].indexOf("@"); + if(l<4 && lat>-1) --l; + if(fmt.length > 4) throw "cannot find right format for |" + fmt + "|"; + if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"]; + switch(fmt.length) { + case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break; + case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break; + case 3: fmt = lat>-1 ? [fmt[0], fmt[1], fmt[0], fmt[2]] : [fmt[0], fmt[1], fmt[2], "@"]; break; + case 4: break; + } + var ff = v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2]; + if(fmt[0].indexOf("[") === -1 && fmt[1].indexOf("[") === -1) return [l, ff]; + if(fmt[0].match(cfregex) != null || fmt[1].match(cfregex) != null) { + var m1 = fmt[0].match(cfregex2); + var m2 = fmt[1].match(cfregex2); + return chkcond(v, m1) ? [l, fmt[0]] : chkcond(v, m2) ? [l, fmt[1]] : [l, fmt[m1 != null && m2 != null ? 2 : 1]]; + } + return [l, ff]; +} +function format(fmt,v,o) { + fixopts(o != null ? o : (o=[])); + var sfmt = ""; + switch(typeof fmt) { + case "string": sfmt = fmt; break; + case "number": sfmt = (o.table != null ? o.table : table_fmt)[fmt]; break; + } + if(isgeneral(sfmt,0)) return general_fmt(v, o); + var f = choose_fmt(sfmt, v); + if(isgeneral(f[1])) return general_fmt(v, o); + if(v === true) v = "TRUE"; else if(v === false) v = "FALSE"; + else if(v === "" || v == null) return ""; + return eval_fmt(f[1], v, o, f[0]); +} +SSF._table = table_fmt; +SSF.load = function load_entry(fmt, idx) { table_fmt[idx] = fmt; }; +SSF.format = format; +SSF.get_table = function get_table() { return table_fmt; }; +SSF.load_table = function load_table(tbl) { for(var i=0; i!=0x0188; ++i) if(tbl[i] !== undefined) SSF.load(tbl[i], i); }; +}; +make_ssf(SSF); +/* map from xlml named formats to SSF TODO: localize */ +var XLMLFormatMap = { + "General Number": "General", + "General Date": SSF._table[22], + "Long Date": "dddd, mmmm dd, yyyy", + "Medium Date": SSF._table[15], + "Short Date": SSF._table[14], + "Long Time": SSF._table[19], + "Medium Time": SSF._table[18], + "Short Time": SSF._table[20], + "Currency": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)', + "Fixed": SSF._table[2], + "Standard": SSF._table[4], + "Percent": SSF._table[10], + "Scientific": SSF._table[11], + "Yes/No": '"Yes";"Yes";"No";@', + "True/False": '"True";"True";"False";@', + "On/Off": '"Yes";"Yes";"No";@' +}; + +var DO_NOT_EXPORT_CFB = true; +/* cfb.js (C) 2013-2014 SheetJS -- http://sheetjs.com */ +/* vim: set ts=2: */ +/*jshint eqnull:true */ + +/* [MS-CFB] v20130118 */ +var CFB = (function _CFB(){ +var exports = {}; +exports.version = '0.10.2'; +function parse(file) { +var mver = 3; // major version +var ssz = 512; // sector size +var nmfs = 0; // number of mini FAT sectors +var ndfs = 0; // number of DIFAT sectors +var dir_start = 0; // first directory sector location +var minifat_start = 0; // first mini FAT sector location +var difat_start = 0; // first mini FAT sector location + +var fat_addrs = []; // locations of FAT sectors + +/* [MS-CFB] 2.2 Compound File Header */ +var blob = file.slice(0,512); +prep_blob(blob, 0); + +/* major version */ +var mv = check_get_mver(blob); +mver = mv[0]; +switch(mver) { + case 3: ssz = 512; break; case 4: ssz = 4096; break; + default: throw "Major Version: Expected 3 or 4 saw " + mver; +} + +/* reprocess header */ +if(ssz !== 512) { blob = file.slice(0,ssz); prep_blob(blob, 28 /* blob.l */); } +/* Save header for final object */ +var header = file.slice(0,ssz); + +check_shifts(blob, mver); + +// Number of Directory Sectors +var nds = blob.read_shift(4, 'i'); +if(mver === 3 && nds !== 0) throw '# Directory Sectors: Expected 0 saw ' + nds; + +// Number of FAT Sectors +//var nfs = blob.read_shift(4, 'i'); +blob.l += 4; + +// First Directory Sector Location +dir_start = blob.read_shift(4, 'i'); + +// Transaction Signature +blob.l += 4; + +// Mini Stream Cutoff Size +blob.chk('00100000', 'Mini Stream Cutoff Size: '); + +// First Mini FAT Sector Location +minifat_start = blob.read_shift(4, 'i'); + +// Number of Mini FAT Sectors +nmfs = blob.read_shift(4, 'i'); + +// First DIFAT sector location +difat_start = blob.read_shift(4, 'i'); + +// Number of DIFAT Sectors +ndfs = blob.read_shift(4, 'i'); + +// Grab FAT Sector Locations +for(var q, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */ + q = blob.read_shift(4, 'i'); + if(q<0) break; + fat_addrs[j] = q; +} + +/** Break the file up into sectors */ +var sectors = sectorify(file, ssz); + +sleuth_fat(difat_start, ndfs, sectors, ssz, fat_addrs); + +/** Chains */ +var sector_list = make_sector_list(sectors, dir_start, fat_addrs, ssz); + +sector_list[dir_start].name = "!Directory"; +if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT"; +sector_list[fat_addrs[0]].name = "!FAT"; +sector_list.fat_addrs = fat_addrs; +sector_list.ssz = ssz; + +/* [MS-CFB] 2.6.1 Compound File Directory Entry */ +var files = {}, Paths = [], FileIndex = [], FullPaths = [], FullPathDir = {}; +read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex); + +build_full_paths(FileIndex, FullPathDir, FullPaths, Paths); + +var root_name = Paths.shift(); +Paths.root = root_name; + +/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ +var find_path = make_find_path(FullPaths, Paths, FileIndex, files, root_name); + +return { + raw: {header: header, sectors: sectors}, + FileIndex: FileIndex, + FullPaths: FullPaths, + FullPathDir: FullPathDir, + find: find_path +}; +} // parse + +/* [MS-CFB] 2.2 Compound File Header -- read up to major version */ +function check_get_mver(blob) { + // header signature 8 + blob.chk(HEADER_SIGNATURE, 'Header Signature: '); + + // clsid 16 + blob.chk(HEADER_CLSID, 'CLSID: '); + + // minor version 2 + var mver = blob.read_shift(2, 'u'); + + return [blob.read_shift(2,'u'), mver]; +} +function check_shifts(blob, mver) { + var shift = 0x09; + + // Byte Order + blob.chk('feff', 'Byte Order: '); + + // Sector Shift + switch((shift = blob.read_shift(2))) { + case 0x09: if(mver !== 3) throw 'MajorVersion/SectorShift Mismatch'; break; + case 0x0c: if(mver !== 4) throw 'MajorVersion/SectorShift Mismatch'; break; + default: throw 'Sector Shift: Expected 9 or 12 saw ' + shift; + } + + // Mini Sector Shift + blob.chk('0600', 'Mini Sector Shift: '); + + // Reserved + blob.chk('000000000000', 'Reserved: '); +} + +/** Break the file up into sectors */ +function sectorify(file, ssz) { + var nsectors = Math.ceil(file.length/ssz)-1; + var sectors = new Array(nsectors); + for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz); + sectors[nsectors-1] = file.slice(nsectors*ssz); + return sectors; +} + +/* [MS-CFB] 2.6.4 Red-Black Tree */ +function build_full_paths(FI, FPD, FP, Paths) { + var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length; + var dad = new Array(pl), q = new Array(pl); + + for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; } + + for(; j < q.length; ++j) { + i = q[j]; + L = FI[i].L; R = FI[i].R; C = FI[i].C; + if(dad[i] === i) { + if(L !== -1 /*NOSTREAM*/ && dad[L] !== L) dad[i] = dad[L]; + if(R !== -1 && dad[R] !== R) dad[i] = dad[R]; + } + if(C !== -1 /*NOSTREAM*/) dad[C] = i; + if(L !== -1) { dad[L] = dad[i]; q.push(L); } + if(R !== -1) { dad[R] = dad[i]; q.push(R); } + } + for(i=1; i !== pl; ++i) if(dad[i] === i) { + if(R !== -1 /*NOSTREAM*/ && dad[R] !== R) dad[i] = dad[R]; + else if(L !== -1 && dad[L] !== L) dad[i] = dad[L]; + } + + for(i=1; i < pl; ++i) { + if(FI[i].type === 0 /* unknown */) continue; + j = dad[i]; + if(j === 0) FP[i] = FP[0] + "/" + FP[i]; + else while(j !== 0) { + FP[i] = FP[j] + "/" + FP[i]; + j = dad[j]; + } + dad[i] = 0; + } + + FP[0] += "/"; + for(i=1; i < pl; ++i) { + if(FI[i].type !== 2 /* stream */) FP[i] += "/"; + FPD[FP[i]] = FI[i]; + } +} + +/* [MS-CFB] 2.6.4 */ +function make_find_path(FullPaths, Paths, FileIndex, files, root_name) { + var UCFullPaths = new Array(FullPaths.length); + var UCPaths = new Array(Paths.length), i; + for(i = 0; i < FullPaths.length; ++i) UCFullPaths[i] = FullPaths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); + for(i = 0; i < Paths.length; ++i) UCPaths[i] = Paths[i].toUpperCase().replace(chr0,'').replace(chr1,'!'); + return function find_path(path) { + var k; + if(path.charCodeAt(0) === 47 /* "/" */) { k=true; path = root_name + path; } + else k = path.indexOf("/") !== -1; + var UCPath = path.toUpperCase().replace(chr0,'').replace(chr1,'!'); + var w = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath); + if(w === -1) return null; + return k === true ? FileIndex[w] : files[Paths[w]]; + }; +} + +/** Chase down the rest of the DIFAT chain to build a comprehensive list + DIFAT chains by storing the next sector number as the last 32 bytes */ +function sleuth_fat(idx, cnt, sectors, ssz, fat_addrs) { + var q; + if(idx === ENDOFCHAIN) { + if(cnt !== 0) throw "DIFAT chain shorter than expected"; + } else if(idx !== -1 /*FREESECT*/) { + var sector = sectors[idx], m = (ssz>>>2)-1; + for(var i = 0; i < m; ++i) { + if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break; + fat_addrs.push(q); + } + sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs); + } +} + +/** Follow the linked list of sectors for a given starting point */ +function get_sector_list(sectors, start, fat_addrs, ssz, chkd) { + var sl = sectors.length; + var buf, buf_chain; + if(!chkd) chkd = new Array(sl); + var modulus = ssz - 1, j, jj; + buf = []; + buf_chain = []; + for(j=start; j>=0;) { + chkd[j] = true; + buf[buf.length] = j; + buf_chain.push(sectors[j]); + var addr = fat_addrs[Math.floor(j*4/ssz)]; + jj = ((j*4) & modulus); + if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + j = __readInt32LE(sectors[addr], jj); + } + return {nodes: buf, data:__toBuffer([buf_chain])}; +} + +/** Chase down the sector linked lists */ +function make_sector_list(sectors, dir_start, fat_addrs, ssz) { + var sl = sectors.length, sector_list = new Array(sl); + var chkd = new Array(sl), buf, buf_chain; + var modulus = ssz - 1, i, j, k, jj; + for(i=0; i < sl; ++i) { + buf = []; + k = (i + dir_start); if(k >= sl) k-=sl; + if(chkd[k] === true) continue; + buf_chain = []; + for(j=k; j>=0;) { + chkd[j] = true; + buf[buf.length] = j; + buf_chain.push(sectors[j]); + var addr = fat_addrs[Math.floor(j*4/ssz)]; + jj = ((j*4) & modulus); + if(ssz < 4 + jj) throw "FAT boundary crossed: " + j + " 4 "+ssz; + j = __readInt32LE(sectors[addr], jj); + } + sector_list[k] = {nodes: buf, data:__toBuffer([buf_chain])}; + } + return sector_list; +} + +/* [MS-CFB] 2.6.1 Compound File Directory Entry */ +function read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex) { + var blob; + var minifat_store = 0, pl = (Paths.length?2:0); + var sector = sector_list[dir_start].data; + var i = 0, namelen = 0, name, o, ctime, mtime; + for(; i < sector.length; i+= 128) { + blob = sector.slice(i, i+128); + prep_blob(blob, 64); + namelen = blob.read_shift(2); + if(namelen === 0) continue; + name = __utf16le(blob,0,namelen-pl); + Paths.push(name); + o = { + name: name, + type: blob.read_shift(1), + color: blob.read_shift(1), + L: blob.read_shift(4, 'i'), + R: blob.read_shift(4, 'i'), + C: blob.read_shift(4, 'i'), + clsid: blob.read_shift(16), + state: blob.read_shift(4, 'i') + }; + ctime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); + if(ctime !== 0) { + o.ctime = ctime; o.ct = read_date(blob, blob.l-8); + } + mtime = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2); + if(mtime !== 0) { + o.mtime = mtime; o.mt = read_date(blob, blob.l-8); + } + o.start = blob.read_shift(4, 'i'); + o.size = blob.read_shift(4, 'i'); + if(o.type === 5) { /* root */ + minifat_store = o.start; + if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData"; + /*minifat_size = o.size;*/ + } else if(o.size >= 4096 /* MSCSZ */) { + o.storage = 'fat'; + if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz); + sector_list[o.start].name = o.name; + o.content = sector_list[o.start].data.slice(0,o.size); + prep_blob(o.content, 0); + } else { + o.storage = 'minifat'; + if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN) { + o.content = sector_list[minifat_store].data.slice(o.start*MSSZ,o.start*MSSZ+o.size); + prep_blob(o.content, 0); + } + } + files[name] = o; + FileIndex.push(o); + } +} + +function read_date(blob, offset) { + return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000); +} + +var fs; +function readFileSync(filename, options) { + if(fs === undefined) fs = require('fs'); + return parse(fs.readFileSync(filename), options); +} + +function readSync(blob, options) { + switch(options !== undefined && options.type !== undefined ? options.type : "base64") { + case "file": return readFileSync(blob, options); + case "base64": return parse(s2a(Base64.decode(blob)), options); + case "binary": return parse(s2a(blob), options); + } + return parse(blob); +} + +/** CFB Constants */ +var MSSZ = 64; /* Mini Sector Size = 1<<6 */ +//var MSCSZ = 4096; /* Mini Stream Cutoff Size */ +/* 2.1 Compound File Sector Numbers and Types */ +var ENDOFCHAIN = -2; +/* 2.2 Compound File Header */ +var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1'; +var HEADER_CLSID = '00000000000000000000000000000000'; +var consts = { + /* 2.1 Compund File Sector Numbers and Types */ + MAXREGSECT: -6, + DIFSECT: -4, + FATSECT: -3, + ENDOFCHAIN: ENDOFCHAIN, + FREESECT: -1, + /* 2.2 Compound File Header */ + HEADER_SIGNATURE: HEADER_SIGNATURE, + HEADER_MINOR_VERSION: '3e00', + MAXREGSID: -6, + NOSTREAM: -1, + HEADER_CLSID: HEADER_CLSID, + /* 2.6.1 Compound File Directory Entry */ + EntryTypes: ['unknown','storage','stream','lockbytes','property','root'] +}; + +exports.read = readSync; +exports.parse = parse; +exports.utils = { + ReadShift: ReadShift, + CheckField: CheckField, + prep_blob: prep_blob, + bconcat: bconcat, + consts: consts +}; + +return exports; +})(); + +if(typeof require !== 'undefined' && typeof module !== 'undefined' && typeof DO_NOT_EXPORT_CFB === 'undefined') { module.exports = CFB; } +function isval(x) { return x !== undefined && x !== null; } + +function keys(o) { return Object.keys(o); } + +function evert_key(obj, key) { + var o = [], K = keys(obj); + for(var i = 0; i !== K.length; ++i) o[obj[K[i]][key]] = K[i]; + return o; +} + +function evert(obj) { + var o = [], K = keys(obj); + for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = K[i]; + return o; +} + +function evert_num(obj) { + var o = [], K = keys(obj); + for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = parseInt(K[i],10); + return o; +} + +function evert_arr(obj) { + var o = [], K = keys(obj); + for(var i = 0; i !== K.length; ++i) { + if(o[obj[K[i]]] == null) o[obj[K[i]]] = []; + o[obj[K[i]]].push(K[i]); + } + return o; +} + +/* TODO: date1904 logic */ +function datenum(v, date1904) { + if(date1904) v+=1462; + var epoch = Date.parse(v); + return (epoch + 2209161600000) / (24 * 60 * 60 * 1000); +} + +function cc2str(arr) { + var o = ""; + for(var i = 0; i != arr.length; ++i) o += String.fromCharCode(arr[i]); + return o; +} + +function getdata(data) { + if(!data) return null; + if(data.name.substr(-4) === ".bin") { + if(data.data) return char_codes(data.data); + if(data.asNodeBuffer && has_buf) return data.asNodeBuffer(); + if(data._data && data._data.getContent) return Array.prototype.slice.call(data._data.getContent()); + } else { + if(data.data) return data.name.substr(-4) !== ".bin" ? debom_xml(data.data) : char_codes(data.data); + if(data.asNodeBuffer && has_buf) return debom_xml(data.asNodeBuffer().toString('binary')); + if(data.asBinary) return debom_xml(data.asBinary()); + if(data._data && data._data.getContent) return debom_xml(cc2str(Array.prototype.slice.call(data._data.getContent(),0))); + } + return null; +} + +function safegetzipfile(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]; + return null; +} + +function getzipfile(zip, file) { + var o = safegetzipfile(zip, file); + if(o == null) throw new Error("Cannot find file " + file + " in zip"); + return o; +} + +function getzipdata(zip, file, safe) { + if(!safe) return getdata(getzipfile(zip, file)); + if(!file) return null; + try { return getzipdata(zip, file); } catch(e) { return null; } +} + +var _fs, jszip; +if(typeof JSZip !== 'undefined') jszip = JSZip; +if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + if(has_buf && typeof jszip === 'undefined') jszip = require('js'+'zip'); + if(typeof jszip === 'undefined') jszip = require('./js'+'zip').JSZip; + _fs = require('f'+'s'); + } +} +var attregexg=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g; +var tagregex=/<[^>]*>/g; +var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/; +function parsexmltag(tag, skip_root) { + var z = []; + var eq = 0, c = 0; + for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break; + if(!skip_root) z[0] = tag.substr(0, eq); + if(eq === tag.length) return z; + var m = tag.match(attregexg), j=0, w="", v="", i=0, q="", cc=""; + if(m) for(i = 0; i != m.length; ++i) { + cc = m[i]; + for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break; + q = cc.substr(0,c); v = cc.substring(c+2, cc.length-1); + for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break; + if(j===q.length) z[q] = v; + else z[(j===5 && q.substr(0,5)==="xmlns"?"xmlns":"")+q.substr(j+1)] = v; + } + return z; +} +function strip_ns(x) { return x.replace(nsregex2, "<$1"); } + +var encodings = { + '"': '"', + ''': "'", + '>': '>', + '<': '<', + '&': '&', + '\\n':'\n' +}; +var rencoding = evert(encodings); +var rencstr = "&<>'\"".split(""); + +// TODO: CP remap (need to read file version to determine OS) +var unescapexml = (function() { + var encregex = /&[a-z]*;/g, coderegex = /_x([\da-fA-F]+)_/g; + return function unescapexml(text){ + var s = text + ''; + return s.replace(encregex, function($$) { return encodings[$$]; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));}); + }; +})(); + +var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g; +function escapexml(text){ + var s = text + ''; + return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).substr(-4) + "_";}); +} + +/* TODO: handle codepages */ +var xlml_fixstr = (function() { + var entregex = /&#(\d+);/g; + function entrepl($$,$1) { return String.fromCharCode(parseInt($1,10)); } + return function xlml_fixstr(str) { return str.replace(entregex,entrepl); }; +})(); + +function parsexmlbool(value, tag) { + switch(value) { + case '1': case 'true': case 'TRUE': return true; + /* case '0': case 'false': case 'FALSE':*/ + default: return false; + } +} + +var utf8read = function utf8reada(orig) { + var out = "", i = 0, c = 0, d = 0, e = 0, f = 0, w = 0; + while (i < orig.length) { + c = orig.charCodeAt(i++); + if (c < 128) { out += String.fromCharCode(c); continue; } + d = orig.charCodeAt(i++); + if (c>191 && c<224) { out += String.fromCharCode(((c & 31) << 6) | (d & 63)); continue; } + e = orig.charCodeAt(i++); + if (c < 240) { out += String.fromCharCode(((c & 15) << 12) | ((d & 63) << 6) | (e & 63)); continue; } + f = orig.charCodeAt(i++); + w = (((c & 7) << 18) | ((d & 63) << 12) | ((e & 63) << 6) | (f & 63))-65536; + out += String.fromCharCode(0xD800 + ((w>>>10)&1023)); + out += String.fromCharCode(0xDC00 + (w&1023)); + } + return out; +}; + + +if(has_buf) { + var utf8readb = function utf8readb(data) { + var out = new Buffer(2*data.length), w, i, j = 1, k = 0, ww=0, c; + for(i = 0; i < data.length; i+=j) { + j = 1; + if((c=data.charCodeAt(i)) < 128) w = c; + else if(c < 224) { w = (c&31)*64+(data.charCodeAt(i+1)&63); j=2; } + else if(c < 240) { w=(c&15)*4096+(data.charCodeAt(i+1)&63)*64+(data.charCodeAt(i+2)&63); j=3; } + else { j = 4; + w = (c & 7)*262144+(data.charCodeAt(i+1)&63)*4096+(data.charCodeAt(i+2)&63)*64+(data.charCodeAt(i+3)&63); + w -= 65536; ww = 0xD800 + ((w>>>10)&1023); w = 0xDC00 + (w&1023); + } + if(ww !== 0) { out[k++] = ww&255; out[k++] = ww>>>8; ww = 0; } + out[k++] = w%256; out[k++] = w>>>8; + } + out.length = k; + return out.toString('ucs2'); + }; + var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; + if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; + var utf8readc = function utf8readc(data) { return Buffer(data, 'binary').toString('utf8'); }; + if(utf8read(corpus) == utf8readc(corpus)) utf8read = utf8readc; +} + +// matches ... extracts content +var matchtag = (function() { + var mtcache = {}; + return function matchtag(f,g) { + var t = f+"|"+g; + if(mtcache[t] !== undefined) return mtcache[t]; + return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([^\u2603]*)',(g||""))); + }; +})(); + +var vtregex = (function(){ var vt_cache = {}; + return function vt_regex(bt) { + if(vt_cache[bt] !== undefined) return vt_cache[bt]; + return (vt_cache[bt] = new RegExp("(.*?)", 'g') ); +};})(); +var vtvregex = /<\/?vt:variant>/g, vtmregex = /]*)>(.*)' + g + '';} + +function wxt_helper(h) { return keys(h).map(function(k) { return " " + k + '="' + h[k] + '"';}).join(""); } +function writextag(f,g,h) { return '<' + f + (isval(h) ? wxt_helper(h) : "") + (isval(g) ? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '';} + +function write_w3cdtf(d, t) { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } } + +function write_vt(s) { + switch(typeof s) { + case 'string': return writextag('vt:lpwstr', s); + case 'number': return writextag((s|0)==s?'vt:i4':'vt:r8', String(s)); + case 'boolean': return writextag('vt:bool',s?'true':'false'); + } + if(s instanceof Date) return writextag('vt:filetime', write_w3cdtf(s)); + throw new Error("Unable to serialize " + s); +} + +var XML_HEADER = '\r\n'; +var XMLNS = { + 'dc': 'http://purl.org/dc/elements/1.1/', + 'dcterms': 'http://purl.org/dc/terms/', + 'dcmitype': 'http://purl.org/dc/dcmitype/', + 'mx': 'http://schemas.microsoft.com/office/mac/excel/2008/main', + 'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships', + 'sjs': 'http://schemas.openxmlformats.org/package/2006/sheetjs/core-properties', + 'vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes', + 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'xsd': 'http://www.w3.org/2001/XMLSchema' +}; + +XMLNS.main = [ + 'http://schemas.openxmlformats.org/spreadsheetml/2006/main', + 'http://purl.oclc.org/ooxml/spreadsheetml/main', + 'http://schemas.microsoft.com/office/excel/2006/main', + 'http://schemas.microsoft.com/office/excel/2006/2' +]; + +function readIEEE754(buf, idx, isLE, nl, ml) { + if(isLE === undefined) isLE = true; + if(!nl) nl = 8; + if(!ml && nl === 8) ml = 52; + var e, m, el = nl * 8 - ml - 1, eMax = (1 << el) - 1, eBias = eMax >> 1; + var bits = -7, d = isLE ? -1 : 1, i = isLE ? (nl - 1) : 0, s = buf[idx + i]; + + i += d; + e = s & ((1 << (-bits)) - 1); s >>>= (-bits); bits += el; + for (; bits > 0; e = e * 256 + buf[idx + i], i += d, bits -= 8); + m = e & ((1 << (-bits)) - 1); e >>>= (-bits); bits += ml; + for (; bits > 0; m = m * 256 + buf[idx + i], i += d, bits -= 8); + if (e === eMax) return m ? NaN : ((s ? -1 : 1) * Infinity); + else if (e === 0) e = 1 - eBias; + else { m = m + Math.pow(2, ml); e = e - eBias; } + return (s ? -1 : 1) * m * Math.pow(2, e - ml); +} + +var __toBuffer, ___toBuffer; +__toBuffer = ___toBuffer = function toBuffer_(bufs) { var x = []; for(var i = 0; i < bufs[0].length; ++i) { x.push.apply(x, bufs[0][i]); } return x; }; +var __utf16le, ___utf16le; +__utf16le = ___utf16le = function utf16le_(b,s,e) { var ss=[]; for(var i=s; i 0 ? __utf8(b, i+4,i+4+len-1) : "";}; +var __lpwstr, ___lpwstr; +__lpwstr = ___lpwstr = function lpwstr_(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";}; +var __double, ___double; +__double = ___double = function(b, idx) { return readIEEE754(b, idx);}; + +var is_buf = function is_buf_a(a) { return Array.isArray(a); }; +if(has_buf) { + __utf16le = function utf16le_b(b,s,e) { if(!Buffer.isBuffer(b)) return ___utf16le(b,s,e); return b.toString('utf16le',s,e); }; + __hexlify = function(b,s,l) { return Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); }; + __lpstr = function lpstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";}; + __lpwstr = function lpwstr_b(b,i) { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);}; + __utf8 = function utf8_b(s,e) { return this.toString('utf8',s,e); }; + __toBuffer = function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);}; + bconcat = function(bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); }; + __double = function double_(b,i) { if(Buffer.isBuffer(b)) return b.readDoubleLE(i); return ___double(b,i); }; + is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a); }; +} + +/* from js-xls */ +if(typeof cptable !== 'undefined') { + __utf16le = function(b,s,e) { return cptable.utils.decode(1200, b.slice(s,e)); }; + __utf8 = function(b,s,e) { return cptable.utils.decode(65001, b.slice(s,e)); }; + __lpstr = function(b,i) { var len = __readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";}; + __lpwstr = function(b,i) { var len = 2*__readUInt32LE(b,i); return len > 0 ? cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";}; +} + +var __readUInt8 = function(b, idx) { return b[idx]; }; +var __readUInt16LE = function(b, idx) { return b[idx+1]*(1<<8)+b[idx]; }; +var __readInt16LE = function(b, idx) { var u = b[idx+1]*(1<<8)+b[idx]; return (u < 0x8000) ? u : (0xffff - u + 1) * -1; }; +var __readUInt32LE = function(b, idx) { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; }; +var __readInt32LE = function(b, idx) { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; }; + +var ___unhexlify = function(s) { return s.match(/../g).map(function(x) { return parseInt(x,16);}); }; +var __unhexlify = typeof Buffer !== "undefined" ? function(s) { return Buffer.isBuffer(s) ? new Buffer(s, 'hex') : ___unhexlify(s); } : ___unhexlify; + +function ReadShift(size, t) { + var o="", oI, oR, oo=[], w, vv, i, loc; + switch(t) { + case 'dbcs': + loc = this.l; + if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le"); + else for(i = 0; i != size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; } + size *= 2; + break; + + case 'utf8': o = __utf8(this, this.l, this.l + size); break; + case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break; + + /* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */ + case 'lpstr': o = __lpstr(this, this.l); size = 5 + o.length; break; + /* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */ + case 'lpwstr': o = __lpwstr(this, this.l); size = 5 + o.length; if(o[o.length-1] == '\u0000') size += 2; break; + + case 'cstr': size = 0; o = ""; + while((w=__readUInt8(this, this.l + size++))!==0) oo.push(_getchar(w)); + o = oo.join(""); break; + case 'wstr': size = 0; o = ""; + while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(_getchar(w));size+=2;} + size+=2; o = oo.join(""); break; + + /* sbcs and dbcs support continue records in the SST way TODO codepages */ + case 'dbcs-cont': o = ""; loc = this.l; + for(i = 0; i != size; ++i) { + if(this.lens && this.lens.indexOf(loc) !== -1) { + w = __readUInt8(this, loc); + this.l = loc + 1; + vv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont'); + return oo.join("") + vv; + } + oo.push(_getchar(__readUInt16LE(this, loc))); + loc+=2; + } o = oo.join(""); size *= 2; break; + + case 'sbcs-cont': o = ""; loc = this.l; + for(i = 0; i != size; ++i) { + if(this.lens && this.lens.indexOf(loc) !== -1) { + w = __readUInt8(this, loc); + this.l = loc + 1; + vv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont'); + return oo.join("") + vv; + } + oo.push(_getchar(__readUInt8(this, loc))); + loc+=1; + } o = oo.join(""); break; + + default: + switch(size) { + case 1: oI = __readUInt8(this, this.l); this.l++; return oI; + case 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI; + case 4: + if(t === 'i' || (this[this.l+3] & 0x80)===0) { oI = __readInt32LE(this, this.l); this.l += 4; return oI; } + else { oR = __readUInt32LE(this, this.l); this.l += 4; return oR; } + case 8: if(t === 'f') { oR = __double(this, this.l); this.l += 8; return oR; } + /* falls through */ + case 16: o = __hexlify(this, this.l, size); break; + }} + this.l+=size; return o; +} + +function WriteShift(t, val, f) { + var size, i; + if(f === 'dbcs') { + for(i = 0; i != val.length; ++i) this.writeUInt16LE(val.charCodeAt(i), this.l + 2 * i); + size = 2 * val.length; + } else switch(t) { + case 1: size = 1; this[this.l] = val&255; break; + case 3: size = 3; this[this.l+2] = val & 255; val >>>= 8; this[this.l+1] = val&255; val >>>= 8; this[this.l] = val&255; break; + case 4: size = 4; this.writeUInt32LE(val, this.l); break; + case 8: size = 8; if(f === 'f') { this.writeDoubleLE(val, this.l); break; } + /* falls through */ + case 16: break; + case -4: size = 4; this.writeInt32LE(val, this.l); break; + } + this.l += size; return this; +} + +function CheckField(hexstr, fld) { + var m = __hexlify(this,this.l,hexstr.length>>1); + if(m !== hexstr) throw fld + 'Expected ' + hexstr + ' saw ' + m; + this.l += hexstr.length>>1; +} + +function prep_blob(blob, pos) { + blob.l = pos; + blob.read_shift = ReadShift; + blob.chk = CheckField; + blob.write_shift = WriteShift; +} + +function parsenoop(blob, length) { blob.l += length; } + +function writenoop(blob, length) { blob.l += length; } + +function new_buf(sz) { + var o = new_raw_buf(sz); + prep_blob(o, 0); + return o; +} + +/* [MS-XLSB] 2.1.4 Record */ +function recordhopper(data, cb, opts) { + var tmpbyte, cntbyte, length; + prep_blob(data, data.l || 0); + while(data.l < data.length) { + var RT = data.read_shift(1); + if(RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F)<<7); + var R = XLSBRecordEnum[RT] || XLSBRecordEnum[0xFFFF]; + tmpbyte = data.read_shift(1); + length = tmpbyte & 0x7F; + for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte); + var d = R.f(data, length, opts); + if(cb(d, R, RT)) return; + } +} + +/* control buffer usage for fixed-length buffers */ +function buf_array() { + var bufs = [], blksz = 2048; + var newblk = function ba_newblk(sz) { + var o = new_buf(sz); + prep_blob(o, 0); + return o; + }; + + var curbuf = newblk(blksz); + + var endbuf = function ba_endbuf() { + curbuf.length = curbuf.l; + if(curbuf.length > 0) bufs.push(curbuf); + curbuf = null; + }; + + var next = function ba_next(sz) { + if(sz < curbuf.length - curbuf.l) return curbuf; + endbuf(); + return (curbuf = newblk(Math.max(sz+1, blksz))); + }; + + var end = function ba_end() { + endbuf(); + return __toBuffer([bufs]); + }; + + var push = function ba_push(buf) { endbuf(); curbuf = buf; next(blksz); }; + + return { next:next, push:push, end:end, _bufs:bufs }; +} + +function write_record(ba, type, payload, length) { + var t = evert_RE[type], l; + if(!length) length = XLSBRecordEnum[t].p || (payload||[]).length || 0; + l = 1 + (t >= 0x80 ? 1 : 0) + 1 + length; + if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l; + var o = ba.next(l); + if(t <= 0x7F) o.write_shift(1, t); + else { + o.write_shift(1, (t & 0x7F) + 0x80); + o.write_shift(1, (t >> 7)); + } + for(var i = 0; i != 4; ++i) { + if(length >= 0x80) { o.write_shift(1, (length & 0x7F)+0x80); length >>= 7; } + else { o.write_shift(1, length); break; } + } + if(length > 0 && is_buf(payload)) ba.push(payload); +} +/* XLS ranges enforced */ +function shift_cell_xls(cell, tgt) { + if(tgt.s) { + if(cell.cRel) cell.c += tgt.s.c; + if(cell.rRel) cell.r += tgt.s.r; + } else { + cell.c += tgt.c; + cell.r += tgt.r; + } + cell.cRel = cell.rRel = 0; + while(cell.c >= 0x100) cell.c -= 0x100; + while(cell.r >= 0x10000) cell.r -= 0x10000; + return cell; +} + +function shift_range_xls(cell, range) { + cell.s = shift_cell_xls(cell.s, range.s); + cell.e = shift_cell_xls(cell.e, range.s); + return cell; +} + +var OFFCRYPTO = {}; +var make_offcrypto = function(O, _crypto) { + var crypto; + if(typeof _crypto !== 'undefined') crypto = _crypto; + else if(typeof require !== 'undefined') { + try { crypto = require('cry'+'pto'); } + catch(e) { crypto = null; } + } + + O.rc4 = function(key, data) { + var S = new Array(256); + var c = 0, i = 0, j = 0, t = 0; + for(i = 0; i != 256; ++i) S[i] = i; + for(i = 0; i != 256; ++i) { + j = (j + S[i] + (key[i%key.length]).charCodeAt(0))&255; + t = S[i]; S[i] = S[j]; S[j] = t; + } + i = j = 0; out = Buffer(data.length); + for(c = 0; c != data.length; ++c) { + i = (i + 1)&255; + j = (j + S[i])%256; + t = S[i]; S[i] = S[j]; S[j] = t; + out[c] = (data[c] ^ S[(S[i]+S[j])&255]); + } + return out; + }; + + if(crypto) { + O.md5 = function(hex) { return crypto.createHash('md5').update(hex).digest('hex'); }; + } else { + O.md5 = function(hex) { throw "unimplemented"; }; + } +}; +make_offcrypto(OFFCRYPTO, typeof crypto !== "undefined" ? crypto : undefined); + + +/* [MS-XLSB] 2.5.143 */ +function parse_StrRun(data, length) { + return { ich: data.read_shift(2), ifnt: data.read_shift(2) }; +} + +/* [MS-XLSB] 2.1.7.121 */ +function parse_RichStr(data, length) { + var start = data.l; + var flags = data.read_shift(1); + var str = parse_XLWideString(data); + var rgsStrRun = []; + var z = { t: str, h: str }; + if((flags & 1) !== 0) { /* fRichStr */ + /* TODO: formatted string */ + var dwSizeStrRun = data.read_shift(4); + for(var i = 0; i != dwSizeStrRun; ++i) rgsStrRun.push(parse_StrRun(data)); + z.r = rgsStrRun; + } + else z.r = "" + escapexml(str) + ""; + if((flags & 2) !== 0) { /* fExtStr */ + /* TODO: phonetic string */ + } + data.l = start + length; + return z; +} +function write_RichStr(str, o) { + /* TODO: formatted string */ + if(o == null) o = new_buf(5+2*str.t.length); + o.write_shift(1,0); + write_XLWideString(str.t, o); + return o; +} + +/* [MS-XLSB] 2.5.9 */ +function parse_XLSBCell(data) { + var col = data.read_shift(4); + var iStyleRef = data.read_shift(2); + iStyleRef += data.read_shift(1) <<16; + var fPhShow = data.read_shift(1); + return { c:col, iStyleRef: iStyleRef }; +} +function write_XLSBCell(cell, o) { + if(o == null) o = new_buf(8); + o.write_shift(-4, cell.c); + o.write_shift(3, cell.iStyleRef === undefined ? cell.iStyleRef : cell.s); + o.write_shift(1, 0); /* fPhShow */ + return o; +} + + +/* [MS-XLSB] 2.5.21 */ +function parse_XLSBCodeName (data, length) { return parse_XLWideString(data, length); } + +/* [MS-XLSB] 2.5.166 */ +function parse_XLNullableWideString(data) { + var cchCharacters = data.read_shift(4); + return cchCharacters === 0 || cchCharacters === 0xFFFFFFFF ? "" : data.read_shift(cchCharacters, 'dbcs'); +} +function write_XLNullableWideString(data, o) { + if(!o) o = new_buf(127); + o.write_shift(4, data.length > 0 ? data.length : 0xFFFFFFFF); + if(data.length > 0) o.write_shift(0, data, 'dbcs'); + return o; +} + +/* [MS-XLSB] 2.5.168 */ +function parse_XLWideString(data) { + var cchCharacters = data.read_shift(4); + return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs'); +} +function write_XLWideString(data, o) { + if(o == null) o = new_buf(4+2*data.length); + o.write_shift(4, data.length); + if(data.length > 0) o.write_shift(0, data, 'dbcs'); + return o; +} + +/* [MS-XLSB] 2.5.114 */ +var parse_RelID = parse_XLNullableWideString; +var write_RelID = write_XLNullableWideString; + + +/* [MS-XLSB] 2.5.122 */ +/* [MS-XLS] 2.5.217 */ +function parse_RkNumber(data) { + var b = data.slice(data.l, data.l+4); + var fX100 = b[0] & 1, fInt = b[0] & 2; + data.l+=4; + b[0] &= 0xFC; // b[0] &= ~3; + var RK = fInt === 0 ? __double([0,0,0,0,b[0],b[1],b[2],b[3]],0) : __readInt32LE(b,0)>>2; + return fX100 ? RK/100 : RK; +} + +/* [MS-XLSB] 2.5.153 */ +function parse_UncheckedRfX(data) { + var cell = {s: {}, e: {}}; + cell.s.r = data.read_shift(4); + cell.e.r = data.read_shift(4); + cell.s.c = data.read_shift(4); + cell.e.c = data.read_shift(4); + return cell; +} + +function write_UncheckedRfX(r, o) { + if(!o) o = new_buf(16); + o.write_shift(4, r.s.r); + o.write_shift(4, r.e.r); + o.write_shift(4, r.s.c); + o.write_shift(4, r.e.c); + return o; +} + +/* [MS-XLSB] 2.5.171 */ +/* [MS-XLS] 2.5.342 */ +function parse_Xnum(data, length) { return data.read_shift(8, 'f'); } +function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, 'f', data); } + +/* [MS-XLSB] 2.5.198.2 */ +var BErr = { + 0x00: "#NULL!", + 0x07: "#DIV/0!", + 0x0F: "#VALUE!", + 0x17: "#REF!", + 0x1D: "#NAME?", + 0x24: "#NUM!", + 0x2A: "#N/A", + 0x2B: "#GETTING_DATA", + 0xFF: "#WTF?" +}; +var RBErr = evert_num(BErr); + +/* [MS-XLSB] 2.4.321 BrtColor */ +function parse_BrtColor(data, length) { + var out = {}; + var d = data.read_shift(1); + out.fValidRGB = d & 1; + out.xColorType = d >>> 1; + out.index = data.read_shift(1); + out.nTintAndShade = data.read_shift(2, 'i'); + out.bRed = data.read_shift(1); + out.bGreen = data.read_shift(1); + out.bBlue = data.read_shift(1); + out.bAlpha = data.read_shift(1); +} + +/* [MS-XLSB] 2.5.52 */ +function parse_FontFlags(data, length) { + var d = data.read_shift(1); + data.l++; + var out = { + fItalic: d & 0x2, + fStrikeout: d & 0x8, + fOutline: d & 0x10, + fShadow: d & 0x20, + fCondense: d & 0x40, + fExtend: d & 0x80 + }; + return out; +} +/* [MS-OLEPS] 2.2 PropertyType */ +{ + var VT_EMPTY = 0x0000; + var VT_NULL = 0x0001; + var VT_I2 = 0x0002; + var VT_I4 = 0x0003; + var VT_R4 = 0x0004; + var VT_R8 = 0x0005; + var VT_CY = 0x0006; + var VT_DATE = 0x0007; + var VT_BSTR = 0x0008; + var VT_ERROR = 0x000A; + var VT_BOOL = 0x000B; + var VT_VARIANT = 0x000C; + var VT_DECIMAL = 0x000E; + var VT_I1 = 0x0010; + var VT_UI1 = 0x0011; + var VT_UI2 = 0x0012; + var VT_UI4 = 0x0013; + var VT_I8 = 0x0014; + var VT_UI8 = 0x0015; + var VT_INT = 0x0016; + var VT_UINT = 0x0017; + var VT_LPSTR = 0x001E; + var VT_LPWSTR = 0x001F; + var VT_FILETIME = 0x0040; + var VT_BLOB = 0x0041; + var VT_STREAM = 0x0042; + var VT_STORAGE = 0x0043; + var VT_STREAMED_Object = 0x0044; + var VT_STORED_Object = 0x0045; + var VT_BLOB_Object = 0x0046; + var VT_CF = 0x0047; + var VT_CLSID = 0x0048; + var VT_VERSIONED_STREAM = 0x0049; + var VT_VECTOR = 0x1000; + var VT_ARRAY = 0x2000; + + var VT_STRING = 0x0050; // 2.3.3.1.11 VtString + var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString + var VT_CUSTOM = [VT_STRING, VT_USTR]; +} + +/* [MS-OSHARED] 2.3.3.2.2.1 Document Summary Information PIDDSI */ +var DocSummaryPIDDSI = { + 0x01: { n: 'CodePage', t: VT_I2 }, + 0x02: { n: 'Category', t: VT_STRING }, + 0x03: { n: 'PresentationFormat', t: VT_STRING }, + 0x04: { n: 'ByteCount', t: VT_I4 }, + 0x05: { n: 'LineCount', t: VT_I4 }, + 0x06: { n: 'ParagraphCount', t: VT_I4 }, + 0x07: { n: 'SlideCount', t: VT_I4 }, + 0x08: { n: 'NoteCount', t: VT_I4 }, + 0x09: { n: 'HiddenCount', t: VT_I4 }, + 0x0a: { n: 'MultimediaClipCount', t: VT_I4 }, + 0x0b: { n: 'Scale', t: VT_BOOL }, + 0x0c: { n: 'HeadingPair', t: VT_VECTOR | VT_VARIANT }, + 0x0d: { n: 'DocParts', t: VT_VECTOR | VT_LPSTR }, + 0x0e: { n: 'Manager', t: VT_STRING }, + 0x0f: { n: 'Company', t: VT_STRING }, + 0x10: { n: 'LinksDirty', t: VT_BOOL }, + 0x11: { n: 'CharacterCount', t: VT_I4 }, + 0x13: { n: 'SharedDoc', t: VT_BOOL }, + 0x16: { n: 'HLinksChanged', t: VT_BOOL }, + 0x17: { n: 'AppVersion', t: VT_I4, p: 'version' }, + 0x1A: { n: 'ContentType', t: VT_STRING }, + 0x1B: { n: 'ContentStatus', t: VT_STRING }, + 0x1C: { n: 'Language', t: VT_STRING }, + 0x1D: { n: 'Version', t: VT_STRING }, + 0xFF: {} +}; + +/* [MS-OSHARED] 2.3.3.2.1.1 Summary Information Property Set PIDSI */ +var SummaryPIDSI = { + 0x01: { n: 'CodePage', t: VT_I2 }, + 0x02: { n: 'Title', t: VT_STRING }, + 0x03: { n: 'Subject', t: VT_STRING }, + 0x04: { n: 'Author', t: VT_STRING }, + 0x05: { n: 'Keywords', t: VT_STRING }, + 0x06: { n: 'Comments', t: VT_STRING }, + 0x07: { n: 'Template', t: VT_STRING }, + 0x08: { n: 'LastAuthor', t: VT_STRING }, + 0x09: { n: 'RevNumber', t: VT_STRING }, + 0x0A: { n: 'EditTime', t: VT_FILETIME }, + 0x0B: { n: 'LastPrinted', t: VT_FILETIME }, + 0x0C: { n: 'CreatedDate', t: VT_FILETIME }, + 0x0D: { n: 'ModifiedDate', t: VT_FILETIME }, + 0x0E: { n: 'PageCount', t: VT_I4 }, + 0x0F: { n: 'WordCount', t: VT_I4 }, + 0x10: { n: 'CharCount', t: VT_I4 }, + 0x11: { n: 'Thumbnail', t: VT_CF }, + 0x12: { n: 'ApplicationName', t: VT_LPSTR }, + 0x13: { n: 'DocumentSecurity', t: VT_I4 }, + 0xFF: {} +}; + +/* [MS-OLEPS] 2.18 */ +var SpecialProperties = { + 0x80000000: { n: 'Locale', t: VT_UI4 }, + 0x80000003: { n: 'Behavior', t: VT_UI4 }, + 0x72627262: {} +}; + +(function() { + for(var y in SpecialProperties) if(SpecialProperties.hasOwnProperty(y)) + DocSummaryPIDDSI[y] = SummaryPIDSI[y] = SpecialProperties[y]; +})(); + +/* [MS-XLS] 2.4.63 Country/Region codes */ +var CountryEnum = { + 0x0001: "US", // United States + 0x0002: "CA", // Canada + 0x0003: "", // Latin America (except Brazil) + 0x0007: "RU", // Russia + 0x0014: "EG", // Egypt + 0x001E: "GR", // Greece + 0x001F: "NL", // Netherlands + 0x0020: "BE", // Belgium + 0x0021: "FR", // France + 0x0022: "ES", // Spain + 0x0024: "HU", // Hungary + 0x0027: "IT", // Italy + 0x0029: "CH", // Switzerland + 0x002B: "AT", // Austria + 0x002C: "GB", // United Kingdom + 0x002D: "DK", // Denmark + 0x002E: "SE", // Sweden + 0x002F: "NO", // Norway + 0x0030: "PL", // Poland + 0x0031: "DE", // Germany + 0x0034: "MX", // Mexico + 0x0037: "BR", // Brazil + 0x003d: "AU", // Australia + 0x0040: "NZ", // New Zealand + 0x0042: "TH", // Thailand + 0x0051: "JP", // Japan + 0x0052: "KR", // Korea + 0x0054: "VN", // Viet Nam + 0x0056: "CN", // China + 0x005A: "TR", // Turkey + 0x0069: "JS", // Ramastan + 0x00D5: "DZ", // Algeria + 0x00D8: "MA", // Morocco + 0x00DA: "LY", // Libya + 0x015F: "PT", // Portugal + 0x0162: "IS", // Iceland + 0x0166: "FI", // Finland + 0x01A4: "CZ", // Czech Republic + 0x0376: "TW", // Taiwan + 0x03C1: "LB", // Lebanon + 0x03C2: "JO", // Jordan + 0x03C3: "SY", // Syria + 0x03C4: "IQ", // Iraq + 0x03C5: "KW", // Kuwait + 0x03C6: "SA", // Saudi Arabia + 0x03CB: "AE", // United Arab Emirates + 0x03CC: "IL", // Israel + 0x03CE: "QA", // Qatar + 0x03D5: "IR", // Iran + 0xFFFF: "US" // United States +}; + +/* [MS-XLS] 2.5.127 */ +var XLSFillPattern = [ + null, + 'solid', + 'mediumGray', + 'darkGray', + 'lightGray', + 'darkHorizontal', + 'darkVertical', + 'darkDown', + 'darkUp', + 'darkGrid', + 'darkTrellis', + 'lightHorizontal', + 'lightVertical', + 'lightDown', + 'lightUp', + 'lightGrid', + 'lightTrellis', + 'gray125', + 'gray0625' +]; + +function rgbify(arr) { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); } + +/* [MS-XLS] 2.5.161 */ +var XLSIcv = rgbify([ + /* Color Constants */ + 0x000000, + 0xFFFFFF, + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFFFF00, + 0xFF00FF, + 0x00FFFF, + + /* Defaults */ + 0x000000, + 0xFFFFFF, + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFFFF00, + 0xFF00FF, + 0x00FFFF, + + 0x800000, + 0x008000, + 0x000080, + 0x808000, + 0x800080, + 0x008080, + 0xC0C0C0, + 0x808080, + 0x9999FF, + 0x993366, + 0xFFFFCC, + 0xCCFFFF, + 0x660066, + 0xFF8080, + 0x0066CC, + 0xCCCCFF, + + 0x000080, + 0xFF00FF, + 0xFFFF00, + 0x00FFFF, + 0x800080, + 0x800000, + 0x008080, + 0x0000FF, + 0x00CCFF, + 0xCCFFFF, + 0xCCFFCC, + 0xFFFF99, + 0x99CCFF, + 0xFF99CC, + 0xCC99FF, + 0xFFCC99, + + 0x3366FF, + 0x33CCCC, + 0x99CC00, + 0xFFCC00, + 0xFF9900, + 0xFF6600, + 0x666699, + 0x969696, + 0x003366, + 0x339966, + 0x003300, + 0x333300, + 0x993300, + 0x993366, + 0x333399, + 0x333333, + + /* Sheet */ + 0xFFFFFF, + 0x000000 +]); + +/* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */ +/* 12.3 Part Summary */ +/* 14.2 Part Summary */ +/* [MS-XLSX] 2.1 Part Enumerations */ +/* [MS-XLSB] 2.1.7 Part Enumeration */ +var ct2type = { + /* Workbook */ + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks", + + /* Worksheet */ + "application/vnd.ms-excel.binIndexWs": "TODO", /* Binary Index */ + + /* Chartsheet */ + "application/vnd.ms-excel.chartsheet": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": "TODO", + + /* Dialogsheet */ + "application/vnd.ms-excel.dialogsheet": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": "TODO", + + /* Macrosheet */ + "application/vnd.ms-excel.macrosheet": "TODO", + "application/vnd.ms-excel.macrosheet+xml": "TODO", + "application/vnd.ms-excel.intlmacrosheet": "TODO", + "application/vnd.ms-excel.binIndexMs": "TODO", /* Binary Index */ + + /* File Properties */ + "application/vnd.openxmlformats-package.core-properties+xml": "coreprops", + "application/vnd.openxmlformats-officedocument.custom-properties+xml": "custprops", + "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops", + + /* Custom Data Properties */ + "application/vnd.openxmlformats-officedocument.customXmlProperties+xml": "TODO", + + /* Comments */ + "application/vnd.ms-excel.comments": "comments", + "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": "comments", + + /* PivotTable */ + "application/vnd.ms-excel.pivotTable": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO", + + /* Calculation Chain */ + "application/vnd.ms-excel.calcChain": "calcchains", + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains", + + /* Printer Settings */ + "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings": "TODO", + + /* ActiveX */ + "application/vnd.ms-office.activeX": "TODO", + "application/vnd.ms-office.activeX+xml": "TODO", + + /* Custom Toolbars */ + "application/vnd.ms-excel.attachedToolbars": "TODO", + + /* External Data Connections */ + "application/vnd.ms-excel.connections": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": "TODO", + + /* External Links */ + "application/vnd.ms-excel.externalLink": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "TODO", + + /* Metadata */ + "application/vnd.ms-excel.sheetMetadata": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "TODO", + + /* PivotCache */ + "application/vnd.ms-excel.pivotCacheDefinition": "TODO", + "application/vnd.ms-excel.pivotCacheRecords": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml": "TODO", + + /* Query Table */ + "application/vnd.ms-excel.queryTable": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml": "TODO", + + /* Shared Workbook */ + "application/vnd.ms-excel.userNames": "TODO", + "application/vnd.ms-excel.revisionHeaders": "TODO", + "application/vnd.ms-excel.revisionLog": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml": "TODO", + + /* Single Cell Table */ + "application/vnd.ms-excel.tableSingleCells": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml": "TODO", + + /* Slicer */ + "application/vnd.ms-excel.slicer": "TODO", + "application/vnd.ms-excel.slicerCache": "TODO", + "application/vnd.ms-excel.slicer+xml": "TODO", + "application/vnd.ms-excel.slicerCache+xml": "TODO", + + /* Sort Map */ + "application/vnd.ms-excel.wsSortMap": "TODO", + + /* Table */ + "application/vnd.ms-excel.table": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": "TODO", + + /* Themes */ + "application/vnd.openxmlformats-officedocument.theme+xml": "themes", + + /* Timeline */ + "application/vnd.ms-excel.Timeline+xml": "TODO", /* verify */ + "application/vnd.ms-excel.TimelineCache+xml": "TODO", /* verify */ + + /* VBA */ + "application/vnd.ms-office.vbaProject": "vba", + "application/vnd.ms-office.vbaProjectSignature": "vba", + + /* Volatile Dependencies */ + "application/vnd.ms-office.volatileDependencies": "TODO", + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml": "TODO", + + /* Control Properties */ + "application/vnd.ms-excel.controlproperties+xml": "TODO", + + /* Data Model */ + "application/vnd.openxmlformats-officedocument.model+data": "TODO", + + /* Survey */ + "application/vnd.ms-excel.Survey+xml": "TODO", + + /* Drawing */ + "application/vnd.openxmlformats-officedocument.drawing+xml": "TODO", + "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO", + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO", + "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO", + "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO", + "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml": "TODO", + "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml": "TODO", + + /* VML */ + "application/vnd.openxmlformats-officedocument.vmlDrawing": "TODO", + + "application/vnd.openxmlformats-package.relationships+xml": "rels", + "application/vnd.openxmlformats-officedocument.oleObject": "TODO", + + "sheet": "js" +}; + +var CT_LIST = (function(){ + var o = { + workbooks: { + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml", + xlsm: "application/vnd.ms-excel.sheet.macroEnabled.main+xml", + xlsb: "application/vnd.ms-excel.sheet.binary.macroEnabled.main", + xltx: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml" + }, + strs: { /* Shared Strings */ + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml", + xlsb: "application/vnd.ms-excel.sharedStrings" + }, + sheets: { + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml", + xlsb: "application/vnd.ms-excel.worksheet" + }, + styles: {/* Styles */ + xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml", + xlsb: "application/vnd.ms-excel.styles" + } + }; + keys(o).forEach(function(k) { if(!o[k].xlsm) o[k].xlsm = o[k].xlsx; }); + keys(o).forEach(function(k){ keys(o[k]).forEach(function(v) { ct2type[o[k][v]] = k; }); }); + return o; +})(); + +var type2ct = evert_arr(ct2type); + +XMLNS.CT = 'http://schemas.openxmlformats.org/package/2006/content-types'; + +function parse_ct(data, opts) { + var ctext = {}; + if(!data || !data.match) return data; + var ct = { workbooks: [], sheets: [], calcchains: [], themes: [], styles: [], + coreprops: [], extprops: [], custprops: [], strs:[], comments: [], vba: [], + TODO:[], rels:[], xmlns: "" }; + (data.match(tagregex)||[]).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0].replace(nsregex,"<")) { + case ' 0 ? ct.calcchains[0] : ""; + ct.sst = ct.strs.length > 0 ? ct.strs[0] : ""; + ct.style = ct.styles.length > 0 ? ct.styles[0] : ""; + ct.defaults = ctext; + delete ct.calcchains; + return ct; +} + +var CTYPE_XML_ROOT = writextag('Types', null, { + 'xmlns': XMLNS.CT, + 'xmlns:xsd': XMLNS.xsd, + 'xmlns:xsi': XMLNS.xsi +}); + +var CTYPE_DEFAULTS = [ + ['xml', 'application/xml'], + ['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'], + ['rels', type2ct.rels[0]] +].map(function(x) { + return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]}); +}); + +function write_ct(ct, opts) { + var o = [], v; + o[o.length] = (XML_HEADER); + o[o.length] = (CTYPE_XML_ROOT); + o = o.concat(CTYPE_DEFAULTS); + var f1 = function(w) { + if(ct[w] && ct[w].length > 0) { + v = ct[w][0]; + o[o.length] = (writextag('Override', null, { + 'PartName': (v[0] == '/' ? "":"/") + v, + 'ContentType': CT_LIST[w][opts.bookType || 'xlsx'] + })); + } + }; + var f2 = function(w) { + ct[w].forEach(function(v) { + o[o.length] = (writextag('Override', null, { + 'PartName': (v[0] == '/' ? "":"/") + v, + 'ContentType': CT_LIST[w][opts.bookType || 'xlsx'] + })); + }); + }; + var f3 = function(t) { + (ct[t]||[]).forEach(function(v) { + o[o.length] = (writextag('Override', null, { + 'PartName': (v[0] == '/' ? "":"/") + v, + 'ContentType': type2ct[t][0] + })); + }); + }; + f1('workbooks'); + f2('sheets'); + f3('themes'); + ['strs', 'styles'].forEach(f1); + ['coreprops', 'extprops', 'custprops'].forEach(f3); + if(o.length>2){ o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* 9.3.2 OPC Relationships Markup */ +var RELS = { + WB: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument", + SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument" +}; + +function parse_rels(data, currentFilePath) { + if (!data) return data; + if (currentFilePath.charAt(0) !== '/') { + currentFilePath = '/'+currentFilePath; + } + var rels = {}; + var hash = {}; + var resolveRelativePathIntoAbsolute = function (to) { + var toksFrom = currentFilePath.split('/'); + toksFrom.pop(); // folder path + var toksTo = to.split('/'); + var reversed = []; + while (toksTo.length !== 0) { + var tokTo = toksTo.shift(); + if (tokTo === '..') { + toksFrom.pop(); + } else if (tokTo !== '.') { + toksFrom.push(tokTo); + } + } + return toksFrom.join('/'); + }; + + data.match(tagregex).forEach(function(x) { + var y = parsexmltag(x); + /* 9.3.2.2 OPC_Relationships */ + if (y[0] === '2){ o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* ECMA-376 Part II 11.1 Core Properties Part */ +/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */ +var CORE_PROPS = [ + ["cp:category", "Category"], + ["cp:contentStatus", "ContentStatus"], + ["cp:keywords", "Keywords"], + ["cp:lastModifiedBy", "LastAuthor"], + ["cp:lastPrinted", "LastPrinted"], + ["cp:revision", "RevNumber"], + ["cp:version", "Version"], + ["dc:creator", "Author"], + ["dc:description", "Comments"], + ["dc:identifier", "Identifier"], + ["dc:language", "Language"], + ["dc:subject", "Subject"], + ["dc:title", "Title"], + ["dcterms:created", "CreatedDate", 'date'], + ["dcterms:modified", "ModifiedDate", 'date'] +]; + +XMLNS.CORE_PROPS = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; +RELS.CORE_PROPS = 'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties'; + +var CORE_PROPS_REGEX = (function() { + var r = new Array(CORE_PROPS.length); + for(var i = 0; i < CORE_PROPS.length; ++i) { + var f = CORE_PROPS[i]; + var g = "(?:"+ f[0].substr(0,f[0].indexOf(":")) +":)"+ f[0].substr(f[0].indexOf(":")+1); + r[i] = new RegExp("<" + g + "[^>]*>(.*)<\/" + g + ">"); + } + return r; +})(); + +function parse_core_props(data) { + var p = {}; + + for(var i = 0; i < CORE_PROPS.length; ++i) { + var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]); + if(cur != null && cur.length > 0) p[f[1]] = cur[1]; + if(f[2] === 'date' && p[f[1]]) p[f[1]] = new Date(p[f[1]]); + } + + return p; +} + +var CORE_PROPS_XML_ROOT = writextag('cp:coreProperties', null, { + //'xmlns': XMLNS.CORE_PROPS, + 'xmlns:cp': XMLNS.CORE_PROPS, + 'xmlns:dc': XMLNS.dc, + 'xmlns:dcterms': XMLNS.dcterms, + 'xmlns:dcmitype': XMLNS.dcmitype, + 'xmlns:xsi': XMLNS.xsi +}); + +function cp_doit(f, g, h, o, p) { + if(p[f] != null || g == null || g === "") return; + p[f] = g; + o[o.length] = (h ? writextag(f,g,h) : writetag(f,g)); +} + +function write_core_props(cp, opts) { + var o = [XML_HEADER, CORE_PROPS_XML_ROOT], p = {}; + if(!cp) return o.join(""); + + + if(cp.CreatedDate != null) cp_doit("dcterms:created", typeof cp.CreatedDate === "string" ? cp.CreatedDate : write_w3cdtf(cp.CreatedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p); + if(cp.ModifiedDate != null) cp_doit("dcterms:modified", typeof cp.ModifiedDate === "string" ? cp.ModifiedDate : write_w3cdtf(cp.ModifiedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p); + + for(var i = 0; i != CORE_PROPS.length; ++i) { var f = CORE_PROPS[i]; cp_doit(f[0], cp[f[1]], null, o, p); } + if(o.length>2){ o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* 15.2.12.3 Extended File Properties Part */ +/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */ +var EXT_PROPS = [ + ["Application", "Application", "string"], + ["AppVersion", "AppVersion", "string"], + ["Company", "Company", "string"], + ["DocSecurity", "DocSecurity", "string"], + ["Manager", "Manager", "string"], + ["HyperlinksChanged", "HyperlinksChanged", "bool"], + ["SharedDoc", "SharedDoc", "bool"], + ["LinksUpToDate", "LinksUpToDate", "bool"], + ["ScaleCrop", "ScaleCrop", "bool"], + ["HeadingPairs", "HeadingPairs", "raw"], + ["TitlesOfParts", "TitlesOfParts", "raw"] +]; + +XMLNS.EXT_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; +RELS.EXT_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties'; + +function parse_ext_props(data, p) { + var q = {}; if(!p) p = {}; + + EXT_PROPS.forEach(function(f) { + switch(f[2]) { + case "string": p[f[1]] = (data.match(matchtag(f[0]))||[])[1]; break; + case "bool": p[f[1]] = (data.match(matchtag(f[0]))||[])[1] === "true"; break; + case "raw": + var cur = data.match(new RegExp("<" + f[0] + "[^>]*>(.*)<\/" + f[0] + ">")); + if(cur && cur.length > 0) q[f[1]] = cur[1]; + break; + } + }); + + 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].v); break; + case "Named Ranges": ++i; break; // TODO: Handle Named Ranges + } + } + var parts = parseVector(q.TitlesOfParts).map(function(x) { return utf8read(x.v); }); + p.SheetNames = parts.slice(widx, widx + p.Worksheets); + } + return p; +} + +var EXT_PROPS_XML_ROOT = writextag('Properties', null, { + 'xmlns': XMLNS.EXT_PROPS, + 'xmlns:vt': XMLNS.vt +}); + +function write_ext_props(cp, opts) { + var o = [], p = {}, W = writextag; + if(!cp) cp = {}; + cp.Application = "SheetJS"; + o[o.length] = (XML_HEADER); + o[o.length] = (EXT_PROPS_XML_ROOT); + + EXT_PROPS.forEach(function(f) { + if(cp[f[1]] === undefined) return; + var v; + switch(f[2]) { + case 'string': v = cp[f[1]]; break; + case 'bool': v = cp[f[1]] ? 'true' : 'false'; break; + } + if(v !== undefined) o[o.length] = (W(f[0], v)); + }); + + /* TODO: HeadingPairs, TitlesOfParts */ + o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', 'Worksheets')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"}))); + o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "" + s + ""; }).join(""), {size: cp.Worksheets, baseType:"lpstr"}))); + if(o.length>2){ o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* 15.2.12.2 Custom File Properties Part */ +XMLNS.CUST_PROPS = "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties"; +RELS.CUST_PROPS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties'; + +var custregex = /<[^>]+>[^<]*/g; +function parse_cust_props(data, opts) { + var p = {}, name; + var m = data.match(custregex); + if(m) for(var i = 0; i != m.length; ++i) { + var x = m[i], y = parsexmltag(x); + switch(y[0]) { + case '': name = null; break; + default: if (x.indexOf(''); + var type = toks[0].substring(4), text = toks[1]; + /* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */ + switch(type) { + case 'lpstr': case 'lpwstr': case 'bstr': case 'lpwstr': + p[name] = unescapexml(text); + break; + case 'bool': + p[name] = parsexmlbool(text, ''); + break; + case 'i1': case 'i2': case 'i4': case 'i8': case 'int': case 'uint': + p[name] = parseInt(text, 10); + break; + case 'r4': case 'r8': case 'decimal': + p[name] = parseFloat(text); + break; + case 'filetime': case 'date': + p[name] = new Date(text); + break; + case 'cy': case 'error': + p[name] = unescapexml(text); + break; + default: + if(typeof console !== 'undefined') console.warn('Unexpected', x, type, toks); + } + } else if(x.substr(0,2) === "2){ o[o.length] = ''; o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +function xlml_set_prop(Props, tag, val) { + /* TODO: Normalize the properties */ + switch(tag) { + case 'Description': tag = 'Comments'; break; + } + Props[tag] = val; +} + +/* [MS-DTYP] 2.3.3 FILETIME */ +/* [MS-OLEDS] 2.1.3 FILETIME (Packet Version) */ +/* [MS-OLEPS] 2.8 FILETIME (Packet Version) */ +function parse_FILETIME(blob) { + var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4); + return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,""); +} + +/* [MS-OSHARED] 2.3.3.1.4 Lpstr */ +function parse_lpstr(blob, type, pad) { + var str = blob.read_shift(0, 'lpstr'); + if(pad) blob.l += (4 - ((str.length+1) & 3)) & 3; + return str; +} + +/* [MS-OSHARED] 2.3.3.1.6 Lpwstr */ +function parse_lpwstr(blob, type, pad) { + var str = blob.read_shift(0, 'lpwstr'); + if(pad) blob.l += (4 - ((str.length+1) & 3)) & 3; + return str; +} + + +/* [MS-OSHARED] 2.3.3.1.11 VtString */ +/* [MS-OSHARED] 2.3.3.1.12 VtUnalignedString */ +function parse_VtStringBase(blob, stringType, pad) { + if(stringType === 0x1F /*VT_LPWSTR*/) return parse_lpwstr(blob); + return parse_lpstr(blob, stringType, pad); +} + +function parse_VtString(blob, t, pad) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); } +function parse_VtUnalignedString(blob, t) { if(!t) throw new Error("dafuq?"); return parse_VtStringBase(blob, t, 0); } + +/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */ +function parse_VtVecUnalignedLpstrValue(blob) { + var length = blob.read_shift(4); + var ret = []; + for(var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr'); + return ret; +} + +/* [MS-OSHARED] 2.3.3.1.10 VtVecUnalignedLpstr */ +function parse_VtVecUnalignedLpstr(blob) { + return parse_VtVecUnalignedLpstrValue(blob); +} + +/* [MS-OSHARED] 2.3.3.1.13 VtHeadingPair */ +function parse_VtHeadingPair(blob) { + var headingString = parse_TypedPropertyValue(blob, VT_USTR); + var headerParts = parse_TypedPropertyValue(blob, VT_I4); + return [headingString, headerParts]; +} + +/* [MS-OSHARED] 2.3.3.1.14 VtVecHeadingPairValue */ +function parse_VtVecHeadingPairValue(blob) { + var cElements = blob.read_shift(4); + var out = []; + for(var i = 0; i != cElements / 2; ++i) out.push(parse_VtHeadingPair(blob)); + return out; +} + +/* [MS-OSHARED] 2.3.3.1.15 VtVecHeadingPair */ +function parse_VtVecHeadingPair(blob) { + // NOTE: When invoked, wType & padding were already consumed + return parse_VtVecHeadingPairValue(blob); +} + +/* [MS-OLEPS] 2.18.1 Dictionary (uses 2.17, 2.16) */ +function parse_dictionary(blob,CodePage) { + var cnt = blob.read_shift(4); + var dict = {}; + for(var j = 0; j != cnt; ++j) { + var pid = blob.read_shift(4); + var len = blob.read_shift(4); + dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!'); + } + if(blob.l & 3) blob.l = (blob.l>>2+1)<<2; + return dict; +} + +/* [MS-OLEPS] 2.9 BLOB */ +function parse_BLOB(blob) { + var size = blob.read_shift(4); + var bytes = blob.slice(blob.l,blob.l+size); + if(size & 3 > 0) blob.l += (4 - (size & 3)) & 3; + return bytes; +} + +/* [MS-OLEPS] 2.11 ClipboardData */ +function parse_ClipboardData(blob) { + // TODO + var o = {}; + o.Size = blob.read_shift(4); + //o.Format = blob.read_shift(4); + blob.l += o.Size; + return o; +} + +/* [MS-OLEPS] 2.14 Vector and Array Property Types */ +function parse_VtVector(blob, cb) { + /* [MS-OLEPS] 2.14.2 VectorHeader */ +/* var Length = blob.read_shift(4); + var o = []; + for(var i = 0; i != Length; ++i) { + o.push(cb(blob)); + } + return o;*/ +} + +/* [MS-OLEPS] 2.15 TypedPropertyValue */ +function parse_TypedPropertyValue(blob, type, _opts) { + var t = blob.read_shift(2), ret, opts = _opts||{}; + blob.l += 2; + if(type !== VT_VARIANT) + if(t !== type && VT_CUSTOM.indexOf(type)===-1) throw new Error('Expected type ' + type + ' saw ' + t); + switch(type === VT_VARIANT ? t : type) { + case 0x02 /*VT_I2*/: ret = blob.read_shift(2, 'i'); if(!opts.raw) blob.l += 2; return ret; + case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret; + case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0; + case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret; + case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,''); + case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob); + case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob); + case 0x41 /*VT_BLOB*/: return parse_BLOB(blob); + case 0x47 /*VT_CF*/: return parse_ClipboardData(blob); + case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw && 4).replace(chr0,''); + case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t, 4).replace(chr0,''); + case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPair(blob); + case 0x101E /*VT_LPSTR*/: return parse_VtVecUnalignedLpstr(blob); + default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t); + } +} +/* [MS-OLEPS] 2.14.2 VectorHeader */ +/*function parse_VTVectorVariant(blob) { + var Length = blob.read_shift(4); + + if(Length & 1 !== 0) throw new Error("VectorHeader Length=" + Length + " must be even"); + var o = []; + for(var i = 0; i != Length; ++i) { + o.push(parse_TypedPropertyValue(blob, VT_VARIANT)); + } + return o; +}*/ + +/* [MS-OLEPS] 2.20 PropertySet */ +function parse_PropertySet(blob, PIDSI) { + var start_addr = blob.l; + var size = blob.read_shift(4); + var NumProps = blob.read_shift(4); + var Props = [], i = 0; + var CodePage = 0; + var Dictionary = -1, DictObj; + for(i = 0; i != NumProps; ++i) { + var PropID = blob.read_shift(4); + var Offset = blob.read_shift(4); + Props[i] = [PropID, Offset + start_addr]; + } + var PropH = {}; + for(i = 0; i != NumProps; ++i) { + if(blob.l !== Props[i][1]) { + var fail = true; + if(i>0 && PIDSI) switch(PIDSI[Props[i-1][0]].t) { + case 0x02 /*VT_I2*/: if(blob.l +2 === Props[i][1]) { blob.l+=2; fail = false; } break; + case 0x50 /*VT_STRING*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break; + case 0x100C /*VT_VECTOR|VT_VARIANT*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break; + } + if(!PIDSI && blob.l <= Props[i][1]) { fail=false; blob.l = Props[i][1]; } + if(fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i); + } + if(PIDSI) { + var piddsi = PIDSI[Props[i][0]]; + PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true}); + if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + String(PropH[piddsi.n] & 0xFFFF); + if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) { + case 0: PropH[piddsi.n] = 1252; + /* falls through */ + case 10000: // OSX Roman + case 1252: // Windows Latin + + case 874: // SB Windows Thai + case 1250: // SB Windows Central Europe + case 1251: // SB Windows Cyrillic + case 1253: // SB Windows Greek + case 1254: // SB Windows Turkish + case 1255: // SB Windows Hebrew + case 1256: // SB Windows Arabic + case 1257: // SB Windows Baltic + case 1258: // SB Windows Vietnam + + case 932: // DB Windows Japanese Shift-JIS + case 936: // DB Windows Simplified Chinese GBK + case 949: // DB Windows Korean + case 950: // DB Windows Traditional Chinese Big5 + + case 1200: // UTF16LE + case 1201: // UTF16BE + case 65000: case -536: // UTF-7 + case 65001: case -535: // UTF-8 + set_cp(CodePage = PropH[piddsi.n]); break; + default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]); + } + } else { + if(Props[i][0] === 0x1) { + CodePage = PropH.CodePage = parse_TypedPropertyValue(blob, VT_I2); + set_cp(CodePage); + if(Dictionary !== -1) { + var oldpos = blob.l; + blob.l = Props[Dictionary][1]; + DictObj = parse_dictionary(blob,CodePage); + blob.l = oldpos; + } + } else if(Props[i][0] === 0) { + if(CodePage === 0) { Dictionary = i; blob.l = Props[i+1][1]; continue; } + DictObj = parse_dictionary(blob,CodePage); + } else { + var name = DictObj[Props[i][0]]; + var val; + /* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */ + switch(blob[blob.l]) { + case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break; + case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; + case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]); break; + case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break; + case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break; + case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break; + case 0x0B /*VT_BOOL*/: blob.l += 4; val = parsebool(blob, 4); break; + case 0x40 /*VT_FILETIME*/: blob.l += 4; val = new Date(parse_FILETIME(blob)); break; + default: throw new Error("unparsed value: " + blob[blob.l]); + } + PropH[name] = val; + } + } + } + blob.l = start_addr + size; /* step ahead to skip padding */ + return PropH; +} + +/* [MS-OLEPS] 2.21 PropertySetStream */ +function parse_PropertySetStream(file, PIDSI) { + var blob = file.content; + prep_blob(blob, 0); + + var NumSets, FMTID0, FMTID1, Offset0, Offset1; + blob.chk('feff', 'Byte Order: '); + + var vers = blob.read_shift(2); // TODO: check version + var SystemIdentifier = blob.read_shift(4); + blob.chk(CFB.utils.consts.HEADER_CLSID, 'CLSID: '); + NumSets = blob.read_shift(4); + if(NumSets !== 1 && NumSets !== 2) throw "Unrecognized #Sets: " + NumSets; + FMTID0 = blob.read_shift(16); Offset0 = blob.read_shift(4); + + if(NumSets === 1 && Offset0 !== blob.l) throw "Length mismatch"; + else if(NumSets === 2) { FMTID1 = blob.read_shift(16); Offset1 = blob.read_shift(4); } + var PSet0 = parse_PropertySet(blob, PIDSI); + + var rval = { SystemIdentifier: SystemIdentifier }; + for(var y in PSet0) rval[y] = PSet0[y]; + //rval.blob = blob; + rval.FMTID = FMTID0; + //rval.PSet0 = PSet0; + if(NumSets === 1) return rval; + if(blob.l !== Offset1) throw "Length mismatch 2: " + blob.l + " !== " + Offset1; + var PSet1; + try { PSet1 = parse_PropertySet(blob, null); } catch(e) { } + for(y in PSet1) rval[y] = PSet1[y]; + rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1 + return rval; +} + + +function parsenoop2(blob, length) { blob.read_shift(length); return null; } + +function parslurp(blob, length, cb) { + var arr = [], target = blob.l + length; + while(blob.l < target) arr.push(cb(blob, target - blob.l)); + if(target !== blob.l) throw new Error("Slurp error"); + return arr; +} + +function parslurp2(blob, length, cb) { + var arr = [], target = blob.l + length, len = blob.read_shift(2); + while(len-- !== 0) arr.push(cb(blob, target - blob.l)); + if(target !== blob.l) throw new Error("Slurp error"); + return arr; +} + +function parsebool(blob, length) { return blob.read_shift(length) === 0x1; } + +function parseuint16(blob) { return blob.read_shift(2, 'u'); } +function parseuint16a(blob, length) { return parslurp(blob,length,parseuint16);} + +/* --- 2.5 Structures --- */ + +/* [MS-XLS] 2.5.14 Boolean */ +var parse_Boolean = parsebool; + +/* [MS-XLS] 2.5.10 Bes (boolean or error) */ +function parse_Bes(blob) { + var v = blob.read_shift(1), t = blob.read_shift(1); + return t === 0x01 ? v : v === 0x01; +} + +/* [MS-XLS] 2.5.240 ShortXLUnicodeString */ +function parse_ShortXLUnicodeString(blob, length, opts) { + var cch = blob.read_shift(1); + var width = 1, encoding = 'sbcs-cont'; + var cp = current_codepage; + if(opts && opts.biff >= 8) current_codepage = 1200; + if(opts === undefined || opts.biff !== 5) { + var fHighByte = blob.read_shift(1); + if(fHighByte) { width = 2; encoding = 'dbcs-cont'; } + } + var o = cch ? blob.read_shift(cch, encoding) : ""; + current_codepage = cp; + return o; +} + +/* 2.5.293 XLUnicodeRichExtendedString */ +function parse_XLUnicodeRichExtendedString(blob) { + var cp = current_codepage; + current_codepage = 1200; + var cch = blob.read_shift(2), flags = blob.read_shift(1); + var fHighByte = flags & 0x1, fExtSt = flags & 0x4, fRichSt = flags & 0x8; + var width = 1 + (flags & 0x1); // 0x0 -> utf8, 0x1 -> dbcs + var cRun, cbExtRst; + var z = {}; + if(fRichSt) cRun = blob.read_shift(2); + if(fExtSt) cbExtRst = blob.read_shift(4); + var encoding = (flags & 0x1) ? 'dbcs-cont' : 'sbcs-cont'; + var msg = cch === 0 ? "" : blob.read_shift(cch, encoding); + if(fRichSt) blob.l += 4 * cRun; //TODO: parse this + if(fExtSt) blob.l += cbExtRst; //TODO: parse this + z.t = msg; + if(!fRichSt) { z.raw = "" + z.t + ""; z.r = z.t; } + current_codepage = cp; + return z; +} + +/* 2.5.296 XLUnicodeStringNoCch */ +function parse_XLUnicodeStringNoCch(blob, cch, opts) { + var retval; + var fHighByte = blob.read_shift(1); + if(fHighByte===0) { retval = blob.read_shift(cch, 'sbcs-cont'); } + else { retval = blob.read_shift(cch, 'dbcs-cont'); } + return retval; +} + +/* 2.5.294 XLUnicodeString */ +function parse_XLUnicodeString(blob, length, opts) { + var cch = blob.read_shift(opts !== undefined && opts.biff > 0 && opts.biff < 8 ? 1 : 2); + if(cch === 0) { blob.l++; return ""; } + return parse_XLUnicodeStringNoCch(blob, cch, opts); +} +/* BIFF5 override */ +function parse_XLUnicodeString2(blob, length, opts) { + if(opts.biff !== 5 && opts.biff !== 2) return parse_XLUnicodeString(blob, length, opts); + var cch = blob.read_shift(1); + if(cch === 0) { blob.l++; return ""; } + return blob.read_shift(cch, 'sbcs-cont'); +} + +/* [MS-XLS] 2.5.61 ControlInfo */ +var parse_ControlInfo = parsenoop; + +/* [MS-OSHARED] 2.3.7.6 URLMoniker TODO: flags */ +var parse_URLMoniker = function(blob, length) { + var len = blob.read_shift(4), start = blob.l; + var extra = false; + if(len > 24) { + /* look ahead */ + blob.l += len - 24; + if(blob.read_shift(16) === "795881f43b1d7f48af2c825dc4852763") extra = true; + blob.l = start; + } + var url = blob.read_shift((extra?len-24:len)>>1, 'utf16le').replace(chr0,""); + if(extra) blob.l += 24; + return url; +}; + +/* [MS-OSHARED] 2.3.7.8 FileMoniker TODO: all fields */ +var parse_FileMoniker = function(blob, length) { + var cAnti = blob.read_shift(2); + var ansiLength = blob.read_shift(4); + var ansiPath = blob.read_shift(ansiLength, 'cstr'); + var endServer = blob.read_shift(2); + var versionNumber = blob.read_shift(2); + var cbUnicodePathSize = blob.read_shift(4); + if(cbUnicodePathSize === 0) return ansiPath.replace(/\\/g,"/"); + var cbUnicodePathBytes = blob.read_shift(4); + var usKeyValue = blob.read_shift(2); + var unicodePath = blob.read_shift(cbUnicodePathBytes>>1, 'utf16le').replace(chr0,""); + return unicodePath; +}; + +/* [MS-OSHARED] 2.3.7.2 HyperlinkMoniker TODO: all the monikers */ +var parse_HyperlinkMoniker = function(blob, length) { + var clsid = blob.read_shift(16); length -= 16; + switch(clsid) { + case "e0c9ea79f9bace118c8200aa004ba90b": return parse_URLMoniker(blob, length); + case "0303000000000000c000000000000046": return parse_FileMoniker(blob, length); + default: throw "unsupported moniker " + clsid; + } +}; + +/* [MS-OSHARED] 2.3.7.9 HyperlinkString */ +var parse_HyperlinkString = function(blob, length) { + var len = blob.read_shift(4); + var o = blob.read_shift(len, 'utf16le').replace(chr0, ""); + return o; +}; + +/* [MS-OSHARED] 2.3.7.1 Hyperlink Object TODO: unify params with XLSX */ +var parse_Hyperlink = function(blob, length) { + var end = blob.l + length; + var sVer = blob.read_shift(4); + if(sVer !== 2) throw new Error("Unrecognized streamVersion: " + sVer); + var flags = blob.read_shift(2); + blob.l += 2; + var displayName, targetFrameName, moniker, oleMoniker, location, guid, fileTime; + if(flags & 0x0010) displayName = parse_HyperlinkString(blob, end - blob.l); + if(flags & 0x0080) targetFrameName = parse_HyperlinkString(blob, end - blob.l); + if((flags & 0x0101) === 0x0101) moniker = parse_HyperlinkString(blob, end - blob.l); + if((flags & 0x0101) === 0x0001) oleMoniker = parse_HyperlinkMoniker(blob, end - blob.l); + if(flags & 0x0008) location = parse_HyperlinkString(blob, end - blob.l); + if(flags & 0x0020) guid = blob.read_shift(16); + if(flags & 0x0040) fileTime = parse_FILETIME(blob, 8); + blob.l = end; + var target = (targetFrameName||moniker||oleMoniker); + if(location) target+="#"+location; + return {Target: target}; +}; + +/* 2.5.178 LongRGBA */ +function parse_LongRGBA(blob, length) { var r = blob.read_shift(1), g = blob.read_shift(1), b = blob.read_shift(1), a = blob.read_shift(1); return [r,g,b,a]; } + +/* 2.5.177 LongRGB */ +function parse_LongRGB(blob, length) { var x = parse_LongRGBA(blob, length); x[3] = 0; return x; } + + +/* --- MS-XLS --- */ + +/* 2.5.19 */ +function parse_XLSCell(blob, length) { + var rw = blob.read_shift(2); // 0-indexed + var col = blob.read_shift(2); + var ixfe = blob.read_shift(2); + return {r:rw, c:col, ixfe:ixfe}; +} + +/* 2.5.134 */ +function parse_frtHeader(blob) { + var rt = blob.read_shift(2); + var flags = blob.read_shift(2); // TODO: parse these flags + blob.l += 8; + return {type: rt, flags: flags}; +} + + + +function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); } + +/* 2.5.158 */ +var HIDEOBJENUM = ['SHOWALL', 'SHOWPLACEHOLDER', 'HIDEALL']; +var parse_HideObjEnum = parseuint16; + +/* 2.5.344 */ +function parse_XTI(blob, length) { + var iSupBook = blob.read_shift(2), itabFirst = blob.read_shift(2,'i'), itabLast = blob.read_shift(2,'i'); + return [iSupBook, itabFirst, itabLast]; +} + +/* 2.5.218 */ +function parse_RkRec(blob, length) { + var ixfe = blob.read_shift(2); + var RK = parse_RkNumber(blob); + //console.log("::", ixfe, RK,";;"); + return [ixfe, RK]; +} + +/* 2.5.1 */ +function parse_AddinUdf(blob, length) { + blob.l += 4; length -= 4; + var l = blob.l + length; + var udfName = parse_ShortXLUnicodeString(blob, length); + var cb = blob.read_shift(2); + l -= blob.l; + if(cb !== l) throw "Malformed AddinUdf: padding = " + l + " != " + cb; + blob.l += cb; + return udfName; +} + +/* 2.5.209 TODO: Check sizes */ +function parse_Ref8U(blob, length) { + var rwFirst = blob.read_shift(2); + var rwLast = blob.read_shift(2); + var colFirst = blob.read_shift(2); + var colLast = blob.read_shift(2); + return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}}; +} + +/* 2.5.211 */ +function parse_RefU(blob, length) { + var rwFirst = blob.read_shift(2); + var rwLast = blob.read_shift(2); + var colFirst = blob.read_shift(1); + var colLast = blob.read_shift(1); + return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}}; +} + +/* 2.5.207 */ +var parse_Ref = parse_RefU; + +/* 2.5.143 */ +function parse_FtCmo(blob, length) { + blob.l += 4; + var ot = blob.read_shift(2); + var id = blob.read_shift(2); + var flags = blob.read_shift(2); + blob.l+=12; + return [id, ot, flags]; +} + +/* 2.5.149 */ +function parse_FtNts(blob, length) { + var out = {}; + blob.l += 4; + blob.l += 16; // GUID TODO + out.fSharedNote = blob.read_shift(2); + blob.l += 4; + return out; +} + +/* 2.5.142 */ +function parse_FtCf(blob, length) { + var out = {}; + blob.l += 4; + blob.cf = blob.read_shift(2); + return out; +} + +/* 2.5.140 - 2.5.154 and friends */ +var FtTab = { + 0x15: parse_FtCmo, + 0x13: parsenoop, /* FtLbsData */ + 0x12: function(blob, length) { blob.l += 12; }, /* FtCblsData */ + 0x11: function(blob, length) { blob.l += 8; }, /* FtRboData */ + 0x10: parsenoop, /* FtEdoData */ + 0x0F: parsenoop, /* FtGboData */ + 0x0D: parse_FtNts, /* FtNts */ + 0x0C: function(blob, length) { blob.l += 24; }, /* FtSbs */ + 0x0B: function(blob, length) { blob.l += 10; }, /* FtRbo */ + 0x0A: function(blob, length) { blob.l += 16; }, /* FtCbls */ + 0x09: parsenoop, /* FtPictFmla */ + 0x08: function(blob, length) { blob.l += 6; }, /* FtPioGrbit */ + 0x07: parse_FtCf, /* FtCf */ + 0x06: function(blob, length) { blob.l += 6; }, /* FtGmo */ + 0x04: parsenoop, /* FtMacro */ + 0x00: function(blob, length) { blob.l += 4; } /* FtEnding */ +}; +function parse_FtArray(blob, length, ot) { + var s = blob.l; + var fts = []; + while(blob.l < s + length) { + var ft = blob.read_shift(2); + blob.l-=2; + try { + fts.push(FtTab[ft](blob, s + length - blob.l)); + } catch(e) { blob.l = s + length; return fts; } + } + if(blob.l != s + length) blob.l = s + length; //throw "bad Object Ft-sequence"; + return fts; +} + +/* 2.5.129 */ +var parse_FontIndex = parseuint16; + +/* --- 2.4 Records --- */ + +/* 2.4.21 */ +function parse_BOF(blob, length) { + var o = {}; + o.BIFFVer = blob.read_shift(2); length -= 2; + switch(o.BIFFVer) { + case 0x0600: /* BIFF8 */ + case 0x0500: /* BIFF5 */ + case 0x0002: case 0x0007: /* BIFF2 */ + break; + default: throw "Unexpected BIFF Ver " + o.BIFFVer; + } + blob.read_shift(length); + return o; +} + + +/* 2.4.146 */ +function parse_InterfaceHdr(blob, length) { + if(length === 0) return 0x04b0; + var q; + if((q=blob.read_shift(2))!==0x04b0) throw 'InterfaceHdr codePage ' + q; + return 0x04b0; +} + + +/* 2.4.349 */ +function parse_WriteAccess(blob, length, opts) { + if(opts.enc) { blob.l += length; return ""; } + var l = blob.l; + // TODO: make sure XLUnicodeString doesnt overrun + var UserName = parse_XLUnicodeString(blob, 0, opts); + blob.read_shift(length + l - blob.l); + return UserName; +} + +/* 2.4.28 */ +function parse_BoundSheet8(blob, length, opts) { + var pos = blob.read_shift(4); + var hidden = blob.read_shift(1) >> 6; + var dt = blob.read_shift(1); + switch(dt) { + case 0: dt = 'Worksheet'; break; + case 1: dt = 'Macrosheet'; break; + case 2: dt = 'Chartsheet'; break; + case 6: dt = 'VBAModule'; break; + } + var name = parse_ShortXLUnicodeString(blob, 0, opts); + if(name.length === 0) name = "Sheet1"; + return { pos:pos, hs:hidden, dt:dt, name:name }; +} + +/* 2.4.265 TODO */ +function parse_SST(blob, length) { + var cnt = blob.read_shift(4); + var ucnt = blob.read_shift(4); + var strs = []; + for(var i = 0; i != ucnt; ++i) { + strs.push(parse_XLUnicodeRichExtendedString(blob)); + } + strs.Count = cnt; strs.Unique = ucnt; + return strs; +} + +/* 2.4.107 */ +function parse_ExtSST(blob, length) { + var extsst = {}; + extsst.dsst = blob.read_shift(2); + blob.l += length-2; + return extsst; +} + + +/* 2.4.221 TODO*/ +function parse_Row(blob, length) { + var rw = blob.read_shift(2), col = blob.read_shift(2), Col = blob.read_shift(2), rht = blob.read_shift(2); + blob.read_shift(4); // reserved(2), unused(2) + var flags = blob.read_shift(1); // various flags + blob.read_shift(1); // reserved + blob.read_shift(2); //ixfe, other flags + return {r:rw, c:col, cnt:Col-col}; +} + + +/* 2.4.125 */ +function parse_ForceFullCalculation(blob, length) { + var header = parse_frtHeader(blob); + if(header.type != 0x08A3) throw "Invalid Future Record " + header.type; + var fullcalc = blob.read_shift(4); + return fullcalc !== 0x0; +} + + +var parse_CompressPictures = parsenoop2; /* 2.4.55 Not interesting */ + + + +/* 2.4.215 rt */ +function parse_RecalcId(blob, length) { + blob.read_shift(2); + return blob.read_shift(4); +} + +/* 2.4.87 */ +function parse_DefaultRowHeight (blob, length) { + var f = blob.read_shift(2), miyRw; + miyRw = blob.read_shift(2); // flags & 0x02 -> hidden, else empty + var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3}; + return [fl, miyRw]; +} + +/* 2.4.345 TODO */ +function parse_Window1(blob, length) { + var xWn = blob.read_shift(2), yWn = blob.read_shift(2), dxWn = blob.read_shift(2), dyWn = blob.read_shift(2); + var flags = blob.read_shift(2), iTabCur = blob.read_shift(2), iTabFirst = blob.read_shift(2); + var ctabSel = blob.read_shift(2), wTabRatio = blob.read_shift(2); + return { Pos: [xWn, yWn], Dim: [dxWn, dyWn], Flags: flags, CurTab: iTabCur, + FirstTab: iTabFirst, Selected: ctabSel, TabRatio: wTabRatio }; +} + +/* 2.4.122 TODO */ +function parse_Font(blob, length, opts) { + blob.l += 14; + var name = parse_ShortXLUnicodeString(blob, 0, opts); + return name; +} + +/* 2.4.149 */ +function parse_LabelSst(blob, length) { + var cell = parse_XLSCell(blob); + cell.isst = blob.read_shift(4); + return cell; +} + +/* 2.4.148 */ +function parse_Label(blob, length, opts) { + var cell = parse_XLSCell(blob, 6); + var str = parse_XLUnicodeString(blob, length-6, opts); + cell.val = str; + return cell; +} + +/* 2.4.126 Number Formats */ +function parse_Format(blob, length, opts) { + var ifmt = blob.read_shift(2); + var fmtstr = parse_XLUnicodeString2(blob, 0, opts); + return [ifmt, fmtstr]; +} + +/* 2.4.90 */ +function parse_Dimensions(blob, length) { + var w = length === 10 ? 2 : 4; + var r = blob.read_shift(w), R = blob.read_shift(w), + c = blob.read_shift(2), C = blob.read_shift(2); + blob.l += 2; + return {s: {r:r, c:c}, e: {r:R, c:C}}; +} + +/* 2.4.220 */ +function parse_RK(blob, length) { + var rw = blob.read_shift(2), col = blob.read_shift(2); + var rkrec = parse_RkRec(blob); + return {r:rw, c:col, ixfe:rkrec[0], rknum:rkrec[1]}; +} + +/* 2.4.175 */ +function parse_MulRk(blob, length) { + var target = blob.l + length - 2; + var rw = blob.read_shift(2), col = blob.read_shift(2); + var rkrecs = []; + while(blob.l < target) rkrecs.push(parse_RkRec(blob)); + if(blob.l !== target) throw "MulRK read error"; + var lastcol = blob.read_shift(2); + if(rkrecs.length != lastcol - col + 1) throw "MulRK length mismatch"; + return {r:rw, c:col, C:lastcol, rkrec:rkrecs}; +} + +/* 2.5.20 2.5.249 TODO */ +function parse_CellStyleXF(blob, length, style) { + var o = {}; + var a = blob.read_shift(4), b = blob.read_shift(4); + var c = blob.read_shift(4), d = blob.read_shift(2); + o.patternType = XLSFillPattern[c >> 26]; + o.icvFore = d & 0x7F; + o.icvBack = (d >> 7) & 0x7F; + return o; +} +function parse_CellXF(blob, length) {return parse_CellStyleXF(blob,length,0);} +function parse_StyleXF(blob, length) {return parse_CellStyleXF(blob,length,1);} + +/* 2.4.353 TODO: actually do this right */ +function parse_XF(blob, length) { + var o = {}; + o.ifnt = blob.read_shift(2); o.ifmt = blob.read_shift(2); o.flags = blob.read_shift(2); + o.fStyle = (o.flags >> 2) & 0x01; + length -= 6; + o.data = parse_CellStyleXF(blob, length, o.fStyle); + return o; +} + +/* 2.4.134 */ +function parse_Guts(blob, length) { + blob.l += 4; + var out = [blob.read_shift(2), blob.read_shift(2)]; + if(out[0] !== 0) out[0]--; + if(out[1] !== 0) out[1]--; + if(out[0] > 7 || out[1] > 7) throw "Bad Gutters: " + out; + return out; +} + +/* 2.4.24 */ +function parse_BoolErr(blob, length) { + var cell = parse_XLSCell(blob, 6); + var val = parse_Bes(blob, 2); + cell.val = val; + cell.t = (val === true || val === false) ? 'b' : 'e'; + return cell; +} + +/* 2.4.180 Number */ +function parse_Number(blob, length) { + var cell = parse_XLSCell(blob, 6); + var xnum = parse_Xnum(blob, 8); + cell.val = xnum; + return cell; +} + +var parse_XLHeaderFooter = parse_OptXLUnicodeString; // TODO: parse 2.4.136 + +/* 2.4.271 */ +function parse_SupBook(blob, length, opts) { + var end = blob.l + length; + var ctab = blob.read_shift(2); + var cch = blob.read_shift(2); + var virtPath; + if(cch >=0x01 && cch <=0xff) virtPath = parse_XLUnicodeStringNoCch(blob, cch); + var rgst = blob.read_shift(end - blob.l); + opts.sbcch = cch; + return [cch, ctab, virtPath, rgst]; +} + +/* 2.4.105 TODO */ +function parse_ExternName(blob, length, opts) { + var flags = blob.read_shift(2); + var body; + var o = { + fBuiltIn: flags & 0x01, + fWantAdvise: (flags >>> 1) & 0x01, + fWantPict: (flags >>> 2) & 0x01, + fOle: (flags >>> 3) & 0x01, + fOleLink: (flags >>> 4) & 0x01, + cf: (flags >>> 5) & 0x3FF, + fIcon: flags >>> 15 & 0x01 + }; + if(opts.sbcch === 0x3A01) body = parse_AddinUdf(blob, length-2); + //else throw new Error("unsupported SupBook cch: " + opts.sbcch); + o.body = body || blob.read_shift(length-2); + return o; +} + +/* 2.4.150 TODO */ +function parse_Lbl(blob, length, opts) { + if(opts.biff < 8) return parse_Label(blob, length, opts); + var target = blob.l + length; + var flags = blob.read_shift(2); + var chKey = blob.read_shift(1); + var cch = blob.read_shift(1); + var cce = blob.read_shift(2); + blob.l += 2; + var itab = blob.read_shift(2); + blob.l += 4; + var name = parse_XLUnicodeStringNoCch(blob, cch, opts); + var rgce = parse_NameParsedFormula(blob, target - blob.l, opts, cce); + return { + chKey: chKey, + Name: name, + rgce: rgce + }; +} + +/* 2.4.106 TODO: verify supbook manipulation */ +function parse_ExternSheet(blob, length, opts) { + if(opts.biff < 8) return parse_ShortXLUnicodeString(blob, length, opts); + var o = parslurp2(blob,length,parse_XTI); + var oo = []; + if(opts.sbcch === 0x0401) { + for(var i = 0; i != o.length; ++i) oo.push(opts.snames[o[i][1]]); + return oo; + } + else return o; +} + +/* 2.4.260 */ +function parse_ShrFmla(blob, length, opts) { + var ref = parse_RefU(blob, 6); + blob.l++; + var cUse = blob.read_shift(1); + length -= 8; + return [parse_SharedParsedFormula(blob, length, opts), cUse]; +} + +/* 2.4.4 TODO */ +function parse_Array(blob, length, opts) { + var ref = parse_Ref(blob, 6); + blob.l += 6; length -= 12; /* TODO: fAlwaysCalc */ + return [ref, parse_ArrayParsedFormula(blob, length, opts, ref)]; +} + +/* 2.4.173 */ +function parse_MTRSettings(blob, length) { + var fMTREnabled = blob.read_shift(4) !== 0x00; + var fUserSetThreadCount = blob.read_shift(4) !== 0x00; + var cUserThreadCount = blob.read_shift(4); + return [fMTREnabled, fUserSetThreadCount, cUserThreadCount]; +} + +/* 2.5.186 TODO: BIFF5 */ +function parse_NoteSh(blob, length, opts) { + if(opts.biff < 8) return; + var row = blob.read_shift(2), col = blob.read_shift(2); + var flags = blob.read_shift(2), idObj = blob.read_shift(2); + var stAuthor = parse_XLUnicodeString2(blob, 0, opts); + if(opts.biff < 8) blob.read_shift(1); + return [{r:row,c:col}, stAuthor, idObj, flags]; +} + +/* 2.4.179 */ +function parse_Note(blob, length, opts) { + /* TODO: Support revisions */ + return parse_NoteSh(blob, length, opts); +} + +/* 2.4.168 */ +function parse_MergeCells(blob, length) { + var merges = []; + var cmcs = blob.read_shift(2); + while (cmcs--) merges.push(parse_Ref8U(blob,length)); + return merges; +} + +/* 2.4.181 TODO: parse all the things! */ +function parse_Obj(blob, length) { + var cmo = parse_FtCmo(blob, 22); // id, ot, flags + var fts = parse_FtArray(blob, length-22, cmo[1]); + return { cmo: cmo, ft:fts }; +} + +/* 2.4.329 TODO: parse properly */ +function parse_TxO(blob, length, opts) { + var s = blob.l; +try { + blob.l += 4; + var ot = (opts.lastobj||{cmo:[0,0]}).cmo[1]; + var controlInfo; + if([0,5,7,11,12,14].indexOf(ot) == -1) blob.l += 6; + else controlInfo = parse_ControlInfo(blob, 6, opts); + var cchText = blob.read_shift(2); + var cbRuns = blob.read_shift(2); + var ifntEmpty = parse_FontIndex(blob, 2); + var len = blob.read_shift(2); + blob.l += len; + //var fmla = parse_ObjFmla(blob, s + length - blob.l); + + var texts = ""; + for(var i = 1; i < blob.lens.length-1; ++i) { + if(blob.l-s != blob.lens[i]) throw "TxO: bad continue record"; + var hdr = blob[blob.l]; + var t = parse_XLUnicodeStringNoCch(blob, blob.lens[i+1]-blob.lens[i]-1); + texts += t; + if(texts.length >= (hdr ? cchText : 2*cchText)) break; + } + if(texts.length !== cchText && texts.length !== cchText*2) { + throw "cchText: " + cchText + " != " + texts.length; + } + + blob.l = s + length; + /* 2.5.272 TxORuns */ +// var rgTxoRuns = []; +// for(var j = 0; j != cbRuns/8-1; ++j) blob.l += 8; +// var cchText2 = blob.read_shift(2); +// if(cchText2 !== cchText) throw "TxOLastRun mismatch: " + cchText2 + " " + cchText; +// blob.l += 6; +// if(s + length != blob.l) throw "TxO " + (s + length) + ", at " + blob.l; + return { t: texts }; +} catch(e) { blob.l = s + length; return { t: texts||"" }; } +} + +/* 2.4.140 */ +var parse_HLink = function(blob, length) { + var ref = parse_Ref8U(blob, 8); + blob.l += 16; /* CLSID */ + var hlink = parse_Hyperlink(blob, length-24); + return [ref, hlink]; +}; + +/* 2.4.141 */ +var parse_HLinkTooltip = function(blob, length) { + var end = blob.l + length; + blob.read_shift(2); + var ref = parse_Ref8U(blob, 8); + var wzTooltip = blob.read_shift((length-10)/2, 'dbcs-cont'); + wzTooltip = wzTooltip.replace(chr0,""); + return [ref, wzTooltip]; +}; + +/* 2.4.63 */ +function parse_Country(blob, length) { + var o = [], d; + d = blob.read_shift(2); o[0] = CountryEnum[d] || d; + d = blob.read_shift(2); o[1] = CountryEnum[d] || d; + return o; +} + +/* 2.4.50 ClrtClient */ +function parse_ClrtClient(blob, length) { + var ccv = blob.read_shift(2); + var o = []; + while(ccv-->0) o.push(parse_LongRGB(blob, 8)); + return o; +} + +/* 2.4.188 */ +function parse_Palette(blob, length) { + var ccv = blob.read_shift(2); + var o = []; + while(ccv-->0) o.push(parse_LongRGB(blob, 8)); + return o; +} + +/* 2.4.354 */ +function parse_XFCRC(blob, length) { + blob.l += 2; + var o = {cxfs:0, crc:0}; + o.cxfs = blob.read_shift(2); + o.crc = blob.read_shift(4); + return o; +} + + +var parse_Style = parsenoop; +var parse_StyleExt = parsenoop; + +var parse_ColInfo = parsenoop; + +var parse_Window2 = parsenoop; + + +var parse_Backup = parsebool; /* 2.4.14 */ +var parse_Blank = parse_XLSCell; /* 2.4.20 Just the cell */ +var parse_BottomMargin = parse_Xnum; /* 2.4.27 */ +var parse_BuiltInFnGroupCount = parseuint16; /* 2.4.30 0x0E or 0x10 but excel 2011 generates 0x11? */ +var parse_CalcCount = parseuint16; /* 2.4.31 #Iterations */ +var parse_CalcDelta = parse_Xnum; /* 2.4.32 */ +var parse_CalcIter = parsebool; /* 2.4.33 1=iterative calc */ +var parse_CalcMode = parseuint16; /* 2.4.34 0=manual, 1=auto (def), 2=table */ +var parse_CalcPrecision = parsebool; /* 2.4.35 */ +var parse_CalcRefMode = parsenoop2; /* 2.4.36 */ +var parse_CalcSaveRecalc = parsebool; /* 2.4.37 */ +var parse_CodePage = parseuint16; /* 2.4.52 */ +var parse_Compat12 = parsebool; /* 2.4.54 true = no compatibility check */ +var parse_Date1904 = parsebool; /* 2.4.77 - 1=1904,0=1900 */ +var parse_DefColWidth = parseuint16; /* 2.4.89 */ +var parse_DSF = parsenoop2; /* 2.4.94 -- MUST be ignored */ +var parse_EntExU2 = parsenoop2; /* 2.4.102 -- Explicitly says to ignore */ +var parse_EOF = parsenoop2; /* 2.4.103 */ +var parse_Excel9File = parsenoop2; /* 2.4.104 -- Optional and unused */ +var parse_FeatHdr = parsenoop2; /* 2.4.112 */ +var parse_FontX = parseuint16; /* 2.4.123 */ +var parse_Footer = parse_XLHeaderFooter; /* 2.4.124 */ +var parse_GridSet = parseuint16; /* 2.4.132, =1 */ +var parse_HCenter = parsebool; /* 2.4.135 sheet centered horizontal on print */ +var parse_Header = parse_XLHeaderFooter; /* 2.4.136 */ +var parse_HideObj = parse_HideObjEnum; /* 2.4.139 */ +var parse_InterfaceEnd = parsenoop2; /* 2.4.145 -- noop */ +var parse_LeftMargin = parse_Xnum; /* 2.4.151 */ +var parse_Mms = parsenoop2; /* 2.4.169 -- Explicitly says to ignore */ +var parse_ObjProtect = parsebool; /* 2.4.183 -- must be 1 if present */ +var parse_Password = parseuint16; /* 2.4.191 */ +var parse_PrintGrid = parsebool; /* 2.4.202 */ +var parse_PrintRowCol = parsebool; /* 2.4.203 */ +var parse_PrintSize = parseuint16; /* 2.4.204 0:3 */ +var parse_Prot4Rev = parsebool; /* 2.4.205 */ +var parse_Prot4RevPass = parseuint16; /* 2.4.206 */ +var parse_Protect = parsebool; /* 2.4.207 */ +var parse_RefreshAll = parsebool; /* 2.4.217 -- must be 0 if not template */ +var parse_RightMargin = parse_Xnum; /* 2.4.219 */ +var parse_RRTabId = parseuint16a; /* 2.4.241 */ +var parse_ScenarioProtect = parsebool; /* 2.4.245 */ +var parse_Scl = parseuint16a; /* 2.4.247 num, den */ +var parse_String = parse_XLUnicodeString; /* 2.4.268 */ +var parse_SxBool = parsebool; /* 2.4.274 */ +var parse_TopMargin = parse_Xnum; /* 2.4.328 */ +var parse_UsesELFs = parsebool; /* 2.4.337 -- should be 0 */ +var parse_VCenter = parsebool; /* 2.4.342 */ +var parse_WinProtect = parsebool; /* 2.4.347 */ +var parse_WriteProtect = parsenoop; /* 2.4.350 empty record */ + + +/* ---- */ +var parse_VerticalPageBreaks = parsenoop; +var parse_HorizontalPageBreaks = parsenoop; +var parse_Selection = parsenoop; +var parse_Continue = parsenoop; +var parse_Pane = parsenoop; +var parse_Pls = parsenoop; +var parse_DCon = parsenoop; +var parse_DConRef = parsenoop; +var parse_DConName = parsenoop; +var parse_XCT = parsenoop; +var parse_CRN = parsenoop; +var parse_FileSharing = parsenoop; +var parse_Uncalced = parsenoop; +var parse_Template = parsenoop; +var parse_Intl = parsenoop; +var parse_WsBool = parsenoop; +var parse_Sort = parsenoop; +var parse_Sync = parsenoop; +var parse_LPr = parsenoop; +var parse_DxGCol = parsenoop; +var parse_FnGroupName = parsenoop; +var parse_FilterMode = parsenoop; +var parse_AutoFilterInfo = parsenoop; +var parse_AutoFilter = parsenoop; +var parse_Setup = parsenoop; +var parse_ScenMan = parsenoop; +var parse_SCENARIO = parsenoop; +var parse_SxView = parsenoop; +var parse_Sxvd = parsenoop; +var parse_SXVI = parsenoop; +var parse_SxIvd = parsenoop; +var parse_SXLI = parsenoop; +var parse_SXPI = parsenoop; +var parse_DocRoute = parsenoop; +var parse_RecipName = parsenoop; +var parse_MulBlank = parsenoop; +var parse_SXDI = parsenoop; +var parse_SXDB = parsenoop; +var parse_SXFDB = parsenoop; +var parse_SXDBB = parsenoop; +var parse_SXNum = parsenoop; +var parse_SxErr = parsenoop; +var parse_SXInt = parsenoop; +var parse_SXString = parsenoop; +var parse_SXDtr = parsenoop; +var parse_SxNil = parsenoop; +var parse_SXTbl = parsenoop; +var parse_SXTBRGIITM = parsenoop; +var parse_SxTbpg = parsenoop; +var parse_ObProj = parsenoop; +var parse_SXStreamID = parsenoop; +var parse_DBCell = parsenoop; +var parse_SXRng = parsenoop; +var parse_SxIsxoper = parsenoop; +var parse_BookBool = parsenoop; +var parse_DbOrParamQry = parsenoop; +var parse_OleObjectSize = parsenoop; +var parse_SXVS = parsenoop; +var parse_BkHim = parsenoop; +var parse_MsoDrawingGroup = parsenoop; +var parse_MsoDrawing = parsenoop; +var parse_MsoDrawingSelection = parsenoop; +var parse_PhoneticInfo = parsenoop; +var parse_SxRule = parsenoop; +var parse_SXEx = parsenoop; +var parse_SxFilt = parsenoop; +var parse_SxDXF = parsenoop; +var parse_SxItm = parsenoop; +var parse_SxName = parsenoop; +var parse_SxSelect = parsenoop; +var parse_SXPair = parsenoop; +var parse_SxFmla = parsenoop; +var parse_SxFormat = parsenoop; +var parse_SXVDEx = parsenoop; +var parse_SXFormula = parsenoop; +var parse_SXDBEx = parsenoop; +var parse_RRDInsDel = parsenoop; +var parse_RRDHead = parsenoop; +var parse_RRDChgCell = parsenoop; +var parse_RRDRenSheet = parsenoop; +var parse_RRSort = parsenoop; +var parse_RRDMove = parsenoop; +var parse_RRFormat = parsenoop; +var parse_RRAutoFmt = parsenoop; +var parse_RRInsertSh = parsenoop; +var parse_RRDMoveBegin = parsenoop; +var parse_RRDMoveEnd = parsenoop; +var parse_RRDInsDelBegin = parsenoop; +var parse_RRDInsDelEnd = parsenoop; +var parse_RRDConflict = parsenoop; +var parse_RRDDefName = parsenoop; +var parse_RRDRstEtxp = parsenoop; +var parse_LRng = parsenoop; +var parse_CUsr = parsenoop; +var parse_CbUsr = parsenoop; +var parse_UsrInfo = parsenoop; +var parse_UsrExcl = parsenoop; +var parse_FileLock = parsenoop; +var parse_RRDInfo = parsenoop; +var parse_BCUsrs = parsenoop; +var parse_UsrChk = parsenoop; +var parse_UserBView = parsenoop; +var parse_UserSViewBegin = parsenoop; // overloaded +var parse_UserSViewEnd = parsenoop; +var parse_RRDUserView = parsenoop; +var parse_Qsi = parsenoop; +var parse_CondFmt = parsenoop; +var parse_CF = parsenoop; +var parse_DVal = parsenoop; +var parse_DConBin = parsenoop; +var parse_Lel = parsenoop; +var parse_XLSCodeName = parse_XLUnicodeString; +var parse_SXFDBType = parsenoop; +var parse_ObNoMacros = parsenoop; +var parse_Dv = parsenoop; +var parse_Index = parsenoop; +var parse_Table = parsenoop; +var parse_BigName = parsenoop; +var parse_ContinueBigName = parsenoop; +var parse_WebPub = parsenoop; +var parse_QsiSXTag = parsenoop; +var parse_DBQueryExt = parsenoop; +var parse_ExtString = parsenoop; +var parse_TxtQry = parsenoop; +var parse_Qsir = parsenoop; +var parse_Qsif = parsenoop; +var parse_RRDTQSIF = parsenoop; +var parse_OleDbConn = parsenoop; +var parse_WOpt = parsenoop; +var parse_SXViewEx = parsenoop; +var parse_SXTH = parsenoop; +var parse_SXPIEx = parsenoop; +var parse_SXVDTEx = parsenoop; +var parse_SXViewEx9 = parsenoop; +var parse_ContinueFrt = parsenoop; +var parse_RealTimeData = parsenoop; +var parse_ChartFrtInfo = parsenoop; +var parse_FrtWrapper = parsenoop; +var parse_StartBlock = parsenoop; +var parse_EndBlock = parsenoop; +var parse_StartObject = parsenoop; +var parse_EndObject = parsenoop; +var parse_CatLab = parsenoop; +var parse_YMult = parsenoop; +var parse_SXViewLink = parsenoop; +var parse_PivotChartBits = parsenoop; +var parse_FrtFontList = parsenoop; +var parse_SheetExt = parsenoop; +var parse_BookExt = parsenoop; +var parse_SXAddl = parsenoop; +var parse_CrErr = parsenoop; +var parse_HFPicture = parsenoop; +var parse_Feat = parsenoop; +var parse_DataLabExt = parsenoop; +var parse_DataLabExtContents = parsenoop; +var parse_CellWatch = parsenoop; +var parse_FeatHdr11 = parsenoop; +var parse_Feature11 = parsenoop; +var parse_DropDownObjIds = parsenoop; +var parse_ContinueFrt11 = parsenoop; +var parse_DConn = parsenoop; +var parse_List12 = parsenoop; +var parse_Feature12 = parsenoop; +var parse_CondFmt12 = parsenoop; +var parse_CF12 = parsenoop; +var parse_CFEx = parsenoop; +var parse_AutoFilter12 = parsenoop; +var parse_ContinueFrt12 = parsenoop; +var parse_MDTInfo = parsenoop; +var parse_MDXStr = parsenoop; +var parse_MDXTuple = parsenoop; +var parse_MDXSet = parsenoop; +var parse_MDXProp = parsenoop; +var parse_MDXKPI = parsenoop; +var parse_MDB = parsenoop; +var parse_PLV = parsenoop; +var parse_DXF = parsenoop; +var parse_TableStyles = parsenoop; +var parse_TableStyle = parsenoop; +var parse_TableStyleElement = parsenoop; +var parse_NamePublish = parsenoop; +var parse_NameCmt = parsenoop; +var parse_SortData = parsenoop; +var parse_GUIDTypeLib = parsenoop; +var parse_FnGrp12 = parsenoop; +var parse_NameFnGrp12 = parsenoop; +var parse_HeaderFooter = parsenoop; +var parse_CrtLayout12 = parsenoop; +var parse_CrtMlFrt = parsenoop; +var parse_CrtMlFrtContinue = parsenoop; +var parse_ShapePropsStream = parsenoop; +var parse_TextPropsStream = parsenoop; +var parse_RichTextStream = parsenoop; +var parse_CrtLayout12A = parsenoop; +var parse_Units = parsenoop; +var parse_Chart = parsenoop; +var parse_Series = parsenoop; +var parse_DataFormat = parsenoop; +var parse_LineFormat = parsenoop; +var parse_MarkerFormat = parsenoop; +var parse_AreaFormat = parsenoop; +var parse_PieFormat = parsenoop; +var parse_AttachedLabel = parsenoop; +var parse_SeriesText = parsenoop; +var parse_ChartFormat = parsenoop; +var parse_Legend = parsenoop; +var parse_SeriesList = parsenoop; +var parse_Bar = parsenoop; +var parse_Line = parsenoop; +var parse_Pie = parsenoop; +var parse_Area = parsenoop; +var parse_Scatter = parsenoop; +var parse_CrtLine = parsenoop; +var parse_Axis = parsenoop; +var parse_Tick = parsenoop; +var parse_ValueRange = parsenoop; +var parse_CatSerRange = parsenoop; +var parse_AxisLine = parsenoop; +var parse_CrtLink = parsenoop; +var parse_DefaultText = parsenoop; +var parse_Text = parsenoop; +var parse_ObjectLink = parsenoop; +var parse_Frame = parsenoop; +var parse_Begin = parsenoop; +var parse_End = parsenoop; +var parse_PlotArea = parsenoop; +var parse_Chart3d = parsenoop; +var parse_PicF = parsenoop; +var parse_DropBar = parsenoop; +var parse_Radar = parsenoop; +var parse_Surf = parsenoop; +var parse_RadarArea = parsenoop; +var parse_AxisParent = parsenoop; +var parse_LegendException = parsenoop; +var parse_ShtProps = parsenoop; +var parse_SerToCrt = parsenoop; +var parse_AxesUsed = parsenoop; +var parse_SBaseRef = parsenoop; +var parse_SerParent = parsenoop; +var parse_SerAuxTrend = parsenoop; +var parse_IFmtRecord = parsenoop; +var parse_Pos = parsenoop; +var parse_AlRuns = parsenoop; +var parse_BRAI = parsenoop; +var parse_SerAuxErrBar = parsenoop; +var parse_SerFmt = parsenoop; +var parse_Chart3DBarShape = parsenoop; +var parse_Fbi = parsenoop; +var parse_BopPop = parsenoop; +var parse_AxcExt = parsenoop; +var parse_Dat = parsenoop; +var parse_PlotGrowth = parsenoop; +var parse_SIIndex = parsenoop; +var parse_GelFrame = parsenoop; +var parse_BopPopCustom = parsenoop; +var parse_Fbi2 = parsenoop; + +/* --- Specific to versions before BIFF8 --- */ +function parse_BIFF5String(blob) { + var len = blob.read_shift(1); + return blob.read_shift(len, 'sbcs-cont'); +} + +/* BIFF2_??? where ??? is the name from [XLS] */ +function parse_BIFF2STR(blob, length, opts) { + var cell = parse_XLSCell(blob, 6); + ++blob.l; + var str = parse_XLUnicodeString2(blob, length-7, opts); + cell.val = str; + return cell; +} + +function parse_BIFF2NUM(blob, length, opts) { + var cell = parse_XLSCell(blob, 6); + ++blob.l; + var num = parse_Xnum(blob, 8); + cell.val = num; + return cell; +} + +/* 18.4.1 charset to codepage mapping */ +var CS2CP = { + 0: 1252, /* ANSI */ + 1: 65001, /* DEFAULT */ + 2: 65001, /* SYMBOL */ + 77: 10000, /* MAC */ + 128: 932, /* SHIFTJIS */ + 129: 949, /* HANGUL */ + 130: 1361, /* JOHAB */ + 134: 936, /* GB2312 */ + 136: 950, /* CHINESEBIG5 */ + 161: 1253, /* GREEK */ + 162: 1254, /* TURKISH */ + 163: 1258, /* VIETNAMESE */ + 177: 1255, /* HEBREW */ + 178: 1256, /* ARABIC */ + 186: 1257, /* BALTIC */ + 204: 1251, /* RUSSIAN */ + 222: 874, /* THAI */ + 238: 1250, /* EASTEUROPE */ + 255: 1252, /* OEM */ + 69: 6969 /* MISC */ +}; + +/* Parse a list of tags */ +var parse_rs = (function parse_rs_factory() { + var tregex = matchtag("t"), rpregex = matchtag("rPr"), rregex = //g, rend = /<\/r>/, nlregex = /\r\n/g; + /* 18.4.7 rPr CT_RPrElt */ + var parse_rpr = function parse_rpr(rpr, intro, outro) { + var font = {}, cp = 65001; + var m = rpr.match(tagregex), i = 0; + if(m) for(;i!=m.length; ++i) { + var y = parsexmltag(m[i]); + switch(y[0]) { + /* 18.8.12 condense CT_BooleanProperty */ + /* ** not required . */ + case '': break; + + /* 18.4.1 charset CT_IntProperty TODO */ + case '': break; + + /* 18.4.5 rFont CT_FontName */ + 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(""); + return cp; + }; + + /* 18.4.4 r CT_RElt */ + function parse_r(r) { + var terms = [[],"",[]]; + /* 18.4.12 t ST_Xstring */ + var t = r.match(tregex), cp = 65001; + if(!isval(t)) return ""; + terms[1] = t[1]; + + var rpr = r.match(rpregex); + if(isval(rpr)) cp = parse_rpr(rpr[1], terms[0], terms[2]); + + return terms[0].join("") + terms[1].replace(nlregex,'
') + terms[2].join(""); + } + return function parse_rs(rs) { + return rs.replace(rregex,"").split(rend).map(parse_r).join(""); + }; +})(); + +/* 18.4.8 si CT_Rst */ +var sitregex = /]*>([^<]*)<\/t>/g, sirregex = //; +function parse_si(x, opts) { + var html = opts ? opts.cellHTML : true; + var z = {}; + if(!x) return null; + var y; + /* 18.4.12 t ST_Xstring (Plaintext String) */ + if(x.charCodeAt(1) === 116) { + z.t = utf8read(unescapexml(x.substr(x.indexOf(">")+1).split(/<\/t>/)[0])); + z.r = x; + if(html) z.h = z.t; + } + /* 18.4.4 r CT_RElt (Rich Text Run) */ + else if((y = x.match(sirregex))) { + z.r = x; + z.t = utf8read(unescapexml(x.match(sitregex).join("").replace(tagregex,""))); + if(html) z.h = 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; +} + +/* 18.4 Shared String Table */ +var sstr0 = /]*)>([\s\S]*)<\/sst>/; +var sstr1 = /<(?:si|sstItem)>/g; +var sstr2 = /<\/(?:si|sstItem)>/; +function parse_sst_xml(data, opts) { + var s = [], ss; + /* 18.4.9 sst CT_Sst */ + var sst = data.match(sstr0); + if(isval(sst)) { + ss = sst[2].replace(sstr1,"").split(sstr2); + for(var i = 0; i != ss.length; ++i) { + var o = parse_si(ss[i], opts); + if(o != null) s[s.length] = o; + } + sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount; + } + return s; +} + +RELS.SST = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"; +var straywsregex = /^\s|\s$|[\t\n\r]/; +function write_sst_xml(sst, opts) { + if(!opts.bookSST) return ""; + var o = [XML_HEADER]; + o[o.length] = (writextag('sst', null, { + xmlns: XMLNS.main[0], + count: sst.Count, + uniqueCount: sst.Unique + })); + for(var i = 0; i != sst.length; ++i) { if(sst[i] == null) continue; + var s = sst[i]; + var sitag = ""; + if(s.r) sitag += s.r; + else { + sitag += ""; + } + sitag += ""; + o[o.length] = (sitag); + } + if(o.length>2){ o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* [MS-XLSB] 2.4.219 BrtBeginSst */ +function parse_BrtBeginSst(data, length) { + return [data.read_shift(4), data.read_shift(4)]; +} + +/* [MS-XLSB] 2.1.7.45 Shared Strings */ +function parse_sst_bin(data, opts) { + var s = []; + var pass = false; + recordhopper(data, function hopper_sst(val, R, RT) { + switch(R.n) { + case 'BrtBeginSst': s.Count = val[0]; s.Unique = val[1]; break; + case 'BrtSSTItem': s.push(val); break; + case 'BrtEndSst': return true; + /* TODO: produce a test case with a future record */ + case 'BrtFRTBegin': pass = true; break; + case 'BrtFRTEnd': pass = false; break; + default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n); + } + }); + return s; +} + +function write_BrtBeginSst(sst, o) { + if(!o) o = new_buf(8); + o.write_shift(4, sst.Count); + o.write_shift(4, sst.Unique); + return o; +} + +var write_BrtSSTItem = write_RichStr; + +function write_sst_bin(sst, opts) { + var ba = buf_array(); + write_record(ba, "BrtBeginSst", write_BrtBeginSst(sst)); + for(var i = 0; i < sst.length; ++i) write_record(ba, "BrtSSTItem", write_BrtSSTItem(sst[i])); + write_record(ba, "BrtEndSst"); + return ba.end(); +} +function _JS2ANSI(str) { if(typeof cptable !== 'undefined') return cptable.utils.encode(1252, str); return str.split("").map(function(x) { return x.charCodeAt(0); }); } + +/* [MS-OFFCRYPTO] 2.1.4 Version */ +function parse_Version(blob, length) { + var o = {}; + o.Major = blob.read_shift(2); + o.Minor = blob.read_shift(2); + return o; +} +/* [MS-OFFCRYPTO] 2.3.2 Encryption Header */ +function parse_EncryptionHeader(blob, length) { + var o = {}; + o.Flags = blob.read_shift(4); + + // Check if SizeExtra is 0x00000000 + var tmp = blob.read_shift(4); + if(tmp !== 0) throw 'Unrecognized SizeExtra: ' + tmp; + + o.AlgID = blob.read_shift(4); + switch(o.AlgID) { + case 0: case 0x6801: case 0x660E: case 0x660F: case 0x6610: break; + default: throw 'Unrecognized encryption algorithm: ' + o.AlgID; + } + parsenoop(blob, length-12); + return o; +} + +/* [MS-OFFCRYPTO] 2.3.3 Encryption Verifier */ +function parse_EncryptionVerifier(blob, length) { + return parsenoop(blob, length); +} +/* [MS-OFFCRYPTO] 2.3.5.1 RC4 CryptoAPI Encryption Header */ +function parse_RC4CryptoHeader(blob, length) { + var o = {}; + var vers = o.EncryptionVersionInfo = parse_Version(blob, 4); length -= 4; + if(vers.Minor != 2) throw 'unrecognized minor version code: ' + vers.Minor; + if(vers.Major > 4 || vers.Major < 2) throw 'unrecognized major version code: ' + vers.Major; + o.Flags = blob.read_shift(4); length -= 4; + var sz = blob.read_shift(4); length -= 4; + o.EncryptionHeader = parse_EncryptionHeader(blob, sz); length -= sz; + o.EncryptionVerifier = parse_EncryptionVerifier(blob, length); + return o; +} +/* [MS-OFFCRYPTO] 2.3.6.1 RC4 Encryption Header */ +function parse_RC4Header(blob, length) { + var o = {}; + var vers = o.EncryptionVersionInfo = parse_Version(blob, 4); length -= 4; + if(vers.Major != 1 || vers.Minor != 1) throw 'unrecognized version code ' + vers.Major + ' : ' + vers.Minor; + o.Salt = blob.read_shift(16); + o.EncryptedVerifier = blob.read_shift(16); + o.EncryptedVerifierHash = blob.read_shift(16); + return o; +} + +/* [MS-OFFCRYPTO] 2.3.7.1 Binary Document Password Verifier Derivation */ +function crypto_CreatePasswordVerifier_Method1(Password) { + var Verifier = 0x0000, PasswordArray; + var PasswordDecoded = _JS2ANSI(Password); + var len = PasswordDecoded.length + 1, i, PasswordByte; + var Intermediate1, Intermediate2, Intermediate3; + PasswordArray = new_raw_buf(len); + PasswordArray[0] = PasswordDecoded.length; + for(i = 1; i != len; ++i) PasswordArray[i] = PasswordDecoded[i-1]; + for(i = len-1; i >= 0; --i) { + PasswordByte = PasswordArray[i]; + Intermediate1 = ((Verifier & 0x4000) === 0x0000) ? 0 : 1; + Intermediate2 = (Verifier << 1) & 0x7FFF; + Intermediate3 = Intermediate1 | Intermediate2; + Verifier = Intermediate3 ^ PasswordByte; + } + return Verifier ^ 0xCE4B; +} + +/* [MS-OFFCRYPTO] 2.3.7.2 Binary Document XOR Array Initialization */ +var crypto_CreateXorArray_Method1 = (function() { + var PadArray = [0xBB, 0xFF, 0xFF, 0xBA, 0xFF, 0xFF, 0xB9, 0x80, 0x00, 0xBE, 0x0F, 0x00, 0xBF, 0x0F, 0x00]; + var InitialCode = [0xE1F0, 0x1D0F, 0xCC9C, 0x84C0, 0x110C, 0x0E10, 0xF1CE, 0x313E, 0x1872, 0xE139, 0xD40F, 0x84F9, 0x280C, 0xA96A, 0x4EC3]; + var XorMatrix = [0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09, 0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF, 0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0, 0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40, 0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5, 0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A, 0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9, 0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0, 0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC, 0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10, 0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168, 0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C, 0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD, 0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC, 0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4]; + var Ror = function(Byte) { return ((Byte/2) | (Byte*128)) & 0xFF; }; + var XorRor = function(byte1, byte2) { return Ror(byte1 ^ byte2); }; + var CreateXorKey_Method1 = function(Password) { + var XorKey = InitialCode[Password.length - 1]; + var CurrentElement = 0x68; + for(var i = Password.length-1; i >= 0; --i) { + var Char = Password[i]; + for(var j = 0; j != 7; ++j) { + if(Char & 0x40) XorKey ^= XorMatrix[CurrentElement]; + Char *= 2; --CurrentElement; + } + } + return XorKey; + }; + return function(password) { + var Password = _JS2ANSI(password); + var XorKey = CreateXorKey_Method1(Password); + var Index = Password.length; + var ObfuscationArray = new_raw_buf(16); + for(var i = 0; i != 16; ++i) ObfuscationArray[i] = 0x00; + var Temp, PasswordLastChar, PadIndex; + if((Index & 1) === 1) { + Temp = XorKey >> 8; + ObfuscationArray[Index] = XorRor(PadArray[0], Temp); + --Index; + Temp = XorKey & 0xFF; + PasswordLastChar = Password[Password.length - 1]; + ObfuscationArray[Index] = XorRor(PasswordLastChar, Temp); + } + while(Index > 0) { + --Index; + Temp = XorKey >> 8; + ObfuscationArray[Index] = XorRor(Password[Index], Temp); + --Index; + Temp = XorKey & 0xFF; + ObfuscationArray[Index] = XorRor(Password[Index], Temp); + } + Index = 15; + PadIndex = 15 - Password.length; + while(PadIndex > 0) { + Temp = XorKey >> 8; + ObfuscationArray[Index] = XorRor(PadArray[PadIndex], Temp); + --Index; + --PadIndex; + Temp = XorKey & 0xFF; + ObfuscationArray[Index] = XorRor(Password[Index], Temp); + --Index; + --PadIndex; + } + return ObfuscationArray; + }; +})(); + +/* [MS-OFFCRYPTO] 2.3.7.3 Binary Document XOR Data Transformation Method 1 */ +var crypto_DecryptData_Method1 = function(password, Data, XorArrayIndex, XorArray, O) { + /* If XorArray is set, use it; if O is not set, make changes in-place */ + if(!O) O = Data; + if(!XorArray) XorArray = crypto_CreateXorArray_Method1(password); + var Index, Value; + for(Index = 0; Index != Data.length; ++Index) { + Value = Data[Index]; + Value ^= XorArray[XorArrayIndex]; + Value = ((Value>>5) | (Value<<3)) & 0xFF; + O[Index] = Value; + ++XorArrayIndex; + } + return [O, XorArrayIndex, XorArray]; +}; + +var crypto_MakeXorDecryptor = function(password) { + var XorArrayIndex = 0, XorArray = crypto_CreateXorArray_Method1(password); + return function(Data) { + var O = crypto_DecryptData_Method1(null, Data, XorArrayIndex, XorArray); + XorArrayIndex = O[1]; + return O[0]; + }; +}; + +/* 2.5.343 */ +function parse_XORObfuscation(blob, length, opts, out) { + var o = { key: parseuint16(blob), verificationBytes: parseuint16(blob) }; + if(opts.password) o.verifier = crypto_CreatePasswordVerifier_Method1(opts.password); + out.valid = o.verificationBytes === o.verifier; + if(out.valid) out.insitu_decrypt = crypto_MakeXorDecryptor(opts.password); + return o; +} + +/* 2.4.117 */ +function parse_FilePassHeader(blob, length, oo) { + var o = oo || {}; o.Info = blob.read_shift(2); blob.l -= 2; + if(o.Info === 1) o.Data = parse_RC4Header(blob, length); + else o.Data = parse_RC4CryptoHeader(blob, length); + return o; +} +function parse_FilePass(blob, length, opts) { + var o = { Type: blob.read_shift(2) }; /* wEncryptionType */ + if(o.Type) parse_FilePassHeader(blob, length-2, o); + else parse_XORObfuscation(blob, length-2, opts, o); + return o; +} + + +function hex2RGB(h) { + var o = h.substr(h[0]==="#"?1:0,6); + return [parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16),parseInt(o.substr(0,2),16)]; +} +function rgb2Hex(rgb) { + for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]); + return o.toString(16).toUpperCase().substr(1); +} + +function rgb2HSL(rgb) { + var R = rgb[0]/255, G = rgb[1]/255, B=rgb[2]/255; + var M = Math.max(R, G, B), m = Math.min(R, G, B), C = M - m; + if(C === 0) return [0, 0, R]; + + var H6 = 0, S = 0, L2 = (M + m); + S = C / (L2 > 1 ? 2 - L2 : L2); + switch(M){ + case R: H6 = ((G - B) / C + 6)%6; break; + case G: H6 = ((B - R) / C + 2); break; + case B: H6 = ((R - G) / C + 4); break; + } + return [H6 / 6, S, L2 / 2]; +} + +function hsl2RGB(hsl){ + var H = hsl[0], S = hsl[1], L = hsl[2]; + var C = S * 2 * (L < 0.5 ? L : 1 - L), m = L - C/2; + var rgb = [m,m,m], h6 = 6*H; + + var X; + if(S !== 0) switch(h6|0) { + case 0: case 6: X = C * h6; rgb[0] += C; rgb[1] += X; break; + case 1: X = C * (2 - h6); rgb[0] += X; rgb[1] += C; break; + case 2: X = C * (h6 - 2); rgb[1] += C; rgb[2] += X; break; + case 3: X = C * (4 - h6); rgb[1] += X; rgb[2] += C; break; + case 4: X = C * (h6 - 4); rgb[2] += C; rgb[0] += X; break; + case 5: X = C * (6 - h6); rgb[2] += X; rgb[0] += C; break; + } + for(var i = 0; i != 3; ++i) rgb[i] = Math.round(rgb[i]*255); + return rgb; +} + +/* 18.8.3 bgColor tint algorithm */ +function rgb_tint(hex, tint) { + if(tint === 0) return hex; + var hsl = rgb2HSL(hex2RGB(hex)); + if (tint < 0) hsl[2] = hsl[2] * (1 + tint); + else hsl[2] = 1 - (1 - hsl[2]) * (1 - tint); + return rgb2Hex(hsl2RGB(hsl)); +} + +/* 18.3.1.13 width calculations */ +var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW; +function width2px(width) { return (( width + ((128/MDW)|0)/256 )* MDW )|0; } +function px2char(px) { return (((px - 5)/MDW * 100 + 0.5)|0)/100; } +function char2width(chr) { return (((chr * MDW + 5)/MDW*256)|0)/256; } +function cycle_width(collw) { return char2width(px2char(width2px(collw))); } +function find_mdw(collw, coll) { + if(cycle_width(collw) != collw) { + for(MDW=DEF_MDW; MDW>MIN_MDW; --MDW) if(cycle_width(collw) === collw) break; + if(MDW === MIN_MDW) for(MDW=DEF_MDW+1; MDW': case '': break; + + /* 18.8.20 fill CT_Fill */ + case '': break; + case '': styles.Fills.push(fill); fill = {}; break; + + /* 18.8.32 patternFill CT_PatternFill */ + case '': case '': break; + + /* 18.8.3 bgColor CT_Color */ + case '': case '': break; + + /* 18.8.19 fgColor CT_Color */ + case '': case '': break; + + default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in fills'; + } + }); +} + +/* 18.8.31 numFmts CT_NumFmts */ +function parse_numFmts(t, opts) { + styles.NumberFmt = []; + var k = keys(SSF._table); + for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = SSF._table[k[i]]; + var m = t[0].match(tagregex); + for(i=0; i < m.length; ++i) { + var y = parsexmltag(m[i]); + switch(y[0]) { + case '': case '': case '': break; + case '0) SSF.load(f,j); + } break; + default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in numFmts'; + } + } +} + +function write_numFmts(NF, opts) { + var o = [""]; + [[5,8],[23,26],[41,44],[63,66],[164,392]].forEach(function(r) { + for(var i = r[0]; i <= r[1]; ++i) if(NF[i] !== undefined) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])})); + }); + if(o.length === 1) return ""; + o[o.length] = (""); + o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">"); + return o.join(""); +} + +/* 18.8.10 cellXfs CT_CellXfs */ +function parse_cellXfs(t, opts) { + styles.CellXf = []; + t[0].match(tagregex).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': case '': case '': break; + + /* 18.8.45 xf CT_Xf */ + case '': break; + + /* 18.8.1 alignment CT_CellAlignment */ + case '': break; + + /* 18.8.33 protection CT_CellProtection */ + case '': case '': break; + + case '': break; + case '"); + if(o.length === 2) return ""; + o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">"); + return o.join(""); +} + +/* 18.8 Styles CT_Stylesheet*/ +var parse_sty_xml= (function make_pstyx() { +var numFmtRegex = /]*)>.*<\/numFmts>/; +var cellXfRegex = /]*)>.*<\/cellXfs>/; +var fillsRegex = /]*)>.*<\/fills>/; + +return function parse_sty_xml(data, opts) { + /* 18.8.39 styleSheet CT_Stylesheet */ + var t; + + /* numFmts CT_NumFmts ? */ + if((t=data.match(numFmtRegex))) parse_numFmts(t, opts); + + /* fonts CT_Fonts ? */ + /*if((t=data.match(/]*)>.*<\/fonts>/))) parse_fonts(t, opts);*/ + + /* fills CT_Fills */ + if((t=data.match(fillsRegex))) parse_fills(t, opts); + + /* borders CT_Borders ? */ + /* cellStyleXfs CT_CellStyleXfs ? */ + + /* cellXfs CT_CellXfs ? */ + if((t=data.match(cellXfRegex))) parse_cellXfs(t, opts); + + /* dxfs CT_Dxfs ? */ + /* tableStyles CT_TableStyles ? */ + /* colors CT_Colors ? */ + /* extLst CT_ExtensionList ? */ + + return styles; +}; +})(); + +var STYLES_XML_ROOT = writextag('styleSheet', null, { + 'xmlns': XMLNS.main[0], + 'xmlns:vt': XMLNS.vt +}); + +RELS.STY = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"; + +function write_sty_xml(wb, opts) { + var o = [XML_HEADER, STYLES_XML_ROOT], w; + if((w = write_numFmts(wb.SSF)) != null) o[o.length] = w; + o[o.length] = (''); + o[o.length] = (''); + o[o.length] = (''); + o[o.length] = (''); + if((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w); + o[o.length] = (''); + o[o.length] = (''); + o[o.length] = (''); + + if(o.length>2){ o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* [MS-XLSB] 2.4.651 BrtFmt */ +function parse_BrtFmt(data, length) { + var ifmt = data.read_shift(2); + var stFmtCode = parse_XLWideString(data,length-2); + return [ifmt, stFmtCode]; +} + +/* [MS-XLSB] 2.4.653 BrtFont TODO */ +function parse_BrtFont(data, length) { + var out = {flags:{}}; + out.dyHeight = data.read_shift(2); + out.grbit = parse_FontFlags(data, 2); + out.bls = data.read_shift(2); + out.sss = data.read_shift(2); + out.uls = data.read_shift(1); + out.bFamily = data.read_shift(1); + out.bCharSet = data.read_shift(1); + data.l++; + out.brtColor = parse_BrtColor(data, 8); + out.bFontScheme = data.read_shift(1); + out.name = parse_XLWideString(data, length - 21); + + out.flags.Bold = out.bls === 0x02BC; + out.flags.Italic = out.grbit.fItalic; + out.flags.Strikeout = out.grbit.fStrikeout; + out.flags.Outline = out.grbit.fOutline; + out.flags.Shadow = out.grbit.fShadow; + out.flags.Condense = out.grbit.fCondense; + out.flags.Extend = out.grbit.fExtend; + out.flags.Sub = out.sss & 0x2; + out.flags.Sup = out.sss & 0x1; + return out; +} + +/* [MS-XLSB] 2.4.816 BrtXF */ +function parse_BrtXF(data, length) { + var ixfeParent = data.read_shift(2); + var ifmt = data.read_shift(2); + parsenoop(data, length-4); + return {ixfe:ixfeParent, ifmt:ifmt }; +} + +/* [MS-XLSB] 2.1.7.50 Styles */ +function parse_sty_bin(data, opts) { + styles.NumberFmt = []; + for(var y in SSF._table) styles.NumberFmt[y] = SSF._table[y]; + + styles.CellXf = []; + var state = ""; /* TODO: this should be a stack */ + var pass = false; + recordhopper(data, function hopper_sty(val, R, RT) { + switch(R.n) { + case 'BrtFmt': + styles.NumberFmt[val[0]] = val[1]; SSF.load(val[1], val[0]); + break; + case 'BrtFont': break; /* TODO */ + case 'BrtKnownFonts': break; /* TODO */ + case 'BrtFill': break; /* TODO */ + case 'BrtBorder': break; /* TODO */ + case 'BrtXF': + if(state === "CELLXFS") { + styles.CellXf.push(val); + } + break; /* TODO */ + case 'BrtStyle': break; /* TODO */ + case 'BrtDXF': break; /* TODO */ + case 'BrtMRUColor': break; /* TODO */ + case 'BrtIndexedColor': break; /* TODO */ + case 'BrtBeginStyleSheet': break; + case 'BrtEndStyleSheet': break; + case 'BrtBeginTableStyle': break; + case 'BrtTableStyleElement': break; + case 'BrtEndTableStyle': break; + case 'BrtBeginFmts': state = "FMTS"; break; + case 'BrtEndFmts': state = ""; break; + case 'BrtBeginFonts': state = "FONTS"; break; + case 'BrtEndFonts': state = ""; break; + case 'BrtACBegin': state = "ACFONTS"; break; + case 'BrtACEnd': state = ""; break; + case 'BrtBeginFills': state = "FILLS"; break; + case 'BrtEndFills': state = ""; break; + case 'BrtBeginBorders': state = "BORDERS"; break; + case 'BrtEndBorders': state = ""; break; + case 'BrtBeginCellStyleXFs': state = "CELLSTYLEXFS"; break; + case 'BrtEndCellStyleXFs': state = ""; break; + case 'BrtBeginCellXFs': state = "CELLXFS"; break; + case 'BrtEndCellXFs': state = ""; break; + case 'BrtBeginStyles': state = "STYLES"; break; + case 'BrtEndStyles': state = ""; break; + case 'BrtBeginDXFs': state = "DXFS"; break; + case 'BrtEndDXFs': state = ""; break; + case 'BrtBeginTableStyles': state = "TABLESTYLES"; break; + case 'BrtEndTableStyles': state = ""; break; + case 'BrtBeginColorPalette': state = "COLORPALETTE"; break; + case 'BrtEndColorPalette': state = ""; break; + case 'BrtBeginIndexedColors': state = "INDEXEDCOLORS"; break; + case 'BrtEndIndexedColors': state = ""; break; + case 'BrtBeginMRUColors': state = "MRUCOLORS"; break; + case 'BrtEndMRUColors': state = ""; break; + case 'BrtFRTBegin': pass = true; break; + case 'BrtFRTEnd': pass = false; break; + case 'BrtBeginStyleSheetExt14': break; + case 'BrtBeginSlicerStyles': break; + case 'BrtEndSlicerStyles': break; + case 'BrtBeginTimelineStylesheetExt15': break; + case 'BrtEndTimelineStylesheetExt15': break; + case 'BrtBeginTimelineStyles': break; + case 'BrtEndTimelineStyles': break; + case 'BrtEndStyleSheetExt14': break; + default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n); + } + }); + return styles; +} + +/* [MS-XLSB] 2.1.7.50 Styles */ +function write_sty_bin(data, opts) { + var ba = buf_array(); + write_record(ba, "BrtBeginStyleSheet"); + /* [FMTS] */ + /* [FONTS] */ + /* [FILLS] */ + /* [BORDERS] */ + /* CELLSTYLEXFS */ + /* CELLXFS*/ + /* STYLES */ + /* DXFS */ + /* TABLESTYLES */ + /* [COLORPALETTE] */ + /* FRTSTYLESHEET*/ + write_record(ba, "BrtEndStyleSheet"); + return ba.end(); +} +RELS.THEME = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"; + +/* 20.1.6.2 clrScheme CT_ColorScheme */ +function parse_clrScheme(t, opts) { + themes.themeElements.clrScheme = []; + var color = {}; + t[0].match(tagregex).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': break; + + /* 20.1.2.3.32 srgbClr CT_SRgbColor */ + case '': + case '': + /* 20.1.4.1.10 dk2 (Dark 2) */ + case '': + case '': + /* 20.1.4.1.22 lt1 (Light 1) */ + case '': + case '': + /* 20.1.4.1.23 lt2 (Light 2) */ + case '': + case '': + /* 20.1.4.1.1 accent1 (Accent 1) */ + case '': + case '': + /* 20.1.4.1.2 accent2 (Accent 2) */ + case '': + case '': + /* 20.1.4.1.3 accent3 (Accent 3) */ + case '': + case '': + /* 20.1.4.1.4 accent4 (Accent 4) */ + case '': + case '': + /* 20.1.4.1.5 accent5 (Accent 5) */ + case '': + case '': + /* 20.1.4.1.6 accent6 (Accent 6) */ + case '': + case '': + /* 20.1.4.1.19 hlink (Hyperlink) */ + case '': + case '': + /* 20.1.4.1.15 folHlink (Followed Hyperlink) */ + case '': + case '': + if (y[0][1] === '/') { + themes.themeElements.clrScheme.push(color); + color = {}; + } else { + color.name = y[0].substring(3, y[0].length - 1); + } + break; + + default: if(opts.WTF) throw 'unrecognized ' + y[0] + ' in clrScheme'; + } + }); +} + +/* 20.1.4.1.18 fontScheme CT_FontScheme */ +function parse_fontScheme(t, opts) { } + +/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */ +function parse_fmtScheme(t, opts) { } + +var clrsregex = /]*)>[^\u2603]*<\/a:clrScheme>/; +var fntsregex = /]*)>[^\u2603]*<\/a:fontScheme>/; +var fmtsregex = /]*)>[^\u2603]*<\/a:fmtScheme>/; + +/* 20.1.6.10 themeElements CT_BaseStyles */ +function parse_themeElements(data, opts) { + themes.themeElements = {}; + + var t; + + [ + /* clrScheme CT_ColorScheme */ + ['clrScheme', clrsregex, parse_clrScheme], + /* fontScheme CT_FontScheme */ + ['fontScheme', fntsregex, parse_fontScheme], + /* fmtScheme CT_StyleMatrix */ + ['fmtScheme', fmtsregex, parse_fmtScheme] + ].forEach(function(m) { + if(!(t=data.match(m[1]))) throw m[0] + ' not found in themeElements'; + m[2](t, opts); + }); +} + +var themeltregex = /]*)>[^\u2603]*<\/a:themeElements>/; + +/* 14.2.7 Theme Part */ +function parse_theme_xml(data, opts) { + /* 20.1.6.9 theme CT_OfficeStyleSheet */ + if(!data || data.length === 0) return themes; + + var t; + + /* themeElements CT_BaseStyles */ + if(!(t=data.match(themeltregex))) throw 'themeElements not found in theme'; + parse_themeElements(t[0], opts); + + return themes; +} + +function write_theme() { return '\n'; } +/* [MS-XLS] 2.4.326 TODO: payload is a zip file */ +function parse_Theme(blob, length) { + var dwThemeVersion = blob.read_shift(4); + if(dwThemeVersion === 124226) return; + blob.l += length-4; +} + +/* 2.5.49 */ +function parse_ColorTheme(blob, length) { return blob.read_shift(4); } + +/* 2.5.155 */ +function parse_FullColorExt(blob, length) { + var o = {}; + o.xclrType = blob.read_shift(2); + o.nTintShade = blob.read_shift(2); + switch(o.xclrType) { + case 0: blob.l += 4; break; + case 1: o.xclrValue = parse_IcvXF(blob, 4); break; + case 2: o.xclrValue = parse_LongRGBA(blob, 4); break; + case 3: o.xclrValue = parse_ColorTheme(blob, 4); break; + case 4: blob.l += 4; break; + } + blob.l += 8; + return o; +} + +/* 2.5.164 TODO: read 7 bits*/ +function parse_IcvXF(blob, length) { + return parsenoop(blob, length); +} + +/* 2.5.280 */ +function parse_XFExtGradient(blob, length) { + return parsenoop(blob, length); +} + +/* 2.5.108 */ +function parse_ExtProp(blob, length) { + var extType = blob.read_shift(2); + var cb = blob.read_shift(2); + var o = [extType]; + switch(extType) { + case 0x04: case 0x05: case 0x07: case 0x08: + case 0x09: case 0x0A: case 0x0B: case 0x0D: + o[1] = parse_FullColorExt(blob, cb); break; + case 0x06: o[1] = parse_XFExtGradient(blob, cb); break; + case 0x0E: case 0x0F: o[1] = blob.read_shift(cb === 5 ? 1 : 2); break; + default: throw new Error("Unrecognized ExtProp type: " + extType + " " + cb); + } + return o; +} + +/* 2.4.355 */ +function parse_XFExt(blob, length) { + var end = blob.l + length; + blob.l += 2; + var ixfe = blob.read_shift(2); + blob.l += 2; + var cexts = blob.read_shift(2); + var ext = []; + while(cexts-- > 0) ext.push(parse_ExtProp(blob, end-blob.l)); + return {ixfe:ixfe, ext:ext}; +} + +/* xf is an XF, see parse_XFExt for xfext */ +function update_xfext(xf, xfext) { + xfext.forEach(function(xfe) { + switch(xfe[0]) { /* 2.5.108 extPropData */ + case 0x04: break; /* foreground color */ + case 0x05: break; /* background color */ + case 0x07: case 0x08: case 0x09: case 0x0a: break; + case 0x0d: break; /* text color */ + case 0x0e: break; /* font scheme */ + default: throw "bafuq" + xfe[0].toString(16); + } + }); +} + +/* 18.6 Calculation Chain */ +function parse_cc_xml(data, opts) { + var d = []; + var l = 0, i = 1; + (data.match(tagregex)||[]).forEach(function(x) { + var y = parsexmltag(x); + switch(y[0]) { + case '': case '': break; + /* 18.6.1 c CT_CalcCell 1 */ + case ' thisCell.r) range.s.r = thisCell.r; + if(range.e.r < thisCell.r) range.e.r = thisCell.r; + if(range.s.c > thisCell.c) range.s.c = thisCell.c; + if(range.e.c < thisCell.c) range.e.c = thisCell.c; + var encoded = encode_range(range); + if (encoded !== sheet["!ref"]) sheet["!ref"] = encoded; + } + + if (!cell.c) cell.c = []; + var o = {a: comment.author, t: comment.t, r: comment.r}; + if(comment.h) o.h = comment.h; + cell.c.push(o); + }); +} + +/* 18.7.3 CT_Comment */ +function parse_comments_xml(data, opts) { + if(data.match(/<(?:\w+:)?comments *\/>/)) return []; + var authors = []; + var commentList = []; + data.match(/<(?:\w+:)?authors>([^\u2603]*)<\/(?:\w+:)?authors>/)[1].split(/<\/\w*:?author>/).forEach(function(x) { + if(x === "" || x.trim() === "") return; + authors.push(x.match(/<(?:\w+:)?author[^>]*>(.*)/)[1]); + }); + (data.match(/<(?:\w+:)?commentList>([^\u2603]*)<\/(?:\w+:)?commentList>/)||["",""])[1].split(/<\/\w*:?comment>/).forEach(function(x, index) { + if(x === "" || x.trim() === "") return; + var y = parsexmltag(x.match(/<(?:\w+:)?comment[^>]*>/)[0]); + var comment = { author: y.authorId && authors[y.authorId] ? authors[y.authorId] : undefined, ref: y.ref, guid: y.guid }; + var cell = decode_cell(y.ref); + if(opts.sheetRows && opts.sheetRows <= cell.r) return; + var textMatch = x.match(/([^\u2603]*)<\/text>/); + if (!textMatch || !textMatch[1]) return; // a comment may contain an empty text tag. + var rt = parse_si(textMatch[1]); + comment.r = rt.r; + comment.t = rt.t; + if(opts.cellHTML) comment.h = rt.h; + commentList.push(comment); + }); + return commentList; +} + +function write_comments_xml(data, opts) { } +/* [MS-XLSB] 2.4.28 BrtBeginComment */ +function parse_BrtBeginComment(data, length) { + var out = {}; + out.iauthor = data.read_shift(4); + var rfx = parse_UncheckedRfX(data, 16); + out.rfx = rfx.s; + out.ref = encode_cell(rfx.s); + data.l += 16; /*var guid = parse_GUID(data); */ + return out; +} + +/* [MS-XLSB] 2.4.324 BrtCommentAuthor */ +var parse_BrtCommentAuthor = parse_XLWideString; + +/* [MS-XLSB] 2.4.325 BrtCommentText */ +var parse_BrtCommentText = parse_RichStr; + +/* [MS-XLSB] 2.1.7.8 Comments */ +function parse_comments_bin(data, opts) { + var out = []; + var authors = []; + var c = {}; + var pass = false; + recordhopper(data, function hopper_cmnt(val, R, RT) { + switch(R.n) { + case 'BrtCommentAuthor': authors.push(val); break; + case 'BrtBeginComment': c = val; break; + case 'BrtCommentText': c.t = val.t; c.h = val.h; c.r = val.r; break; + case 'BrtEndComment': + c.author = authors[c.iauthor]; + delete c.iauthor; + if(opts.sheetRows && opts.sheetRows <= c.rfx.r) break; + delete c.rfx; out.push(c); break; + case 'BrtBeginComments': break; + case 'BrtEndComments': break; + case 'BrtBeginCommentAuthors': break; + case 'BrtEndCommentAuthors': break; + case 'BrtBeginCommentList': break; + case 'BrtEndCommentList': break; + default: if(!pass || opts.WTF) throw new Error("Unexpected record " + RT + " " + R.n); + } + }); + return out; +} + +function write_comments_bin(data, opts) { } +/* TODO: it will be useful to parse the function str */ +var rc_to_a1 = (function(){ + var rcregex = /(^|[^A-Za-z])R(\[?)(-?\d+|)\]?C(\[?)(-?\d+|)\]?/g; + var rcbase; + function rcfunc($$,$1,$2,$3,$4,$5) { + var R = $3.length>0?parseInt($3,10)|0:0, C = $5.length>0?parseInt($5,10)|0:0; + if(C<0 && $4.length === 0) C=0; + if($4.length > 0) C += rcbase.c; + if($2.length > 0) R += rcbase.r; + return $1 + encode_col(C) + encode_row(R); + } + return function rc_to_a1(fstr, base) { + rcbase = base; + return fstr.replace(rcregex, rcfunc); + }; +})(); + +/* --- formula references point to MS-XLS --- */ +/* Small helpers */ +function parseread(l) { return function(blob, length) { blob.l+=l; return; }; } +function parseread1(blob, length) { blob.l+=1; return; } + +/* Rgce Helpers */ + +/* 2.5.51 */ +function parse_ColRelU(blob, length) { + var c = blob.read_shift(2); + return [c & 0x3FFF, (c >> 14) & 1, (c >> 15) & 1]; +} + +/* 2.5.198.105 */ +function parse_RgceArea(blob, length) { + var r=blob.read_shift(2), R=blob.read_shift(2); + var c=parse_ColRelU(blob, 2); + var C=parse_ColRelU(blob, 2); + return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} }; +} + +/* 2.5.198.105 TODO */ +function parse_RgceAreaRel(blob, length) { + var r=blob.read_shift(2), R=blob.read_shift(2); + var c=parse_ColRelU(blob, 2); + var C=parse_ColRelU(blob, 2); + return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} }; +} + +/* 2.5.198.109 */ +function parse_RgceLoc(blob, length) { + var r = blob.read_shift(2); + var c = parse_ColRelU(blob, 2); + return {r:r, c:c[0], cRel:c[1], rRel:c[2]}; +} + +/* 2.5.198.111 */ +function parse_RgceLocRel(blob, length) { + var r = blob.read_shift(2); + var cl = blob.read_shift(2); + var cRel = (cl & 0x8000) >> 15, rRel = (cl & 0x4000) >> 14; + cl &= 0x3FFF; + if(cRel !== 0) while(cl >= 0x100) cl -= 0x100; + return {r:r,c:cl,cRel:cRel,rRel:rRel}; +} + +/* Ptg Tokens */ + +/* 2.5.198.27 */ +function parse_PtgArea(blob, length) { + var type = (blob[blob.l++] & 0x60) >> 5; + var area = parse_RgceArea(blob, 8); + return [type, area]; +} + +/* 2.5.198.28 */ +function parse_PtgArea3d(blob, length) { + var type = (blob[blob.l++] & 0x60) >> 5; + var ixti = blob.read_shift(2); + var area = parse_RgceArea(blob, 8); + return [type, ixti, area]; +} + +/* 2.5.198.29 */ +function parse_PtgAreaErr(blob, length) { + var type = (blob[blob.l++] & 0x60) >> 5; + blob.l += 8; + return [type]; +} +/* 2.5.198.30 */ +function parse_PtgAreaErr3d(blob, length) { + var type = (blob[blob.l++] & 0x60) >> 5; + var ixti = blob.read_shift(2); + blob.l += 8; + return [type, ixti]; +} + +/* 2.5.198.31 */ +function parse_PtgAreaN(blob, length) { + var type = (blob[blob.l++] & 0x60) >> 5; + var area = parse_RgceAreaRel(blob, 8); + return [type, area]; +} + +/* 2.5.198.32 -- ignore this and look in PtgExtraArray for shape + values */ +function parse_PtgArray(blob, length) { + var type = (blob[blob.l++] & 0x60) >> 5; + blob.l += 7; + return [type]; +} + +/* 2.5.198.33 */ +function parse_PtgAttrBaxcel(blob, length) { + var bitSemi = blob[blob.l+1] & 0x01; /* 1 = volatile */ + var bitBaxcel = 1; + blob.l += 4; + return [bitSemi, bitBaxcel]; +} + +/* 2.5.198.34 */ +function parse_PtgAttrChoose(blob, length) { + blob.l +=2; + var offset = blob.read_shift(2); + var o = []; + /* offset is 1 less than the number of elements */ + for(var i = 0; i <= offset; ++i) o.push(blob.read_shift(2)); + return o; +} + +/* 2.5.198.35 */ +function parse_PtgAttrGoto(blob, length) { + var bitGoto = (blob[blob.l+1] & 0xFF) ? 1 : 0; + blob.l += 2; + return [bitGoto, blob.read_shift(2)]; +} + +/* 2.5.198.36 */ +function parse_PtgAttrIf(blob, length) { + var bitIf = (blob[blob.l+1] & 0xFF) ? 1 : 0; + blob.l += 2; + return [bitIf, blob.read_shift(2)]; +} + +/* 2.5.198.37 */ +function parse_PtgAttrSemi(blob, length) { + var bitSemi = (blob[blob.l+1] & 0xFF) ? 1 : 0; + blob.l += 4; + return [bitSemi]; +} + +/* 2.5.198.40 (used by PtgAttrSpace and PtgAttrSpaceSemi) */ +function parse_PtgAttrSpaceType(blob, length) { + var type = blob.read_shift(1), cch = blob.read_shift(1); + return [type, cch]; +} + +/* 2.5.198.38 */ +function parse_PtgAttrSpace(blob, length) { + blob.read_shift(2); + return parse_PtgAttrSpaceType(blob, 2); +} + +/* 2.5.198.39 */ +function parse_PtgAttrSpaceSemi(blob, length) { + blob.read_shift(2); + return parse_PtgAttrSpaceType(blob, 2); +} + +/* 2.5.198.84 TODO */ +function parse_PtgRef(blob, length) { + var ptg = blob[blob.l] & 0x1F; + var type = (blob[blob.l] & 0x60)>>5; + blob.l += 1; + var loc = parse_RgceLoc(blob,4); + return [type, loc]; +} + +/* 2.5.198.88 TODO */ +function parse_PtgRefN(blob, length) { + var ptg = blob[blob.l] & 0x1F; + var type = (blob[blob.l] & 0x60)>>5; + blob.l += 1; + var loc = parse_RgceLocRel(blob,4); + return [type, loc]; +} + +/* 2.5.198.85 TODO */ +function parse_PtgRef3d(blob, length) { + var ptg = blob[blob.l] & 0x1F; + var type = (blob[blob.l] & 0x60)>>5; + blob.l += 1; + var ixti = blob.read_shift(2); // XtiIndex + var loc = parse_RgceLoc(blob,4); + return [type, ixti, loc]; +} + + +/* 2.5.198.62 TODO */ +function parse_PtgFunc(blob, length) { + var ptg = blob[blob.l] & 0x1F; + var type = (blob[blob.l] & 0x60)>>5; + blob.l += 1; + var iftab = blob.read_shift(2); + return [FtabArgc[iftab], Ftab[iftab]]; +} +/* 2.5.198.63 TODO */ +function parse_PtgFuncVar(blob, length) { + blob.l++; + var cparams = blob.read_shift(1), tab = parsetab(blob); + return [cparams, (tab[0] === 0 ? Ftab : Cetab)[tab[1]]]; +} + +function parsetab(blob, length) { + return [blob[blob.l+1]>>7, blob.read_shift(2) & 0x7FFF]; +} + +/* 2.5.198.41 */ +var parse_PtgAttrSum = parseread(4); +/* 2.5.198.43 */ +var parse_PtgConcat = parseread1; + +/* 2.5.198.58 */ +function parse_PtgExp(blob, length) { + blob.l++; + var row = blob.read_shift(2); + var col = blob.read_shift(2); + return [row, col]; +} + +/* 2.5.198.57 */ +function parse_PtgErr(blob, length) { blob.l++; return BErr[blob.read_shift(1)]; } + +/* 2.5.198.66 TODO */ +function parse_PtgInt(blob, length) { blob.l++; return blob.read_shift(2); } + +/* 2.5.198.42 */ +function parse_PtgBool(blob, length) { blob.l++; return blob.read_shift(1)!==0;} + +/* 2.5.198.79 */ +function parse_PtgNum(blob, length) { blob.l++; return parse_Xnum(blob, 8); } + +/* 2.5.198.89 */ +function parse_PtgStr(blob, length) { blob.l++; return parse_ShortXLUnicodeString(blob); } + +/* 2.5.192.112 + 2.5.192.11{3,4,5,6,7} */ +function parse_SerAr(blob) { + var val = []; + switch((val[0] = blob.read_shift(1))) { + /* 2.5.192.113 */ + case 0x04: /* SerBool -- boolean */ + val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE'; + blob.l += 7; break; + /* 2.5.192.114 */ + case 0x10: /* SerErr -- error */ + val[1] = BErr[blob[blob.l]]; + blob.l += 8; break; + /* 2.5.192.115 */ + case 0x00: /* SerNil -- honestly, I'm not sure how to reproduce this */ + blob.l += 8; break; + /* 2.5.192.116 */ + case 0x01: /* SerNum -- Xnum */ + val[1] = parse_Xnum(blob, 8); break; + /* 2.5.192.117 */ + case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */ + val[1] = parse_XLUnicodeString(blob); break; + // default: throw "Bad SerAr: " + val[0]; /* Unreachable */ + } + return val; +} + +/* 2.5.198.61 */ +function parse_PtgExtraMem(blob, cce) { + var count = blob.read_shift(2); + var out = []; + for(var i = 0; i != count; ++i) out.push(parse_Ref8U(blob, 8)); + return out; +} + +/* 2.5.198.59 */ +function parse_PtgExtraArray(blob) { + var cols = 1 + blob.read_shift(1); //DColByteU + var rows = 1 + blob.read_shift(2); //DRw + for(var i = 0, o=[]; i != rows && (o[i] = []); ++i) + for(var j = 0; j != cols; ++j) o[i][j] = parse_SerAr(blob); + return o; +} + +/* 2.5.198.76 */ +function parse_PtgName(blob, length) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var nameindex = blob.read_shift(4); + return [type, 0, nameindex]; +} + +/* 2.5.198.77 */ +function parse_PtgNameX(blob, length) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var ixti = blob.read_shift(2); // XtiIndex + var nameindex = blob.read_shift(4); + return [type, ixti, nameindex]; +} + +/* 2.5.198.70 */ +function parse_PtgMemArea(blob, length) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + blob.l += 4; + var cce = blob.read_shift(2); + return [type, cce]; +} + +/* 2.5.198.72 */ +function parse_PtgMemFunc(blob, length) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + var cce = blob.read_shift(2); + return [type, cce]; +} + + +/* 2.5.198.86 */ +function parse_PtgRefErr(blob, length) { + var type = (blob.read_shift(1) >>> 5) & 0x03; + blob.l += 4; + return [type]; +} + +/* 2.5.198.26 */ +var parse_PtgAdd = parseread1; +/* 2.5.198.45 */ +var parse_PtgDiv = parseread1; +/* 2.5.198.56 */ +var parse_PtgEq = parseread1; +/* 2.5.198.64 */ +var parse_PtgGe = parseread1; +/* 2.5.198.65 */ +var parse_PtgGt = parseread1; +/* 2.5.198.67 */ +var parse_PtgIsect = parseread1; +/* 2.5.198.68 */ +var parse_PtgLe = parseread1; +/* 2.5.198.69 */ +var parse_PtgLt = parseread1; +/* 2.5.198.74 */ +var parse_PtgMissArg = parseread1; +/* 2.5.198.75 */ +var parse_PtgMul = parseread1; +/* 2.5.198.78 */ +var parse_PtgNe = parseread1; +/* 2.5.198.80 */ +var parse_PtgParen = parseread1; +/* 2.5.198.81 */ +var parse_PtgPercent = parseread1; +/* 2.5.198.82 */ +var parse_PtgPower = parseread1; +/* 2.5.198.83 */ +var parse_PtgRange = parseread1; +/* 2.5.198.90 */ +var parse_PtgSub = parseread1; +/* 2.5.198.93 */ +var parse_PtgUminus = parseread1; +/* 2.5.198.94 */ +var parse_PtgUnion = parseread1; +/* 2.5.198.95 */ +var parse_PtgUplus = parseread1; + +/* 2.5.198.71 */ +var parse_PtgMemErr = parsenoop; +/* 2.5.198.73 */ +var parse_PtgMemNoMem = parsenoop; +/* 2.5.198.87 */ +var parse_PtgRefErr3d = parsenoop; +/* 2.5.198.92 */ +var parse_PtgTbl = parsenoop; + +/* 2.5.198.25 */ +var PtgTypes = { + 0x01: { n:'PtgExp', f:parse_PtgExp }, + 0x02: { n:'PtgTbl', f:parse_PtgTbl }, + 0x03: { n:'PtgAdd', f:parse_PtgAdd }, + 0x04: { n:'PtgSub', f:parse_PtgSub }, + 0x05: { n:'PtgMul', f:parse_PtgMul }, + 0x06: { n:'PtgDiv', f:parse_PtgDiv }, + 0x07: { n:'PtgPower', f:parse_PtgPower }, + 0x08: { n:'PtgConcat', f:parse_PtgConcat }, + 0x09: { n:'PtgLt', f:parse_PtgLt }, + 0x0A: { n:'PtgLe', f:parse_PtgLe }, + 0x0B: { n:'PtgEq', f:parse_PtgEq }, + 0x0C: { n:'PtgGe', f:parse_PtgGe }, + 0x0D: { n:'PtgGt', f:parse_PtgGt }, + 0x0E: { n:'PtgNe', f:parse_PtgNe }, + 0x0F: { n:'PtgIsect', f:parse_PtgIsect }, + 0x10: { n:'PtgUnion', f:parse_PtgUnion }, + 0x11: { n:'PtgRange', f:parse_PtgRange }, + 0x12: { n:'PtgUplus', f:parse_PtgUplus }, + 0x13: { n:'PtgUminus', f:parse_PtgUminus }, + 0x14: { n:'PtgPercent', f:parse_PtgPercent }, + 0x15: { n:'PtgParen', f:parse_PtgParen }, + 0x16: { n:'PtgMissArg', f:parse_PtgMissArg }, + 0x17: { n:'PtgStr', f:parse_PtgStr }, + 0x1C: { n:'PtgErr', f:parse_PtgErr }, + 0x1D: { n:'PtgBool', f:parse_PtgBool }, + 0x1E: { n:'PtgInt', f:parse_PtgInt }, + 0x1F: { n:'PtgNum', f:parse_PtgNum }, + 0x20: { n:'PtgArray', f:parse_PtgArray }, + 0x21: { n:'PtgFunc', f:parse_PtgFunc }, + 0x22: { n:'PtgFuncVar', f:parse_PtgFuncVar }, + 0x23: { n:'PtgName', f:parse_PtgName }, + 0x24: { n:'PtgRef', f:parse_PtgRef }, + 0x25: { n:'PtgArea', f:parse_PtgArea }, + 0x26: { n:'PtgMemArea', f:parse_PtgMemArea }, + 0x27: { n:'PtgMemErr', f:parse_PtgMemErr }, + 0x28: { n:'PtgMemNoMem', f:parse_PtgMemNoMem }, + 0x29: { n:'PtgMemFunc', f:parse_PtgMemFunc }, + 0x2A: { n:'PtgRefErr', f:parse_PtgRefErr }, + 0x2B: { n:'PtgAreaErr', f:parse_PtgAreaErr }, + 0x2C: { n:'PtgRefN', f:parse_PtgRefN }, + 0x2D: { n:'PtgAreaN', f:parse_PtgAreaN }, + 0x39: { n:'PtgNameX', f:parse_PtgNameX }, + 0x3A: { n:'PtgRef3d', f:parse_PtgRef3d }, + 0x3B: { n:'PtgArea3d', f:parse_PtgArea3d }, + 0x3C: { n:'PtgRefErr3d', f:parse_PtgRefErr3d }, + 0x3D: { n:'PtgAreaErr3d', f:parse_PtgAreaErr3d }, + 0xFF: {} +}; +/* These are duplicated in the PtgTypes table */ +var PtgDupes = { + 0x40: 0x20, 0x60: 0x20, + 0x41: 0x21, 0x61: 0x21, + 0x42: 0x22, 0x62: 0x22, + 0x43: 0x23, 0x63: 0x23, + 0x44: 0x24, 0x64: 0x24, + 0x45: 0x25, 0x65: 0x25, + 0x46: 0x26, 0x66: 0x26, + 0x47: 0x27, 0x67: 0x27, + 0x48: 0x28, 0x68: 0x28, + 0x49: 0x29, 0x69: 0x29, + 0x4A: 0x2A, 0x6A: 0x2A, + 0x4B: 0x2B, 0x6B: 0x2B, + 0x4C: 0x2C, 0x6C: 0x2C, + 0x4D: 0x2D, 0x6D: 0x2D, + 0x59: 0x39, 0x79: 0x39, + 0x5A: 0x3A, 0x7A: 0x3A, + 0x5B: 0x3B, 0x7B: 0x3B, + 0x5C: 0x3C, 0x7C: 0x3C, + 0x5D: 0x3D, 0x7D: 0x3D +}; +(function(){for(var y in PtgDupes) PtgTypes[y] = PtgTypes[PtgDupes[y]];})(); + +var Ptg18 = {}; +var Ptg19 = { + 0x01: { n:'PtgAttrSemi', f:parse_PtgAttrSemi }, + 0x02: { n:'PtgAttrIf', f:parse_PtgAttrIf }, + 0x04: { n:'PtgAttrChoose', f:parse_PtgAttrChoose }, + 0x08: { n:'PtgAttrGoto', f:parse_PtgAttrGoto }, + 0x10: { n:'PtgAttrSum', f:parse_PtgAttrSum }, + 0x20: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel }, + 0x40: { n:'PtgAttrSpace', f:parse_PtgAttrSpace }, + 0x41: { n:'PtgAttrSpaceSemi', f:parse_PtgAttrSpaceSemi }, + 0xFF: {} +}; + +/* 2.4.127 TODO */ +function parse_Formula(blob, length, opts) { + var cell = parse_XLSCell(blob, 6); + var val = parse_FormulaValue(blob,8); + var flags = blob.read_shift(1); + blob.read_shift(1); + var chn = blob.read_shift(4); + var cbf = ""; + if(opts.biff === 5) blob.l += length-20; + else cbf = parse_XLSCellParsedFormula(blob, length-20, opts); + return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]}; +} + +/* 2.5.133 TODO: how to emit empty strings? */ +function parse_FormulaValue(blob) { + var b; + if(__readUInt16LE(blob,blob.l + 6) !== 0xFFFF) return [parse_Xnum(blob),'n']; + switch(blob[blob.l]) { + case 0x00: blob.l += 8; return ["String", 's']; + case 0x01: b = blob[blob.l+2] === 0x1; blob.l += 8; return [b,'b']; + case 0x02: b = blob[blob.l+2]; blob.l += 8; return [b,'e']; + case 0x03: blob.l += 8; return ["",'s']; + } +} + +/* 2.5.198.103 */ +function parse_RgbExtra(blob, length, rgce, opts) { + if(opts.biff < 8) return parsenoop(blob, length); + var target = blob.l + length; + var o = []; + for(var i = 0; i !== rgce.length; ++i) { + switch(rgce[i][0]) { + case 'PtgArray': /* PtgArray -> PtgExtraArray */ + rgce[i][1] = parse_PtgExtraArray(blob); + o.push(rgce[i][1]); + break; + case 'PtgMemArea': /* PtgMemArea -> PtgExtraMem */ + rgce[i][2] = parse_PtgExtraMem(blob, rgce[i][1]); + o.push(rgce[i][2]); + break; + default: break; + } + } + length = target - blob.l; + if(length !== 0) o.push(parsenoop(blob, length)); + return o; +} + +/* 2.5.198.21 */ +function parse_NameParsedFormula(blob, length, opts, cce) { + var target = blob.l + length; + var rgce = parse_Rgce(blob, cce); + var rgcb; + if(target !== blob.l) rgcb = parse_RgbExtra(blob, target - blob.l, rgce, opts); + return [rgce, rgcb]; +} + +/* 2.5.198.3 TODO */ +function parse_XLSCellParsedFormula(blob, length, opts) { + var target = blob.l + length; + var rgcb, cce = blob.read_shift(2); // length of rgce + if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)]; + var rgce = parse_Rgce(blob, cce); + if(length !== cce + 2) rgcb = parse_RgbExtra(blob, length - cce - 2, rgce, opts); + return [rgce, rgcb]; +} + +/* 2.5.198.118 TODO */ +function parse_SharedParsedFormula(blob, length, opts) { + var target = blob.l + length; + var rgcb, cce = blob.read_shift(2); // length of rgce + var rgce = parse_Rgce(blob, cce); + if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)]; + if(length !== cce + 2) rgcb = parse_RgbExtra(blob, target - cce - 2, rgce, opts); + return [rgce, rgcb]; +} + +/* 2.5.198.1 TODO */ +function parse_ArrayParsedFormula(blob, length, opts, ref) { + var target = blob.l + length; + var rgcb, cce = blob.read_shift(2); // length of rgce + if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)]; + var rgce = parse_Rgce(blob, cce); + if(length !== cce + 2) rgcb = parse_RgbExtra(blob, target - cce - 2, rgce, opts); + return [rgce, rgcb]; +} + +/* 2.5.198.104 */ +function parse_Rgce(blob, length) { + var target = blob.l + length; + var R, id, ptgs = []; + while(target != blob.l) { + length = target - blob.l; + id = blob[blob.l]; + R = PtgTypes[id]; + //console.log("ptg", id, R) + if(id === 0x18 || id === 0x19) { + id = blob[blob.l + 1]; + R = (id === 0x18 ? Ptg18 : Ptg19)[id]; + } + if(!R || !R.f) { ptgs.push(parsenoop(blob, length)); } + else { ptgs.push([R.n, R.f(blob, length)]); } + } + return ptgs; +} + +function mapper(x) { return x.map(function f2(y) { return y[1];}).join(",");} + +/* 2.2.2 + Magic TODO */ +function stringify_formula(formula, range, cell, supbooks, opts) { + if(opts !== undefined && opts.biff === 5) return "BIFF5??"; + var _range = range !== undefined ? range : {s:{c:0, r:0}}; + var stack = [], e1, e2, type, c, ixti, nameidx, r; + if(!formula[0] || !formula[0][0]) return ""; + //console.log("--",cell,formula[0]) + for(var ff = 0, fflen = formula[0].length; ff < fflen; ++ff) { + var f = formula[0][ff]; + //console.log("++",f, stack) + switch(f[0]) { + /* 2.2.2.1 Unary Operator Tokens */ + /* 2.5.198.93 */ + case 'PtgUminus': stack.push("-" + stack.pop()); break; + /* 2.5.198.95 */ + case 'PtgUplus': stack.push("+" + stack.pop()); break; + /* 2.5.198.81 */ + case 'PtgPercent': stack.push(stack.pop() + "%"); break; + + /* 2.2.2.1 Binary Value Operator Token */ + /* 2.5.198.26 */ + case 'PtgAdd': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"+"+e1); + break; + /* 2.5.198.90 */ + case 'PtgSub': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"-"+e1); + break; + /* 2.5.198.75 */ + case 'PtgMul': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"*"+e1); + break; + /* 2.5.198.45 */ + case 'PtgDiv': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"/"+e1); + break; + /* 2.5.198.82 */ + case 'PtgPower': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"^"+e1); + break; + /* 2.5.198.43 */ + case 'PtgConcat': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"&"+e1); + break; + /* 2.5.198.69 */ + case 'PtgLt': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"<"+e1); + break; + /* 2.5.198.68 */ + case 'PtgLe': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"<="+e1); + break; + /* 2.5.198.56 */ + case 'PtgEq': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"="+e1); + break; + /* 2.5.198.64 */ + case 'PtgGe': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+">="+e1); + break; + /* 2.5.198.65 */ + case 'PtgGt': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+">"+e1); + break; + /* 2.5.198.78 */ + case 'PtgNe': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+"<>"+e1); + break; + + /* 2.2.2.1 Binary Reference Operator Token */ + /* 2.5.198.67 */ + case 'PtgIsect': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+" "+e1); + break; + case 'PtgUnion': + e1 = stack.pop(); e2 = stack.pop(); + stack.push(e2+","+e1); + break; + case 'PtgRange': break; + + /* 2.2.2.3 Control Tokens "can be ignored" */ + /* 2.5.198.34 */ + case 'PtgAttrChoose': break; + /* 2.5.198.35 */ + case 'PtgAttrGoto': break; + /* 2.5.198.36 */ + case 'PtgAttrIf': break; + + + /* 2.5.198.84 */ + case 'PtgRef': + type = f[1][0]; c = shift_cell_xls(decode_cell(encode_cell(f[1][1])), _range); + stack.push(encode_cell(c)); + break; + /* 2.5.198.88 */ + case 'PtgRefN': + type = f[1][0]; c = shift_cell_xls(decode_cell(encode_cell(f[1][1])), cell); + stack.push(encode_cell(c)); + break; + case 'PtgRef3d': // TODO: lots of stuff + type = f[1][0]; ixti = f[1][1]; c = shift_cell_xls(f[1][2], _range); + stack.push(supbooks[1][ixti+1]+"!"+encode_cell(c)); + break; + + /* Function Call */ + /* 2.5.198.62 */ + case 'PtgFunc': + /* 2.5.198.63 */ + case 'PtgFuncVar': + /* f[1] = [argc, func] */ + var argc = f[1][0], func = f[1][1]; + if(!argc) argc = 0; + var args = stack.slice(-argc); + stack.length -= argc; + if(func === 'User') func = args.shift(); + stack.push(func + "(" + args.join(",") + ")"); + break; + + /* 2.5.198.42 */ + case 'PtgBool': stack.push(f[1] ? "TRUE" : "FALSE"); break; + /* 2.5.198.66 */ + case 'PtgInt': stack.push(f[1]); break; + /* 2.5.198.79 TODO: precision? */ + case 'PtgNum': stack.push(String(f[1])); break; + /* 2.5.198.89 */ + case 'PtgStr': stack.push('"' + f[1] + '"'); break; + /* 2.5.198.57 */ + case 'PtgErr': stack.push(f[1]); break; + /* 2.5.198.27 TODO: fixed points */ + case 'PtgArea': + type = f[1][0]; r = shift_range_xls(f[1][1], _range); + stack.push(encode_range(r)); + break; + /* 2.5.198.28 */ + case 'PtgArea3d': // TODO: lots of stuff + type = f[1][0]; ixti = f[1][1]; r = f[1][2]; + stack.push(supbooks[1][ixti+1]+"!"+encode_range(r)); + break; + /* 2.5.198.41 */ + case 'PtgAttrSum': + stack.push("SUM(" + stack.pop() + ")"); + break; + + /* Expression Prefixes */ + /* 2.5.198.37 */ + case 'PtgAttrSemi': break; + + /* 2.5.97.60 TODO: do something different for revisions */ + case 'PtgName': + /* f[1] = type, 0, nameindex */ + nameidx = f[1][2]; + var lbl = supbooks[0][nameidx]; + var name = lbl.Name; + if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name]; + stack.push(name); + break; + + /* 2.5.97.61 TODO: do something different for revisions */ + case 'PtgNameX': + /* f[1] = type, ixti, nameindex */ + var bookidx = f[1][1]; nameidx = f[1][2]; var externbook; + /* TODO: Properly handle missing values */ + if(supbooks[bookidx+1]) externbook = supbooks[bookidx+1][nameidx]; + else if(supbooks[bookidx-1]) externbook = supbooks[bookidx-1][nameidx]; + if(!externbook) externbook = {body: "??NAMEX??"}; + stack.push(externbook.body); + break; + + /* 2.2.2.4 Display Tokens */ + /* 2.5.198.80 */ + case 'PtgParen': stack.push('(' + stack.pop() + ')'); break; + + /* 2.5.198.86 */ + case 'PtgRefErr': stack.push('#REF!'); break; + + /* */ + /* 2.5.198.58 TODO */ + case 'PtgExp': + c = {c:f[1][1],r:f[1][0]}; + var q = {c: cell.c, r:cell.r}; + if(supbooks.sharedf[encode_cell(c)]) { + var parsedf = (supbooks.sharedf[encode_cell(c)]); + stack.push(stringify_formula(parsedf, _range, q, supbooks, opts)); + } + else { + var fnd = false; + for(e1=0;e1!=supbooks.arrayf.length; ++e1) { + /* TODO: should be something like range_has */ + e2 = supbooks.arrayf[e1]; + if(c.c < e2[0].s.c || c.c > e2[0].e.c) continue; + if(c.r < e2[0].s.r || c.r > e2[0].e.r) continue; + stack.push(stringify_formula(e2[1], _range, q, supbooks, opts)); + } + if(!fnd) stack.push(f[1]); + } + break; + + /* 2.5.198.32 TODO */ + case 'PtgArray': + stack.push("{" + f[1].map(mapper).join(";") + "}"); + break; + + /* 2.2.2.5 Mem Tokens */ + /* 2.5.198.70 TODO: confirm this is a non-display */ + case 'PtgMemArea': + //stack.push("(" + f[2].map(encode_range).join(",") + ")"); + break; + + /* 2.5.198.38 TODO */ + case 'PtgAttrSpace': break; + + /* 2.5.198.92 TODO */ + case 'PtgTbl': break; + + /* 2.5.198.71 */ + case 'PtgMemErr': break; + + /* 2.5.198.74 */ + case 'PtgMissArg': + stack.push(""); + break; + + /* 2.5.198.29 TODO */ + case 'PtgAreaErr': break; + + /* 2.5.198.31 TODO */ + case 'PtgAreaN': stack.push(""); break; + + /* 2.5.198.87 TODO */ + case 'PtgRefErr3d': break; + + /* 2.5.198.72 TODO */ + case 'PtgMemFunc': break; + + default: throw 'Unrecognized Formula Token: ' + f; + } + //console.log("::",f, stack) + } + //console.log("--",stack); + return stack[0]; +} + +/* [MS-XLSB] 2.5.97.4 CellParsedFormula TODO: use similar logic to js-xls */ +function parse_XLSBCellParsedFormula(data, length) { + var cce = data.read_shift(4); + return parsenoop(data, length-4); +} +/* [MS-XLS] 2.5.198.44 */ +var PtgDataType = { + 0x1: "REFERENCE", // reference to range + 0x2: "VALUE", // single value + 0x3: "ARRAY" // array of values +}; + +/* [MS-XLS] 2.5.198.4 */ +var Cetab = { + 0x0000: 'BEEP', + 0x0001: 'OPEN', + 0x0002: 'OPEN.LINKS', + 0x0003: 'CLOSE.ALL', + 0x0004: 'SAVE', + 0x0005: 'SAVE.AS', + 0x0006: 'FILE.DELETE', + 0x0007: 'PAGE.SETUP', + 0x0008: 'PRINT', + 0x0009: 'PRINTER.SETUP', + 0x000A: 'QUIT', + 0x000B: 'NEW.WINDOW', + 0x000C: 'ARRANGE.ALL', + 0x000D: 'WINDOW.SIZE', + 0x000E: 'WINDOW.MOVE', + 0x000F: 'FULL', + 0x0010: 'CLOSE', + 0x0011: 'RUN', + 0x0016: 'SET.PRINT.AREA', + 0x0017: 'SET.PRINT.TITLES', + 0x0018: 'SET.PAGE.BREAK', + 0x0019: 'REMOVE.PAGE.BREAK', + 0x001A: 'FONT', + 0x001B: 'DISPLAY', + 0x001C: 'PROTECT.DOCUMENT', + 0x001D: 'PRECISION', + 0x001E: 'A1.R1C1', + 0x001F: 'CALCULATE.NOW', + 0x0020: 'CALCULATION', + 0x0022: 'DATA.FIND', + 0x0023: 'EXTRACT', + 0x0024: 'DATA.DELETE', + 0x0025: 'SET.DATABASE', + 0x0026: 'SET.CRITERIA', + 0x0027: 'SORT', + 0x0028: 'DATA.SERIES', + 0x0029: 'TABLE', + 0x002A: 'FORMAT.NUMBER', + 0x002B: 'ALIGNMENT', + 0x002C: 'STYLE', + 0x002D: 'BORDER', + 0x002E: 'CELL.PROTECTION', + 0x002F: 'COLUMN.WIDTH', + 0x0030: 'UNDO', + 0x0031: 'CUT', + 0x0032: 'COPY', + 0x0033: 'PASTE', + 0x0034: 'CLEAR', + 0x0035: 'PASTE.SPECIAL', + 0x0036: 'EDIT.DELETE', + 0x0037: 'INSERT', + 0x0038: 'FILL.RIGHT', + 0x0039: 'FILL.DOWN', + 0x003D: 'DEFINE.NAME', + 0x003E: 'CREATE.NAMES', + 0x003F: 'FORMULA.GOTO', + 0x0040: 'FORMULA.FIND', + 0x0041: 'SELECT.LAST.CELL', + 0x0042: 'SHOW.ACTIVE.CELL', + 0x0043: 'GALLERY.AREA', + 0x0044: 'GALLERY.BAR', + 0x0045: 'GALLERY.COLUMN', + 0x0046: 'GALLERY.LINE', + 0x0047: 'GALLERY.PIE', + 0x0048: 'GALLERY.SCATTER', + 0x0049: 'COMBINATION', + 0x004A: 'PREFERRED', + 0x004B: 'ADD.OVERLAY', + 0x004C: 'GRIDLINES', + 0x004D: 'SET.PREFERRED', + 0x004E: 'AXES', + 0x004F: 'LEGEND', + 0x0050: 'ATTACH.TEXT', + 0x0051: 'ADD.ARROW', + 0x0052: 'SELECT.CHART', + 0x0053: 'SELECT.PLOT.AREA', + 0x0054: 'PATTERNS', + 0x0055: 'MAIN.CHART', + 0x0056: 'OVERLAY', + 0x0057: 'SCALE', + 0x0058: 'FORMAT.LEGEND', + 0x0059: 'FORMAT.TEXT', + 0x005A: 'EDIT.REPEAT', + 0x005B: 'PARSE', + 0x005C: 'JUSTIFY', + 0x005D: 'HIDE', + 0x005E: 'UNHIDE', + 0x005F: 'WORKSPACE', + 0x0060: 'FORMULA', + 0x0061: 'FORMULA.FILL', + 0x0062: 'FORMULA.ARRAY', + 0x0063: 'DATA.FIND.NEXT', + 0x0064: 'DATA.FIND.PREV', + 0x0065: 'FORMULA.FIND.NEXT', + 0x0066: 'FORMULA.FIND.PREV', + 0x0067: 'ACTIVATE', + 0x0068: 'ACTIVATE.NEXT', + 0x0069: 'ACTIVATE.PREV', + 0x006A: 'UNLOCKED.NEXT', + 0x006B: 'UNLOCKED.PREV', + 0x006C: 'COPY.PICTURE', + 0x006D: 'SELECT', + 0x006E: 'DELETE.NAME', + 0x006F: 'DELETE.FORMAT', + 0x0070: 'VLINE', + 0x0071: 'HLINE', + 0x0072: 'VPAGE', + 0x0073: 'HPAGE', + 0x0074: 'VSCROLL', + 0x0075: 'HSCROLL', + 0x0076: 'ALERT', + 0x0077: 'NEW', + 0x0078: 'CANCEL.COPY', + 0x0079: 'SHOW.CLIPBOARD', + 0x007A: 'MESSAGE', + 0x007C: 'PASTE.LINK', + 0x007D: 'APP.ACTIVATE', + 0x007E: 'DELETE.ARROW', + 0x007F: 'ROW.HEIGHT', + 0x0080: 'FORMAT.MOVE', + 0x0081: 'FORMAT.SIZE', + 0x0082: 'FORMULA.REPLACE', + 0x0083: 'SEND.KEYS', + 0x0084: 'SELECT.SPECIAL', + 0x0085: 'APPLY.NAMES', + 0x0086: 'REPLACE.FONT', + 0x0087: 'FREEZE.PANES', + 0x0088: 'SHOW.INFO', + 0x0089: 'SPLIT', + 0x008A: 'ON.WINDOW', + 0x008B: 'ON.DATA', + 0x008C: 'DISABLE.INPUT', + 0x008E: 'OUTLINE', + 0x008F: 'LIST.NAMES', + 0x0090: 'FILE.CLOSE', + 0x0091: 'SAVE.WORKBOOK', + 0x0092: 'DATA.FORM', + 0x0093: 'COPY.CHART', + 0x0094: 'ON.TIME', + 0x0095: 'WAIT', + 0x0096: 'FORMAT.FONT', + 0x0097: 'FILL.UP', + 0x0098: 'FILL.LEFT', + 0x0099: 'DELETE.OVERLAY', + 0x009B: 'SHORT.MENUS', + 0x009F: 'SET.UPDATE.STATUS', + 0x00A1: 'COLOR.PALETTE', + 0x00A2: 'DELETE.STYLE', + 0x00A3: 'WINDOW.RESTORE', + 0x00A4: 'WINDOW.MAXIMIZE', + 0x00A6: 'CHANGE.LINK', + 0x00A7: 'CALCULATE.DOCUMENT', + 0x00A8: 'ON.KEY', + 0x00A9: 'APP.RESTORE', + 0x00AA: 'APP.MOVE', + 0x00AB: 'APP.SIZE', + 0x00AC: 'APP.MINIMIZE', + 0x00AD: 'APP.MAXIMIZE', + 0x00AE: 'BRING.TO.FRONT', + 0x00AF: 'SEND.TO.BACK', + 0x00B9: 'MAIN.CHART.TYPE', + 0x00BA: 'OVERLAY.CHART.TYPE', + 0x00BB: 'SELECT.END', + 0x00BC: 'OPEN.MAIL', + 0x00BD: 'SEND.MAIL', + 0x00BE: 'STANDARD.FONT', + 0x00BF: 'CONSOLIDATE', + 0x00C0: 'SORT.SPECIAL', + 0x00C1: 'GALLERY.3D.AREA', + 0x00C2: 'GALLERY.3D.COLUMN', + 0x00C3: 'GALLERY.3D.LINE', + 0x00C4: 'GALLERY.3D.PIE', + 0x00C5: 'VIEW.3D', + 0x00C6: 'GOAL.SEEK', + 0x00C7: 'WORKGROUP', + 0x00C8: 'FILL.GROUP', + 0x00C9: 'UPDATE.LINK', + 0x00CA: 'PROMOTE', + 0x00CB: 'DEMOTE', + 0x00CC: 'SHOW.DETAIL', + 0x00CE: 'UNGROUP', + 0x00CF: 'OBJECT.PROPERTIES', + 0x00D0: 'SAVE.NEW.OBJECT', + 0x00D1: 'SHARE', + 0x00D2: 'SHARE.NAME', + 0x00D3: 'DUPLICATE', + 0x00D4: 'APPLY.STYLE', + 0x00D5: 'ASSIGN.TO.OBJECT', + 0x00D6: 'OBJECT.PROTECTION', + 0x00D7: 'HIDE.OBJECT', + 0x00D8: 'SET.EXTRACT', + 0x00D9: 'CREATE.PUBLISHER', + 0x00DA: 'SUBSCRIBE.TO', + 0x00DB: 'ATTRIBUTES', + 0x00DC: 'SHOW.TOOLBAR', + 0x00DE: 'PRINT.PREVIEW', + 0x00DF: 'EDIT.COLOR', + 0x00E0: 'SHOW.LEVELS', + 0x00E1: 'FORMAT.MAIN', + 0x00E2: 'FORMAT.OVERLAY', + 0x00E3: 'ON.RECALC', + 0x00E4: 'EDIT.SERIES', + 0x00E5: 'DEFINE.STYLE', + 0x00F0: 'LINE.PRINT', + 0x00F3: 'ENTER.DATA', + 0x00F9: 'GALLERY.RADAR', + 0x00FA: 'MERGE.STYLES', + 0x00FB: 'EDITION.OPTIONS', + 0x00FC: 'PASTE.PICTURE', + 0x00FD: 'PASTE.PICTURE.LINK', + 0x00FE: 'SPELLING', + 0x0100: 'ZOOM', + 0x0103: 'INSERT.OBJECT', + 0x0104: 'WINDOW.MINIMIZE', + 0x0109: 'SOUND.NOTE', + 0x010A: 'SOUND.PLAY', + 0x010B: 'FORMAT.SHAPE', + 0x010C: 'EXTEND.POLYGON', + 0x010D: 'FORMAT.AUTO', + 0x0110: 'GALLERY.3D.BAR', + 0x0111: 'GALLERY.3D.SURFACE', + 0x0112: 'FILL.AUTO', + 0x0114: 'CUSTOMIZE.TOOLBAR', + 0x0115: 'ADD.TOOL', + 0x0116: 'EDIT.OBJECT', + 0x0117: 'ON.DOUBLECLICK', + 0x0118: 'ON.ENTRY', + 0x0119: 'WORKBOOK.ADD', + 0x011A: 'WORKBOOK.MOVE', + 0x011B: 'WORKBOOK.COPY', + 0x011C: 'WORKBOOK.OPTIONS', + 0x011D: 'SAVE.WORKSPACE', + 0x0120: 'CHART.WIZARD', + 0x0121: 'DELETE.TOOL', + 0x0122: 'MOVE.TOOL', + 0x0123: 'WORKBOOK.SELECT', + 0x0124: 'WORKBOOK.ACTIVATE', + 0x0125: 'ASSIGN.TO.TOOL', + 0x0127: 'COPY.TOOL', + 0x0128: 'RESET.TOOL', + 0x0129: 'CONSTRAIN.NUMERIC', + 0x012A: 'PASTE.TOOL', + 0x012E: 'WORKBOOK.NEW', + 0x0131: 'SCENARIO.CELLS', + 0x0132: 'SCENARIO.DELETE', + 0x0133: 'SCENARIO.ADD', + 0x0134: 'SCENARIO.EDIT', + 0x0135: 'SCENARIO.SHOW', + 0x0136: 'SCENARIO.SHOW.NEXT', + 0x0137: 'SCENARIO.SUMMARY', + 0x0138: 'PIVOT.TABLE.WIZARD', + 0x0139: 'PIVOT.FIELD.PROPERTIES', + 0x013A: 'PIVOT.FIELD', + 0x013B: 'PIVOT.ITEM', + 0x013C: 'PIVOT.ADD.FIELDS', + 0x013E: 'OPTIONS.CALCULATION', + 0x013F: 'OPTIONS.EDIT', + 0x0140: 'OPTIONS.VIEW', + 0x0141: 'ADDIN.MANAGER', + 0x0142: 'MENU.EDITOR', + 0x0143: 'ATTACH.TOOLBARS', + 0x0144: 'VBAActivate', + 0x0145: 'OPTIONS.CHART', + 0x0148: 'VBA.INSERT.FILE', + 0x014A: 'VBA.PROCEDURE.DEFINITION', + 0x0150: 'ROUTING.SLIP', + 0x0152: 'ROUTE.DOCUMENT', + 0x0153: 'MAIL.LOGON', + 0x0156: 'INSERT.PICTURE', + 0x0157: 'EDIT.TOOL', + 0x0158: 'GALLERY.DOUGHNUT', + 0x015E: 'CHART.TREND', + 0x0160: 'PIVOT.ITEM.PROPERTIES', + 0x0162: 'WORKBOOK.INSERT', + 0x0163: 'OPTIONS.TRANSITION', + 0x0164: 'OPTIONS.GENERAL', + 0x0172: 'FILTER.ADVANCED', + 0x0175: 'MAIL.ADD.MAILER', + 0x0176: 'MAIL.DELETE.MAILER', + 0x0177: 'MAIL.REPLY', + 0x0178: 'MAIL.REPLY.ALL', + 0x0179: 'MAIL.FORWARD', + 0x017A: 'MAIL.NEXT.LETTER', + 0x017B: 'DATA.LABEL', + 0x017C: 'INSERT.TITLE', + 0x017D: 'FONT.PROPERTIES', + 0x017E: 'MACRO.OPTIONS', + 0x017F: 'WORKBOOK.HIDE', + 0x0180: 'WORKBOOK.UNHIDE', + 0x0181: 'WORKBOOK.DELETE', + 0x0182: 'WORKBOOK.NAME', + 0x0184: 'GALLERY.CUSTOM', + 0x0186: 'ADD.CHART.AUTOFORMAT', + 0x0187: 'DELETE.CHART.AUTOFORMAT', + 0x0188: 'CHART.ADD.DATA', + 0x0189: 'AUTO.OUTLINE', + 0x018A: 'TAB.ORDER', + 0x018B: 'SHOW.DIALOG', + 0x018C: 'SELECT.ALL', + 0x018D: 'UNGROUP.SHEETS', + 0x018E: 'SUBTOTAL.CREATE', + 0x018F: 'SUBTOTAL.REMOVE', + 0x0190: 'RENAME.OBJECT', + 0x019C: 'WORKBOOK.SCROLL', + 0x019D: 'WORKBOOK.NEXT', + 0x019E: 'WORKBOOK.PREV', + 0x019F: 'WORKBOOK.TAB.SPLIT', + 0x01A0: 'FULL.SCREEN', + 0x01A1: 'WORKBOOK.PROTECT', + 0x01A4: 'SCROLLBAR.PROPERTIES', + 0x01A5: 'PIVOT.SHOW.PAGES', + 0x01A6: 'TEXT.TO.COLUMNS', + 0x01A7: 'FORMAT.CHARTTYPE', + 0x01A8: 'LINK.FORMAT', + 0x01A9: 'TRACER.DISPLAY', + 0x01AE: 'TRACER.NAVIGATE', + 0x01AF: 'TRACER.CLEAR', + 0x01B0: 'TRACER.ERROR', + 0x01B1: 'PIVOT.FIELD.GROUP', + 0x01B2: 'PIVOT.FIELD.UNGROUP', + 0x01B3: 'CHECKBOX.PROPERTIES', + 0x01B4: 'LABEL.PROPERTIES', + 0x01B5: 'LISTBOX.PROPERTIES', + 0x01B6: 'EDITBOX.PROPERTIES', + 0x01B7: 'PIVOT.REFRESH', + 0x01B8: 'LINK.COMBO', + 0x01B9: 'OPEN.TEXT', + 0x01BA: 'HIDE.DIALOG', + 0x01BB: 'SET.DIALOG.FOCUS', + 0x01BC: 'ENABLE.OBJECT', + 0x01BD: 'PUSHBUTTON.PROPERTIES', + 0x01BE: 'SET.DIALOG.DEFAULT', + 0x01BF: 'FILTER', + 0x01C0: 'FILTER.SHOW.ALL', + 0x01C1: 'CLEAR.OUTLINE', + 0x01C2: 'FUNCTION.WIZARD', + 0x01C3: 'ADD.LIST.ITEM', + 0x01C4: 'SET.LIST.ITEM', + 0x01C5: 'REMOVE.LIST.ITEM', + 0x01C6: 'SELECT.LIST.ITEM', + 0x01C7: 'SET.CONTROL.VALUE', + 0x01C8: 'SAVE.COPY.AS', + 0x01CA: 'OPTIONS.LISTS.ADD', + 0x01CB: 'OPTIONS.LISTS.DELETE', + 0x01CC: 'SERIES.AXES', + 0x01CD: 'SERIES.X', + 0x01CE: 'SERIES.Y', + 0x01CF: 'ERRORBAR.X', + 0x01D0: 'ERRORBAR.Y', + 0x01D1: 'FORMAT.CHART', + 0x01D2: 'SERIES.ORDER', + 0x01D3: 'MAIL.LOGOFF', + 0x01D4: 'CLEAR.ROUTING.SLIP', + 0x01D5: 'APP.ACTIVATE.MICROSOFT', + 0x01D6: 'MAIL.EDIT.MAILER', + 0x01D7: 'ON.SHEET', + 0x01D8: 'STANDARD.WIDTH', + 0x01D9: 'SCENARIO.MERGE', + 0x01DA: 'SUMMARY.INFO', + 0x01DB: 'FIND.FILE', + 0x01DC: 'ACTIVE.CELL.FONT', + 0x01DD: 'ENABLE.TIPWIZARD', + 0x01DE: 'VBA.MAKE.ADDIN', + 0x01E0: 'INSERTDATATABLE', + 0x01E1: 'WORKGROUP.OPTIONS', + 0x01E2: 'MAIL.SEND.MAILER', + 0x01E5: 'AUTOCORRECT', + 0x01E9: 'POST.DOCUMENT', + 0x01EB: 'PICKLIST', + 0x01ED: 'VIEW.SHOW', + 0x01EE: 'VIEW.DEFINE', + 0x01EF: 'VIEW.DELETE', + 0x01FD: 'SHEET.BACKGROUND', + 0x01FE: 'INSERT.MAP.OBJECT', + 0x01FF: 'OPTIONS.MENONO', + 0x0205: 'MSOCHECKS', + 0x0206: 'NORMAL', + 0x0207: 'LAYOUT', + 0x0208: 'RM.PRINT.AREA', + 0x0209: 'CLEAR.PRINT.AREA', + 0x020A: 'ADD.PRINT.AREA', + 0x020B: 'MOVE.BRK', + 0x0221: 'HIDECURR.NOTE', + 0x0222: 'HIDEALL.NOTES', + 0x0223: 'DELETE.NOTE', + 0x0224: 'TRAVERSE.NOTES', + 0x0225: 'ACTIVATE.NOTES', + 0x026C: 'PROTECT.REVISIONS', + 0x026D: 'UNPROTECT.REVISIONS', + 0x0287: 'OPTIONS.ME', + 0x028D: 'WEB.PUBLISH', + 0x029B: 'NEWWEBQUERY', + 0x02A1: 'PIVOT.TABLE.CHART', + 0x02F1: 'OPTIONS.SAVE', + 0x02F3: 'OPTIONS.SPELL', + 0x0328: 'HIDEALL.INKANNOTS' +}; + +/* [MS-XLS] 2.5.198.17 */ +var Ftab = { + 0x0000: 'COUNT', + 0x0001: 'IF', + 0x0002: 'ISNA', + 0x0003: 'ISERROR', + 0x0004: 'SUM', + 0x0005: 'AVERAGE', + 0x0006: 'MIN', + 0x0007: 'MAX', + 0x0008: 'ROW', + 0x0009: 'COLUMN', + 0x000A: 'NA', + 0x000B: 'NPV', + 0x000C: 'STDEV', + 0x000D: 'DOLLAR', + 0x000E: 'FIXED', + 0x000F: 'SIN', + 0x0010: 'COS', + 0x0011: 'TAN', + 0x0012: 'ATAN', + 0x0013: 'PI', + 0x0014: 'SQRT', + 0x0015: 'EXP', + 0x0016: 'LN', + 0x0017: 'LOG10', + 0x0018: 'ABS', + 0x0019: 'INT', + 0x001A: 'SIGN', + 0x001B: 'ROUND', + 0x001C: 'LOOKUP', + 0x001D: 'INDEX', + 0x001E: 'REPT', + 0x001F: 'MID', + 0x0020: 'LEN', + 0x0021: 'VALUE', + 0x0022: 'TRUE', + 0x0023: 'FALSE', + 0x0024: 'AND', + 0x0025: 'OR', + 0x0026: 'NOT', + 0x0027: 'MOD', + 0x0028: 'DCOUNT', + 0x0029: 'DSUM', + 0x002A: 'DAVERAGE', + 0x002B: 'DMIN', + 0x002C: 'DMAX', + 0x002D: 'DSTDEV', + 0x002E: 'VAR', + 0x002F: 'DVAR', + 0x0030: 'TEXT', + 0x0031: 'LINEST', + 0x0032: 'TREND', + 0x0033: 'LOGEST', + 0x0034: 'GROWTH', + 0x0035: 'GOTO', + 0x0036: 'HALT', + 0x0037: 'RETURN', + 0x0038: 'PV', + 0x0039: 'FV', + 0x003A: 'NPER', + 0x003B: 'PMT', + 0x003C: 'RATE', + 0x003D: 'MIRR', + 0x003E: 'IRR', + 0x003F: 'RAND', + 0x0040: 'MATCH', + 0x0041: 'DATE', + 0x0042: 'TIME', + 0x0043: 'DAY', + 0x0044: 'MONTH', + 0x0045: 'YEAR', + 0x0046: 'WEEKDAY', + 0x0047: 'HOUR', + 0x0048: 'MINUTE', + 0x0049: 'SECOND', + 0x004A: 'NOW', + 0x004B: 'AREAS', + 0x004C: 'ROWS', + 0x004D: 'COLUMNS', + 0x004E: 'OFFSET', + 0x004F: 'ABSREF', + 0x0050: 'RELREF', + 0x0051: 'ARGUMENT', + 0x0052: 'SEARCH', + 0x0053: 'TRANSPOSE', + 0x0054: 'ERROR', + 0x0055: 'STEP', + 0x0056: 'TYPE', + 0x0057: 'ECHO', + 0x0058: 'SET.NAME', + 0x0059: 'CALLER', + 0x005A: 'DEREF', + 0x005B: 'WINDOWS', + 0x005C: 'SERIES', + 0x005D: 'DOCUMENTS', + 0x005E: 'ACTIVE.CELL', + 0x005F: 'SELECTION', + 0x0060: 'RESULT', + 0x0061: 'ATAN2', + 0x0062: 'ASIN', + 0x0063: 'ACOS', + 0x0064: 'CHOOSE', + 0x0065: 'HLOOKUP', + 0x0066: 'VLOOKUP', + 0x0067: 'LINKS', + 0x0068: 'INPUT', + 0x0069: 'ISREF', + 0x006A: 'GET.FORMULA', + 0x006B: 'GET.NAME', + 0x006C: 'SET.VALUE', + 0x006D: 'LOG', + 0x006E: 'EXEC', + 0x006F: 'CHAR', + 0x0070: 'LOWER', + 0x0071: 'UPPER', + 0x0072: 'PROPER', + 0x0073: 'LEFT', + 0x0074: 'RIGHT', + 0x0075: 'EXACT', + 0x0076: 'TRIM', + 0x0077: 'REPLACE', + 0x0078: 'SUBSTITUTE', + 0x0079: 'CODE', + 0x007A: 'NAMES', + 0x007B: 'DIRECTORY', + 0x007C: 'FIND', + 0x007D: 'CELL', + 0x007E: 'ISERR', + 0x007F: 'ISTEXT', + 0x0080: 'ISNUMBER', + 0x0081: 'ISBLANK', + 0x0082: 'T', + 0x0083: 'N', + 0x0084: 'FOPEN', + 0x0085: 'FCLOSE', + 0x0086: 'FSIZE', + 0x0087: 'FREADLN', + 0x0088: 'FREAD', + 0x0089: 'FWRITELN', + 0x008A: 'FWRITE', + 0x008B: 'FPOS', + 0x008C: 'DATEVALUE', + 0x008D: 'TIMEVALUE', + 0x008E: 'SLN', + 0x008F: 'SYD', + 0x0090: 'DDB', + 0x0091: 'GET.DEF', + 0x0092: 'REFTEXT', + 0x0093: 'TEXTREF', + 0x0094: 'INDIRECT', + 0x0095: 'REGISTER', + 0x0096: 'CALL', + 0x0097: 'ADD.BAR', + 0x0098: 'ADD.MENU', + 0x0099: 'ADD.COMMAND', + 0x009A: 'ENABLE.COMMAND', + 0x009B: 'CHECK.COMMAND', + 0x009C: 'RENAME.COMMAND', + 0x009D: 'SHOW.BAR', + 0x009E: 'DELETE.MENU', + 0x009F: 'DELETE.COMMAND', + 0x00A0: 'GET.CHART.ITEM', + 0x00A1: 'DIALOG.BOX', + 0x00A2: 'CLEAN', + 0x00A3: 'MDETERM', + 0x00A4: 'MINVERSE', + 0x00A5: 'MMULT', + 0x00A6: 'FILES', + 0x00A7: 'IPMT', + 0x00A8: 'PPMT', + 0x00A9: 'COUNTA', + 0x00AA: 'CANCEL.KEY', + 0x00AB: 'FOR', + 0x00AC: 'WHILE', + 0x00AD: 'BREAK', + 0x00AE: 'NEXT', + 0x00AF: 'INITIATE', + 0x00B0: 'REQUEST', + 0x00B1: 'POKE', + 0x00B2: 'EXECUTE', + 0x00B3: 'TERMINATE', + 0x00B4: 'RESTART', + 0x00B5: 'HELP', + 0x00B6: 'GET.BAR', + 0x00B7: 'PRODUCT', + 0x00B8: 'FACT', + 0x00B9: 'GET.CELL', + 0x00BA: 'GET.WORKSPACE', + 0x00BB: 'GET.WINDOW', + 0x00BC: 'GET.DOCUMENT', + 0x00BD: 'DPRODUCT', + 0x00BE: 'ISNONTEXT', + 0x00BF: 'GET.NOTE', + 0x00C0: 'NOTE', + 0x00C1: 'STDEVP', + 0x00C2: 'VARP', + 0x00C3: 'DSTDEVP', + 0x00C4: 'DVARP', + 0x00C5: 'TRUNC', + 0x00C6: 'ISLOGICAL', + 0x00C7: 'DCOUNTA', + 0x00C8: 'DELETE.BAR', + 0x00C9: 'UNREGISTER', + 0x00CC: 'USDOLLAR', + 0x00CD: 'FINDB', + 0x00CE: 'SEARCHB', + 0x00CF: 'REPLACEB', + 0x00D0: 'LEFTB', + 0x00D1: 'RIGHTB', + 0x00D2: 'MIDB', + 0x00D3: 'LENB', + 0x00D4: 'ROUNDUP', + 0x00D5: 'ROUNDDOWN', + 0x00D6: 'ASC', + 0x00D7: 'DBCS', + 0x00D8: 'RANK', + 0x00DB: 'ADDRESS', + 0x00DC: 'DAYS360', + 0x00DD: 'TODAY', + 0x00DE: 'VDB', + 0x00DF: 'ELSE', + 0x00E0: 'ELSE.IF', + 0x00E1: 'END.IF', + 0x00E2: 'FOR.CELL', + 0x00E3: 'MEDIAN', + 0x00E4: 'SUMPRODUCT', + 0x00E5: 'SINH', + 0x00E6: 'COSH', + 0x00E7: 'TANH', + 0x00E8: 'ASINH', + 0x00E9: 'ACOSH', + 0x00EA: 'ATANH', + 0x00EB: 'DGET', + 0x00EC: 'CREATE.OBJECT', + 0x00ED: 'VOLATILE', + 0x00EE: 'LAST.ERROR', + 0x00EF: 'CUSTOM.UNDO', + 0x00F0: 'CUSTOM.REPEAT', + 0x00F1: 'FORMULA.CONVERT', + 0x00F2: 'GET.LINK.INFO', + 0x00F3: 'TEXT.BOX', + 0x00F4: 'INFO', + 0x00F5: 'GROUP', + 0x00F6: 'GET.OBJECT', + 0x00F7: 'DB', + 0x00F8: 'PAUSE', + 0x00FB: 'RESUME', + 0x00FC: 'FREQUENCY', + 0x00FD: 'ADD.TOOLBAR', + 0x00FE: 'DELETE.TOOLBAR', + 0x00FF: 'User', + 0x0100: 'RESET.TOOLBAR', + 0x0101: 'EVALUATE', + 0x0102: 'GET.TOOLBAR', + 0x0103: 'GET.TOOL', + 0x0104: 'SPELLING.CHECK', + 0x0105: 'ERROR.TYPE', + 0x0106: 'APP.TITLE', + 0x0107: 'WINDOW.TITLE', + 0x0108: 'SAVE.TOOLBAR', + 0x0109: 'ENABLE.TOOL', + 0x010A: 'PRESS.TOOL', + 0x010B: 'REGISTER.ID', + 0x010C: 'GET.WORKBOOK', + 0x010D: 'AVEDEV', + 0x010E: 'BETADIST', + 0x010F: 'GAMMALN', + 0x0110: 'BETAINV', + 0x0111: 'BINOMDIST', + 0x0112: 'CHIDIST', + 0x0113: 'CHIINV', + 0x0114: 'COMBIN', + 0x0115: 'CONFIDENCE', + 0x0116: 'CRITBINOM', + 0x0117: 'EVEN', + 0x0118: 'EXPONDIST', + 0x0119: 'FDIST', + 0x011A: 'FINV', + 0x011B: 'FISHER', + 0x011C: 'FISHERINV', + 0x011D: 'FLOOR', + 0x011E: 'GAMMADIST', + 0x011F: 'GAMMAINV', + 0x0120: 'CEILING', + 0x0121: 'HYPGEOMDIST', + 0x0122: 'LOGNORMDIST', + 0x0123: 'LOGINV', + 0x0124: 'NEGBINOMDIST', + 0x0125: 'NORMDIST', + 0x0126: 'NORMSDIST', + 0x0127: 'NORMINV', + 0x0128: 'NORMSINV', + 0x0129: 'STANDARDIZE', + 0x012A: 'ODD', + 0x012B: 'PERMUT', + 0x012C: 'POISSON', + 0x012D: 'TDIST', + 0x012E: 'WEIBULL', + 0x012F: 'SUMXMY2', + 0x0130: 'SUMX2MY2', + 0x0131: 'SUMX2PY2', + 0x0132: 'CHITEST', + 0x0133: 'CORREL', + 0x0134: 'COVAR', + 0x0135: 'FORECAST', + 0x0136: 'FTEST', + 0x0137: 'INTERCEPT', + 0x0138: 'PEARSON', + 0x0139: 'RSQ', + 0x013A: 'STEYX', + 0x013B: 'SLOPE', + 0x013C: 'TTEST', + 0x013D: 'PROB', + 0x013E: 'DEVSQ', + 0x013F: 'GEOMEAN', + 0x0140: 'HARMEAN', + 0x0141: 'SUMSQ', + 0x0142: 'KURT', + 0x0143: 'SKEW', + 0x0144: 'ZTEST', + 0x0145: 'LARGE', + 0x0146: 'SMALL', + 0x0147: 'QUARTILE', + 0x0148: 'PERCENTILE', + 0x0149: 'PERCENTRANK', + 0x014A: 'MODE', + 0x014B: 'TRIMMEAN', + 0x014C: 'TINV', + 0x014E: 'MOVIE.COMMAND', + 0x014F: 'GET.MOVIE', + 0x0150: 'CONCATENATE', + 0x0151: 'POWER', + 0x0152: 'PIVOT.ADD.DATA', + 0x0153: 'GET.PIVOT.TABLE', + 0x0154: 'GET.PIVOT.FIELD', + 0x0155: 'GET.PIVOT.ITEM', + 0x0156: 'RADIANS', + 0x0157: 'DEGREES', + 0x0158: 'SUBTOTAL', + 0x0159: 'SUMIF', + 0x015A: 'COUNTIF', + 0x015B: 'COUNTBLANK', + 0x015C: 'SCENARIO.GET', + 0x015D: 'OPTIONS.LISTS.GET', + 0x015E: 'ISPMT', + 0x015F: 'DATEDIF', + 0x0160: 'DATESTRING', + 0x0161: 'NUMBERSTRING', + 0x0162: 'ROMAN', + 0x0163: 'OPEN.DIALOG', + 0x0164: 'SAVE.DIALOG', + 0x0165: 'VIEW.GET', + 0x0166: 'GETPIVOTDATA', + 0x0167: 'HYPERLINK', + 0x0168: 'PHONETIC', + 0x0169: 'AVERAGEA', + 0x016A: 'MAXA', + 0x016B: 'MINA', + 0x016C: 'STDEVPA', + 0x016D: 'VARPA', + 0x016E: 'STDEVA', + 0x016F: 'VARA', + 0x0170: 'BAHTTEXT', + 0x0171: 'THAIDAYOFWEEK', + 0x0172: 'THAIDIGIT', + 0x0173: 'THAIMONTHOFYEAR', + 0x0174: 'THAINUMSOUND', + 0x0175: 'THAINUMSTRING', + 0x0176: 'THAISTRINGLENGTH', + 0x0177: 'ISTHAIDIGIT', + 0x0178: 'ROUNDBAHTDOWN', + 0x0179: 'ROUNDBAHTUP', + 0x017A: 'THAIYEAR', + 0x017B: 'RTD' +}; +var FtabArgc = { + 0x0002: 1, /* ISNA */ + 0x0003: 1, /* ISERROR */ + 0x000F: 1, /* SIN */ + 0x0010: 1, /* COS */ + 0x0011: 1, /* TAN */ + 0x0012: 1, /* ATAN */ + 0x0014: 1, /* SQRT */ + 0x0015: 1, /* EXP */ + 0x0016: 1, /* LN */ + 0x0017: 1, /* LOG10 */ + 0x0018: 1, /* ABS */ + 0x0019: 1, /* INT */ + 0x001A: 1, /* SIGN */ + 0x001B: 2, /* ROUND */ + 0x001E: 2, /* REPT */ + 0x001F: 3, /* MID */ + 0x0020: 1, /* LEN */ + 0x0021: 1, /* VALUE */ + 0x0026: 1, /* NOT */ + 0x0027: 2, /* MOD */ + 0x0028: 3, /* DCOUNT */ + 0x0029: 3, /* DSUM */ + 0x002A: 3, /* DAVERAGE */ + 0x002B: 3, /* DMIN */ + 0x002C: 3, /* DMAX */ + 0x002D: 3, /* DSTDEV */ + 0x002F: 3, /* DVAR */ + 0x0030: 2, /* TEXT */ + 0x0035: 1, /* GOTO */ + 0x003D: 3, /* MIRR */ + 0x0041: 3, /* DATE */ + 0x0042: 3, /* TIME */ + 0x0043: 1, /* DAY */ + 0x0044: 1, /* MONTH */ + 0x0045: 1, /* YEAR */ + 0x0047: 1, /* HOUR */ + 0x0048: 1, /* MINUTE */ + 0x0049: 1, /* SECOND */ + 0x004B: 1, /* AREAS */ + 0x004C: 1, /* ROWS */ + 0x004D: 1, /* COLUMNS */ + 0x004F: 2, /* ABSREF */ + 0x0050: 2, /* RELREF */ + 0x0053: 1, /* TRANSPOSE */ + 0x0056: 1, /* TYPE */ + 0x005A: 1, /* DEREF */ + 0x0061: 2, /* ATAN2 */ + 0x0062: 1, /* ASIN */ + 0x0063: 1, /* ACOS */ + 0x0069: 1, /* ISREF */ + 0x006F: 1, /* CHAR */ + 0x0070: 1, /* LOWER */ + 0x0071: 1, /* UPPER */ + 0x0072: 1, /* PROPER */ + 0x0075: 2, /* EXACT */ + 0x0076: 1, /* TRIM */ + 0x0077: 4, /* REPLACE */ + 0x0079: 1, /* CODE */ + 0x007E: 1, /* ISERR */ + 0x007F: 1, /* ISTEXT */ + 0x0080: 1, /* ISNUMBER */ + 0x0081: 1, /* ISBLANK */ + 0x0082: 1, /* T */ + 0x0083: 1, /* N */ + 0x0085: 1, /* FCLOSE */ + 0x0086: 1, /* FSIZE */ + 0x0087: 1, /* FREADLN */ + 0x0088: 2, /* FREAD */ + 0x0089: 2, /* FWRITELN */ + 0x008A: 2, /* FWRITE */ + 0x008C: 1, /* DATEVALUE */ + 0x008D: 1, /* TIMEVALUE */ + 0x008E: 3, /* SLN */ + 0x008F: 4, /* SYD */ + 0x00A2: 1, /* CLEAN */ + 0x00A3: 1, /* MDETERM */ + 0x00A4: 1, /* MINVERSE */ + 0x00A5: 2, /* MMULT */ + 0x00AC: 1, /* WHILE */ + 0x00AF: 2, /* INITIATE */ + 0x00B0: 2, /* REQUEST */ + 0x00B1: 3, /* POKE */ + 0x00B2: 2, /* EXECUTE */ + 0x00B3: 1, /* TERMINATE */ + 0x00B8: 1, /* FACT */ + 0x00BD: 3, /* DPRODUCT */ + 0x00BE: 1, /* ISNONTEXT */ + 0x00C3: 3, /* DSTDEVP */ + 0x00C4: 3, /* DVARP */ + 0x00C6: 1, /* ISLOGICAL */ + 0x00C7: 3, /* DCOUNTA */ + 0x00C9: 1, /* UNREGISTER */ + 0x00CF: 4, /* REPLACEB */ + 0x00D2: 3, /* MIDB */ + 0x00D3: 1, /* LENB */ + 0x00D4: 2, /* ROUNDUP */ + 0x00D5: 2, /* ROUNDDOWN */ + 0x00D6: 1, /* ASC */ + 0x00D7: 1, /* DBCS */ + 0x00E5: 1, /* SINH */ + 0x00E6: 1, /* COSH */ + 0x00E7: 1, /* TANH */ + 0x00E8: 1, /* ASINH */ + 0x00E9: 1, /* ACOSH */ + 0x00EA: 1, /* ATANH */ + 0x00EB: 3, /* DGET */ + 0x00F4: 1, /* INFO */ + 0x00FC: 2, /* FREQUENCY */ + 0x0101: 1, /* EVALUATE */ + 0x0105: 1, /* ERROR.TYPE */ + 0x010F: 1, /* GAMMALN */ + 0x0111: 4, /* BINOMDIST */ + 0x0112: 2, /* CHIDIST */ + 0x0113: 2, /* CHIINV */ + 0x0114: 2, /* COMBIN */ + 0x0115: 3, /* CONFIDENCE */ + 0x0116: 3, /* CRITBINOM */ + 0x0117: 1, /* EVEN */ + 0x0118: 3, /* EXPONDIST */ + 0x0119: 3, /* FDIST */ + 0x011A: 3, /* FINV */ + 0x011B: 1, /* FISHER */ + 0x011C: 1, /* FISHERINV */ + 0x011D: 2, /* FLOOR */ + 0x011E: 4, /* GAMMADIST */ + 0x011F: 3, /* GAMMAINV */ + 0x0120: 2, /* CEILING */ + 0x0121: 4, /* HYPGEOMDIST */ + 0x0122: 3, /* LOGNORMDIST */ + 0x0123: 3, /* LOGINV */ + 0x0124: 3, /* NEGBINOMDIST */ + 0x0125: 4, /* NORMDIST */ + 0x0126: 1, /* NORMSDIST */ + 0x0127: 3, /* NORMINV */ + 0x0128: 1, /* NORMSINV */ + 0x0129: 3, /* STANDARDIZE */ + 0x012A: 1, /* ODD */ + 0x012B: 2, /* PERMUT */ + 0x012C: 3, /* POISSON */ + 0x012D: 3, /* TDIST */ + 0x012E: 4, /* WEIBULL */ + 0x012F: 2, /* SUMXMY2 */ + 0x0130: 2, /* SUMX2MY2 */ + 0x0131: 2, /* SUMX2PY2 */ + 0x0132: 2, /* CHITEST */ + 0x0133: 2, /* CORREL */ + 0x0134: 2, /* COVAR */ + 0x0135: 3, /* FORECAST */ + 0x0136: 2, /* FTEST */ + 0x0137: 2, /* INTERCEPT */ + 0x0138: 2, /* PEARSON */ + 0x0139: 2, /* RSQ */ + 0x013A: 2, /* STEYX */ + 0x013B: 2, /* SLOPE */ + 0x013C: 4, /* TTEST */ + 0x0145: 2, /* LARGE */ + 0x0146: 2, /* SMALL */ + 0x0147: 2, /* QUARTILE */ + 0x0148: 2, /* PERCENTILE */ + 0x014B: 2, /* TRIMMEAN */ + 0x014C: 2, /* TINV */ + 0x0151: 2, /* POWER */ + 0x0156: 1, /* RADIANS */ + 0x0157: 1, /* DEGREES */ + 0x015A: 2, /* COUNTIF */ + 0x015B: 1, /* COUNTBLANK */ + 0x015E: 4, /* ISPMT */ + 0x015F: 3, /* DATEDIF */ + 0x0160: 1, /* DATESTRING */ + 0x0161: 2, /* NUMBERSTRING */ + 0x0168: 1, /* PHONETIC */ + 0x0170: 1, /* BAHTTEXT */ + 0x0171: 1, /* THAIDAYOFWEEK */ + 0x0172: 1, /* THAIDIGIT */ + 0x0173: 1, /* THAIMONTHOFYEAR */ + 0x0174: 1, /* THAINUMSOUND */ + 0x0175: 1, /* THAINUMSTRING */ + 0x0176: 1, /* THAISTRINGLENGTH */ + 0x0177: 1, /* ISTHAIDIGIT */ + 0x0178: 1, /* ROUNDBAHTDOWN */ + 0x0179: 1, /* ROUNDBAHTUP */ + 0x017A: 1, /* THAIYEAR */ + 0xFFFF: 0 +}; +/* [MS-XLSX] 2.2.3 Functions */ +var XLSXFutureFunctions = { + "_xlfn.ACOT": "ACOT", + "_xlfn.ACOTH": "ACOTH", + "_xlfn.AGGREGATE": "AGGREGATE", + "_xlfn.ARABIC": "ARABIC", + "_xlfn.AVERAGEIF": "AVERAGEIF", + "_xlfn.AVERAGEIFS": "AVERAGEIFS", + "_xlfn.BASE": "BASE", + "_xlfn.BETA.DIST": "BETA.DIST", + "_xlfn.BETA.INV": "BETA.INV", + "_xlfn.BINOM.DIST": "BINOM.DIST", + "_xlfn.BINOM.DIST.RANGE": "BINOM.DIST.RANGE", + "_xlfn.BINOM.INV": "BINOM.INV", + "_xlfn.BITAND": "BITAND", + "_xlfn.BITLSHIFT": "BITLSHIFT", + "_xlfn.BITOR": "BITOR", + "_xlfn.BITRSHIFT": "BITRSHIFT", + "_xlfn.BITXOR": "BITXOR", + "_xlfn.CEILING.MATH": "CEILING.MATH", + "_xlfn.CEILING.PRECISE": "CEILING.PRECISE", + "_xlfn.CHISQ.DIST": "CHISQ.DIST", + "_xlfn.CHISQ.DIST.RT": "CHISQ.DIST.RT", + "_xlfn.CHISQ.INV": "CHISQ.INV", + "_xlfn.CHISQ.INV.RT": "CHISQ.INV.RT", + "_xlfn.CHISQ.TEST": "CHISQ.TEST", + "_xlfn.COMBINA": "COMBINA", + "_xlfn.CONFIDENCE.NORM": "CONFIDENCE.NORM", + "_xlfn.CONFIDENCE.T": "CONFIDENCE.T", + "_xlfn.COT": "COT", + "_xlfn.COTH": "COTH", + "_xlfn.COUNTIFS": "COUNTIFS", + "_xlfn.COVARIANCE.P": "COVARIANCE.P", + "_xlfn.COVARIANCE.S": "COVARIANCE.S", + "_xlfn.CSC": "CSC", + "_xlfn.CSCH": "CSCH", + "_xlfn.DAYS": "DAYS", + "_xlfn.DECIMAL": "DECIMAL", + "_xlfn.ECMA.CEILING": "ECMA.CEILING", + "_xlfn.ERF.PRECISE": "ERF.PRECISE", + "_xlfn.ERFC.PRECISE": "ERFC.PRECISE", + "_xlfn.EXPON.DIST": "EXPON.DIST", + "_xlfn.F.DIST": "F.DIST", + "_xlfn.F.DIST.RT": "F.DIST.RT", + "_xlfn.F.INV": "F.INV", + "_xlfn.F.INV.RT": "F.INV.RT", + "_xlfn.F.TEST": "F.TEST", + "_xlfn.FILTERXML": "FILTERXML", + "_xlfn.FLOOR.MATH": "FLOOR.MATH", + "_xlfn.FLOOR.PRECISE": "FLOOR.PRECISE", + "_xlfn.FORMULATEXT": "FORMULATEXT", + "_xlfn.GAMMA": "GAMMA", + "_xlfn.GAMMA.DIST": "GAMMA.DIST", + "_xlfn.GAMMA.INV": "GAMMA.INV", + "_xlfn.GAMMALN.PRECISE": "GAMMALN.PRECISE", + "_xlfn.GAUSS": "GAUSS", + "_xlfn.HYPGEOM.DIST": "HYPGEOM.DIST", + "_xlfn.IFNA": "IFNA", + "_xlfn.IFERROR": "IFERROR", + "_xlfn.IMCOSH": "IMCOSH", + "_xlfn.IMCOT": "IMCOT", + "_xlfn.IMCSC": "IMCSC", + "_xlfn.IMCSCH": "IMCSCH", + "_xlfn.IMSEC": "IMSEC", + "_xlfn.IMSECH": "IMSECH", + "_xlfn.IMSINH": "IMSINH", + "_xlfn.IMTAN": "IMTAN", + "_xlfn.ISFORMULA": "ISFORMULA", + "_xlfn.ISO.CEILING": "ISO.CEILING", + "_xlfn.ISOWEEKNUM": "ISOWEEKNUM", + "_xlfn.LOGNORM.DIST": "LOGNORM.DIST", + "_xlfn.LOGNORM.INV": "LOGNORM.INV", + "_xlfn.MODE.MULT": "MODE.MULT", + "_xlfn.MODE.SNGL": "MODE.SNGL", + "_xlfn.MUNIT": "MUNIT", + "_xlfn.NEGBINOM.DIST": "NEGBINOM.DIST", + "_xlfn.NETWORKDAYS.INTL": "NETWORKDAYS.INTL", + "_xlfn.NIGBINOM": "NIGBINOM", + "_xlfn.NORM.DIST": "NORM.DIST", + "_xlfn.NORM.INV": "NORM.INV", + "_xlfn.NORM.S.DIST": "NORM.S.DIST", + "_xlfn.NORM.S.INV": "NORM.S.INV", + "_xlfn.NUMBERVALUE": "NUMBERVALUE", + "_xlfn.PDURATION": "PDURATION", + "_xlfn.PERCENTILE.EXC": "PERCENTILE.EXC", + "_xlfn.PERCENTILE.INC": "PERCENTILE.INC", + "_xlfn.PERCENTRANK.EXC": "PERCENTRANK.EXC", + "_xlfn.PERCENTRANK.INC": "PERCENTRANK.INC", + "_xlfn.PERMUTATIONA": "PERMUTATIONA", + "_xlfn.PHI": "PHI", + "_xlfn.POISSON.DIST": "POISSON.DIST", + "_xlfn.QUARTILE.EXC": "QUARTILE.EXC", + "_xlfn.QUARTILE.INC": "QUARTILE.INC", + "_xlfn.QUERYSTRING": "QUERYSTRING", + "_xlfn.RANK.AVG": "RANK.AVG", + "_xlfn.RANK.EQ": "RANK.EQ", + "_xlfn.RRI": "RRI", + "_xlfn.SEC": "SEC", + "_xlfn.SECH": "SECH", + "_xlfn.SHEET": "SHEET", + "_xlfn.SHEETS": "SHEETS", + "_xlfn.SKEW.P": "SKEW.P", + "_xlfn.STDEV.P": "STDEV.P", + "_xlfn.STDEV.S": "STDEV.S", + "_xlfn.SUMIFS": "SUMIFS", + "_xlfn.T.DIST": "T.DIST", + "_xlfn.T.DIST.2T": "T.DIST.2T", + "_xlfn.T.DIST.RT": "T.DIST.RT", + "_xlfn.T.INV": "T.INV", + "_xlfn.T.INV.2T": "T.INV.2T", + "_xlfn.T.TEST": "T.TEST", + "_xlfn.UNICHAR": "UNICHAR", + "_xlfn.UNICODE": "UNICODE", + "_xlfn.VAR.P": "VAR.P", + "_xlfn.VAR.S": "VAR.S", + "_xlfn.WEBSERVICE": "WEBSERVICE", + "_xlfn.WEIBULL.DIST": "WEIBULL.DIST", + "_xlfn.WORKDAY.INTL": "WORKDAY.INTL", + "_xlfn.XOR": "XOR", + "_xlfn.Z.TEST": "Z.TEST" +}; + +var strs = {}; // shared strings +var _ssfopts = {}; // spreadsheet formatting options + +RELS.WS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"; + +function get_sst_id(sst, str) { + for(var i = 0, len = sst.length; i < len; ++i) if(sst[i].t === str) { sst.Count ++; return i; } + sst[len] = {t:str}; sst.Count ++; sst.Unique ++; return len; +} + +function get_cell_style(styles, cell, opts) { + var z = opts.revssf[cell.z != null ? cell.z : "General"]; + for(var i = 0, len = styles.length; i != len; ++i) if(styles[i].numFmtId === z) return i; + styles[len] = { + numFmtId:z, + fontId:0, + fillId:0, + borderId:0, + xfId:0, + applyNumberFormat:1 + }; + return len; +} + +function safe_format(p, fmtid, fillid, opts) { + try { + if(p.t === 'e') p.w = p.w || BErr[p.v]; + else if(fmtid === 0) { + if(p.t === 'n') { + if((p.v|0) === p.v) p.w = SSF._general_int(p.v,_ssfopts); + else p.w = SSF._general_num(p.v,_ssfopts); + } + else if(p.t === 'd') { + var dd = datenum(p.v); + if((dd|0) === dd) p.w = SSF._general_int(dd,_ssfopts); + else p.w = SSF._general_num(dd,_ssfopts); + } + else if(p.v === undefined) return ""; + else p.w = SSF._general(p.v,_ssfopts); + } + else if(p.t === 'd') p.w = SSF.format(fmtid,datenum(p.v),_ssfopts); + else p.w = SSF.format(fmtid,p.v,_ssfopts); + if(opts.cellNF) p.z = SSF._table[fmtid]; + } catch(e) { if(opts.WTF) throw e; } + if(fillid) try { + p.s = styles.Fills[fillid]; + if (p.s.fgColor && p.s.fgColor.theme) { + p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0); + if(opts.WTF) p.s.fgColor.raw_rgb = themes.themeElements.clrScheme[p.s.fgColor.theme].rgb; + } + if (p.s.bgColor && p.s.bgColor.theme) { + p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0); + if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb; + } + } catch(e) { if(opts.WTF) throw e; } +} +function parse_ws_xml_dim(ws, s) { + var d = safe_decode_range(s); + if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d); +} +var mergecregex = //g; +var sheetdataregex = /<(?:\w+:)?sheetData>([^\u2603]*)<\/(?:\w+:)?sheetData>/; +var hlinkregex = /]*\/>/g; +var dimregex = /"(\w*:\w*)"/; +var colregex = /]*\/>/g; +/* 18.3 Worksheets */ +function parse_ws_xml(data, opts, rels) { + if(!data) return data; + /* 18.3.1.99 worksheet CT_Worksheet */ + var s = {}; + + /* 18.3.1.35 dimension CT_SheetDimension ? */ + var ridx = data.indexOf(" 0) { + var ref = data.substr(ridx,50).match(dimregex); + if(ref != null) parse_ws_xml_dim(s, ref[1]); + } + + /* 18.3.1.55 mergeCells CT_MergeCells */ + var mergecells = []; + if(data.indexOf("")!==-1) { + var merges = data.match(mergecregex); + for(ridx = 0; ridx != merges.length; ++ridx) + mergecells[ridx] = safe_decode_range(merges[ridx].substr(merges[ridx].indexOf("\"")+1)); + } + + /* 18.3.1.17 cols CT_Cols */ + var columns = []; + if(opts.cellStyles && data.indexOf("")!==-1) { + /* 18.3.1.13 col CT_Col */ + var cols = data.match(colregex); + parse_ws_xml_cols(columns, cols); + } + + var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} }; + + /* 18.3.1.80 sheetData CT_SheetData ? */ + var mtch=data.match(sheetdataregex); + if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess); + + /* 18.3.1.48 hyperlinks CT_Hyperlinks */ + if(data.indexOf("")!==-1) parse_ws_xml_hlinks(s, data.match(hlinkregex), rels); + + if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess); + if(opts.sheetRows > 0 && s["!ref"]) { + var tmpref = safe_decode_range(s["!ref"]); + if(opts.sheetRows < +tmpref.e.r) { + tmpref.e.r = opts.sheetRows - 1; + if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r; + if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r; + if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c; + if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c; + s["!fullref"] = s["!ref"]; + s["!ref"] = encode_range(tmpref); + } + } + if(mergecells.length > 0) s["!merges"] = mergecells; + if(columns.length > 0) s["!cols"] = columns; + return s; +} + +function write_ws_xml_merges(merges) { + if(merges.length == 0) return ""; + var o = ''; + for(var i = 0; i != merges.length; ++i) o += ''; + return o + ''; +} + +function parse_ws_xml_hlinks(s, data, rels) { + for(var i = 0; i != data.length; ++i) { + var val = parsexmltag(data[i], true); + if(!val.ref) return; + var rel = rels ? rels['!id'][val.id] : null; + if(rel) { + val.Target = rel.Target; + if(val.location) val.Target += "#"+val.location; + val.Rel = rel; + } else { + val.Target = val.location; + rel = {Target: val.location, TargetMode: 'Internal'}; + val.Rel = rel; + } + var rng = safe_decode_range(val.ref); + for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) { + var addr = encode_cell({c:C,r:R}); + if(!s[addr]) s[addr] = {t:"stub",v:undefined}; + s[addr].l = val; + } + } +} + +function parse_ws_xml_cols(columns, cols) { + var seencol = false; + for(var coli = 0; coli != cols.length; ++coli) { + var coll = parsexmltag(cols[coli], true); + var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1; + delete coll.min; delete coll.max; + if(!seencol && coll.width) { seencol = true; find_mdw(+coll.width, coll); } + if(coll.width) { + coll.wpx = width2px(+coll.width); + coll.wch = px2char(coll.wpx); + coll.MDW = MDW; + } + while(colm <= colM) columns[colm++] = coll; + } +} + +function write_ws_xml_cols(ws, cols) { + var o = [""], col, width; + for(var i = 0; i != cols.length; ++i) { + if(!(col = cols[i])) continue; + var p = {min:i+1,max:i+1}; + /* wch (chars), wpx (pixels) */ + width = -1; + if(col.wpx) width = px2char(col.wpx); + else if(col.wch) width = col.wch; + if(width > -1) { p.width = char2width(width); p.customWidth= 1; } + o[o.length] = (writextag('col', null, p)); + } + o[o.length] = ""; + return o.join(""); +} + +function write_ws_xml_cell(cell, ref, ws, opts, idx, wb) { + if(cell.v === undefined) return ""; + var vv = ""; + var oldt = cell.t, oldv = cell.v; + switch(cell.t) { + case 'b': vv = cell.v ? "1" : "0"; break; + case 'n': vv = ''+cell.v; break; + case 'e': vv = BErr[cell.v]; break; + case 'd': + if(opts.cellDates) vv = new Date(cell.v).toISOString(); + else { + cell.t = 'n'; + vv = ''+(cell.v = datenum(cell.v)); + if(typeof cell.z === 'undefined') cell.z = SSF._table[14]; + } + break; + default: vv = cell.v; break; + } + var v = writetag('v', escapexml(vv)), o = {r:ref}; + /* TODO: cell style */ + var os = get_cell_style(opts.cellXfs, cell, opts); + if(os !== 0) o.s = os; + switch(cell.t) { + case 'n': break; + case 'd': o.t = "d"; break; + case 'b': o.t = "b"; break; + case 'e': o.t = "e"; break; + default: + if(opts.bookSST) { + v = writetag('v', ''+get_sst_id(opts.Strings, cell.v)); + o.t = "s"; break; + } + o.t = "str"; break; + } + if(cell.t != oldt) { cell.t = oldt; cell.v = oldv; } + return writextag('c', v, o); +} + +var parse_ws_xml_data = (function parse_ws_xml_data_factory() { + var cellregex = /<(?:\w+:)?c[ >]/, rowregex = /<\/(?:\w+:)?row>/; + var rregex = /r=["']([^"']*)["']/, isregex = /([\S\s]*?)<\/is>/; + var match_v = matchtag("v"), match_f = matchtag("f"); + +return function parse_ws_xml_data(sdata, s, opts, guess) { + var ri = 0, x = "", cells = [], cref = [], idx = 0, i=0, cc=0, d="", p; + var tag, tagr = 0, tagc = 0; + var sstr; + var fmtid = 0, fillid = 0, do_format = Array.isArray(styles.CellXf), cf; + for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) { + x = marr[mt].trim(); + var xlen = x.length; + if(xlen === 0) continue; + + /* 18.3.1.73 row CT_Row */ + for(ri = 0; ri < xlen; ++ri) if(x.charCodeAt(ri) === 62) break; ++ri; + tag = parsexmltag(x.substr(0,ri), true); + /* SpreadSheetGear uses implicit r/c */ + tagr = typeof tag.r !== 'undefined' ? parseInt(tag.r, 10) : tagr+1; tagc = -1; + if(opts.sheetRows && opts.sheetRows < tagr) continue; + if(guess.s.r > tagr - 1) guess.s.r = tagr - 1; + if(guess.e.r < tagr - 1) guess.e.r = tagr - 1; + + /* 18.3.1.4 c CT_Cell */ + cells = x.substr(ri).split(cellregex); + for(ri = typeof tag.r === 'undefined' ? 0 : 1; ri != cells.length; ++ri) { + x = cells[ri].trim(); + if(x.length === 0) continue; + cref = x.match(rregex); idx = ri; i=0; cc=0; + x = "":"") + x; + if(cref !== null && cref.length === 2) { + idx = 0; d=cref[1]; + for(i=0; i != d.length; ++i) { + if((cc=d.charCodeAt(i)-64) < 1 || cc > 26) break; + idx = 26*idx + cc; + } + --idx; + tagc = idx; + } else ++tagc; + for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i; + tag = parsexmltag(x.substr(0,i), true); + if(!tag.r) tag.r = utils.encode_cell({r:tagr-1, c:tagc}); + d = x.substr(i); + p = {t:""}; + + if((cref=d.match(match_v))!== null && cref[1] !== '') p.v=unescapexml(cref[1]); + if(opts.cellFormula && (cref=d.match(match_f))!== null) p.f=unescapexml(cref[1]); + + /* SCHEMA IS ACTUALLY INCORRECT HERE. IF A CELL HAS NO T, EMIT "" */ + if(tag.t === undefined && p.v === undefined) { + if(!opts.sheetStubs) continue; + p.t = "stub"; + } + else p.t = tag.t || "n"; + if(guess.s.c > idx) guess.s.c = idx; + if(guess.e.c < idx) guess.e.c = idx; + /* 18.18.11 t ST_CellType */ + switch(p.t) { + case 'n': p.v = parseFloat(p.v); break; + case 's': + sstr = strs[parseInt(p.v, 10)]; + p.v = sstr.t; + p.r = sstr.r; + sstr = unescapexml(sstr) + if(opts.cellHTML) p.h = sstr.h; + break; + case 'str': + p.t = "s"; + p.v = (p.v!=null) ? utf8read(p.v) : ''; + if(opts.cellHTML) p.h = p.v; + break; + case 'inlineStr': + cref = d.match(isregex); + p.t = 's'; + if(cref !== null) { sstr = parse_si(cref[1]); p.v = sstr.t; } else p.v = ""; + break; // inline string + case 'b': p.v = parsexmlbool(p.v); break; + case 'd': + if(!opts.cellDates) { p.v = datenum(p.v); p.t = 'n'; } + break; + /* error string in .v, number in .v */ + case 'e': p.w = p.v; p.v = RBErr[p.v]; break; + } + /* formatting */ + fmtid = fillid = 0; + if(do_format && tag.s !== undefined) { + cf = styles.CellXf[tag.s]; + if(cf != null) { + if(cf.numFmtId != null) fmtid = cf.numFmtId; + if(opts.cellStyles && cf.fillId != null) fillid = cf.fillId; + } + } + safe_format(p, fmtid, fillid, opts); + s[tag.r] = p; + } + } +}; })(); + +function write_ws_xml_data(ws, opts, idx, wb) { + var o = [], r = [], range = safe_decode_range(ws['!ref']), cell, ref, rr = "", cols = [], R, C; + for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C); + for(R = range.s.r; R <= range.e.r; ++R) { + r = []; + rr = encode_row(R); + for(C = range.s.c; C <= range.e.c; ++C) { + ref = cols[C] + rr; + if(ws[ref] === undefined) continue; + if((cell = write_ws_xml_cell(ws[ref], ref, ws, opts, idx, wb)) != null) r.push(cell); + } + if(r.length > 0) o[o.length] = (writextag('row', r.join(""), {r:rr})); + } + return o.join(""); +} + +var WS_XML_ROOT = writextag('worksheet', null, { + 'xmlns': XMLNS.main[0], + 'xmlns:r': XMLNS.r +}); + +function write_ws_xml(idx, opts, wb) { + var o = [XML_HEADER, WS_XML_ROOT]; + var s = wb.SheetNames[idx], sidx = 0, rdata = ""; + var ws = wb.Sheets[s]; + if(ws === undefined) ws = {}; + var ref = ws['!ref']; if(ref === undefined) ref = 'A1'; + o[o.length] = (writextag('dimension', null, {'ref': ref})); + + if(ws['!cols'] !== undefined && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols'])); + o[sidx = o.length] = ''; + if(ws['!ref'] !== undefined) { + rdata = write_ws_xml_data(ws, opts, idx, wb); + if(rdata.length > 0) o[o.length] = (rdata); + } + if(o.length>sidx+1) { o[o.length] = (''); o[sidx]=o[sidx].replace("/>",">"); } + + if(ws['!merges'] !== undefined && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges'])); + + if(o.length>2) { o[o.length] = (''); o[1]=o[1].replace("/>",">"); } + return o.join(""); +} + +/* [MS-XLSB] 2.4.718 BrtRowHdr */ +function parse_BrtRowHdr(data, length) { + var z = []; + z.r = data.read_shift(4); + data.l += length-4; + return z; +} + +/* [MS-XLSB] 2.4.812 BrtWsDim */ +var parse_BrtWsDim = parse_UncheckedRfX; +var write_BrtWsDim = write_UncheckedRfX; + +/* [MS-XLSB] 2.4.815 BrtWsProp */ +function parse_BrtWsProp(data, length) { + var z = {}; + /* TODO: pull flags */ + data.l += 19; + z.name = parse_XLSBCodeName(data, length - 19); + return z; +} + +/* [MS-XLSB] 2.4.303 BrtCellBlank */ +function parse_BrtCellBlank(data, length) { + var cell = parse_XLSBCell(data); + return [cell]; +} +function write_BrtCellBlank(cell, val, o) { + if(o == null) o = new_buf(8); + return write_XLSBCell(val, o); +} + + +/* [MS-XLSB] 2.4.304 BrtCellBool */ +function parse_BrtCellBool(data, length) { + var cell = parse_XLSBCell(data); + var fBool = data.read_shift(1); + return [cell, fBool, 'b']; +} + +/* [MS-XLSB] 2.4.305 BrtCellError */ +function parse_BrtCellError(data, length) { + var cell = parse_XLSBCell(data); + var fBool = data.read_shift(1); + return [cell, fBool, 'e']; +} + +/* [MS-XLSB] 2.4.308 BrtCellIsst */ +function parse_BrtCellIsst(data, length) { + var cell = parse_XLSBCell(data); + var isst = data.read_shift(4); + return [cell, isst, 's']; +} + +/* [MS-XLSB] 2.4.310 BrtCellReal */ +function parse_BrtCellReal(data, length) { + var cell = parse_XLSBCell(data); + var value = parse_Xnum(data); + return [cell, value, 'n']; +} + +/* [MS-XLSB] 2.4.311 BrtCellRk */ +function parse_BrtCellRk(data, length) { + var cell = parse_XLSBCell(data); + var value = parse_RkNumber(data); + return [cell, value, 'n']; +} + +/* [MS-XLSB] 2.4.314 BrtCellSt */ +function parse_BrtCellSt(data, length) { + var cell = parse_XLSBCell(data); + var value = parse_XLWideString(data); + return [cell, value, 'str']; +} + +/* [MS-XLSB] 2.4.647 BrtFmlaBool */ +function parse_BrtFmlaBool(data, length, opts) { + var cell = parse_XLSBCell(data); + var value = data.read_shift(1); + var o = [cell, value, 'b']; + if(opts.cellFormula) { + var formula = parse_XLSBCellParsedFormula(data, length-9); + o[3] = ""; /* TODO */ + } + else data.l += length-9; + return o; +} + +/* [MS-XLSB] 2.4.648 BrtFmlaError */ +function parse_BrtFmlaError(data, length, opts) { + var cell = parse_XLSBCell(data); + var value = data.read_shift(1); + var o = [cell, value, 'e']; + if(opts.cellFormula) { + var formula = parse_XLSBCellParsedFormula(data, length-9); + o[3] = ""; /* TODO */ + } + else data.l += length-9; + return o; +} + +/* [MS-XLSB] 2.4.649 BrtFmlaNum */ +function parse_BrtFmlaNum(data, length, opts) { + var cell = parse_XLSBCell(data); + var value = parse_Xnum(data); + var o = [cell, value, 'n']; + if(opts.cellFormula) { + var formula = parse_XLSBCellParsedFormula(data, length - 16); + o[3] = ""; /* TODO */ + } + else data.l += length-16; + return o; +} + +/* [MS-XLSB] 2.4.650 BrtFmlaString */ +function parse_BrtFmlaString(data, length, opts) { + var start = data.l; + var cell = parse_XLSBCell(data); + var value = parse_XLWideString(data); + var o = [cell, value, 'str']; + if(opts.cellFormula) { + var formula = parse_XLSBCellParsedFormula(data, start + length - data.l); + } + else data.l = start + length; + return o; +} + +/* [MS-XLSB] 2.4.676 BrtMergeCell */ +var parse_BrtMergeCell = parse_UncheckedRfX; + +/* [MS-XLSB] 2.4.656 BrtHLink */ +function parse_BrtHLink(data, length, opts) { + var end = data.l + length; + var rfx = parse_UncheckedRfX(data, 16); + var relId = parse_XLNullableWideString(data); + var loc = parse_XLWideString(data); + var tooltip = parse_XLWideString(data); + var display = parse_XLWideString(data); + data.l = end; + return {rfx:rfx, relId:relId, loc:loc, tooltip:tooltip, display:display}; +} + +/* [MS-XLSB] 2.1.7.61 Worksheet */ +function parse_ws_bin(data, opts, rels) { + if(!data) return data; + if(!rels) rels = {'!id':{}}; + var s = {}; + + var ref; + var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} }; + + var pass = false, end = false; + var row, p, cf, R, C, addr, sstr, rr; + var mergecells = []; + recordhopper(data, function ws_parse(val, R) { + if(end) return; + switch(R.n) { + case 'BrtWsDim': ref = val; break; + case 'BrtRowHdr': + row = val; + if(opts.sheetRows && opts.sheetRows <= row.r) end=true; + rr = encode_row(row.r); + break; + + case 'BrtFmlaBool': + case 'BrtFmlaError': + case 'BrtFmlaNum': + case 'BrtFmlaString': + case 'BrtCellBool': + case 'BrtCellError': + case 'BrtCellIsst': + case 'BrtCellReal': + case 'BrtCellRk': + case 'BrtCellSt': + p = {t:val[2]}; + switch(val[2]) { + case 'n': p.v = val[1]; break; + case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break; + case 'b': p.v = val[1] ? true : false; break; + case 'e': p.v = val[1]; p.w = BErr[p.v]; break; + case 'str': p.t = 's'; p.v = utf8read(val[1]); break; + } + if(opts.cellFormula && val.length > 3) p.f = val[3]; + if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.ifmt,null,opts); + s[encode_col(C=val[0].c) + rr] = p; + if(refguess.s.r > row.r) refguess.s.r = row.r; + if(refguess.s.c > C) refguess.s.c = C; + if(refguess.e.r < row.r) refguess.e.r = row.r; + if(refguess.e.c < C) refguess.e.c = C; + break; + + case 'BrtCellBlank': if(!opts.sheetStubs) break; + p = {t:'s',v:undefined}; + s[encode_col(C=val[0].c) + rr] = p; + if(refguess.s.r > row.r) refguess.s.r = row.r; + if(refguess.s.c > C) refguess.s.c = C; + if(refguess.e.r < row.r) refguess.e.r = row.r; + if(refguess.e.c < C) refguess.e.c = C; + break; + + /* Merge Cells */ + case 'BrtBeginMergeCells': break; + case 'BrtEndMergeCells': break; + case 'BrtMergeCell': mergecells.push(val); break; + + case 'BrtHLink': + var rel = rels['!id'][val.relId]; + if(rel) { + val.Target = rel.Target; + if(val.loc) val.Target += "#"+val.loc; + val.Rel = rel; + } + for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) { + addr = encode_cell({c:C,r:R}); + if(!s[addr]) s[addr] = {t:'s',v:undefined}; + s[addr].l = val; + } + break; + + case 'BrtArrFmla': break; // TODO + case 'BrtShrFmla': break; // TODO + case 'BrtBeginSheet': break; + case 'BrtWsProp': break; // TODO + case 'BrtSheetCalcProp': break; // TODO + case 'BrtBeginWsViews': break; // TODO + case 'BrtBeginWsView': break; // TODO + case 'BrtPane': break; // TODO + case 'BrtSel': break; // TODO + case 'BrtEndWsView': break; // TODO + case 'BrtEndWsViews': break; // TODO + case 'BrtACBegin': break; // TODO + case 'BrtRwDescent': break; // TODO + case 'BrtACEnd': break; // TODO + case 'BrtWsFmtInfoEx14': break; // TODO + case 'BrtWsFmtInfo': break; // TODO + case 'BrtBeginColInfos': break; // TODO + case 'BrtColInfo': break; // TODO + case 'BrtEndColInfos': break; // TODO + case 'BrtBeginSheetData': break; // TODO + case 'BrtEndSheetData': break; // TODO + case 'BrtSheetProtection': break; // TODO + case 'BrtPrintOptions': break; // TODO + case 'BrtMargins': break; // TODO + case 'BrtPageSetup': break; // TODO + case 'BrtFRTBegin': pass = true; break; + case 'BrtFRTEnd': pass = false; break; + case 'BrtEndSheet': break; // TODO + case 'BrtDrawing': break; // TODO + case 'BrtLegacyDrawing': break; // TODO + case 'BrtLegacyDrawingHF': break; // TODO + case 'BrtPhoneticInfo': break; // TODO + case 'BrtBeginHeaderFooter': break; // TODO + case 'BrtEndHeaderFooter': break; // TODO + case 'BrtBrk': break; // TODO + case 'BrtBeginRwBrk': break; // TODO + case 'BrtEndRwBrk': break; // TODO + case 'BrtBeginColBrk': break; // TODO + case 'BrtEndColBrk': break; // TODO + case 'BrtBeginUserShViews': break; // TODO + case 'BrtBeginUserShView': break; // TODO + case 'BrtEndUserShView': break; // TODO + case 'BrtEndUserShViews': break; // TODO + case 'BrtBkHim': break; // TODO + case 'BrtBeginOleObjects': break; // TODO + case 'BrtOleObject': break; // TODO + case 'BrtEndOleObjects': break; // TODO + case 'BrtBeginListParts': break; // TODO + case 'BrtListPart': break; // TODO + case 'BrtEndListParts': break; // TODO + case 'BrtBeginSortState': break; // TODO + case 'BrtBeginSortCond': break; // TODO + case 'BrtEndSortCond': break; // TODO + case 'BrtEndSortState': break; // TODO + case 'BrtBeginConditionalFormatting': break; // TODO + case 'BrtEndConditionalFormatting': break; // TODO + case 'BrtBeginCFRule': break; // TODO + case 'BrtEndCFRule': break; // TODO + case 'BrtBeginDVals': break; // TODO + case 'BrtDVal': break; // TODO + case 'BrtEndDVals': break; // TODO + case 'BrtRangeProtection': break; // TODO + case 'BrtBeginDCon': break; // TODO + case 'BrtEndDCon': break; // TODO + case 'BrtBeginDRefs': break; + case 'BrtDRef': break; + case 'BrtEndDRefs': break; + + /* ActiveX */ + case 'BrtBeginActiveXControls': break; + case 'BrtActiveX': break; + case 'BrtEndActiveXControls': break; + + /* AutoFilter */ + case 'BrtBeginAFilter': break; + case 'BrtEndAFilter': break; + case 'BrtBeginFilterColumn': break; + case 'BrtBeginFilters': break; + case 'BrtFilter': break; + case 'BrtEndFilters': break; + case 'BrtEndFilterColumn': break; + case 'BrtDynamicFilter': break; + case 'BrtTop10Filter': break; + case 'BrtBeginCustomFilters': break; + case 'BrtCustomFilter': break; + case 'BrtEndCustomFilters': break; + + /* Smart Tags */ + case 'BrtBeginSmartTags': break; + case 'BrtBeginCellSmartTags': break; + case 'BrtBeginCellSmartTag': break; + case 'BrtCellSmartTagProperty': break; + case 'BrtEndCellSmartTag': break; + case 'BrtEndCellSmartTags': break; + case 'BrtEndSmartTags': break; + + /* Cell Watch */ + case 'BrtBeginCellWatches': break; + case 'BrtCellWatch': break; + case 'BrtEndCellWatches': break; + + /* Table */ + case 'BrtTable': break; + + /* Ignore Cell Errors */ + case 'BrtBeginCellIgnoreECs': break; + case 'BrtCellIgnoreEC': break; + case 'BrtEndCellIgnoreECs': break; + + default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n); + } + }, opts); + if(!s["!ref"] && (refguess.s.r < 1000000 || ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0)) s["!ref"] = encode_range(ref); + if(opts.sheetRows && s["!ref"]) { + var tmpref = safe_decode_range(s["!ref"]); + if(opts.sheetRows < +tmpref.e.r) { + tmpref.e.r = opts.sheetRows - 1; + if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r; + if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r; + if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c; + if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c; + s["!fullref"] = s["!ref"]; + s["!ref"] = encode_range(tmpref); + } + } + if(mergecells.length > 0) s["!merges"] = mergecells; + return s; +} + +/* TODO: something useful -- this is a stub */ +function write_ws_bin_cell(ba, cell, R, C, opts) { + if(cell.v === undefined) return ""; + var vv = ""; + switch(cell.t) { + case 'b': vv = cell.v ? "1" : "0"; break; + case 'n': case 'e': vv = ''+cell.v; break; + default: vv = cell.v; break; + } + var o = {r:R, c:C}; + /* TODO: cell style */ + o.s = get_cell_style(opts.cellXfs, cell, opts); + switch(cell.t) { + case 's': case 'str': + if(opts.bookSST) { + vv = get_sst_id(opts.Strings, cell.v); + o.t = "s"; break; + } + o.t = "str"; break; + case 'n': break; + case 'b': o.t = "b"; break; + case 'e': o.t = "e"; break; + } + write_record(ba, "BrtCellBlank", write_BrtCellBlank(cell, o)); +} + +function write_CELLTABLE(ba, ws, idx, opts, wb) { + var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols = []; + write_record(ba, 'BrtBeginSheetData'); + for(var R = range.s.r; R <= range.e.r; ++R) { + rr = encode_row(R); + /* [ACCELLTABLE] */ + /* BrtRowHdr */ + for(var C = range.s.c; C <= range.e.c; ++C) { + /* *16384CELL */ + if(R === range.s.r) cols[C] = encode_col(C); + ref = cols[C] + rr; + if(!ws[ref]) continue; + /* write cell */ + write_ws_bin_cell(ba, ws[ref], R, C, opts); + } + } + write_record(ba, 'BrtEndSheetData'); +} + +function write_ws_bin(idx, opts, wb) { + var ba = buf_array(); + var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {}; + var r = safe_decode_range(ws['!ref'] || "A1"); + write_record(ba, "BrtBeginSheet"); + /* [BrtWsProp] */ + write_record(ba, "BrtWsDim", write_BrtWsDim(r)); + /* [WSVIEWS2] */ + /* [WSFMTINFO] */ + /* *COLINFOS */ + write_CELLTABLE(ba, ws, idx, opts, wb); + /* [BrtSheetCalcProp] */ + /* [[BrtSheetProtectionIso] BrtSheetProtection] */ + /* *([BrtRangeProtectionIso] BrtRangeProtection) */ + /* [SCENMAN] */ + /* [AUTOFILTER] */ + /* [SORTSTATE] */ + /* [DCON] */ + /* [USERSHVIEWS] */ + /* [MERGECELLS] */ + /* [BrtPhoneticInfo] */ + /* *CONDITIONALFORMATTING */ + /* [DVALS] */ + /* *BrtHLink */ + /* [BrtPrintOptions] */ + /* [BrtMargins] */ + /* [BrtPageSetup] */ + /* [HEADERFOOTER] */ + /* [RWBRK] */ + /* [COLBRK] */ + /* *BrtBigName */ + /* [CELLWATCHES] */ + /* [IGNOREECS] */ + /* [SMARTTAGS] */ + /* [BrtDrawing] */ + /* [BrtLegacyDrawing] */ + /* [BrtLegacyDrawingHF] */ + /* [BrtBkHim] */ + /* [OLEOBJECTS] */ + /* [ACTIVEXCONTROLS] */ + /* [WEBPUBITEMS] */ + /* [LISTPARTS] */ + /* FRTWORKSHEET */ + write_record(ba, "BrtEndSheet"); + return ba.end(); +} +/* 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'] +]; + +function push_defaults_array(target, defaults) { + for(var j = 0; j != target.length; ++j) { var w = target[j]; + for(var i=0; i != defaults.length; ++i) { var z = defaults[i]; + if(w[z[0]] == null) w[z[0]] = z[1]; + } + } +} +function push_defaults(target, defaults) { + for(var i = 0; i != defaults.length; ++i) { var z = defaults[i]; + if(target[z[0]] == null) target[z[0]] = z[1]; + } +} + +function parse_wb_defaults(wb) { + push_defaults(wb.WBProps, WBPropsDef); + push_defaults(wb.CalcPr, CalcPrDef); + + push_defaults_array(wb.WBView, WBViewDef); + push_defaults_array(wb.Sheets, SheetDef); + + _ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904, 'date1904'); +} +/* 18.2 Workbook */ +var wbnsregex = /<\w+:workbook/; +function parse_wb_xml(data, opts) { + var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; + var pass = false, xmlns = "xmlns"; + data.match(tagregex).forEach(function xml_wb(x) { + var y = parsexmltag(x); + switch(strip_ns(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 '': case '': break; + /* 18.2.8 externalReference CT_ExternalReference + */ + case '': break; + case '': 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; + + default: if(!pass && opts.WTF) throw 'unrecognized ' + y[0] + ' in workbook'; + } + }); + if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns); + + parse_wb_defaults(wb); + + return wb; +} + +var WB_XML_ROOT = writextag('workbook', null, { + 'xmlns': XMLNS.main[0], + //'xmlns:mx': XMLNS.mx, + //'xmlns:s': XMLNS.main[0], + 'xmlns:r': XMLNS.r +}); + +function safe1904(wb) { + /* TODO: store date1904 somewhere else */ + try { return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false"; } catch(e) { return "false"; } +} + +function write_wb_xml(wb, opts) { + var o = [XML_HEADER]; + o[o.length] = WB_XML_ROOT; + o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb)})); + o[o.length] = ""; + for(var i = 0; i != wb.SheetNames.length; ++i) + o[o.length] = (writextag('sheet',null,{name:wb.SheetNames[i].substr(0,31), sheetId:""+(i+1), "r:id":"rId"+(i+1)})); + o[o.length] = ""; + if(o.length>2){ o[o.length] = ''; o[1]=o[1].replace("/>",">"); } + return o.join(""); +} +/* [MS-XLSB] 2.4.301 BrtBundleSh */ +function parse_BrtBundleSh(data, length) { + var z = {}; + z.hsState = data.read_shift(4); //ST_SheetState + z.iTabID = data.read_shift(4); + z.strRelID = parse_RelID(data,length-8); + z.name = parse_XLWideString(data); + return z; +} +function write_BrtBundleSh(data, o) { + if(!o) o = new_buf(127); + o.write_shift(4, data.hsState); + o.write_shift(4, data.iTabID); + write_RelID(data.strRelID, o); + write_XLWideString(data.name.substr(0,31), o); + return o; +} + +/* [MS-XLSB] 2.4.807 BrtWbProp */ +function parse_BrtWbProp(data, length) { + data.read_shift(4); + var dwThemeVersion = data.read_shift(4); + var strName = (length > 8) ? parse_XLWideString(data) : ""; + return [dwThemeVersion, strName]; +} +function write_BrtWbProp(data, o) { + if(!o) o = new_buf(8); + o.write_shift(4, 0); + o.write_shift(4, 0); + return o; +} + +function parse_BrtFRTArchID$(data, length) { + var o = {}; + data.read_shift(4); + o.ArchID = data.read_shift(4); + data.l += length - 8; + return o; +} + +/* [MS-XLSB] 2.1.7.60 Workbook */ +function parse_wb_bin(data, opts) { + var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" }; + var pass = false, z; + + recordhopper(data, function hopper_wb(val, R) { + switch(R.n) { + case 'BrtBundleSh': wb.Sheets.push(val); break; + + case 'BrtBeginBook': break; + case 'BrtFileVersion': break; + case 'BrtWbProp': break; + case 'BrtACBegin': break; + case 'BrtAbsPath15': break; + case 'BrtACEnd': break; + case 'BrtWbFactoid': break; + /*case 'BrtBookProtectionIso': break;*/ + case 'BrtBookProtection': break; + case 'BrtBeginBookViews': break; + case 'BrtBookView': break; + case 'BrtEndBookViews': break; + case 'BrtBeginBundleShs': break; + case 'BrtEndBundleShs': break; + case 'BrtBeginFnGroup': break; + case 'BrtEndFnGroup': break; + case 'BrtBeginExternals': break; + case 'BrtSupSelf': break; + case 'BrtSupBookSrc': break; + case 'BrtExternSheet': break; + case 'BrtEndExternals': break; + case 'BrtName': break; + case 'BrtCalcProp': break; + case 'BrtUserBookView': break; + case 'BrtBeginPivotCacheIDs': break; + case 'BrtBeginPivotCacheID': break; + case 'BrtEndPivotCacheID': break; + case 'BrtEndPivotCacheIDs': break; + case 'BrtWebOpt': break; + case 'BrtFileRecover': break; + case 'BrtFileSharing': break; + /*case 'BrtBeginWebPubItems': break; + case 'BrtBeginWebPubItem': break; + case 'BrtEndWebPubItem': break; + case 'BrtEndWebPubItems': break;*/ + + /* Smart Tags */ + case 'BrtBeginSmartTagTypes': break; + case 'BrtSmartTagType': break; + case 'BrtEndSmartTagTypes': break; + + case 'BrtFRTBegin': pass = true; break; + case 'BrtFRTArchID$': break; + case 'BrtWorkBookPr15': break; + case 'BrtFRTEnd': pass = false; break; + case 'BrtEndBook': break; + default: if(!pass || opts.WTF) throw new Error("Unexpected record " + R.n); + } + }); + + parse_wb_defaults(wb); + + return wb; +} + +/* [MS-XLSB] 2.1.7.60 Workbook */ +function write_BUNDLESHS(ba, wb, opts) { + write_record(ba, "BrtBeginBundleShs"); + for(var idx = 0; idx != wb.SheetNames.length; ++idx) { + var d = { hsState: 0, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] }; + write_record(ba, "BrtBundleSh", write_BrtBundleSh(d)); + } + write_record(ba, "BrtEndBundleShs"); +} + +/* [MS-XLSB] 2.4.643 BrtFileVersion */ +function write_BrtFileVersion(data, o) { + if(!o) o = new_buf(127); + for(var i = 0; i != 4; ++i) o.write_shift(4, 0); + write_XLWideString("SheetJS", o); + write_XLWideString(XLSX.version, o); + write_XLWideString(XLSX.version, o); + write_XLWideString("7262", o); + o.length = o.l; + return o; +} + +/* [MS-XLSB] 2.1.7.60 Workbook */ +function write_BOOKVIEWS(ba, wb, opts) { + write_record(ba, "BrtBeginBookViews"); + /* 1*(BrtBookView *FRT) */ + write_record(ba, "BrtEndBookViews"); +} + +/* [MS-XLSB] 2.4.302 BrtCalcProp */ +function write_BrtCalcProp(data, o) { + if(!o) o = new_buf(26); + o.write_shift(4,0); /* force recalc */ + o.write_shift(4,1); + o.write_shift(4,0); + write_Xnum(0, o); + o.write_shift(-4, 1023); + o.write_shift(1, 0x33); + o.write_shift(1, 0x00); + return o; +} + +function write_BrtFileRecover(data, o) { + if(!o) o = new_buf(1); + o.write_shift(1,0); + return o; +} + +/* [MS-XLSB] 2.1.7.60 Workbook */ +function write_wb_bin(wb, opts) { + var ba = buf_array(); + write_record(ba, "BrtBeginBook"); + write_record(ba, "BrtFileVersion", write_BrtFileVersion()); + /* [[BrtFileSharingIso] BrtFileSharing] */ + write_record(ba, "BrtWbProp", write_BrtWbProp()); + /* [ACABSPATH] */ + /* [[BrtBookProtectionIso] BrtBookProtection] */ + write_BOOKVIEWS(ba, wb, opts); + write_BUNDLESHS(ba, wb, opts); + /* [FNGROUP] */ + /* [EXTERNALS] */ + /* *BrtName */ + write_record(ba, "BrtCalcProp", write_BrtCalcProp()); + /* [BrtOleSize] */ + /* *(BrtUserBookView *FRT) */ + /* [PIVOTCACHEIDS] */ + /* [BrtWbFactoid] */ + /* [SMARTTAGTYPES] */ + /* [BrtWebOpt] */ + write_record(ba, "BrtFileRecover", write_BrtFileRecover()); + /* [WEBPUBITEMS] */ + /* [CRERRS] */ + /* FRTWORKBOOK */ + write_record(ba, "BrtEndBook"); + + return ba.end(); +} +function parse_wb(data, name, opts) { + return (name.substr(-4)===".bin" ? parse_wb_bin : parse_wb_xml)(data, opts); +} + +function parse_ws(data, name, opts, rels) { + return (name.substr(-4)===".bin" ? parse_ws_bin : parse_ws_xml)(data, opts, rels); +} + +function parse_sty(data, name, opts) { + return (name.substr(-4)===".bin" ? parse_sty_bin : parse_sty_xml)(data, opts); +} + +function parse_theme(data, name, opts) { + return parse_theme_xml(data, opts); +} + +function parse_sst(data, name, opts) { + return (name.substr(-4)===".bin" ? parse_sst_bin : parse_sst_xml)(data, opts); +} + +function parse_cmnt(data, name, opts) { + return (name.substr(-4)===".bin" ? parse_comments_bin : parse_comments_xml)(data, opts); +} + +function parse_cc(data, name, opts) { + return (name.substr(-4)===".bin" ? parse_cc_bin : parse_cc_xml)(data, opts); +} + +function write_wb(wb, name, opts) { + return (name.substr(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts); +} + +function write_ws(data, name, opts, wb) { + return (name.substr(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb); +} + +function write_sty(data, name, opts) { + return (name.substr(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts); +} + +function write_sst(data, name, opts) { + return (name.substr(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts); +} +/* +function write_cmnt(data, name, opts) { + return (name.substr(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts); +} + +function write_cc(data, name, opts) { + return (name.substr(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts); +} +*/ +var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g; +var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/; +var _chr = function(c) { return String.fromCharCode(c); }; +function xlml_parsexmltag(tag, skip_root) { + var words = tag.split(/\s+/); + var z = []; if(!skip_root) z[0] = words[0]; + if(words.length === 1) return z; + var m = tag.match(attregexg2), y, j, w, i; + if(m) for(i = 0; i != m.length; ++i) { + y = m[i].match(attregex2); + if((j=y[1].indexOf(":")) === -1) z[y[1]] = y[2].substr(1,y[2].length-2); + else { + if(y[1].substr(0,6) === "xmlns:") w = "xmlns"+y[1].substr(6); + else w = y[1].substr(j+1); + z[w] = y[2].substr(1,y[2].length-2); + } + } + return z; +} +function xlml_parsexmltagobj(tag) { + var words = tag.split(/\s+/); + var z = {}; + if(words.length === 1) return z; + var m = tag.match(attregexg2), y, j, w, i; + if(m) for(i = 0; i != m.length; ++i) { + y = m[i].match(attregex2); + if((j=y[1].indexOf(":")) === -1) z[y[1]] = y[2].substr(1,y[2].length-2); + else { + if(y[1].substr(0,6) === "xmlns:") w = "xmlns"+y[1].substr(6); + else w = y[1].substr(j+1); + z[w] = y[2].substr(1,y[2].length-2); + } + } + return z; +} + +// ---- + +function xlml_format(format, value) { + var fmt = XLMLFormatMap[format] || unescapexml(format); + if(fmt === "General") return SSF._general(value); + return SSF.format(fmt, value); +} + +function xlml_set_custprop(Custprops, Rn, cp, val) { + switch((cp[0].match(/dt:dt="([\w.]+)"/)||["",""])[1]) { + case "boolean": val = parsexmlbool(val); break; + case "i2": case "int": val = parseInt(val, 10); break; + case "r4": case "float": val = parseFloat(val); break; + case "date": case "dateTime.tz": val = new Date(val); break; + case "i8": case "string": case "fixed": case "uuid": case "bin.base64": break; + default: throw "bad custprop:" + cp[0]; + } + Custprops[unescapexml(Rn[3])] = val; +} + +function safe_format_xlml(cell, nf, o) { + try { + if(cell.t === 'e') { cell.w = cell.w || BErr[cell.v]; } + else if(nf === "General") { + if(cell.t === 'n') { + if((cell.v|0) === cell.v) cell.w = SSF._general_int(cell.v); + else cell.w = SSF._general_num(cell.v); + } + else cell.w = SSF._general(cell.v); + } + else cell.w = xlml_format(nf||"General", cell.v); + if(o.cellNF) cell.z = XLMLFormatMap[nf]||nf||"General"; + } catch(e) { if(o.WTF) throw e; } +} + +function process_style_xlml(styles, stag, opts) { + if(opts.cellStyles) { + if(stag.Interior) { + var I = stag.Interior; + if(I.Pattern) I.patternType = XLMLPatternTypeMap[I.Pattern] || I.Pattern; + } + } + styles[stag.ID] = stag; +} + +/* TODO: there must exist some form of OSP-blessed spec */ +function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, o) { + var nf = "General", sid = cell.StyleID, S = {}; o = o || {}; + var interiors = []; + if(sid === undefined && row) sid = row.StyleID; + if(sid === undefined && csty) sid = csty.StyleID; + while(styles[sid] !== undefined) { + if(styles[sid].nf) nf = styles[sid].nf; + if(styles[sid].Interior) interiors.push(styles[sid].Interior); + if(!styles[sid].Parent) break; + sid = styles[sid].Parent; + } + switch(data.Type) { + case 'Boolean': + cell.t = 'b'; + cell.v = parsexmlbool(xml); + break; + case 'String': + cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml)); + cell.v = xml.indexOf("<") > -1 ? ss : cell.r; + break; + case 'DateTime': + cell.v = (Date.parse(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); + if(cell.v !== cell.v) cell.v = unescapexml(xml); + else if(cell.v >= 1 && cell.v<60) cell.v = cell.v -1; + if(!nf || nf == "General") nf = "yyyy-mm-dd"; + /* falls through */ + case 'Number': + if(cell.v === undefined) cell.v=+xml; + if(!cell.t) cell.t = 'n'; + break; + case 'Error': cell.t = 'e'; cell.v = RBErr[xml]; cell.w = xml; break; + default: cell.t = 's'; cell.v = xlml_fixstr(ss); break; + } + safe_format_xlml(cell, nf, o); + if(o.cellFormula != null && cell.Formula) { + cell.f = rc_to_a1(unescapexml(cell.Formula), base); + cell.Formula = undefined; + } + if(o.cellStyles) { + interiors.forEach(function(x) { + if(!S.patternType && x.patternType) S.patternType = x.patternType; + }); + cell.s = S; + } + cell.ixfe = cell.StyleID !== undefined ? cell.StyleID : 'Default'; +} + +function xlml_clean_comment(comment) { + comment.t = comment.v; + comment.v = comment.w = comment.ixfe = undefined; +} + +function xlml_normalize(d) { + if(has_buf && Buffer.isBuffer(d)) return d.toString('utf8'); + if(typeof d === 'string') return d; + throw "badf"; +} + +/* TODO: Everything */ +var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg; +function parse_xlml_xml(d, opts) { + var str = xlml_normalize(d); + var Rn; + var state = [], tmp; + var sheets = {}, sheetnames = [], cursheet = {}, sheetname = ""; + var table = {}, cell = {}, row = {}, dtag, didx; + var c = 0, r = 0; + var refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} }; + var styles = {}, stag = {}; + var ss = "", fidx = 0; + var mergecells = []; + var Props = {}, Custprops = {}, pidx = 0, cp = {}; + var comments = [], comment = {}; + var cstys = [], csty; + xlmlregex.lastIndex = 0; + while((Rn = xlmlregex.exec(str))) switch(Rn[3]) { + case 'Data': + if(state[state.length-1][1]) break; + if(Rn[1]==='/') parse_xlml_data(str.slice(didx, Rn.index), ss, dtag, state[state.length-1][0]=="Comment"?comment:cell, {c:c,r:r}, styles, cstys[c], row, opts); + else { ss = ""; dtag = xlml_parsexmltag(Rn[0]); didx = Rn.index + Rn[0].length; } + break; + case 'Cell': + if(Rn[1]==='/'){ + if(comments.length > 0) cell.c = comments; + if((!opts.sheetRows || opts.sheetRows > r) && cell.v !== undefined) cursheet[encode_col(c) + encode_row(r)] = cell; + if(cell.HRef) { + cell.l = {Target:cell.HRef, tooltip:cell.HRefScreenTip}; + cell.HRef = cell.HRefScreenTip = undefined; + } + if(cell.MergeAcross || cell.MergeDown) { + var cc = c + (parseInt(cell.MergeAcross,10)|0); + var rr = r + (parseInt(cell.MergeDown,10)|0); + mergecells.push({s:{c:c,r:r},e:{c:cc,r:rr}}); + } + ++c; + if(cell.MergeAcross) c += +cell.MergeAcross; + } else { + cell = xlml_parsexmltagobj(Rn[0]); + if(cell.Index) c = +cell.Index - 1; + if(c < refguess.s.c) refguess.s.c = c; + if(c > refguess.e.c) refguess.e.c = c; + if(Rn[0].substr(-2) === "/>") ++c; + comments = []; + } + break; + case 'Row': + if(Rn[1]==='/' || Rn[0].substr(-2) === "/>") { + if(r < refguess.s.r) refguess.s.r = r; + if(r > refguess.e.r) refguess.e.r = r; + if(Rn[0].substr(-2) === "/>") { + row = xlml_parsexmltag(Rn[0]); + if(row.Index) r = +row.Index - 1; + } + c = 0; ++r; + } else { + row = xlml_parsexmltag(Rn[0]); + if(row.Index) r = +row.Index - 1; + } + break; + case 'Worksheet': /* TODO: read range from FullRows/FullColumns */ + if(Rn[1]==='/'){ + if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp; + sheetnames.push(sheetname); + if(refguess.s.r <= refguess.e.r && refguess.s.c <= refguess.e.c) cursheet["!ref"] = encode_range(refguess); + if(mergecells.length) cursheet["!merges"] = mergecells; + sheets[sheetname] = cursheet; + } else { + refguess = {s: {r:1000000, c:1000000}, e: {r:0, c:0} }; + r = c = 0; + state.push([Rn[3], false]); + tmp = xlml_parsexmltag(Rn[0]); + sheetname = tmp.Name; + cursheet = {}; + mergecells = []; + } + break; + case 'Table': + if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;} + else if(Rn[0].slice(-2) == "/>") break; + else { + table = xlml_parsexmltag(Rn[0]); + state.push([Rn[3], false]); + cstys = []; + } + break; + + case 'Style': + if(Rn[1]==='/') process_style_xlml(styles, stag, opts); + else stag = xlml_parsexmltag(Rn[0]); + break; + + case 'NumberFormat': + stag.nf = xlml_parsexmltag(Rn[0]).Format || "General"; + break; + + case 'Column': + if(state[state.length-1][0] !== 'Table') break; + csty = xlml_parsexmltag(Rn[0]); + cstys[(csty.Index-1||cstys.length)] = csty; + for(var i = 0; i < +csty.Span; ++i) cstys[cstys.length] = csty; + break; + + case 'NamedRange': break; + case 'NamedCell': break; + case 'B': break; + case 'I': break; + case 'U': break; + case 'S': break; + case 'Sub': break; + case 'Sup': break; + case 'Span': break; + case 'Border': break; + case 'Alignment': break; + case 'Borders': break; + case 'Font': + if(Rn[0].substr(-2) === "/>") break; + else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index); + else fidx = Rn.index + Rn[0].length; + break; + case 'Interior': + if(!opts.cellStyles) break; + stag.Interior = xlml_parsexmltag(Rn[0]); + break; + case 'Protection': break; + + case 'Author': + case 'Title': + case 'Description': + case 'Created': + case 'Keywords': + case 'Subject': + case 'Category': + case 'Company': + case 'LastAuthor': + case 'LastSaved': + case 'LastPrinted': + case 'Version': + case 'Revision': + case 'TotalTime': + case 'HyperlinkBase': + case 'Manager': + if(Rn[0].substr(-2) === "/>") break; + else if(Rn[1]==="/") xlml_set_prop(Props, Rn[3], str.slice(pidx, Rn.index)); + else pidx = Rn.index + Rn[0].length; + break; + case 'Paragraphs': break; + + case 'Styles': + case 'Workbook': + if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;} + else state.push([Rn[3], false]); + break; + + case 'Comment': + if(Rn[1]==='/'){ + if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp; + xlml_clean_comment(comment); + comments.push(comment); + } else { + state.push([Rn[3], false]); + tmp = xlml_parsexmltag(Rn[0]); + comment = {a:tmp.Author}; + } + break; + + case 'Name': break; + + case 'ComponentOptions': + case 'DocumentProperties': + case 'CustomDocumentProperties': + case 'OfficeDocumentSettings': + case 'PivotTable': + case 'PivotCache': + case 'Names': + case 'MapInfo': + case 'PageBreaks': + case 'QueryTable': + case 'DataValidation': + case 'AutoFilter': + case 'Sorting': + case 'Schema': + case 'data': + case 'ConditionalFormatting': + case 'SmartTagType': + case 'SmartTags': + case 'ExcelWorkbook': + case 'WorkbookOptions': + case 'WorksheetOptions': + if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;} + else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]); + break; + + default: + var seen = true; + switch(state[state.length-1][0]) { + /* OfficeDocumentSettings */ + case 'OfficeDocumentSettings': switch(Rn[3]) { + case 'AllowPNG': break; + case 'RemovePersonalInformation': break; + case 'DownloadComponents': break; + case 'LocationOfComponents': break; + case 'Colors': break; + case 'Color': break; + case 'Index': break; + case 'RGB': break; + case 'PixelsPerInch': break; + case 'TargetScreenSize': break; + case 'ReadOnlyRecommended': break; + default: seen = false; + } break; + + /* ComponentOptions */ + case 'ComponentOptions': switch(Rn[3]) { + case 'Toolbar': break; + case 'HideOfficeLogo': break; + case 'SpreadsheetAutoFit': break; + case 'Label': break; + case 'Caption': break; + case 'MaxHeight': break; + case 'MaxWidth': break; + case 'NextSheetNumber': break; + default: seen = false; + } break; + + /* ExcelWorkbook */ + case 'ExcelWorkbook': switch(Rn[3]) { + case 'WindowHeight': break; + case 'WindowWidth': break; + case 'WindowTopX': break; + case 'WindowTopY': break; + case 'TabRatio': break; + case 'ProtectStructure': break; + case 'ProtectWindows': break; + case 'ActiveSheet': break; + case 'DisplayInkNotes': break; + case 'FirstVisibleSheet': break; + case 'SupBook': break; + case 'SheetName': break; + case 'SheetIndex': break; + case 'SheetIndexFirst': break; + case 'SheetIndexLast': break; + case 'Dll': break; + case 'AcceptLabelsInFormulas': break; + case 'DoNotSaveLinkValues': break; + case 'Date1904': break; + case 'Iteration': break; + case 'MaxIterations': break; + case 'MaxChange': break; + case 'Path': break; + case 'Xct': break; + case 'Count': break; + case 'SelectedSheets': break; + case 'Calculation': break; + case 'Uncalced': break; + case 'StartupPrompt': break; + case 'Crn': break; + case 'ExternName': break; + case 'Formula': break; + case 'ColFirst': break; + case 'ColLast': break; + case 'WantAdvise': break; + case 'Boolean': break; + case 'Error': break; + case 'Text': break; + case 'OLE': break; + case 'NoAutoRecover': break; + case 'PublishObjects': break; + case 'DoNotCalculateBeforeSave': break; + case 'Number': break; + case 'RefModeR1C1': break; + case 'EmbedSaveSmartTags': break; + default: seen = false; + } break; + + /* WorkbookOptions */ + case 'WorkbookOptions': switch(Rn[3]) { + case 'OWCVersion': break; + case 'Height': break; + case 'Width': break; + default: seen = false; + } break; + + /* WorksheetOptions */ + case 'WorksheetOptions': switch(Rn[3]) { + case 'Unsynced': break; + case 'Visible': break; + case 'Print': break; + case 'Panes': break; + case 'Scale': break; + case 'Pane': break; + case 'Number': break; + case 'Layout': break; + case 'Header': break; + case 'Footer': break; + case 'PageSetup': break; + case 'PageMargins': break; + case 'Selected': break; + case 'ProtectObjects': break; + case 'EnableSelection': break; + case 'ProtectScenarios': break; + case 'ValidPrinterInfo': break; + case 'HorizontalResolution': break; + case 'VerticalResolution': break; + case 'NumberofCopies': break; + case 'ActiveRow': break; + case 'ActiveCol': break; + case 'ActivePane': break; + case 'TopRowVisible': break; + case 'TopRowBottomPane': break; + case 'LeftColumnVisible': break; + case 'LeftColumnRightPane': break; + case 'FitToPage': break; + case 'RangeSelection': break; + case 'PaperSizeIndex': break; + case 'PageLayoutZoom': break; + case 'PageBreakZoom': break; + case 'FilterOn': break; + case 'DoNotDisplayGridlines': break; + case 'SplitHorizontal': break; + case 'SplitVertical': break; + case 'FreezePanes': break; + case 'FrozenNoSplit': break; + case 'FitWidth': break; + case 'FitHeight': break; + case 'CommentsLayout': break; + case 'Zoom': break; + case 'LeftToRight': break; + case 'Gridlines': break; + case 'AllowSort': break; + case 'AllowFilter': break; + case 'AllowInsertRows': break; + case 'AllowDeleteRows': break; + case 'AllowInsertCols': break; + case 'AllowDeleteCols': break; + case 'AllowInsertHyperlinks': break; + case 'AllowFormatCells': break; + case 'AllowSizeCols': break; + case 'AllowSizeRows': break; + case 'NoSummaryRowsBelowDetail': break; + case 'TabColorIndex': break; + case 'DoNotDisplayHeadings': break; + case 'ShowPageLayoutZoom': break; + case 'NoSummaryColumnsRightDetail': break; + case 'BlackAndWhite': break; + case 'DoNotDisplayZeros': break; + case 'DisplayPageBreak': break; + case 'RowColHeadings': break; + case 'DoNotDisplayOutline': break; + case 'NoOrientation': break; + case 'AllowUsePivotTables': break; + case 'ZeroHeight': break; + case 'ViewableRange': break; + case 'Selection': break; + case 'ProtectContents': break; + default: seen = false; + } break; + + /* PivotTable */ + case 'PivotTable': case 'PivotCache': switch(Rn[3]) { + case 'ImmediateItemsOnDrop': break; + case 'ShowPageMultipleItemLabel': break; + case 'CompactRowIndent': break; + case 'Location': break; + case 'PivotField': break; + case 'Orientation': break; + case 'LayoutForm': break; + case 'LayoutSubtotalLocation': break; + case 'LayoutCompactRow': break; + case 'Position': break; + case 'PivotItem': break; + case 'DataType': break; + case 'DataField': break; + case 'SourceName': break; + case 'ParentField': break; + case 'PTLineItems': break; + case 'PTLineItem': break; + case 'CountOfSameItems': break; + case 'Item': break; + case 'ItemType': break; + case 'PTSource': break; + case 'CacheIndex': break; + case 'ConsolidationReference': break; + case 'FileName': break; + case 'Reference': break; + case 'NoColumnGrand': break; + case 'NoRowGrand': break; + case 'BlankLineAfterItems': break; + case 'Hidden': break; + case 'Subtotal': break; + case 'BaseField': break; + case 'MapChildItems': break; + case 'Function': break; + case 'RefreshOnFileOpen': break; + case 'PrintSetTitles': break; + case 'MergeLabels': break; + case 'DefaultVersion': break; + case 'RefreshName': break; + case 'RefreshDate': break; + case 'RefreshDateCopy': break; + case 'VersionLastRefresh': break; + case 'VersionLastUpdate': break; + case 'VersionUpdateableMin': break; + case 'VersionRefreshableMin': break; + case 'Calculation': break; + default: seen = false; + } break; + + /* PageBreaks */ + case 'PageBreaks': switch(Rn[3]) { + case 'ColBreaks': break; + case 'ColBreak': break; + case 'RowBreaks': break; + case 'RowBreak': break; + case 'ColStart': break; + case 'ColEnd': break; + case 'RowEnd': break; + default: seen = false; + } break; + + /* AutoFilter */ + case 'AutoFilter': switch(Rn[3]) { + case 'AutoFilterColumn': break; + case 'AutoFilterCondition': break; + case 'AutoFilterAnd': break; + case 'AutoFilterOr': break; + default: seen = false; + } break; + + /* QueryTable */ + case 'QueryTable': switch(Rn[3]) { + case 'Id': break; + case 'AutoFormatFont': break; + case 'AutoFormatPattern': break; + case 'QuerySource': break; + case 'QueryType': break; + case 'EnableRedirections': break; + case 'RefreshedInXl9': break; + case 'URLString': break; + case 'HTMLTables': break; + case 'Connection': break; + case 'CommandText': break; + case 'RefreshInfo': break; + case 'NoTitles': break; + case 'NextId': break; + case 'ColumnInfo': break; + case 'OverwriteCells': break; + case 'DoNotPromptForFile': break; + case 'TextWizardSettings': break; + case 'Source': break; + case 'Number': break; + case 'Decimal': break; + case 'ThousandSeparator': break; + case 'TrailingMinusNumbers': break; + case 'FormatSettings': break; + case 'FieldType': break; + case 'Delimiters': break; + case 'Tab': break; + case 'Comma': break; + case 'AutoFormatName': break; + case 'VersionLastEdit': break; + case 'VersionLastRefresh': break; + default: seen = false; + } break; + + /* Sorting */ + case 'Sorting': + /* ConditionalFormatting */ + case 'ConditionalFormatting': + /* DataValidation */ + case 'DataValidation': switch(Rn[3]) { + case 'Range': break; + case 'Type': break; + case 'Min': break; + case 'Max': break; + case 'Sort': break; + case 'Descending': break; + case 'Order': break; + case 'CaseSensitive': break; + case 'Value': break; + case 'ErrorStyle': break; + case 'ErrorMessage': break; + case 'ErrorTitle': break; + case 'CellRangeList': break; + case 'InputMessage': break; + case 'InputTitle': break; + case 'ComboHide': break; + case 'InputHide': break; + case 'Condition': break; + case 'Qualifier': break; + case 'UseBlank': break; + case 'Value1': break; + case 'Value2': break; + case 'Format': break; + default: seen = false; + } break; + + /* MapInfo (schema) */ + case 'MapInfo': case 'Schema': case 'data': switch(Rn[3]) { + case 'Map': break; + case 'Entry': break; + case 'Range': break; + case 'XPath': break; + case 'Field': break; + case 'XSDType': break; + case 'FilterOn': break; + case 'Aggregate': break; + case 'ElementType': break; + case 'AttributeType': break; + /* These are from xsd (XML Schema Definition) */ + case 'schema': + case 'element': + case 'complexType': + case 'datatype': + case 'all': + case 'attribute': + case 'extends': break; + + case 'row': break; + default: seen = false; + } break; + + /* SmartTags (can be anything) */ + case 'SmartTags': break; + + default: seen = false; break; + } + if(seen) break; + /* CustomDocumentProperties */ + if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|"); + if(state[state.length-1][0]==='CustomDocumentProperties') { + if(Rn[0].substr(-2) === "/>") break; + else if(Rn[1]==="/") xlml_set_custprop(Custprops, Rn, cp, str.slice(pidx, Rn.index)); + else { cp = Rn; pidx = Rn.index + Rn[0].length; } + break; + } + if(opts.WTF) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|"); + } + var out = {}; + if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets; + out.SheetNames = sheetnames; + out.SSF = SSF.get_table(); + out.Props = Props; + out.Custprops = Custprops; + return out; +} + +function parse_xlml(data, opts) { + fix_read_opts(opts=opts||{}); + switch(opts.type||"base64") { + case "base64": return parse_xlml_xml(Base64.decode(data), opts); + case "binary": case "buffer": case "file": return parse_xlml_xml(data, opts); + case "array": return parse_xlml_xml(data.map(_chr).join(""), opts); + } +} + +function write_xlml(wb, opts) { } + +/* [MS-OLEDS] 2.3.8 CompObjStream */ +function parse_compobj(obj) { + var v = {}; + var o = obj.content; + + /* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */ + var l = 28, m; + m = __lpstr(o, l); + l += 4 + __readUInt32LE(o,l); + v.UserType = m; + + /* [MS-OLEDS] 2.3.1 ClipboardFormatOrAnsiString */ + m = __readUInt32LE(o,l); l+= 4; + switch(m) { + case 0x00000000: break; + case 0xffffffff: case 0xfffffffe: l+=4; break; + default: + if(m > 0x190) throw new Error("Unsupported Clipboard: " + m.toString(16)); + l += m; + } + + m = __lpstr(o, l); l += m.length === 0 ? 0 : 5 + m.length; v.Reserved1 = m; + + if((m = __readUInt32LE(o,l)) !== 0x71b2e9f4) return v; + throw "Unsupported Unicode Extension"; +} + +/* 2.4.58 Continue logic */ +function slurp(R, blob, length, opts) { + var l = length; + var bufs = []; + var d = blob.slice(blob.l,blob.l+l); + if(opts && opts.enc && opts.enc.insitu_decrypt) switch(R.n) { + case 'BOF': case 'FilePass': case 'FileLock': case 'InterfaceHdr': case 'RRDInfo': case 'RRDHead': case 'UsrExcl': break; + default: + if(d.length === 0) break; + opts.enc.insitu_decrypt(d); + } + bufs.push(d); + blob.l += l; + var next = (XLSRecordEnum[__readUInt16LE(blob,blob.l)]); + while(next != null && next.n === 'Continue') { + l = __readUInt16LE(blob,blob.l+2); + bufs.push(blob.slice(blob.l+4,blob.l+4+l)); + blob.l += 4+l; + next = (XLSRecordEnum[__readUInt16LE(blob, blob.l)]); + } + var b = bconcat(bufs); + prep_blob(b, 0); + var ll = 0; b.lens = []; + for(var j = 0; j < bufs.length; ++j) { b.lens.push(ll); ll += bufs[j].length; } + return R.f(b, b.length, opts); +} + +function safe_format_xf(p, opts, date1904) { + if(!p.XF) return; + try { + var fmtid = p.XF.ifmt||0; + if(p.t === 'e') { p.w = p.w || BErr[p.v]; } + else if(fmtid === 0) { + if(p.t === 'n') { + if((p.v|0) === p.v) p.w = SSF._general_int(p.v); + else p.w = SSF._general_num(p.v); + } + else p.w = SSF._general(p.v); + } + else p.w = SSF.format(fmtid,p.v, {date1904:date1904||false}); + if(opts.cellNF) p.z = SSF._table[fmtid]; + } catch(e) { if(opts.WTF) throw e; } +} + +function make_cell(val, ixfe, t) { + return {v:val, ixfe:ixfe, t:t}; +} + +// 2.3.2 +function parse_workbook(blob, options) { + var wb = {opts:{}}; + var Sheets = {}; + var out = {}; + var Directory = {}; + var found_sheet = false; + var range = {}; + var last_formula = null; + var sst = []; + var cur_sheet = ""; + var Preamble = {}; + var lastcell, last_cell, cc, cmnt, rng, rngC, rngR; + var shared_formulae = {}; + var array_formulae = []; /* TODO: something more clever */ + var temp_val; + var country; + var cell_valid = true; + var XFs = []; /* XF records */ + var palette = []; + var get_rgb = function getrgb(icv) { + if(icv < 8) return XLSIcv[icv]; + if(icv < 64) return palette[icv-8] || XLSIcv[icv]; + return XLSIcv[icv]; + }; + var process_cell_style = function pcs(cell, line) { + var xfd = line.XF.data; + if(!xfd || !xfd.patternType) return; + line.s = {}; + line.s.patternType = xfd.patternType; + var t; + if((t = rgb2Hex(get_rgb(xfd.icvFore)))) { line.s.fgColor = {rgb:t}; } + if((t = rgb2Hex(get_rgb(xfd.icvBack)))) { line.s.bgColor = {rgb:t}; } + }; + var addcell = function addcell(cell, line, options) { + if(!cell_valid) return; + if(options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line); + lastcell = cell; + last_cell = encode_cell(cell); + if(range.s) { + if(cell.r < range.s.r) range.s.r = cell.r; + if(cell.c < range.s.c) range.s.c = cell.c; + } + if(range.e) { + if(cell.r + 1 > range.e.r) range.e.r = cell.r + 1; + if(cell.c + 1 > range.e.c) range.e.c = cell.c + 1; + } + if(options.sheetRows && lastcell.r >= options.sheetRows) cell_valid = false; + else out[last_cell] = line; + }; + var opts = { + enc: false, // encrypted + sbcch: 0, // cch in the preceding SupBook + snames: [], // sheetnames + sharedf: shared_formulae, // shared formulae by address + arrayf: array_formulae, // array formulae array + rrtabid: [], // RRTabId + lastuser: "", // Last User from WriteAccess + biff: 8, // BIFF version + codepage: 0, // CP from CodePage record + winlocked: 0, // fLockWn from WinProtect + wtf: false + }; + if(options.password) opts.password = options.password; + var mergecells = []; + var objects = []; + var supbooks = [[]]; // 1-indexed, will hold extern names + var sbc = 0, sbci = 0, sbcli = 0; + supbooks.SheetNames = opts.snames; + supbooks.sharedf = opts.sharedf; + supbooks.arrayf = opts.arrayf; + var last_Rn = ''; + var file_depth = 0; /* TODO: make a real stack */ + + /* explicit override for some broken writers */ + opts.codepage = 1200; + set_cp(1200); + + while(blob.l < blob.length - 1) { + var s = blob.l; + var RecordType = blob.read_shift(2); + if(RecordType === 0 && last_Rn === 'EOF') break; + var length = (blob.l === blob.length ? 0 : blob.read_shift(2)), y; + var R = XLSRecordEnum[RecordType]; + if(R && R.f) { + if(options.bookSheets) { + if(last_Rn === 'BoundSheet8' && R.n !== 'BoundSheet8') break; + } + last_Rn = R.n; + if(R.r === 2 || R.r == 12) { + var rt = blob.read_shift(2); length -= 2; + if(!opts.enc && rt !== RecordType) throw "rt mismatch"; + if(R.r == 12){ blob.l += 10; length -= 10; } // skip FRT + } + //console.error(R,blob.l,length,blob.length); + var val; + if(R.n === 'EOF') val = R.f(blob, length, opts); + else val = slurp(R, blob, length, opts); + var Rn = R.n; + /* BIFF5 overrides */ + if(opts.biff === 5 || opts.biff === 2) switch(Rn) { + case 'Lbl': Rn = 'Label'; break; + } + /* nested switch statements to workaround V8 128 limit */ + switch(Rn) { + /* Workbook Options */ + case 'Date1904': wb.opts.Date1904 = val; break; + case 'WriteProtect': wb.opts.WriteProtect = true; break; + case 'FilePass': + if(!opts.enc) blob.l = 0; + opts.enc = val; + if(opts.WTF) console.error(val); + if(!options.password) throw new Error("File is password-protected"); + if(val.Type !== 0) throw new Error("Encryption scheme unsupported"); + if(!val.valid) throw new Error("Password is incorrect"); + break; + case 'WriteAccess': opts.lastuser = val; break; + case 'FileSharing': break; //TODO + case 'CodePage': + /* overrides based on test cases */ + if(val === 0x5212) val = 1200; + else if(val === 0x8001) val = 1252; + opts.codepage = val; + set_cp(val); + break; + case 'RRTabId': opts.rrtabid = val; break; + case 'WinProtect': opts.winlocked = val; break; + case 'Template': break; // TODO + case 'RefreshAll': wb.opts.RefreshAll = val; break; + case 'BookBool': break; // TODO + case 'UsesELFs': /* if(val) console.error("Unsupported ELFs"); */ break; + case 'MTRSettings': { + if(val[0] && val[1]) throw "Unsupported threads: " + val; + } break; // TODO: actually support threads + case 'CalcCount': wb.opts.CalcCount = val; break; + case 'CalcDelta': wb.opts.CalcDelta = val; break; + case 'CalcIter': wb.opts.CalcIter = val; break; + case 'CalcMode': wb.opts.CalcMode = val; break; + case 'CalcPrecision': wb.opts.CalcPrecision = val; break; + case 'CalcSaveRecalc': wb.opts.CalcSaveRecalc = val; break; + case 'CalcRefMode': opts.CalcRefMode = val; break; // TODO: implement R1C1 + case 'Uncalced': break; + case 'ForceFullCalculation': wb.opts.FullCalc = val; break; + case 'WsBool': break; // TODO + case 'XF': XFs.push(val); break; + case 'ExtSST': break; // TODO + case 'BookExt': break; // TODO + case 'RichTextStream': break; + case 'BkHim': break; + + case 'SupBook': supbooks[++sbc] = [val]; sbci = 0; break; + case 'ExternName': supbooks[sbc][++sbci] = val; break; + case 'Index': break; // TODO + case 'Lbl': supbooks[0][++sbcli] = val; break; + case 'ExternSheet': supbooks[sbc] = supbooks[sbc].concat(val); sbci += val.length; break; + + case 'Protect': out["!protect"] = val; break; /* for sheet or book */ + case 'Password': if(val !== 0 && opts.WTF) console.error("Password verifier: " + val); break; + case 'Prot4Rev': case 'Prot4RevPass': break; /*TODO: Revision Control*/ + + case 'BoundSheet8': { + Directory[val.pos] = val; + opts.snames.push(val.name); + } break; + case 'EOF': { + if(--file_depth) break; + if(range.e) { + out["!range"] = range; + if(range.e.r > 0 && range.e.c > 0) { + range.e.r--; range.e.c--; + out["!ref"] = encode_range(range); + range.e.r++; range.e.c++; + } + if(mergecells.length > 0) out["!merges"] = mergecells; + if(objects.length > 0) out["!objects"] = objects; + } + if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out; + out = {}; + } break; + case 'BOF': { + if(opts.biff !== 8); + else if(val.BIFFVer === 0x0500) opts.biff = 5; + else if(val.BIFFVer === 0x0002) opts.biff = 2; + else if(val.BIFFVer === 0x0007) opts.biff = 2; + if(file_depth++) break; + cell_valid = true; + out = {}; + if(opts.biff === 2) { + if(cur_sheet === "") cur_sheet = "Sheet1"; + range = {s:{r:0,c:0},e:{r:0,c:0}}; + } + else cur_sheet = (Directory[s] || {name:""}).name; + mergecells = []; + objects = []; + } break; + case 'Number': case 'BIFF2NUM': { + temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:'n'}; + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell({c:val.c, r:val.r}, temp_val, options); + } break; + case 'BoolErr': { + temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}; + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell({c:val.c, r:val.r}, temp_val, options); + } break; + case 'RK': { + temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}; + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell({c:val.c, r:val.r}, temp_val, options); + } break; + case 'MulRk': { + for(var j = val.c; j <= val.C; ++j) { + var ixfe = val.rkrec[j-val.c][0]; + temp_val= {ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}; + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell({c:j, r:val.r}, temp_val, options); + } + } break; + case 'Formula': { + switch(val.val) { + case 'String': last_formula = val; break; + case 'Array Formula': throw "Array Formula unsupported"; + default: + temp_val = {v:val.val, ixfe:val.cell.ixfe, t:val.tt}; + temp_val.XF = XFs[temp_val.ixfe]; + if(options.cellFormula) temp_val.f = "="+stringify_formula(val.formula,range,val.cell,supbooks, opts); + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell(val.cell, temp_val, options); + last_formula = val; + } + } break; + case 'String': { + if(last_formula) { + last_formula.val = val; + temp_val = {v:last_formula.val, ixfe:last_formula.cell.ixfe, t:'s'}; + temp_val.XF = XFs[temp_val.ixfe]; + if(options.cellFormula) temp_val.f = "="+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts); + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell(last_formula.cell, temp_val, options); + last_formula = null; + } + } break; + case 'Array': { + array_formulae.push(val); + } break; + case 'ShrFmla': { + if(!cell_valid) break; + //if(options.cellFormula) out[last_cell].f = stringify_formula(val[0], range, lastcell, supbooks, opts); + /* TODO: capture range */ + shared_formulae[encode_cell(last_formula.cell)]= val[0]; + } break; + case 'LabelSst': + //temp_val={v:sst[val.isst].t, ixfe:val.ixfe, t:'s'}; + temp_val=make_cell(sst[val.isst].t, val.ixfe, 's'); + temp_val.XF = XFs[temp_val.ixfe]; + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell({c:val.c, r:val.r}, temp_val, options); + break; + case 'Label': case 'BIFF2STR': + /* Some writers erroneously write Label */ + temp_val=make_cell(val.val, val.ixfe, 's'); + temp_val.XF = XFs[temp_val.ixfe]; + if(temp_val.XF) safe_format_xf(temp_val, options, wb.opts.Date1904); + addcell({c:val.c, r:val.r}, temp_val, options); + break; + case 'Dimensions': { + if(file_depth === 1) range = val; /* TODO: stack */ + } break; + case 'SST': { + sst = val; + } break; + case 'Format': { /* val = [id, fmt] */ + SSF.load(val[1], val[0]); + } break; + + case 'MergeCells': mergecells = mergecells.concat(val); break; + + case 'Obj': objects[val.cmo[0]] = opts.lastobj = val; break; + case 'TxO': opts.lastobj.TxO = val; break; + + case 'HLink': { + for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) + for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) + if(out[encode_cell({c:rngC,r:rngR})]) + out[encode_cell({c:rngC,r:rngR})].l = val[1]; + } break; + case 'HLinkTooltip': { + for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) + for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) + if(out[encode_cell({c:rngC,r:rngR})]) + out[encode_cell({c:rngC,r:rngR})].l.tooltip = val[1]; + } break; + + /* Comments */ + case 'Note': { + if(opts.biff <= 5 && opts.biff >= 2) break; /* TODO: BIFF5 */ + cc = out[encode_cell(val[0])]; + var noteobj = objects[val[2]]; + if(!cc) break; + if(!cc.c) cc.c = []; + cmnt = {a:val[1],t:noteobj.TxO.t}; + cc.c.push(cmnt); + } break; + + default: switch(R.n) { /* nested */ + case 'ClrtClient': break; + case 'XFExt': update_xfext(XFs[val.ixfe], val.ext); break; + + case 'NameCmt': break; + case 'Header': break; // TODO + case 'Footer': break; // TODO + case 'HCenter': break; // TODO + case 'VCenter': break; // TODO + case 'Pls': break; // TODO + case 'Setup': break; // TODO + case 'DefColWidth': break; // TODO + case 'GCW': break; + case 'LHRecord': break; + case 'ColInfo': break; // TODO + case 'Row': break; // TODO + case 'DBCell': break; // TODO + case 'MulBlank': break; // TODO + case 'EntExU2': break; // TODO + case 'SxView': break; // TODO + case 'Sxvd': break; // TODO + case 'SXVI': break; // TODO + case 'SXVDEx': break; // TODO + case 'SxIvd': break; // TODO + case 'SXDI': break; // TODO + case 'SXLI': break; // TODO + case 'SXEx': break; // TODO + case 'QsiSXTag': break; // TODO + case 'Selection': break; + case 'Feat': break; + case 'FeatHdr': case 'FeatHdr11': break; + case 'Feature11': case 'Feature12': case 'List12': break; + case 'Blank': break; + case 'Country': country = val; break; + case 'RecalcId': break; + case 'DefaultRowHeight': case 'DxGCol': break; // TODO: htmlify + case 'Fbi': case 'Fbi2': case 'GelFrame': break; + case 'Font': break; // TODO + case 'XFCRC': break; // TODO + case 'Style': break; // TODO + case 'StyleExt': break; // TODO + case 'Palette': palette = val; break; // TODO + case 'Theme': break; // TODO + /* Protection */ + case 'ScenarioProtect': break; + case 'ObjProtect': break; + + /* Conditional Formatting */ + case 'CondFmt12': break; + + /* Table */ + case 'Table': break; // TODO + case 'TableStyles': break; // TODO + case 'TableStyle': break; // TODO + case 'TableStyleElement': break; // TODO + + /* PivotTable */ + case 'SXStreamID': break; // TODO + case 'SXVS': break; // TODO + case 'DConRef': break; // TODO + case 'SXAddl': break; // TODO + case 'DConBin': break; // TODO + case 'DConName': break; // TODO + case 'SXPI': break; // TODO + case 'SxFormat': break; // TODO + case 'SxSelect': break; // TODO + case 'SxRule': break; // TODO + case 'SxFilt': break; // TODO + case 'SxItm': break; // TODO + case 'SxDXF': break; // TODO + + /* Scenario Manager */ + case 'ScenMan': break; + + /* Data Consolidation */ + case 'DCon': break; + + /* Watched Cell */ + case 'CellWatch': break; + + /* Print Settings */ + case 'PrintRowCol': break; + case 'PrintGrid': break; + case 'PrintSize': break; + + case 'XCT': break; + case 'CRN': break; + + case 'Scl': { + //console.log("Zoom Level:", val[0]/val[1],val); + } break; + case 'SheetExt': { + + } break; + case 'SheetExtOptional': { + + } break; + + /* VBA */ + case 'ObNoMacros': { + + } break; + case 'ObProj': { + + } break; + case 'CodeName': { + + } break; + case 'GUIDTypeLib': { + + } break; + + case 'WOpt': break; // TODO: WTF? + case 'PhoneticInfo': break; + + case 'OleObjectSize': break; + + /* Differential Formatting */ + case 'DXF': case 'DXFN': case 'DXFN12': case 'DXFN12List': case 'DXFN12NoCB': break; + + /* Data Validation */ + case 'Dv': case 'DVal': break; + + /* Data Series */ + case 'BRAI': case 'Series': case 'SeriesText': break; + + /* Data Connection */ + case 'DConn': break; + case 'DbOrParamQry': break; + case 'DBQueryExt': break; + + /* Formatting */ + case 'IFmtRecord': break; + case 'CondFmt': case 'CF': case 'CF12': case 'CFEx': break; + + /* Explicitly Ignored */ + case 'Excel9File': break; + case 'Units': break; + case 'InterfaceHdr': case 'Mms': case 'InterfaceEnd': case 'DSF': case 'BuiltInFnGroupCount': + /* View Stuff */ + case 'Window1': case 'Window2': case 'HideObj': case 'GridSet': case 'Guts': + case 'UserBView': case 'UserSViewBegin': case 'UserSViewEnd': + case 'Pane': break; + default: switch(R.n) { /* nested */ + /* Chart */ + case 'Dat': + case 'Begin': case 'End': + case 'StartBlock': case 'EndBlock': + case 'Frame': case 'Area': + case 'Axis': case 'AxisLine': case 'Tick': break; + case 'AxesUsed': + case 'CrtLayout12': case 'CrtLayout12A': case 'CrtLink': case 'CrtLine': case 'CrtMlFrt': case 'CrtMlFrtContinue': break; + case 'LineFormat': case 'AreaFormat': + case 'Chart': case 'Chart3d': case 'Chart3DBarShape': case 'ChartFormat': case 'ChartFrtInfo': break; + case 'PlotArea': case 'PlotGrowth': break; + case 'SeriesList': case 'SerParent': case 'SerAuxTrend': break; + case 'DataFormat': case 'SerToCrt': case 'FontX': break; + case 'CatSerRange': case 'AxcExt': case 'SerFmt': break; + case 'ShtProps': break; + case 'DefaultText': case 'Text': case 'CatLab': break; + case 'DataLabExtContents': break; + case 'Legend': case 'LegendException': break; + case 'Pie': case 'Scatter': break; + case 'PieFormat': case 'MarkerFormat': break; + case 'StartObject': case 'EndObject': break; + case 'AlRuns': case 'ObjectLink': break; + case 'SIIndex': break; + case 'AttachedLabel': case 'YMult': break; + + /* Chart Group */ + case 'Line': case 'Bar': break; + case 'Surf': break; + + /* Axis Group */ + case 'AxisParent': break; + case 'Pos': break; + case 'ValueRange': break; + + /* Pivot Chart */ + case 'SXViewEx9': break; // TODO + case 'SXViewLink': break; + case 'PivotChartBits': break; + case 'SBaseRef': break; + case 'TextPropsStream': break; + + /* Chart Misc */ + case 'LnExt': break; + case 'MkrExt': break; + case 'CrtCoopt': break; + + /* Query Table */ + case 'Qsi': case 'Qsif': case 'Qsir': case 'QsiSXTag': break; + case 'TxtQry': break; + + /* Filter */ + case 'FilterMode': break; + case 'AutoFilter': case 'AutoFilterInfo': break; + case 'AutoFilter12': break; + case 'DropDownObjIds': break; + case 'Sort': break; + case 'SortData': break; + + /* Drawing */ + case 'ShapePropsStream': break; + case 'MsoDrawing': case 'MsoDrawingGroup': case 'MsoDrawingSelection': break; + case 'ImData': break; + /* Pub Stuff */ + case 'WebPub': case 'AutoWebPub': + + /* Print Stuff */ + case 'RightMargin': case 'LeftMargin': case 'TopMargin': case 'BottomMargin': + case 'HeaderFooter': case 'HFPicture': case 'PLV': + case 'HorizontalPageBreaks': case 'VerticalPageBreaks': + /* Behavioral */ + case 'Backup': case 'CompressPictures': case 'Compat12': break; + + /* Should not Happen */ + case 'Continue': case 'ContinueFrt12': break; + + /* Future Records */ + case 'FrtFontList': case 'FrtWrapper': break; + + /* BIFF5 records */ + case 'ExternCount': break; + case 'RString': break; + case 'TabIdConf': case 'Radar': case 'RadarArea': case 'DropBar': case 'Intl': case 'CoordList': case 'SerAuxErrBar': break; + + default: switch(R.n) { /* nested */ + /* Miscellaneous */ + case 'SCENARIO': case 'DConBin': case 'PicF': case 'DataLabExt': + case 'Lel': case 'BopPop': case 'BopPopCustom': case 'RealTimeData': + case 'Name': break; + default: if(options.WTF) throw 'Unrecognized Record ' + R.n; + }}}} + } else blob.l += length; + } + var sheetnamesraw = opts.biff === 2 ? ['Sheet1'] : Object.keys(Directory).sort(function(a,b) { return Number(a) - Number(b); }).map(function(x){return Directory[x].name;}); + var sheetnames = sheetnamesraw.slice(); + wb.Directory=sheetnamesraw; + wb.SheetNames=sheetnamesraw; + if(!options.bookSheets) wb.Sheets=Sheets; + wb.Preamble=Preamble; + wb.Strings = sst; + wb.SSF = SSF.get_table(); + if(opts.enc) wb.Encryption = opts.enc; + wb.Metadata = {}; + if(country !== undefined) wb.Metadata.Country = country; + return wb; +} + +function parse_xlscfb(cfb, options) { +if(!options) options = {}; +fix_read_opts(options); +reset_cp(); +var CompObj, Summary, Workbook; +if(cfb.find) { + CompObj = cfb.find('!CompObj'); + Summary = cfb.find('!SummaryInformation'); + Workbook = cfb.find('/Workbook'); +} else { + prep_blob(cfb, 0); + Workbook = {content: cfb}; +} + +if(!Workbook) Workbook = cfb.find('/Book'); +var CompObjP, SummaryP, WorkbookP; + +if(CompObj) CompObjP = parse_compobj(CompObj); +if(options.bookProps && !options.bookSheets) WorkbookP = {}; +else { + if(Workbook) WorkbookP = parse_workbook(Workbook.content, options, !!Workbook.find); + else throw new Error("Cannot find Workbook stream"); +} + +if(cfb.find) parse_props(cfb); + +var props = {}; +for(var y in cfb.Summary) props[y] = cfb.Summary[y]; +for(y in cfb.DocSummary) props[y] = cfb.DocSummary[y]; +WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */ +if(options.bookFiles) WorkbookP.cfb = cfb; +WorkbookP.CompObjP = CompObjP; +return WorkbookP; +} + +/* TODO: WTF */ +function parse_props(cfb) { + /* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */ + var DSI = cfb.find('!DocumentSummaryInformation'); + if(DSI) try { cfb.DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI); } catch(e) {} + + /* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/ + var SI = cfb.find('!SummaryInformation'); + if(SI) try { cfb.Summary = parse_PropertySetStream(SI, SummaryPIDSI); } catch(e) {} +} + +/* [MS-XLSB] 2.3 Record Enumeration */ +var XLSBRecordEnum = { + 0x0000: { n:"BrtRowHdr", f:parse_BrtRowHdr }, + 0x0001: { n:"BrtCellBlank", f:parse_BrtCellBlank }, + 0x0002: { n:"BrtCellRk", f:parse_BrtCellRk }, + 0x0003: { n:"BrtCellError", f:parse_BrtCellError }, + 0x0004: { n:"BrtCellBool", f:parse_BrtCellBool }, + 0x0005: { n:"BrtCellReal", f:parse_BrtCellReal }, + 0x0006: { n:"BrtCellSt", f:parse_BrtCellSt }, + 0x0007: { n:"BrtCellIsst", f:parse_BrtCellIsst }, + 0x0008: { n:"BrtFmlaString", f:parse_BrtFmlaString }, + 0x0009: { n:"BrtFmlaNum", f:parse_BrtFmlaNum }, + 0x000A: { n:"BrtFmlaBool", f:parse_BrtFmlaBool }, + 0x000B: { n:"BrtFmlaError", f:parse_BrtFmlaError }, + 0x0010: { n:"BrtFRTArchID$", f:parse_BrtFRTArchID$ }, + 0x0013: { n:"BrtSSTItem", f:parse_RichStr }, + 0x0014: { n:"BrtPCDIMissing", f:parsenoop }, + 0x0015: { n:"BrtPCDINumber", f:parsenoop }, + 0x0016: { n:"BrtPCDIBoolean", f:parsenoop }, + 0x0017: { n:"BrtPCDIError", f:parsenoop }, + 0x0018: { n:"BrtPCDIString", f:parsenoop }, + 0x0019: { n:"BrtPCDIDatetime", f:parsenoop }, + 0x001A: { n:"BrtPCDIIndex", f:parsenoop }, + 0x001B: { n:"BrtPCDIAMissing", f:parsenoop }, + 0x001C: { n:"BrtPCDIANumber", f:parsenoop }, + 0x001D: { n:"BrtPCDIABoolean", f:parsenoop }, + 0x001E: { n:"BrtPCDIAError", f:parsenoop }, + 0x001F: { n:"BrtPCDIAString", f:parsenoop }, + 0x0020: { n:"BrtPCDIADatetime", f:parsenoop }, + 0x0021: { n:"BrtPCRRecord", f:parsenoop }, + 0x0022: { n:"BrtPCRRecordDt", f:parsenoop }, + 0x0023: { n:"BrtFRTBegin", f:parsenoop }, + 0x0024: { n:"BrtFRTEnd", f:parsenoop }, + 0x0025: { n:"BrtACBegin", f:parsenoop }, + 0x0026: { n:"BrtACEnd", f:parsenoop }, + 0x0027: { n:"BrtName", f:parsenoop }, + 0x0028: { n:"BrtIndexRowBlock", f:parsenoop }, + 0x002A: { n:"BrtIndexBlock", f:parsenoop }, + 0x002B: { n:"BrtFont", f:parse_BrtFont }, + 0x002C: { n:"BrtFmt", f:parse_BrtFmt }, + 0x002D: { n:"BrtFill", f:parsenoop }, + 0x002E: { n:"BrtBorder", f:parsenoop }, + 0x002F: { n:"BrtXF", f:parse_BrtXF }, + 0x0030: { n:"BrtStyle", f:parsenoop }, + 0x0031: { n:"BrtCellMeta", f:parsenoop }, + 0x0032: { n:"BrtValueMeta", f:parsenoop }, + 0x0033: { n:"BrtMdb", f:parsenoop }, + 0x0034: { n:"BrtBeginFmd", f:parsenoop }, + 0x0035: { n:"BrtEndFmd", f:parsenoop }, + 0x0036: { n:"BrtBeginMdx", f:parsenoop }, + 0x0037: { n:"BrtEndMdx", f:parsenoop }, + 0x0038: { n:"BrtBeginMdxTuple", f:parsenoop }, + 0x0039: { n:"BrtEndMdxTuple", f:parsenoop }, + 0x003A: { n:"BrtMdxMbrIstr", f:parsenoop }, + 0x003B: { n:"BrtStr", f:parsenoop }, + 0x003C: { n:"BrtColInfo", f:parsenoop }, + 0x003E: { n:"BrtCellRString", f:parsenoop }, + 0x003F: { n:"BrtCalcChainItem$", f:parse_BrtCalcChainItem$ }, + 0x0040: { n:"BrtDVal", f:parsenoop }, + 0x0041: { n:"BrtSxvcellNum", f:parsenoop }, + 0x0042: { n:"BrtSxvcellStr", f:parsenoop }, + 0x0043: { n:"BrtSxvcellBool", f:parsenoop }, + 0x0044: { n:"BrtSxvcellErr", f:parsenoop }, + 0x0045: { n:"BrtSxvcellDate", f:parsenoop }, + 0x0046: { n:"BrtSxvcellNil", f:parsenoop }, + 0x0080: { n:"BrtFileVersion", f:parsenoop }, + 0x0081: { n:"BrtBeginSheet", f:parsenoop }, + 0x0082: { n:"BrtEndSheet", f:parsenoop }, + 0x0083: { n:"BrtBeginBook", f:parsenoop, p:0 }, + 0x0084: { n:"BrtEndBook", f:parsenoop }, + 0x0085: { n:"BrtBeginWsViews", f:parsenoop }, + 0x0086: { n:"BrtEndWsViews", f:parsenoop }, + 0x0087: { n:"BrtBeginBookViews", f:parsenoop }, + 0x0088: { n:"BrtEndBookViews", f:parsenoop }, + 0x0089: { n:"BrtBeginWsView", f:parsenoop }, + 0x008A: { n:"BrtEndWsView", f:parsenoop }, + 0x008B: { n:"BrtBeginCsViews", f:parsenoop }, + 0x008C: { n:"BrtEndCsViews", f:parsenoop }, + 0x008D: { n:"BrtBeginCsView", f:parsenoop }, + 0x008E: { n:"BrtEndCsView", f:parsenoop }, + 0x008F: { n:"BrtBeginBundleShs", f:parsenoop }, + 0x0090: { n:"BrtEndBundleShs", f:parsenoop }, + 0x0091: { n:"BrtBeginSheetData", f:parsenoop }, + 0x0092: { n:"BrtEndSheetData", f:parsenoop }, + 0x0093: { n:"BrtWsProp", f:parse_BrtWsProp }, + 0x0094: { n:"BrtWsDim", f:parse_BrtWsDim, p:16 }, + 0x0097: { n:"BrtPane", f:parsenoop }, + 0x0098: { n:"BrtSel", f:parsenoop }, + 0x0099: { n:"BrtWbProp", f:parse_BrtWbProp }, + 0x009A: { n:"BrtWbFactoid", f:parsenoop }, + 0x009B: { n:"BrtFileRecover", f:parsenoop }, + 0x009C: { n:"BrtBundleSh", f:parse_BrtBundleSh }, + 0x009D: { n:"BrtCalcProp", f:parsenoop }, + 0x009E: { n:"BrtBookView", f:parsenoop }, + 0x009F: { n:"BrtBeginSst", f:parse_BrtBeginSst }, + 0x00A0: { n:"BrtEndSst", f:parsenoop }, + 0x00A1: { n:"BrtBeginAFilter", f:parsenoop }, + 0x00A2: { n:"BrtEndAFilter", f:parsenoop }, + 0x00A3: { n:"BrtBeginFilterColumn", f:parsenoop }, + 0x00A4: { n:"BrtEndFilterColumn", f:parsenoop }, + 0x00A5: { n:"BrtBeginFilters", f:parsenoop }, + 0x00A6: { n:"BrtEndFilters", f:parsenoop }, + 0x00A7: { n:"BrtFilter", f:parsenoop }, + 0x00A8: { n:"BrtColorFilter", f:parsenoop }, + 0x00A9: { n:"BrtIconFilter", f:parsenoop }, + 0x00AA: { n:"BrtTop10Filter", f:parsenoop }, + 0x00AB: { n:"BrtDynamicFilter", f:parsenoop }, + 0x00AC: { n:"BrtBeginCustomFilters", f:parsenoop }, + 0x00AD: { n:"BrtEndCustomFilters", f:parsenoop }, + 0x00AE: { n:"BrtCustomFilter", f:parsenoop }, + 0x00AF: { n:"BrtAFilterDateGroupItem", f:parsenoop }, + 0x00B0: { n:"BrtMergeCell", f:parse_BrtMergeCell }, + 0x00B1: { n:"BrtBeginMergeCells", f:parsenoop }, + 0x00B2: { n:"BrtEndMergeCells", f:parsenoop }, + 0x00B3: { n:"BrtBeginPivotCacheDef", f:parsenoop }, + 0x00B4: { n:"BrtEndPivotCacheDef", f:parsenoop }, + 0x00B5: { n:"BrtBeginPCDFields", f:parsenoop }, + 0x00B6: { n:"BrtEndPCDFields", f:parsenoop }, + 0x00B7: { n:"BrtBeginPCDField", f:parsenoop }, + 0x00B8: { n:"BrtEndPCDField", f:parsenoop }, + 0x00B9: { n:"BrtBeginPCDSource", f:parsenoop }, + 0x00BA: { n:"BrtEndPCDSource", f:parsenoop }, + 0x00BB: { n:"BrtBeginPCDSRange", f:parsenoop }, + 0x00BC: { n:"BrtEndPCDSRange", f:parsenoop }, + 0x00BD: { n:"BrtBeginPCDFAtbl", f:parsenoop }, + 0x00BE: { n:"BrtEndPCDFAtbl", f:parsenoop }, + 0x00BF: { n:"BrtBeginPCDIRun", f:parsenoop }, + 0x00C0: { n:"BrtEndPCDIRun", f:parsenoop }, + 0x00C1: { n:"BrtBeginPivotCacheRecords", f:parsenoop }, + 0x00C2: { n:"BrtEndPivotCacheRecords", f:parsenoop }, + 0x00C3: { n:"BrtBeginPCDHierarchies", f:parsenoop }, + 0x00C4: { n:"BrtEndPCDHierarchies", f:parsenoop }, + 0x00C5: { n:"BrtBeginPCDHierarchy", f:parsenoop }, + 0x00C6: { n:"BrtEndPCDHierarchy", f:parsenoop }, + 0x00C7: { n:"BrtBeginPCDHFieldsUsage", f:parsenoop }, + 0x00C8: { n:"BrtEndPCDHFieldsUsage", f:parsenoop }, + 0x00C9: { n:"BrtBeginExtConnection", f:parsenoop }, + 0x00CA: { n:"BrtEndExtConnection", f:parsenoop }, + 0x00CB: { n:"BrtBeginECDbProps", f:parsenoop }, + 0x00CC: { n:"BrtEndECDbProps", f:parsenoop }, + 0x00CD: { n:"BrtBeginECOlapProps", f:parsenoop }, + 0x00CE: { n:"BrtEndECOlapProps", f:parsenoop }, + 0x00CF: { n:"BrtBeginPCDSConsol", f:parsenoop }, + 0x00D0: { n:"BrtEndPCDSConsol", f:parsenoop }, + 0x00D1: { n:"BrtBeginPCDSCPages", f:parsenoop }, + 0x00D2: { n:"BrtEndPCDSCPages", f:parsenoop }, + 0x00D3: { n:"BrtBeginPCDSCPage", f:parsenoop }, + 0x00D4: { n:"BrtEndPCDSCPage", f:parsenoop }, + 0x00D5: { n:"BrtBeginPCDSCPItem", f:parsenoop }, + 0x00D6: { n:"BrtEndPCDSCPItem", f:parsenoop }, + 0x00D7: { n:"BrtBeginPCDSCSets", f:parsenoop }, + 0x00D8: { n:"BrtEndPCDSCSets", f:parsenoop }, + 0x00D9: { n:"BrtBeginPCDSCSet", f:parsenoop }, + 0x00DA: { n:"BrtEndPCDSCSet", f:parsenoop }, + 0x00DB: { n:"BrtBeginPCDFGroup", f:parsenoop }, + 0x00DC: { n:"BrtEndPCDFGroup", f:parsenoop }, + 0x00DD: { n:"BrtBeginPCDFGItems", f:parsenoop }, + 0x00DE: { n:"BrtEndPCDFGItems", f:parsenoop }, + 0x00DF: { n:"BrtBeginPCDFGRange", f:parsenoop }, + 0x00E0: { n:"BrtEndPCDFGRange", f:parsenoop }, + 0x00E1: { n:"BrtBeginPCDFGDiscrete", f:parsenoop }, + 0x00E2: { n:"BrtEndPCDFGDiscrete", f:parsenoop }, + 0x00E3: { n:"BrtBeginPCDSDTupleCache", f:parsenoop }, + 0x00E4: { n:"BrtEndPCDSDTupleCache", f:parsenoop }, + 0x00E5: { n:"BrtBeginPCDSDTCEntries", f:parsenoop }, + 0x00E6: { n:"BrtEndPCDSDTCEntries", f:parsenoop }, + 0x00E7: { n:"BrtBeginPCDSDTCEMembers", f:parsenoop }, + 0x00E8: { n:"BrtEndPCDSDTCEMembers", f:parsenoop }, + 0x00E9: { n:"BrtBeginPCDSDTCEMember", f:parsenoop }, + 0x00EA: { n:"BrtEndPCDSDTCEMember", f:parsenoop }, + 0x00EB: { n:"BrtBeginPCDSDTCQueries", f:parsenoop }, + 0x00EC: { n:"BrtEndPCDSDTCQueries", f:parsenoop }, + 0x00ED: { n:"BrtBeginPCDSDTCQuery", f:parsenoop }, + 0x00EE: { n:"BrtEndPCDSDTCQuery", f:parsenoop }, + 0x00EF: { n:"BrtBeginPCDSDTCSets", f:parsenoop }, + 0x00F0: { n:"BrtEndPCDSDTCSets", f:parsenoop }, + 0x00F1: { n:"BrtBeginPCDSDTCSet", f:parsenoop }, + 0x00F2: { n:"BrtEndPCDSDTCSet", f:parsenoop }, + 0x00F3: { n:"BrtBeginPCDCalcItems", f:parsenoop }, + 0x00F4: { n:"BrtEndPCDCalcItems", f:parsenoop }, + 0x00F5: { n:"BrtBeginPCDCalcItem", f:parsenoop }, + 0x00F6: { n:"BrtEndPCDCalcItem", f:parsenoop }, + 0x00F7: { n:"BrtBeginPRule", f:parsenoop }, + 0x00F8: { n:"BrtEndPRule", f:parsenoop }, + 0x00F9: { n:"BrtBeginPRFilters", f:parsenoop }, + 0x00FA: { n:"BrtEndPRFilters", f:parsenoop }, + 0x00FB: { n:"BrtBeginPRFilter", f:parsenoop }, + 0x00FC: { n:"BrtEndPRFilter", f:parsenoop }, + 0x00FD: { n:"BrtBeginPNames", f:parsenoop }, + 0x00FE: { n:"BrtEndPNames", f:parsenoop }, + 0x00FF: { n:"BrtBeginPName", f:parsenoop }, + 0x0100: { n:"BrtEndPName", f:parsenoop }, + 0x0101: { n:"BrtBeginPNPairs", f:parsenoop }, + 0x0102: { n:"BrtEndPNPairs", f:parsenoop }, + 0x0103: { n:"BrtBeginPNPair", f:parsenoop }, + 0x0104: { n:"BrtEndPNPair", f:parsenoop }, + 0x0105: { n:"BrtBeginECWebProps", f:parsenoop }, + 0x0106: { n:"BrtEndECWebProps", f:parsenoop }, + 0x0107: { n:"BrtBeginEcWpTables", f:parsenoop }, + 0x0108: { n:"BrtEndECWPTables", f:parsenoop }, + 0x0109: { n:"BrtBeginECParams", f:parsenoop }, + 0x010A: { n:"BrtEndECParams", f:parsenoop }, + 0x010B: { n:"BrtBeginECParam", f:parsenoop }, + 0x010C: { n:"BrtEndECParam", f:parsenoop }, + 0x010D: { n:"BrtBeginPCDKPIs", f:parsenoop }, + 0x010E: { n:"BrtEndPCDKPIs", f:parsenoop }, + 0x010F: { n:"BrtBeginPCDKPI", f:parsenoop }, + 0x0110: { n:"BrtEndPCDKPI", f:parsenoop }, + 0x0111: { n:"BrtBeginDims", f:parsenoop }, + 0x0112: { n:"BrtEndDims", f:parsenoop }, + 0x0113: { n:"BrtBeginDim", f:parsenoop }, + 0x0114: { n:"BrtEndDim", f:parsenoop }, + 0x0115: { n:"BrtIndexPartEnd", f:parsenoop }, + 0x0116: { n:"BrtBeginStyleSheet", f:parsenoop }, + 0x0117: { n:"BrtEndStyleSheet", f:parsenoop }, + 0x0118: { n:"BrtBeginSXView", f:parsenoop }, + 0x0119: { n:"BrtEndSXVI", f:parsenoop }, + 0x011A: { n:"BrtBeginSXVI", f:parsenoop }, + 0x011B: { n:"BrtBeginSXVIs", f:parsenoop }, + 0x011C: { n:"BrtEndSXVIs", f:parsenoop }, + 0x011D: { n:"BrtBeginSXVD", f:parsenoop }, + 0x011E: { n:"BrtEndSXVD", f:parsenoop }, + 0x011F: { n:"BrtBeginSXVDs", f:parsenoop }, + 0x0120: { n:"BrtEndSXVDs", f:parsenoop }, + 0x0121: { n:"BrtBeginSXPI", f:parsenoop }, + 0x0122: { n:"BrtEndSXPI", f:parsenoop }, + 0x0123: { n:"BrtBeginSXPIs", f:parsenoop }, + 0x0124: { n:"BrtEndSXPIs", f:parsenoop }, + 0x0125: { n:"BrtBeginSXDI", f:parsenoop }, + 0x0126: { n:"BrtEndSXDI", f:parsenoop }, + 0x0127: { n:"BrtBeginSXDIs", f:parsenoop }, + 0x0128: { n:"BrtEndSXDIs", f:parsenoop }, + 0x0129: { n:"BrtBeginSXLI", f:parsenoop }, + 0x012A: { n:"BrtEndSXLI", f:parsenoop }, + 0x012B: { n:"BrtBeginSXLIRws", f:parsenoop }, + 0x012C: { n:"BrtEndSXLIRws", f:parsenoop }, + 0x012D: { n:"BrtBeginSXLICols", f:parsenoop }, + 0x012E: { n:"BrtEndSXLICols", f:parsenoop }, + 0x012F: { n:"BrtBeginSXFormat", f:parsenoop }, + 0x0130: { n:"BrtEndSXFormat", f:parsenoop }, + 0x0131: { n:"BrtBeginSXFormats", f:parsenoop }, + 0x0132: { n:"BrtEndSxFormats", f:parsenoop }, + 0x0133: { n:"BrtBeginSxSelect", f:parsenoop }, + 0x0134: { n:"BrtEndSxSelect", f:parsenoop }, + 0x0135: { n:"BrtBeginISXVDRws", f:parsenoop }, + 0x0136: { n:"BrtEndISXVDRws", f:parsenoop }, + 0x0137: { n:"BrtBeginISXVDCols", f:parsenoop }, + 0x0138: { n:"BrtEndISXVDCols", f:parsenoop }, + 0x0139: { n:"BrtEndSXLocation", f:parsenoop }, + 0x013A: { n:"BrtBeginSXLocation", f:parsenoop }, + 0x013B: { n:"BrtEndSXView", f:parsenoop }, + 0x013C: { n:"BrtBeginSXTHs", f:parsenoop }, + 0x013D: { n:"BrtEndSXTHs", f:parsenoop }, + 0x013E: { n:"BrtBeginSXTH", f:parsenoop }, + 0x013F: { n:"BrtEndSXTH", f:parsenoop }, + 0x0140: { n:"BrtBeginISXTHRws", f:parsenoop }, + 0x0141: { n:"BrtEndISXTHRws", f:parsenoop }, + 0x0142: { n:"BrtBeginISXTHCols", f:parsenoop }, + 0x0143: { n:"BrtEndISXTHCols", f:parsenoop }, + 0x0144: { n:"BrtBeginSXTDMPS", f:parsenoop }, + 0x0145: { n:"BrtEndSXTDMPs", f:parsenoop }, + 0x0146: { n:"BrtBeginSXTDMP", f:parsenoop }, + 0x0147: { n:"BrtEndSXTDMP", f:parsenoop }, + 0x0148: { n:"BrtBeginSXTHItems", f:parsenoop }, + 0x0149: { n:"BrtEndSXTHItems", f:parsenoop }, + 0x014A: { n:"BrtBeginSXTHItem", f:parsenoop }, + 0x014B: { n:"BrtEndSXTHItem", f:parsenoop }, + 0x014C: { n:"BrtBeginMetadata", f:parsenoop }, + 0x014D: { n:"BrtEndMetadata", f:parsenoop }, + 0x014E: { n:"BrtBeginEsmdtinfo", f:parsenoop }, + 0x014F: { n:"BrtMdtinfo", f:parsenoop }, + 0x0150: { n:"BrtEndEsmdtinfo", f:parsenoop }, + 0x0151: { n:"BrtBeginEsmdb", f:parsenoop }, + 0x0152: { n:"BrtEndEsmdb", f:parsenoop }, + 0x0153: { n:"BrtBeginEsfmd", f:parsenoop }, + 0x0154: { n:"BrtEndEsfmd", f:parsenoop }, + 0x0155: { n:"BrtBeginSingleCells", f:parsenoop }, + 0x0156: { n:"BrtEndSingleCells", f:parsenoop }, + 0x0157: { n:"BrtBeginList", f:parsenoop }, + 0x0158: { n:"BrtEndList", f:parsenoop }, + 0x0159: { n:"BrtBeginListCols", f:parsenoop }, + 0x015A: { n:"BrtEndListCols", f:parsenoop }, + 0x015B: { n:"BrtBeginListCol", f:parsenoop }, + 0x015C: { n:"BrtEndListCol", f:parsenoop }, + 0x015D: { n:"BrtBeginListXmlCPr", f:parsenoop }, + 0x015E: { n:"BrtEndListXmlCPr", f:parsenoop }, + 0x015F: { n:"BrtListCCFmla", f:parsenoop }, + 0x0160: { n:"BrtListTrFmla", f:parsenoop }, + 0x0161: { n:"BrtBeginExternals", f:parsenoop }, + 0x0162: { n:"BrtEndExternals", f:parsenoop }, + 0x0163: { n:"BrtSupBookSrc", f:parsenoop }, + 0x0165: { n:"BrtSupSelf", f:parsenoop }, + 0x0166: { n:"BrtSupSame", f:parsenoop }, + 0x0167: { n:"BrtSupTabs", f:parsenoop }, + 0x0168: { n:"BrtBeginSupBook", f:parsenoop }, + 0x0169: { n:"BrtPlaceholderName", f:parsenoop }, + 0x016A: { n:"BrtExternSheet", f:parsenoop }, + 0x016B: { n:"BrtExternTableStart", f:parsenoop }, + 0x016C: { n:"BrtExternTableEnd", f:parsenoop }, + 0x016E: { n:"BrtExternRowHdr", f:parsenoop }, + 0x016F: { n:"BrtExternCellBlank", f:parsenoop }, + 0x0170: { n:"BrtExternCellReal", f:parsenoop }, + 0x0171: { n:"BrtExternCellBool", f:parsenoop }, + 0x0172: { n:"BrtExternCellError", f:parsenoop }, + 0x0173: { n:"BrtExternCellString", f:parsenoop }, + 0x0174: { n:"BrtBeginEsmdx", f:parsenoop }, + 0x0175: { n:"BrtEndEsmdx", f:parsenoop }, + 0x0176: { n:"BrtBeginMdxSet", f:parsenoop }, + 0x0177: { n:"BrtEndMdxSet", f:parsenoop }, + 0x0178: { n:"BrtBeginMdxMbrProp", f:parsenoop }, + 0x0179: { n:"BrtEndMdxMbrProp", f:parsenoop }, + 0x017A: { n:"BrtBeginMdxKPI", f:parsenoop }, + 0x017B: { n:"BrtEndMdxKPI", f:parsenoop }, + 0x017C: { n:"BrtBeginEsstr", f:parsenoop }, + 0x017D: { n:"BrtEndEsstr", f:parsenoop }, + 0x017E: { n:"BrtBeginPRFItem", f:parsenoop }, + 0x017F: { n:"BrtEndPRFItem", f:parsenoop }, + 0x0180: { n:"BrtBeginPivotCacheIDs", f:parsenoop }, + 0x0181: { n:"BrtEndPivotCacheIDs", f:parsenoop }, + 0x0182: { n:"BrtBeginPivotCacheID", f:parsenoop }, + 0x0183: { n:"BrtEndPivotCacheID", f:parsenoop }, + 0x0184: { n:"BrtBeginISXVIs", f:parsenoop }, + 0x0185: { n:"BrtEndISXVIs", f:parsenoop }, + 0x0186: { n:"BrtBeginColInfos", f:parsenoop }, + 0x0187: { n:"BrtEndColInfos", f:parsenoop }, + 0x0188: { n:"BrtBeginRwBrk", f:parsenoop }, + 0x0189: { n:"BrtEndRwBrk", f:parsenoop }, + 0x018A: { n:"BrtBeginColBrk", f:parsenoop }, + 0x018B: { n:"BrtEndColBrk", f:parsenoop }, + 0x018C: { n:"BrtBrk", f:parsenoop }, + 0x018D: { n:"BrtUserBookView", f:parsenoop }, + 0x018E: { n:"BrtInfo", f:parsenoop }, + 0x018F: { n:"BrtCUsr", f:parsenoop }, + 0x0190: { n:"BrtUsr", f:parsenoop }, + 0x0191: { n:"BrtBeginUsers", f:parsenoop }, + 0x0193: { n:"BrtEOF", f:parsenoop }, + 0x0194: { n:"BrtUCR", f:parsenoop }, + 0x0195: { n:"BrtRRInsDel", f:parsenoop }, + 0x0196: { n:"BrtRREndInsDel", f:parsenoop }, + 0x0197: { n:"BrtRRMove", f:parsenoop }, + 0x0198: { n:"BrtRREndMove", f:parsenoop }, + 0x0199: { n:"BrtRRChgCell", f:parsenoop }, + 0x019A: { n:"BrtRREndChgCell", f:parsenoop }, + 0x019B: { n:"BrtRRHeader", f:parsenoop }, + 0x019C: { n:"BrtRRUserView", f:parsenoop }, + 0x019D: { n:"BrtRRRenSheet", f:parsenoop }, + 0x019E: { n:"BrtRRInsertSh", f:parsenoop }, + 0x019F: { n:"BrtRRDefName", f:parsenoop }, + 0x01A0: { n:"BrtRRNote", f:parsenoop }, + 0x01A1: { n:"BrtRRConflict", f:parsenoop }, + 0x01A2: { n:"BrtRRTQSIF", f:parsenoop }, + 0x01A3: { n:"BrtRRFormat", f:parsenoop }, + 0x01A4: { n:"BrtRREndFormat", f:parsenoop }, + 0x01A5: { n:"BrtRRAutoFmt", f:parsenoop }, + 0x01A6: { n:"BrtBeginUserShViews", f:parsenoop }, + 0x01A7: { n:"BrtBeginUserShView", f:parsenoop }, + 0x01A8: { n:"BrtEndUserShView", f:parsenoop }, + 0x01A9: { n:"BrtEndUserShViews", f:parsenoop }, + 0x01AA: { n:"BrtArrFmla", f:parsenoop }, + 0x01AB: { n:"BrtShrFmla", f:parsenoop }, + 0x01AC: { n:"BrtTable", f:parsenoop }, + 0x01AD: { n:"BrtBeginExtConnections", f:parsenoop }, + 0x01AE: { n:"BrtEndExtConnections", f:parsenoop }, + 0x01AF: { n:"BrtBeginPCDCalcMems", f:parsenoop }, + 0x01B0: { n:"BrtEndPCDCalcMems", f:parsenoop }, + 0x01B1: { n:"BrtBeginPCDCalcMem", f:parsenoop }, + 0x01B2: { n:"BrtEndPCDCalcMem", f:parsenoop }, + 0x01B3: { n:"BrtBeginPCDHGLevels", f:parsenoop }, + 0x01B4: { n:"BrtEndPCDHGLevels", f:parsenoop }, + 0x01B5: { n:"BrtBeginPCDHGLevel", f:parsenoop }, + 0x01B6: { n:"BrtEndPCDHGLevel", f:parsenoop }, + 0x01B7: { n:"BrtBeginPCDHGLGroups", f:parsenoop }, + 0x01B8: { n:"BrtEndPCDHGLGroups", f:parsenoop }, + 0x01B9: { n:"BrtBeginPCDHGLGroup", f:parsenoop }, + 0x01BA: { n:"BrtEndPCDHGLGroup", f:parsenoop }, + 0x01BB: { n:"BrtBeginPCDHGLGMembers", f:parsenoop }, + 0x01BC: { n:"BrtEndPCDHGLGMembers", f:parsenoop }, + 0x01BD: { n:"BrtBeginPCDHGLGMember", f:parsenoop }, + 0x01BE: { n:"BrtEndPCDHGLGMember", f:parsenoop }, + 0x01BF: { n:"BrtBeginQSI", f:parsenoop }, + 0x01C0: { n:"BrtEndQSI", f:parsenoop }, + 0x01C1: { n:"BrtBeginQSIR", f:parsenoop }, + 0x01C2: { n:"BrtEndQSIR", f:parsenoop }, + 0x01C3: { n:"BrtBeginDeletedNames", f:parsenoop }, + 0x01C4: { n:"BrtEndDeletedNames", f:parsenoop }, + 0x01C5: { n:"BrtBeginDeletedName", f:parsenoop }, + 0x01C6: { n:"BrtEndDeletedName", f:parsenoop }, + 0x01C7: { n:"BrtBeginQSIFs", f:parsenoop }, + 0x01C8: { n:"BrtEndQSIFs", f:parsenoop }, + 0x01C9: { n:"BrtBeginQSIF", f:parsenoop }, + 0x01CA: { n:"BrtEndQSIF", f:parsenoop }, + 0x01CB: { n:"BrtBeginAutoSortScope", f:parsenoop }, + 0x01CC: { n:"BrtEndAutoSortScope", f:parsenoop }, + 0x01CD: { n:"BrtBeginConditionalFormatting", f:parsenoop }, + 0x01CE: { n:"BrtEndConditionalFormatting", f:parsenoop }, + 0x01CF: { n:"BrtBeginCFRule", f:parsenoop }, + 0x01D0: { n:"BrtEndCFRule", f:parsenoop }, + 0x01D1: { n:"BrtBeginIconSet", f:parsenoop }, + 0x01D2: { n:"BrtEndIconSet", f:parsenoop }, + 0x01D3: { n:"BrtBeginDatabar", f:parsenoop }, + 0x01D4: { n:"BrtEndDatabar", f:parsenoop }, + 0x01D5: { n:"BrtBeginColorScale", f:parsenoop }, + 0x01D6: { n:"BrtEndColorScale", f:parsenoop }, + 0x01D7: { n:"BrtCFVO", f:parsenoop }, + 0x01D8: { n:"BrtExternValueMeta", f:parsenoop }, + 0x01D9: { n:"BrtBeginColorPalette", f:parsenoop }, + 0x01DA: { n:"BrtEndColorPalette", f:parsenoop }, + 0x01DB: { n:"BrtIndexedColor", f:parsenoop }, + 0x01DC: { n:"BrtMargins", f:parsenoop }, + 0x01DD: { n:"BrtPrintOptions", f:parsenoop }, + 0x01DE: { n:"BrtPageSetup", f:parsenoop }, + 0x01DF: { n:"BrtBeginHeaderFooter", f:parsenoop }, + 0x01E0: { n:"BrtEndHeaderFooter", f:parsenoop }, + 0x01E1: { n:"BrtBeginSXCrtFormat", f:parsenoop }, + 0x01E2: { n:"BrtEndSXCrtFormat", f:parsenoop }, + 0x01E3: { n:"BrtBeginSXCrtFormats", f:parsenoop }, + 0x01E4: { n:"BrtEndSXCrtFormats", f:parsenoop }, + 0x01E5: { n:"BrtWsFmtInfo", f:parsenoop }, + 0x01E6: { n:"BrtBeginMgs", f:parsenoop }, + 0x01E7: { n:"BrtEndMGs", f:parsenoop }, + 0x01E8: { n:"BrtBeginMGMaps", f:parsenoop }, + 0x01E9: { n:"BrtEndMGMaps", f:parsenoop }, + 0x01EA: { n:"BrtBeginMG", f:parsenoop }, + 0x01EB: { n:"BrtEndMG", f:parsenoop }, + 0x01EC: { n:"BrtBeginMap", f:parsenoop }, + 0x01ED: { n:"BrtEndMap", f:parsenoop }, + 0x01EE: { n:"BrtHLink", f:parse_BrtHLink }, + 0x01EF: { n:"BrtBeginDCon", f:parsenoop }, + 0x01F0: { n:"BrtEndDCon", f:parsenoop }, + 0x01F1: { n:"BrtBeginDRefs", f:parsenoop }, + 0x01F2: { n:"BrtEndDRefs", f:parsenoop }, + 0x01F3: { n:"BrtDRef", f:parsenoop }, + 0x01F4: { n:"BrtBeginScenMan", f:parsenoop }, + 0x01F5: { n:"BrtEndScenMan", f:parsenoop }, + 0x01F6: { n:"BrtBeginSct", f:parsenoop }, + 0x01F7: { n:"BrtEndSct", f:parsenoop }, + 0x01F8: { n:"BrtSlc", f:parsenoop }, + 0x01F9: { n:"BrtBeginDXFs", f:parsenoop }, + 0x01FA: { n:"BrtEndDXFs", f:parsenoop }, + 0x01FB: { n:"BrtDXF", f:parsenoop }, + 0x01FC: { n:"BrtBeginTableStyles", f:parsenoop }, + 0x01FD: { n:"BrtEndTableStyles", f:parsenoop }, + 0x01FE: { n:"BrtBeginTableStyle", f:parsenoop }, + 0x01FF: { n:"BrtEndTableStyle", f:parsenoop }, + 0x0200: { n:"BrtTableStyleElement", f:parsenoop }, + 0x0201: { n:"BrtTableStyleClient", f:parsenoop }, + 0x0202: { n:"BrtBeginVolDeps", f:parsenoop }, + 0x0203: { n:"BrtEndVolDeps", f:parsenoop }, + 0x0204: { n:"BrtBeginVolType", f:parsenoop }, + 0x0205: { n:"BrtEndVolType", f:parsenoop }, + 0x0206: { n:"BrtBeginVolMain", f:parsenoop }, + 0x0207: { n:"BrtEndVolMain", f:parsenoop }, + 0x0208: { n:"BrtBeginVolTopic", f:parsenoop }, + 0x0209: { n:"BrtEndVolTopic", f:parsenoop }, + 0x020A: { n:"BrtVolSubtopic", f:parsenoop }, + 0x020B: { n:"BrtVolRef", f:parsenoop }, + 0x020C: { n:"BrtVolNum", f:parsenoop }, + 0x020D: { n:"BrtVolErr", f:parsenoop }, + 0x020E: { n:"BrtVolStr", f:parsenoop }, + 0x020F: { n:"BrtVolBool", f:parsenoop }, + 0x0210: { n:"BrtBeginCalcChain$", f:parsenoop }, + 0x0211: { n:"BrtEndCalcChain$", f:parsenoop }, + 0x0212: { n:"BrtBeginSortState", f:parsenoop }, + 0x0213: { n:"BrtEndSortState", f:parsenoop }, + 0x0214: { n:"BrtBeginSortCond", f:parsenoop }, + 0x0215: { n:"BrtEndSortCond", f:parsenoop }, + 0x0216: { n:"BrtBookProtection", f:parsenoop }, + 0x0217: { n:"BrtSheetProtection", f:parsenoop }, + 0x0218: { n:"BrtRangeProtection", f:parsenoop }, + 0x0219: { n:"BrtPhoneticInfo", f:parsenoop }, + 0x021A: { n:"BrtBeginECTxtWiz", f:parsenoop }, + 0x021B: { n:"BrtEndECTxtWiz", f:parsenoop }, + 0x021C: { n:"BrtBeginECTWFldInfoLst", f:parsenoop }, + 0x021D: { n:"BrtEndECTWFldInfoLst", f:parsenoop }, + 0x021E: { n:"BrtBeginECTwFldInfo", f:parsenoop }, + 0x0224: { n:"BrtFileSharing", f:parsenoop }, + 0x0225: { n:"BrtOleSize", f:parsenoop }, + 0x0226: { n:"BrtDrawing", f:parsenoop }, + 0x0227: { n:"BrtLegacyDrawing", f:parsenoop }, + 0x0228: { n:"BrtLegacyDrawingHF", f:parsenoop }, + 0x0229: { n:"BrtWebOpt", f:parsenoop }, + 0x022A: { n:"BrtBeginWebPubItems", f:parsenoop }, + 0x022B: { n:"BrtEndWebPubItems", f:parsenoop }, + 0x022C: { n:"BrtBeginWebPubItem", f:parsenoop }, + 0x022D: { n:"BrtEndWebPubItem", f:parsenoop }, + 0x022E: { n:"BrtBeginSXCondFmt", f:parsenoop }, + 0x022F: { n:"BrtEndSXCondFmt", f:parsenoop }, + 0x0230: { n:"BrtBeginSXCondFmts", f:parsenoop }, + 0x0231: { n:"BrtEndSXCondFmts", f:parsenoop }, + 0x0232: { n:"BrtBkHim", f:parsenoop }, + 0x0234: { n:"BrtColor", f:parsenoop }, + 0x0235: { n:"BrtBeginIndexedColors", f:parsenoop }, + 0x0236: { n:"BrtEndIndexedColors", f:parsenoop }, + 0x0239: { n:"BrtBeginMRUColors", f:parsenoop }, + 0x023A: { n:"BrtEndMRUColors", f:parsenoop }, + 0x023C: { n:"BrtMRUColor", f:parsenoop }, + 0x023D: { n:"BrtBeginDVals", f:parsenoop }, + 0x023E: { n:"BrtEndDVals", f:parsenoop }, + 0x0241: { n:"BrtSupNameStart", f:parsenoop }, + 0x0242: { n:"BrtSupNameValueStart", f:parsenoop }, + 0x0243: { n:"BrtSupNameValueEnd", f:parsenoop }, + 0x0244: { n:"BrtSupNameNum", f:parsenoop }, + 0x0245: { n:"BrtSupNameErr", f:parsenoop }, + 0x0246: { n:"BrtSupNameSt", f:parsenoop }, + 0x0247: { n:"BrtSupNameNil", f:parsenoop }, + 0x0248: { n:"BrtSupNameBool", f:parsenoop }, + 0x0249: { n:"BrtSupNameFmla", f:parsenoop }, + 0x024A: { n:"BrtSupNameBits", f:parsenoop }, + 0x024B: { n:"BrtSupNameEnd", f:parsenoop }, + 0x024C: { n:"BrtEndSupBook", f:parsenoop }, + 0x024D: { n:"BrtCellSmartTagProperty", f:parsenoop }, + 0x024E: { n:"BrtBeginCellSmartTag", f:parsenoop }, + 0x024F: { n:"BrtEndCellSmartTag", f:parsenoop }, + 0x0250: { n:"BrtBeginCellSmartTags", f:parsenoop }, + 0x0251: { n:"BrtEndCellSmartTags", f:parsenoop }, + 0x0252: { n:"BrtBeginSmartTags", f:parsenoop }, + 0x0253: { n:"BrtEndSmartTags", f:parsenoop }, + 0x0254: { n:"BrtSmartTagType", f:parsenoop }, + 0x0255: { n:"BrtBeginSmartTagTypes", f:parsenoop }, + 0x0256: { n:"BrtEndSmartTagTypes", f:parsenoop }, + 0x0257: { n:"BrtBeginSXFilters", f:parsenoop }, + 0x0258: { n:"BrtEndSXFilters", f:parsenoop }, + 0x0259: { n:"BrtBeginSXFILTER", f:parsenoop }, + 0x025A: { n:"BrtEndSXFilter", f:parsenoop }, + 0x025B: { n:"BrtBeginFills", f:parsenoop }, + 0x025C: { n:"BrtEndFills", f:parsenoop }, + 0x025D: { n:"BrtBeginCellWatches", f:parsenoop }, + 0x025E: { n:"BrtEndCellWatches", f:parsenoop }, + 0x025F: { n:"BrtCellWatch", f:parsenoop }, + 0x0260: { n:"BrtBeginCRErrs", f:parsenoop }, + 0x0261: { n:"BrtEndCRErrs", f:parsenoop }, + 0x0262: { n:"BrtCrashRecErr", f:parsenoop }, + 0x0263: { n:"BrtBeginFonts", f:parsenoop }, + 0x0264: { n:"BrtEndFonts", f:parsenoop }, + 0x0265: { n:"BrtBeginBorders", f:parsenoop }, + 0x0266: { n:"BrtEndBorders", f:parsenoop }, + 0x0267: { n:"BrtBeginFmts", f:parsenoop }, + 0x0268: { n:"BrtEndFmts", f:parsenoop }, + 0x0269: { n:"BrtBeginCellXFs", f:parsenoop }, + 0x026A: { n:"BrtEndCellXFs", f:parsenoop }, + 0x026B: { n:"BrtBeginStyles", f:parsenoop }, + 0x026C: { n:"BrtEndStyles", f:parsenoop }, + 0x0271: { n:"BrtBigName", f:parsenoop }, + 0x0272: { n:"BrtBeginCellStyleXFs", f:parsenoop }, + 0x0273: { n:"BrtEndCellStyleXFs", f:parsenoop }, + 0x0274: { n:"BrtBeginComments", f:parsenoop }, + 0x0275: { n:"BrtEndComments", f:parsenoop }, + 0x0276: { n:"BrtBeginCommentAuthors", f:parsenoop }, + 0x0277: { n:"BrtEndCommentAuthors", f:parsenoop }, + 0x0278: { n:"BrtCommentAuthor", f:parse_BrtCommentAuthor }, + 0x0279: { n:"BrtBeginCommentList", f:parsenoop }, + 0x027A: { n:"BrtEndCommentList", f:parsenoop }, + 0x027B: { n:"BrtBeginComment", f:parse_BrtBeginComment}, + 0x027C: { n:"BrtEndComment", f:parsenoop }, + 0x027D: { n:"BrtCommentText", f:parse_BrtCommentText }, + 0x027E: { n:"BrtBeginOleObjects", f:parsenoop }, + 0x027F: { n:"BrtOleObject", f:parsenoop }, + 0x0280: { n:"BrtEndOleObjects", f:parsenoop }, + 0x0281: { n:"BrtBeginSxrules", f:parsenoop }, + 0x0282: { n:"BrtEndSxRules", f:parsenoop }, + 0x0283: { n:"BrtBeginActiveXControls", f:parsenoop }, + 0x0284: { n:"BrtActiveX", f:parsenoop }, + 0x0285: { n:"BrtEndActiveXControls", f:parsenoop }, + 0x0286: { n:"BrtBeginPCDSDTCEMembersSortBy", f:parsenoop }, + 0x0288: { n:"BrtBeginCellIgnoreECs", f:parsenoop }, + 0x0289: { n:"BrtCellIgnoreEC", f:parsenoop }, + 0x028A: { n:"BrtEndCellIgnoreECs", f:parsenoop }, + 0x028B: { n:"BrtCsProp", f:parsenoop }, + 0x028C: { n:"BrtCsPageSetup", f:parsenoop }, + 0x028D: { n:"BrtBeginUserCsViews", f:parsenoop }, + 0x028E: { n:"BrtEndUserCsViews", f:parsenoop }, + 0x028F: { n:"BrtBeginUserCsView", f:parsenoop }, + 0x0290: { n:"BrtEndUserCsView", f:parsenoop }, + 0x0291: { n:"BrtBeginPcdSFCIEntries", f:parsenoop }, + 0x0292: { n:"BrtEndPCDSFCIEntries", f:parsenoop }, + 0x0293: { n:"BrtPCDSFCIEntry", f:parsenoop }, + 0x0294: { n:"BrtBeginListParts", f:parsenoop }, + 0x0295: { n:"BrtListPart", f:parsenoop }, + 0x0296: { n:"BrtEndListParts", f:parsenoop }, + 0x0297: { n:"BrtSheetCalcProp", f:parsenoop }, + 0x0298: { n:"BrtBeginFnGroup", f:parsenoop }, + 0x0299: { n:"BrtFnGroup", f:parsenoop }, + 0x029A: { n:"BrtEndFnGroup", f:parsenoop }, + 0x029B: { n:"BrtSupAddin", f:parsenoop }, + 0x029C: { n:"BrtSXTDMPOrder", f:parsenoop }, + 0x029D: { n:"BrtCsProtection", f:parsenoop }, + 0x029F: { n:"BrtBeginWsSortMap", f:parsenoop }, + 0x02A0: { n:"BrtEndWsSortMap", f:parsenoop }, + 0x02A1: { n:"BrtBeginRRSort", f:parsenoop }, + 0x02A2: { n:"BrtEndRRSort", f:parsenoop }, + 0x02A3: { n:"BrtRRSortItem", f:parsenoop }, + 0x02A4: { n:"BrtFileSharingIso", f:parsenoop }, + 0x02A5: { n:"BrtBookProtectionIso", f:parsenoop }, + 0x02A6: { n:"BrtSheetProtectionIso", f:parsenoop }, + 0x02A7: { n:"BrtCsProtectionIso", f:parsenoop }, + 0x02A8: { n:"BrtRangeProtectionIso", f:parsenoop }, + 0x0400: { n:"BrtRwDescent", f:parsenoop }, + 0x0401: { n:"BrtKnownFonts", f:parsenoop }, + 0x0402: { n:"BrtBeginSXTupleSet", f:parsenoop }, + 0x0403: { n:"BrtEndSXTupleSet", f:parsenoop }, + 0x0404: { n:"BrtBeginSXTupleSetHeader", f:parsenoop }, + 0x0405: { n:"BrtEndSXTupleSetHeader", f:parsenoop }, + 0x0406: { n:"BrtSXTupleSetHeaderItem", f:parsenoop }, + 0x0407: { n:"BrtBeginSXTupleSetData", f:parsenoop }, + 0x0408: { n:"BrtEndSXTupleSetData", f:parsenoop }, + 0x0409: { n:"BrtBeginSXTupleSetRow", f:parsenoop }, + 0x040A: { n:"BrtEndSXTupleSetRow", f:parsenoop }, + 0x040B: { n:"BrtSXTupleSetRowItem", f:parsenoop }, + 0x040C: { n:"BrtNameExt", f:parsenoop }, + 0x040D: { n:"BrtPCDH14", f:parsenoop }, + 0x040E: { n:"BrtBeginPCDCalcMem14", f:parsenoop }, + 0x040F: { n:"BrtEndPCDCalcMem14", f:parsenoop }, + 0x0410: { n:"BrtSXTH14", f:parsenoop }, + 0x0411: { n:"BrtBeginSparklineGroup", f:parsenoop }, + 0x0412: { n:"BrtEndSparklineGroup", f:parsenoop }, + 0x0413: { n:"BrtSparkline", f:parsenoop }, + 0x0414: { n:"BrtSXDI14", f:parsenoop }, + 0x0415: { n:"BrtWsFmtInfoEx14", f:parsenoop }, + 0x0416: { n:"BrtBeginConditionalFormatting14", f:parsenoop }, + 0x0417: { n:"BrtEndConditionalFormatting14", f:parsenoop }, + 0x0418: { n:"BrtBeginCFRule14", f:parsenoop }, + 0x0419: { n:"BrtEndCFRule14", f:parsenoop }, + 0x041A: { n:"BrtCFVO14", f:parsenoop }, + 0x041B: { n:"BrtBeginDatabar14", f:parsenoop }, + 0x041C: { n:"BrtBeginIconSet14", f:parsenoop }, + 0x041D: { n:"BrtDVal14", f:parsenoop }, + 0x041E: { n:"BrtBeginDVals14", f:parsenoop }, + 0x041F: { n:"BrtColor14", f:parsenoop }, + 0x0420: { n:"BrtBeginSparklines", f:parsenoop }, + 0x0421: { n:"BrtEndSparklines", f:parsenoop }, + 0x0422: { n:"BrtBeginSparklineGroups", f:parsenoop }, + 0x0423: { n:"BrtEndSparklineGroups", f:parsenoop }, + 0x0425: { n:"BrtSXVD14", f:parsenoop }, + 0x0426: { n:"BrtBeginSxview14", f:parsenoop }, + 0x0427: { n:"BrtEndSxview14", f:parsenoop }, + 0x042A: { n:"BrtBeginPCD14", f:parsenoop }, + 0x042B: { n:"BrtEndPCD14", f:parsenoop }, + 0x042C: { n:"BrtBeginExtConn14", f:parsenoop }, + 0x042D: { n:"BrtEndExtConn14", f:parsenoop }, + 0x042E: { n:"BrtBeginSlicerCacheIDs", f:parsenoop }, + 0x042F: { n:"BrtEndSlicerCacheIDs", f:parsenoop }, + 0x0430: { n:"BrtBeginSlicerCacheID", f:parsenoop }, + 0x0431: { n:"BrtEndSlicerCacheID", f:parsenoop }, + 0x0433: { n:"BrtBeginSlicerCache", f:parsenoop }, + 0x0434: { n:"BrtEndSlicerCache", f:parsenoop }, + 0x0435: { n:"BrtBeginSlicerCacheDef", f:parsenoop }, + 0x0436: { n:"BrtEndSlicerCacheDef", f:parsenoop }, + 0x0437: { n:"BrtBeginSlicersEx", f:parsenoop }, + 0x0438: { n:"BrtEndSlicersEx", f:parsenoop }, + 0x0439: { n:"BrtBeginSlicerEx", f:parsenoop }, + 0x043A: { n:"BrtEndSlicerEx", f:parsenoop }, + 0x043B: { n:"BrtBeginSlicer", f:parsenoop }, + 0x043C: { n:"BrtEndSlicer", f:parsenoop }, + 0x043D: { n:"BrtSlicerCachePivotTables", f:parsenoop }, + 0x043E: { n:"BrtBeginSlicerCacheOlapImpl", f:parsenoop }, + 0x043F: { n:"BrtEndSlicerCacheOlapImpl", f:parsenoop }, + 0x0440: { n:"BrtBeginSlicerCacheLevelsData", f:parsenoop }, + 0x0441: { n:"BrtEndSlicerCacheLevelsData", f:parsenoop }, + 0x0442: { n:"BrtBeginSlicerCacheLevelData", f:parsenoop }, + 0x0443: { n:"BrtEndSlicerCacheLevelData", f:parsenoop }, + 0x0444: { n:"BrtBeginSlicerCacheSiRanges", f:parsenoop }, + 0x0445: { n:"BrtEndSlicerCacheSiRanges", f:parsenoop }, + 0x0446: { n:"BrtBeginSlicerCacheSiRange", f:parsenoop }, + 0x0447: { n:"BrtEndSlicerCacheSiRange", f:parsenoop }, + 0x0448: { n:"BrtSlicerCacheOlapItem", f:parsenoop }, + 0x0449: { n:"BrtBeginSlicerCacheSelections", f:parsenoop }, + 0x044A: { n:"BrtSlicerCacheSelection", f:parsenoop }, + 0x044B: { n:"BrtEndSlicerCacheSelections", f:parsenoop }, + 0x044C: { n:"BrtBeginSlicerCacheNative", f:parsenoop }, + 0x044D: { n:"BrtEndSlicerCacheNative", f:parsenoop }, + 0x044E: { n:"BrtSlicerCacheNativeItem", f:parsenoop }, + 0x044F: { n:"BrtRangeProtection14", f:parsenoop }, + 0x0450: { n:"BrtRangeProtectionIso14", f:parsenoop }, + 0x0451: { n:"BrtCellIgnoreEC14", f:parsenoop }, + 0x0457: { n:"BrtList14", f:parsenoop }, + 0x0458: { n:"BrtCFIcon", f:parsenoop }, + 0x0459: { n:"BrtBeginSlicerCachesPivotCacheIDs", f:parsenoop }, + 0x045A: { n:"BrtEndSlicerCachesPivotCacheIDs", f:parsenoop }, + 0x045B: { n:"BrtBeginSlicers", f:parsenoop }, + 0x045C: { n:"BrtEndSlicers", f:parsenoop }, + 0x045D: { n:"BrtWbProp14", f:parsenoop }, + 0x045E: { n:"BrtBeginSXEdit", f:parsenoop }, + 0x045F: { n:"BrtEndSXEdit", f:parsenoop }, + 0x0460: { n:"BrtBeginSXEdits", f:parsenoop }, + 0x0461: { n:"BrtEndSXEdits", f:parsenoop }, + 0x0462: { n:"BrtBeginSXChange", f:parsenoop }, + 0x0463: { n:"BrtEndSXChange", f:parsenoop }, + 0x0464: { n:"BrtBeginSXChanges", f:parsenoop }, + 0x0465: { n:"BrtEndSXChanges", f:parsenoop }, + 0x0466: { n:"BrtSXTupleItems", f:parsenoop }, + 0x0468: { n:"BrtBeginSlicerStyle", f:parsenoop }, + 0x0469: { n:"BrtEndSlicerStyle", f:parsenoop }, + 0x046A: { n:"BrtSlicerStyleElement", f:parsenoop }, + 0x046B: { n:"BrtBeginStyleSheetExt14", f:parsenoop }, + 0x046C: { n:"BrtEndStyleSheetExt14", f:parsenoop }, + 0x046D: { n:"BrtBeginSlicerCachesPivotCacheID", f:parsenoop }, + 0x046E: { n:"BrtEndSlicerCachesPivotCacheID", f:parsenoop }, + 0x046F: { n:"BrtBeginConditionalFormattings", f:parsenoop }, + 0x0470: { n:"BrtEndConditionalFormattings", f:parsenoop }, + 0x0471: { n:"BrtBeginPCDCalcMemExt", f:parsenoop }, + 0x0472: { n:"BrtEndPCDCalcMemExt", f:parsenoop }, + 0x0473: { n:"BrtBeginPCDCalcMemsExt", f:parsenoop }, + 0x0474: { n:"BrtEndPCDCalcMemsExt", f:parsenoop }, + 0x0475: { n:"BrtPCDField14", f:parsenoop }, + 0x0476: { n:"BrtBeginSlicerStyles", f:parsenoop }, + 0x0477: { n:"BrtEndSlicerStyles", f:parsenoop }, + 0x0478: { n:"BrtBeginSlicerStyleElements", f:parsenoop }, + 0x0479: { n:"BrtEndSlicerStyleElements", f:parsenoop }, + 0x047A: { n:"BrtCFRuleExt", f:parsenoop }, + 0x047B: { n:"BrtBeginSXCondFmt14", f:parsenoop }, + 0x047C: { n:"BrtEndSXCondFmt14", f:parsenoop }, + 0x047D: { n:"BrtBeginSXCondFmts14", f:parsenoop }, + 0x047E: { n:"BrtEndSXCondFmts14", f:parsenoop }, + 0x0480: { n:"BrtBeginSortCond14", f:parsenoop }, + 0x0481: { n:"BrtEndSortCond14", f:parsenoop }, + 0x0482: { n:"BrtEndDVals14", f:parsenoop }, + 0x0483: { n:"BrtEndIconSet14", f:parsenoop }, + 0x0484: { n:"BrtEndDatabar14", f:parsenoop }, + 0x0485: { n:"BrtBeginColorScale14", f:parsenoop }, + 0x0486: { n:"BrtEndColorScale14", f:parsenoop }, + 0x0487: { n:"BrtBeginSxrules14", f:parsenoop }, + 0x0488: { n:"BrtEndSxrules14", f:parsenoop }, + 0x0489: { n:"BrtBeginPRule14", f:parsenoop }, + 0x048A: { n:"BrtEndPRule14", f:parsenoop }, + 0x048B: { n:"BrtBeginPRFilters14", f:parsenoop }, + 0x048C: { n:"BrtEndPRFilters14", f:parsenoop }, + 0x048D: { n:"BrtBeginPRFilter14", f:parsenoop }, + 0x048E: { n:"BrtEndPRFilter14", f:parsenoop }, + 0x048F: { n:"BrtBeginPRFItem14", f:parsenoop }, + 0x0490: { n:"BrtEndPRFItem14", f:parsenoop }, + 0x0491: { n:"BrtBeginCellIgnoreECs14", f:parsenoop }, + 0x0492: { n:"BrtEndCellIgnoreECs14", f:parsenoop }, + 0x0493: { n:"BrtDxf14", f:parsenoop }, + 0x0494: { n:"BrtBeginDxF14s", f:parsenoop }, + 0x0495: { n:"BrtEndDxf14s", f:parsenoop }, + 0x0499: { n:"BrtFilter14", f:parsenoop }, + 0x049A: { n:"BrtBeginCustomFilters14", f:parsenoop }, + 0x049C: { n:"BrtCustomFilter14", f:parsenoop }, + 0x049D: { n:"BrtIconFilter14", f:parsenoop }, + 0x049E: { n:"BrtPivotCacheConnectionName", f:parsenoop }, + 0x0800: { n:"BrtBeginDecoupledPivotCacheIDs", f:parsenoop }, + 0x0801: { n:"BrtEndDecoupledPivotCacheIDs", f:parsenoop }, + 0x0802: { n:"BrtDecoupledPivotCacheID", f:parsenoop }, + 0x0803: { n:"BrtBeginPivotTableRefs", f:parsenoop }, + 0x0804: { n:"BrtEndPivotTableRefs", f:parsenoop }, + 0x0805: { n:"BrtPivotTableRef", f:parsenoop }, + 0x0806: { n:"BrtSlicerCacheBookPivotTables", f:parsenoop }, + 0x0807: { n:"BrtBeginSxvcells", f:parsenoop }, + 0x0808: { n:"BrtEndSxvcells", f:parsenoop }, + 0x0809: { n:"BrtBeginSxRow", f:parsenoop }, + 0x080A: { n:"BrtEndSxRow", f:parsenoop }, + 0x080C: { n:"BrtPcdCalcMem15", f:parsenoop }, + 0x0813: { n:"BrtQsi15", f:parsenoop }, + 0x0814: { n:"BrtBeginWebExtensions", f:parsenoop }, + 0x0815: { n:"BrtEndWebExtensions", f:parsenoop }, + 0x0816: { n:"BrtWebExtension", f:parsenoop }, + 0x0817: { n:"BrtAbsPath15", f:parsenoop }, + 0x0818: { n:"BrtBeginPivotTableUISettings", f:parsenoop }, + 0x0819: { n:"BrtEndPivotTableUISettings", f:parsenoop }, + 0x081B: { n:"BrtTableSlicerCacheIDs", f:parsenoop }, + 0x081C: { n:"BrtTableSlicerCacheID", f:parsenoop }, + 0x081D: { n:"BrtBeginTableSlicerCache", f:parsenoop }, + 0x081E: { n:"BrtEndTableSlicerCache", f:parsenoop }, + 0x081F: { n:"BrtSxFilter15", f:parsenoop }, + 0x0820: { n:"BrtBeginTimelineCachePivotCacheIDs", f:parsenoop }, + 0x0821: { n:"BrtEndTimelineCachePivotCacheIDs", f:parsenoop }, + 0x0822: { n:"BrtTimelineCachePivotCacheID", f:parsenoop }, + 0x0823: { n:"BrtBeginTimelineCacheIDs", f:parsenoop }, + 0x0824: { n:"BrtEndTimelineCacheIDs", f:parsenoop }, + 0x0825: { n:"BrtBeginTimelineCacheID", f:parsenoop }, + 0x0826: { n:"BrtEndTimelineCacheID", f:parsenoop }, + 0x0827: { n:"BrtBeginTimelinesEx", f:parsenoop }, + 0x0828: { n:"BrtEndTimelinesEx", f:parsenoop }, + 0x0829: { n:"BrtBeginTimelineEx", f:parsenoop }, + 0x082A: { n:"BrtEndTimelineEx", f:parsenoop }, + 0x082B: { n:"BrtWorkBookPr15", f:parsenoop }, + 0x082C: { n:"BrtPCDH15", f:parsenoop }, + 0x082D: { n:"BrtBeginTimelineStyle", f:parsenoop }, + 0x082E: { n:"BrtEndTimelineStyle", f:parsenoop }, + 0x082F: { n:"BrtTimelineStyleElement", f:parsenoop }, + 0x0830: { n:"BrtBeginTimelineStylesheetExt15", f:parsenoop }, + 0x0831: { n:"BrtEndTimelineStylesheetExt15", f:parsenoop }, + 0x0832: { n:"BrtBeginTimelineStyles", f:parsenoop }, + 0x0833: { n:"BrtEndTimelineStyles", f:parsenoop }, + 0x0834: { n:"BrtBeginTimelineStyleElements", f:parsenoop }, + 0x0835: { n:"BrtEndTimelineStyleElements", f:parsenoop }, + 0x0836: { n:"BrtDxf15", f:parsenoop }, + 0x0837: { n:"BrtBeginDxfs15", f:parsenoop }, + 0x0838: { n:"brtEndDxfs15", f:parsenoop }, + 0x0839: { n:"BrtSlicerCacheHideItemsWithNoData", f:parsenoop }, + 0x083A: { n:"BrtBeginItemUniqueNames", f:parsenoop }, + 0x083B: { n:"BrtEndItemUniqueNames", f:parsenoop }, + 0x083C: { n:"BrtItemUniqueName", f:parsenoop }, + 0x083D: { n:"BrtBeginExtConn15", f:parsenoop }, + 0x083E: { n:"BrtEndExtConn15", f:parsenoop }, + 0x083F: { n:"BrtBeginOledbPr15", f:parsenoop }, + 0x0840: { n:"BrtEndOledbPr15", f:parsenoop }, + 0x0841: { n:"BrtBeginDataFeedPr15", f:parsenoop }, + 0x0842: { n:"BrtEndDataFeedPr15", f:parsenoop }, + 0x0843: { n:"BrtTextPr15", f:parsenoop }, + 0x0844: { n:"BrtRangePr15", f:parsenoop }, + 0x0845: { n:"BrtDbCommand15", f:parsenoop }, + 0x0846: { n:"BrtBeginDbTables15", f:parsenoop }, + 0x0847: { n:"BrtEndDbTables15", f:parsenoop }, + 0x0848: { n:"BrtDbTable15", f:parsenoop }, + 0x0849: { n:"BrtBeginDataModel", f:parsenoop }, + 0x084A: { n:"BrtEndDataModel", f:parsenoop }, + 0x084B: { n:"BrtBeginModelTables", f:parsenoop }, + 0x084C: { n:"BrtEndModelTables", f:parsenoop }, + 0x084D: { n:"BrtModelTable", f:parsenoop }, + 0x084E: { n:"BrtBeginModelRelationships", f:parsenoop }, + 0x084F: { n:"BrtEndModelRelationships", f:parsenoop }, + 0x0850: { n:"BrtModelRelationship", f:parsenoop }, + 0x0851: { n:"BrtBeginECTxtWiz15", f:parsenoop }, + 0x0852: { n:"BrtEndECTxtWiz15", f:parsenoop }, + 0x0853: { n:"BrtBeginECTWFldInfoLst15", f:parsenoop }, + 0x0854: { n:"BrtEndECTWFldInfoLst15", f:parsenoop }, + 0x0855: { n:"BrtBeginECTWFldInfo15", f:parsenoop }, + 0x0856: { n:"BrtFieldListActiveItem", f:parsenoop }, + 0x0857: { n:"BrtPivotCacheIdVersion", f:parsenoop }, + 0x0858: { n:"BrtSXDI15", f:parsenoop }, + 0xFFFF: { n:"", f:parsenoop } +}; + +var evert_RE = evert_key(XLSBRecordEnum, 'n'); + +/* [MS-XLS] 2.3 Record Enumeration */ +var XLSRecordEnum = { + 0x0003: { n:"BIFF2NUM", f:parse_BIFF2NUM }, + 0x0004: { n:"BIFF2STR", f:parse_BIFF2STR }, + 0x0006: { n:"Formula", f:parse_Formula }, + 0x0009: { n:'BOF', f:parse_BOF }, + 0x000a: { n:'EOF', f:parse_EOF }, + 0x000c: { n:"CalcCount", f:parse_CalcCount }, + 0x000d: { n:"CalcMode", f:parse_CalcMode }, + 0x000e: { n:"CalcPrecision", f:parse_CalcPrecision }, + 0x000f: { n:"CalcRefMode", f:parse_CalcRefMode }, + 0x0010: { n:"CalcDelta", f:parse_CalcDelta }, + 0x0011: { n:"CalcIter", f:parse_CalcIter }, + 0x0012: { n:"Protect", f:parse_Protect }, + 0x0013: { n:"Password", f:parse_Password }, + 0x0014: { n:"Header", f:parse_Header }, + 0x0015: { n:"Footer", f:parse_Footer }, + 0x0017: { n:"ExternSheet", f:parse_ExternSheet }, + 0x0018: { n:"Lbl", f:parse_Lbl }, + 0x0019: { n:"WinProtect", f:parse_WinProtect }, + 0x001a: { n:"VerticalPageBreaks", f:parse_VerticalPageBreaks }, + 0x001b: { n:"HorizontalPageBreaks", f:parse_HorizontalPageBreaks }, + 0x001c: { n:"Note", f:parse_Note }, + 0x001d: { n:"Selection", f:parse_Selection }, + 0x0022: { n:"Date1904", f:parse_Date1904 }, + 0x0023: { n:"ExternName", f:parse_ExternName }, + 0x0026: { n:"LeftMargin", f:parse_LeftMargin }, + 0x0027: { n:"RightMargin", f:parse_RightMargin }, + 0x0028: { n:"TopMargin", f:parse_TopMargin }, + 0x0029: { n:"BottomMargin", f:parse_BottomMargin }, + 0x002a: { n:"PrintRowCol", f:parse_PrintRowCol }, + 0x002b: { n:"PrintGrid", f:parse_PrintGrid }, + 0x002f: { n:"FilePass", f:parse_FilePass }, + 0x0031: { n:"Font", f:parse_Font }, + 0x0033: { n:"PrintSize", f:parse_PrintSize }, + 0x003c: { n:"Continue", f:parse_Continue }, + 0x003d: { n:"Window1", f:parse_Window1 }, + 0x0040: { n:"Backup", f:parse_Backup }, + 0x0041: { n:"Pane", f:parse_Pane }, + 0x0042: { n:'CodePage', f:parse_CodePage }, + 0x004d: { n:"Pls", f:parse_Pls }, + 0x0050: { n:"DCon", f:parse_DCon }, + 0x0051: { n:"DConRef", f:parse_DConRef }, + 0x0052: { n:"DConName", f:parse_DConName }, + 0x0055: { n:"DefColWidth", f:parse_DefColWidth }, + 0x0059: { n:"XCT", f:parse_XCT }, + 0x005a: { n:"CRN", f:parse_CRN }, + 0x005b: { n:"FileSharing", f:parse_FileSharing }, + 0x005c: { n:'WriteAccess', f:parse_WriteAccess }, + 0x005d: { n:"Obj", f:parse_Obj }, + 0x005e: { n:"Uncalced", f:parse_Uncalced }, + 0x005f: { n:"CalcSaveRecalc", f:parse_CalcSaveRecalc }, + 0x0060: { n:"Template", f:parse_Template }, + 0x0061: { n:"Intl", f:parse_Intl }, + 0x0063: { n:"ObjProtect", f:parse_ObjProtect }, + 0x007d: { n:"ColInfo", f:parse_ColInfo }, + 0x0080: { n:"Guts", f:parse_Guts }, + 0x0081: { n:"WsBool", f:parse_WsBool }, + 0x0082: { n:"GridSet", f:parse_GridSet }, + 0x0083: { n:"HCenter", f:parse_HCenter }, + 0x0084: { n:"VCenter", f:parse_VCenter }, + 0x0085: { n:'BoundSheet8', f:parse_BoundSheet8 }, + 0x0086: { n:"WriteProtect", f:parse_WriteProtect }, + 0x008c: { n:"Country", f:parse_Country }, + 0x008d: { n:"HideObj", f:parse_HideObj }, + 0x0090: { n:"Sort", f:parse_Sort }, + 0x0092: { n:"Palette", f:parse_Palette }, + 0x0097: { n:"Sync", f:parse_Sync }, + 0x0098: { n:"LPr", f:parse_LPr }, + 0x0099: { n:"DxGCol", f:parse_DxGCol }, + 0x009a: { n:"FnGroupName", f:parse_FnGroupName }, + 0x009b: { n:"FilterMode", f:parse_FilterMode }, + 0x009c: { n:"BuiltInFnGroupCount", f:parse_BuiltInFnGroupCount }, + 0x009d: { n:"AutoFilterInfo", f:parse_AutoFilterInfo }, + 0x009e: { n:"AutoFilter", f:parse_AutoFilter }, + 0x00a0: { n:"Scl", f:parse_Scl }, + 0x00a1: { n:"Setup", f:parse_Setup }, + 0x00ae: { n:"ScenMan", f:parse_ScenMan }, + 0x00af: { n:"SCENARIO", f:parse_SCENARIO }, + 0x00b0: { n:"SxView", f:parse_SxView }, + 0x00b1: { n:"Sxvd", f:parse_Sxvd }, + 0x00b2: { n:"SXVI", f:parse_SXVI }, + 0x00b4: { n:"SxIvd", f:parse_SxIvd }, + 0x00b5: { n:"SXLI", f:parse_SXLI }, + 0x00b6: { n:"SXPI", f:parse_SXPI }, + 0x00b8: { n:"DocRoute", f:parse_DocRoute }, + 0x00b9: { n:"RecipName", f:parse_RecipName }, + 0x00bd: { n:"MulRk", f:parse_MulRk }, + 0x00be: { n:"MulBlank", f:parse_MulBlank }, + 0x00c1: { n:'Mms', f:parse_Mms }, + 0x00c5: { n:"SXDI", f:parse_SXDI }, + 0x00c6: { n:"SXDB", f:parse_SXDB }, + 0x00c7: { n:"SXFDB", f:parse_SXFDB }, + 0x00c8: { n:"SXDBB", f:parse_SXDBB }, + 0x00c9: { n:"SXNum", f:parse_SXNum }, + 0x00ca: { n:"SxBool", f:parse_SxBool }, + 0x00cb: { n:"SxErr", f:parse_SxErr }, + 0x00cc: { n:"SXInt", f:parse_SXInt }, + 0x00cd: { n:"SXString", f:parse_SXString }, + 0x00ce: { n:"SXDtr", f:parse_SXDtr }, + 0x00cf: { n:"SxNil", f:parse_SxNil }, + 0x00d0: { n:"SXTbl", f:parse_SXTbl }, + 0x00d1: { n:"SXTBRGIITM", f:parse_SXTBRGIITM }, + 0x00d2: { n:"SxTbpg", f:parse_SxTbpg }, + 0x00d3: { n:"ObProj", f:parse_ObProj }, + 0x00d5: { n:"SXStreamID", f:parse_SXStreamID }, + 0x00d7: { n:"DBCell", f:parse_DBCell }, + 0x00d8: { n:"SXRng", f:parse_SXRng }, + 0x00d9: { n:"SxIsxoper", f:parse_SxIsxoper }, + 0x00da: { n:"BookBool", f:parse_BookBool }, + 0x00dc: { n:"DbOrParamQry", f:parse_DbOrParamQry }, + 0x00dd: { n:"ScenarioProtect", f:parse_ScenarioProtect }, + 0x00de: { n:"OleObjectSize", f:parse_OleObjectSize }, + 0x00e0: { n:"XF", f:parse_XF }, + 0x00e1: { n:'InterfaceHdr', f:parse_InterfaceHdr }, + 0x00e2: { n:'InterfaceEnd', f:parse_InterfaceEnd }, + 0x00e3: { n:"SXVS", f:parse_SXVS }, + 0x00e5: { n:"MergeCells", f:parse_MergeCells }, + 0x00e9: { n:"BkHim", f:parse_BkHim }, + 0x00eb: { n:"MsoDrawingGroup", f:parse_MsoDrawingGroup }, + 0x00ec: { n:"MsoDrawing", f:parse_MsoDrawing }, + 0x00ed: { n:"MsoDrawingSelection", f:parse_MsoDrawingSelection }, + 0x00ef: { n:"PhoneticInfo", f:parse_PhoneticInfo }, + 0x00f0: { n:"SxRule", f:parse_SxRule }, + 0x00f1: { n:"SXEx", f:parse_SXEx }, + 0x00f2: { n:"SxFilt", f:parse_SxFilt }, + 0x00f4: { n:"SxDXF", f:parse_SxDXF }, + 0x00f5: { n:"SxItm", f:parse_SxItm }, + 0x00f6: { n:"SxName", f:parse_SxName }, + 0x00f7: { n:"SxSelect", f:parse_SxSelect }, + 0x00f8: { n:"SXPair", f:parse_SXPair }, + 0x00f9: { n:"SxFmla", f:parse_SxFmla }, + 0x00fb: { n:"SxFormat", f:parse_SxFormat }, + 0x00fc: { n:"SST", f:parse_SST }, + 0x00fd: { n:"LabelSst", f:parse_LabelSst }, + 0x00ff: { n:"ExtSST", f:parse_ExtSST }, + 0x0100: { n:"SXVDEx", f:parse_SXVDEx }, + 0x0103: { n:"SXFormula", f:parse_SXFormula }, + 0x0122: { n:"SXDBEx", f:parse_SXDBEx }, + 0x0137: { n:"RRDInsDel", f:parse_RRDInsDel }, + 0x0138: { n:"RRDHead", f:parse_RRDHead }, + 0x013b: { n:"RRDChgCell", f:parse_RRDChgCell }, + 0x013d: { n:"RRTabId", f:parse_RRTabId }, + 0x013e: { n:"RRDRenSheet", f:parse_RRDRenSheet }, + 0x013f: { n:"RRSort", f:parse_RRSort }, + 0x0140: { n:"RRDMove", f:parse_RRDMove }, + 0x014a: { n:"RRFormat", f:parse_RRFormat }, + 0x014b: { n:"RRAutoFmt", f:parse_RRAutoFmt }, + 0x014d: { n:"RRInsertSh", f:parse_RRInsertSh }, + 0x014e: { n:"RRDMoveBegin", f:parse_RRDMoveBegin }, + 0x014f: { n:"RRDMoveEnd", f:parse_RRDMoveEnd }, + 0x0150: { n:"RRDInsDelBegin", f:parse_RRDInsDelBegin }, + 0x0151: { n:"RRDInsDelEnd", f:parse_RRDInsDelEnd }, + 0x0152: { n:"RRDConflict", f:parse_RRDConflict }, + 0x0153: { n:"RRDDefName", f:parse_RRDDefName }, + 0x0154: { n:"RRDRstEtxp", f:parse_RRDRstEtxp }, + 0x015f: { n:"LRng", f:parse_LRng }, + 0x0160: { n:"UsesELFs", f:parse_UsesELFs }, + 0x0161: { n:"DSF", f:parse_DSF }, + 0x0191: { n:"CUsr", f:parse_CUsr }, + 0x0192: { n:"CbUsr", f:parse_CbUsr }, + 0x0193: { n:"UsrInfo", f:parse_UsrInfo }, + 0x0194: { n:"UsrExcl", f:parse_UsrExcl }, + 0x0195: { n:"FileLock", f:parse_FileLock }, + 0x0196: { n:"RRDInfo", f:parse_RRDInfo }, + 0x0197: { n:"BCUsrs", f:parse_BCUsrs }, + 0x0198: { n:"UsrChk", f:parse_UsrChk }, + 0x01a9: { n:"UserBView", f:parse_UserBView }, + 0x01aa: { n:"UserSViewBegin", f:parse_UserSViewBegin }, + 0x01ab: { n:"UserSViewEnd", f:parse_UserSViewEnd }, + 0x01ac: { n:"RRDUserView", f:parse_RRDUserView }, + 0x01ad: { n:"Qsi", f:parse_Qsi }, + 0x01ae: { n:"SupBook", f:parse_SupBook }, + 0x01af: { n:"Prot4Rev", f:parse_Prot4Rev }, + 0x01b0: { n:"CondFmt", f:parse_CondFmt }, + 0x01b1: { n:"CF", f:parse_CF }, + 0x01b2: { n:"DVal", f:parse_DVal }, + 0x01b5: { n:"DConBin", f:parse_DConBin }, + 0x01b6: { n:"TxO", f:parse_TxO }, + 0x01b7: { n:"RefreshAll", f:parse_RefreshAll }, + 0x01b8: { n:"HLink", f:parse_HLink }, + 0x01b9: { n:"Lel", f:parse_Lel }, + 0x01ba: { n:"CodeName", f:parse_XLSCodeName }, + 0x01bb: { n:"SXFDBType", f:parse_SXFDBType }, + 0x01bc: { n:"Prot4RevPass", f:parse_Prot4RevPass }, + 0x01bd: { n:"ObNoMacros", f:parse_ObNoMacros }, + 0x01be: { n:"Dv", f:parse_Dv }, + 0x01c0: { n:"Excel9File", f:parse_Excel9File }, + 0x01c1: { n:"RecalcId", f:parse_RecalcId, r:2}, + 0x01c2: { n:"EntExU2", f:parse_EntExU2 }, + 0x0200: { n:"Dimensions", f:parse_Dimensions }, + 0x0201: { n:"Blank", f:parse_Blank }, + 0x0203: { n:"Number", f:parse_Number }, + 0x0204: { n:"Label", f:parse_Label }, + 0x0205: { n:"BoolErr", f:parse_BoolErr }, + 0x0207: { n:"String", f:parse_String }, + 0x0208: { n:'Row', f:parse_Row }, + 0x020b: { n:"Index", f:parse_Index }, + 0x0221: { n:"Array", f:parse_Array }, + 0x0225: { n:"DefaultRowHeight", f:parse_DefaultRowHeight }, + 0x0236: { n:"Table", f:parse_Table }, + 0x023e: { n:"Window2", f:parse_Window2 }, + 0x027e: { n:"RK", f:parse_RK }, + 0x0293: { n:"Style", f:parse_Style }, + 0x0418: { n:"BigName", f:parse_BigName }, + 0x041e: { n:"Format", f:parse_Format }, + 0x043c: { n:"ContinueBigName", f:parse_ContinueBigName }, + 0x04bc: { n:"ShrFmla", f:parse_ShrFmla }, + 0x0800: { n:"HLinkTooltip", f:parse_HLinkTooltip }, + 0x0801: { n:"WebPub", f:parse_WebPub }, + 0x0802: { n:"QsiSXTag", f:parse_QsiSXTag }, + 0x0803: { n:"DBQueryExt", f:parse_DBQueryExt }, + 0x0804: { n:"ExtString", f:parse_ExtString }, + 0x0805: { n:"TxtQry", f:parse_TxtQry }, + 0x0806: { n:"Qsir", f:parse_Qsir }, + 0x0807: { n:"Qsif", f:parse_Qsif }, + 0x0808: { n:"RRDTQSIF", f:parse_RRDTQSIF }, + 0x0809: { n:'BOF', f:parse_BOF }, + 0x080a: { n:"OleDbConn", f:parse_OleDbConn }, + 0x080b: { n:"WOpt", f:parse_WOpt }, + 0x080c: { n:"SXViewEx", f:parse_SXViewEx }, + 0x080d: { n:"SXTH", f:parse_SXTH }, + 0x080e: { n:"SXPIEx", f:parse_SXPIEx }, + 0x080f: { n:"SXVDTEx", f:parse_SXVDTEx }, + 0x0810: { n:"SXViewEx9", f:parse_SXViewEx9 }, + 0x0812: { n:"ContinueFrt", f:parse_ContinueFrt }, + 0x0813: { n:"RealTimeData", f:parse_RealTimeData }, + 0x0850: { n:"ChartFrtInfo", f:parse_ChartFrtInfo }, + 0x0851: { n:"FrtWrapper", f:parse_FrtWrapper }, + 0x0852: { n:"StartBlock", f:parse_StartBlock }, + 0x0853: { n:"EndBlock", f:parse_EndBlock }, + 0x0854: { n:"StartObject", f:parse_StartObject }, + 0x0855: { n:"EndObject", f:parse_EndObject }, + 0x0856: { n:"CatLab", f:parse_CatLab }, + 0x0857: { n:"YMult", f:parse_YMult }, + 0x0858: { n:"SXViewLink", f:parse_SXViewLink }, + 0x0859: { n:"PivotChartBits", f:parse_PivotChartBits }, + 0x085a: { n:"FrtFontList", f:parse_FrtFontList }, + 0x0862: { n:"SheetExt", f:parse_SheetExt }, + 0x0863: { n:"BookExt", f:parse_BookExt, r:12}, + 0x0864: { n:"SXAddl", f:parse_SXAddl }, + 0x0865: { n:"CrErr", f:parse_CrErr }, + 0x0866: { n:"HFPicture", f:parse_HFPicture }, + 0x0867: { n:'FeatHdr', f:parse_FeatHdr }, + 0x0868: { n:"Feat", f:parse_Feat }, + 0x086a: { n:"DataLabExt", f:parse_DataLabExt }, + 0x086b: { n:"DataLabExtContents", f:parse_DataLabExtContents }, + 0x086c: { n:"CellWatch", f:parse_CellWatch }, + 0x0871: { n:"FeatHdr11", f:parse_FeatHdr11 }, + 0x0872: { n:"Feature11", f:parse_Feature11 }, + 0x0874: { n:"DropDownObjIds", f:parse_DropDownObjIds }, + 0x0875: { n:"ContinueFrt11", f:parse_ContinueFrt11 }, + 0x0876: { n:"DConn", f:parse_DConn }, + 0x0877: { n:"List12", f:parse_List12 }, + 0x0878: { n:"Feature12", f:parse_Feature12 }, + 0x0879: { n:"CondFmt12", f:parse_CondFmt12 }, + 0x087a: { n:"CF12", f:parse_CF12 }, + 0x087b: { n:"CFEx", f:parse_CFEx }, + 0x087c: { n:"XFCRC", f:parse_XFCRC, r:12 }, + 0x087d: { n:"XFExt", f:parse_XFExt, r:12 }, + 0x087e: { n:"AutoFilter12", f:parse_AutoFilter12 }, + 0x087f: { n:"ContinueFrt12", f:parse_ContinueFrt12 }, + 0x0884: { n:"MDTInfo", f:parse_MDTInfo }, + 0x0885: { n:"MDXStr", f:parse_MDXStr }, + 0x0886: { n:"MDXTuple", f:parse_MDXTuple }, + 0x0887: { n:"MDXSet", f:parse_MDXSet }, + 0x0888: { n:"MDXProp", f:parse_MDXProp }, + 0x0889: { n:"MDXKPI", f:parse_MDXKPI }, + 0x088a: { n:"MDB", f:parse_MDB }, + 0x088b: { n:"PLV", f:parse_PLV }, + 0x088c: { n:"Compat12", f:parse_Compat12, r:12 }, + 0x088d: { n:"DXF", f:parse_DXF }, + 0x088e: { n:"TableStyles", f:parse_TableStyles, r:12 }, + 0x088f: { n:"TableStyle", f:parse_TableStyle }, + 0x0890: { n:"TableStyleElement", f:parse_TableStyleElement }, + 0x0892: { n:"StyleExt", f:parse_StyleExt }, + 0x0893: { n:"NamePublish", f:parse_NamePublish }, + 0x0894: { n:"NameCmt", f:parse_NameCmt }, + 0x0895: { n:"SortData", f:parse_SortData }, + 0x0896: { n:"Theme", f:parse_Theme, r:12 }, + 0x0897: { n:"GUIDTypeLib", f:parse_GUIDTypeLib }, + 0x0898: { n:"FnGrp12", f:parse_FnGrp12 }, + 0x0899: { n:"NameFnGrp12", f:parse_NameFnGrp12 }, + 0x089a: { n:"MTRSettings", f:parse_MTRSettings, r:12 }, + 0x089b: { n:"CompressPictures", f:parse_CompressPictures }, + 0x089c: { n:"HeaderFooter", f:parse_HeaderFooter }, + 0x089d: { n:"CrtLayout12", f:parse_CrtLayout12 }, + 0x089e: { n:"CrtMlFrt", f:parse_CrtMlFrt }, + 0x089f: { n:"CrtMlFrtContinue", f:parse_CrtMlFrtContinue }, + 0x08a3: { n:"ForceFullCalculation", f:parse_ForceFullCalculation }, + 0x08a4: { n:"ShapePropsStream", f:parse_ShapePropsStream }, + 0x08a5: { n:"TextPropsStream", f:parse_TextPropsStream }, + 0x08a6: { n:"RichTextStream", f:parse_RichTextStream }, + 0x08a7: { n:"CrtLayout12A", f:parse_CrtLayout12A }, + 0x1001: { n:"Units", f:parse_Units }, + 0x1002: { n:"Chart", f:parse_Chart }, + 0x1003: { n:"Series", f:parse_Series }, + 0x1006: { n:"DataFormat", f:parse_DataFormat }, + 0x1007: { n:"LineFormat", f:parse_LineFormat }, + 0x1009: { n:"MarkerFormat", f:parse_MarkerFormat }, + 0x100a: { n:"AreaFormat", f:parse_AreaFormat }, + 0x100b: { n:"PieFormat", f:parse_PieFormat }, + 0x100c: { n:"AttachedLabel", f:parse_AttachedLabel }, + 0x100d: { n:"SeriesText", f:parse_SeriesText }, + 0x1014: { n:"ChartFormat", f:parse_ChartFormat }, + 0x1015: { n:"Legend", f:parse_Legend }, + 0x1016: { n:"SeriesList", f:parse_SeriesList }, + 0x1017: { n:"Bar", f:parse_Bar }, + 0x1018: { n:"Line", f:parse_Line }, + 0x1019: { n:"Pie", f:parse_Pie }, + 0x101a: { n:"Area", f:parse_Area }, + 0x101b: { n:"Scatter", f:parse_Scatter }, + 0x101c: { n:"CrtLine", f:parse_CrtLine }, + 0x101d: { n:"Axis", f:parse_Axis }, + 0x101e: { n:"Tick", f:parse_Tick }, + 0x101f: { n:"ValueRange", f:parse_ValueRange }, + 0x1020: { n:"CatSerRange", f:parse_CatSerRange }, + 0x1021: { n:"AxisLine", f:parse_AxisLine }, + 0x1022: { n:"CrtLink", f:parse_CrtLink }, + 0x1024: { n:"DefaultText", f:parse_DefaultText }, + 0x1025: { n:"Text", f:parse_Text }, + 0x1026: { n:"FontX", f:parse_FontX }, + 0x1027: { n:"ObjectLink", f:parse_ObjectLink }, + 0x1032: { n:"Frame", f:parse_Frame }, + 0x1033: { n:"Begin", f:parse_Begin }, + 0x1034: { n:"End", f:parse_End }, + 0x1035: { n:"PlotArea", f:parse_PlotArea }, + 0x103a: { n:"Chart3d", f:parse_Chart3d }, + 0x103c: { n:"PicF", f:parse_PicF }, + 0x103d: { n:"DropBar", f:parse_DropBar }, + 0x103e: { n:"Radar", f:parse_Radar }, + 0x103f: { n:"Surf", f:parse_Surf }, + 0x1040: { n:"RadarArea", f:parse_RadarArea }, + 0x1041: { n:"AxisParent", f:parse_AxisParent }, + 0x1043: { n:"LegendException", f:parse_LegendException }, + 0x1044: { n:"ShtProps", f:parse_ShtProps }, + 0x1045: { n:"SerToCrt", f:parse_SerToCrt }, + 0x1046: { n:"AxesUsed", f:parse_AxesUsed }, + 0x1048: { n:"SBaseRef", f:parse_SBaseRef }, + 0x104a: { n:"SerParent", f:parse_SerParent }, + 0x104b: { n:"SerAuxTrend", f:parse_SerAuxTrend }, + 0x104e: { n:"IFmtRecord", f:parse_IFmtRecord }, + 0x104f: { n:"Pos", f:parse_Pos }, + 0x1050: { n:"AlRuns", f:parse_AlRuns }, + 0x1051: { n:"BRAI", f:parse_BRAI }, + 0x105b: { n:"SerAuxErrBar", f:parse_SerAuxErrBar }, + 0x105c: { n:"ClrtClient", f:parse_ClrtClient }, + 0x105d: { n:"SerFmt", f:parse_SerFmt }, + 0x105f: { n:"Chart3DBarShape", f:parse_Chart3DBarShape }, + 0x1060: { n:"Fbi", f:parse_Fbi }, + 0x1061: { n:"BopPop", f:parse_BopPop }, + 0x1062: { n:"AxcExt", f:parse_AxcExt }, + 0x1063: { n:"Dat", f:parse_Dat }, + 0x1064: { n:"PlotGrowth", f:parse_PlotGrowth }, + 0x1065: { n:"SIIndex", f:parse_SIIndex }, + 0x1066: { n:"GelFrame", f:parse_GelFrame }, + 0x1067: { n:"BopPopCustom", f:parse_BopPopCustom }, + 0x1068: { n:"Fbi2", f:parse_Fbi2 }, + + /* These are specified in an older version of the spec */ + 0x0016: { n:"ExternCount", f:parsenoop }, + 0x007e: { n:"RK", f:parsenoop }, /* Not necessarily same as 0x027e */ + 0x007f: { n:"ImData", f:parsenoop }, + 0x0087: { n:"Addin", f:parsenoop }, + 0x0088: { n:"Edg", f:parsenoop }, + 0x0089: { n:"Pub", f:parsenoop }, + 0x0091: { n:"Sub", f:parsenoop }, + 0x0094: { n:"LHRecord", f:parsenoop }, + 0x0095: { n:"LHNGraph", f:parsenoop }, + 0x0096: { n:"Sound", f:parsenoop }, + 0x00a9: { n:"CoordList", f:parsenoop }, + 0x00ab: { n:"GCW", f:parsenoop }, + 0x00bc: { n:"ShrFmla", f:parsenoop }, /* Not necessarily same as 0x04bc */ + 0x00c2: { n:"AddMenu", f:parsenoop }, + 0x00c3: { n:"DelMenu", f:parsenoop }, + 0x00d6: { n:"RString", f:parsenoop }, + 0x00df: { n:"UDDesc", f:parsenoop }, + 0x00ea: { n:"TabIdConf", f:parsenoop }, + 0x0162: { n:"XL5Modify", f:parsenoop }, + 0x01a5: { n:"FileSharing2", f:parsenoop }, + 0x0218: { n:"Name", f:parsenoop }, + 0x0223: { n:"ExternName", f:parse_ExternName }, + 0x0231: { n:"Font", f:parsenoop }, + 0x0406: { n:"Formula", f:parse_Formula }, + 0x086d: { n:"FeatInfo", f:parsenoop }, + 0x0873: { n:"FeatInfo11", f:parsenoop }, + 0x0881: { n:"SXAddl12", f:parsenoop }, + 0x08c0: { n:"AutoWebPub", f:parsenoop }, + 0x08c1: { n:"ListObj", f:parsenoop }, + 0x08c2: { n:"ListField", f:parsenoop }, + 0x08c3: { n:"ListDV", f:parsenoop }, + 0x08c4: { n:"ListCondFmt", f:parsenoop }, + 0x08c5: { n:"ListCF", f:parsenoop }, + 0x08c6: { n:"FMQry", f:parsenoop }, + 0x08c7: { n:"FMSQry", f:parsenoop }, + 0x08c8: { n:"PLV", f:parsenoop }, /* supposedly PLV for Excel 11 */ + 0x08c9: { n:"LnExt", f:parsenoop }, + 0x08ca: { n:"MkrExt", f:parsenoop }, + 0x08cb: { n:"CrtCoopt", f:parsenoop }, + + 0x0000: {} +}; + + +/* Helper function to call out to ODS parser */ +function parse_ods(zip, opts) { + if(typeof module !== "undefined" && typeof require !== 'undefined' && typeof ODS === 'undefined') ODS = require('./od' + 's'); + if(typeof ODS === 'undefined' || !ODS.parse_ods) throw new Error("Unsupported ODS"); + return ODS.parse_ods(zip, opts); +} +function fix_opts_func(defaults) { + return function fix_opts(opts) { + for(var i = 0; i != defaults.length; ++i) { + var d = defaults[i]; + if(opts[d[0]] === undefined) opts[d[0]] = d[1]; + if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]); + } + }; +} + +var fix_read_opts = fix_opts_func([ + ['cellNF', false], /* emit cell number format string as .z */ + ['cellHTML', true], /* emit html string as .h */ + ['cellFormula', true], /* emit formulae as .f */ + ['cellStyles', false], /* emits style/theme as .s */ + ['cellDates', false], /* emit date cells with type `d` */ + + ['sheetStubs', false], /* emit empty cells */ + ['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */ + + ['bookDeps', false], /* parse calculation chains */ + ['bookSheets', false], /* only try to get sheet names (no Sheets) */ + ['bookProps', false], /* only try to get properties (no Sheets) */ + ['bookFiles', false], /* include raw file structure (keys, files, cfb) */ + ['bookVBA', false], /* include vba raw data (vbaraw) */ + + ['password',''], /* password */ + ['WTF', false] /* WTF mode (throws errors) */ +]); + + +var fix_write_opts = fix_opts_func([ + ['cellDates', false], /* write date cells with type `d` */ + + ['bookSST', false], /* Generate Shared String Table */ + + ['bookType', 'xlsx'], /* Type of workbook (xlsx/m/b) */ + + ['WTF', false] /* WTF mode (throws errors) */ +]); +function safe_parse_wbrels(wbrels, sheets) { + if(!wbrels) return 0; + try { + wbrels = sheets.map(function pwbr(w) { return [w.name, wbrels['!id'][w.id].Target]; }); + } catch(e) { return null; } + return !wbrels || wbrels.length === 0 ? null : wbrels; +} + +function safe_parse_ws(zip, path, relsPath, sheet, sheetRels, sheets, opts) { + try { + sheetRels[sheet]=parse_rels(getzipdata(zip, relsPath, true), path); + sheets[sheet]=parse_ws(getzipdata(zip, path),path,opts,sheetRels[sheet]); + } catch(e) { if(opts.WTF) throw e; } +} + +var nodirs = function nodirs(x){return x.substr(-1) != '/';}; +function parse_zip(zip, opts) { + make_ssf(SSF); + opts = opts || {}; + fix_read_opts(opts); + reset_cp(); + + /* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */ + if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts); + + var entries = keys(zip.files).filter(nodirs).sort(); + var dir = parse_ct(getzipdata(zip, '[Content_Types].xml'), opts); + var xlsb = false; + var sheets, binname; + if(dir.workbooks.length === 0) { + binname = "xl/workbook.xml"; + if(getzipdata(zip,binname, true)) dir.workbooks.push(binname); + } + if(dir.workbooks.length === 0) { + binname = "xl/workbook.bin"; + if(!getzipfile(zip,binname,true)) throw new Error("Could not find workbook"); + dir.workbooks.push(binname); + xlsb = true; + } + if(dir.workbooks[0].substr(-3) == "bin") xlsb = true; + if(xlsb) set_cp(1200); + + if(!opts.bookSheets && !opts.bookProps) { + strs = []; + if(dir.sst) strs=parse_sst(getzipdata(zip, dir.sst.replace(/^\//,'')), dir.sst, opts); + + styles = {}; + if(dir.style) styles = parse_sty(getzipdata(zip, dir.style.replace(/^\//,'')),dir.style, opts); + + themes = {}; + if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipdata(zip, dir.themes[0].replace(/^\//,''), true),dir.themes[0], opts); + } + + var wb = parse_wb(getzipdata(zip, dir.workbooks[0].replace(/^\//,'')), dir.workbooks[0], opts); + + var props = {}, propdata = ""; + + if(dir.coreprops.length !== 0) { + propdata = getzipdata(zip, dir.coreprops[0].replace(/^\//,''), true); + if(propdata) props = parse_core_props(propdata); + if(dir.extprops.length !== 0) { + propdata = getzipdata(zip, dir.extprops[0].replace(/^\//,''), true); + if(propdata) parse_ext_props(propdata, props); + } + } + + var custprops = {}; + if(!opts.bookSheets || opts.bookProps) { + if (dir.custprops.length !== 0) { + propdata = getzipdata(zip, dir.custprops[0].replace(/^\//,''), true); + if(propdata) custprops = parse_cust_props(propdata, opts); + } + } + + var out = {}; + if(opts.bookSheets || opts.bookProps) { + if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames; + else if(wb.Sheets) sheets = wb.Sheets.map(function pluck(x){ return x.name; }); + if(opts.bookProps) { out.Props = props; out.Custprops = custprops; } + if(typeof sheets !== 'undefined') out.SheetNames = sheets; + if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out; + } + sheets = {}; + + var deps = {}; + if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, dir.calcchain.replace(/^\//,'')),dir.calcchain,opts); + + var i=0; + var sheetRels = {}; + var path, relsPath; + if(!props.Worksheets) { + var wbsheets = wb.Sheets; + props.Worksheets = wbsheets.length; + props.SheetNames = []; + for(var j = 0; j != wbsheets.length; ++j) { + props.SheetNames[j] = wbsheets[j].name; + } + } + + var wbext = xlsb ? "bin" : "xml"; + var wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels'; + var wbrels = parse_rels(getzipdata(zip, wbrelsfile, true), wbrelsfile); + if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets); + /* Numbers iOS hack */ + var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0; + for(i = 0; i != props.Worksheets; ++i) { + if(wbrels) path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, ""); + else { + path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext; + path = path.replace(/sheet0\./,"sheet."); + } + relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels"); + safe_parse_ws(zip, path, relsPath, props.SheetNames[i], sheetRels, sheets, opts); + } + + if(dir.comments) parse_comments(zip, dir.comments, sheets, sheetRels, opts); + + out = { + Directory: dir, + Workbook: wb, + Props: props, + Custprops: custprops, + Deps: deps, + Sheets: sheets, + SheetNames: props.SheetNames, + Strings: strs, + Styles: styles, + Themes: themes, + SSF: SSF.get_table() + }; + if(opts.bookFiles) { + out.keys = entries; + out.files = zip.files; + } + if(opts.bookVBA) { + if(dir.vba.length > 0) out.vbaraw = getzipdata(zip,dir.vba[0],true); + else if(dir.defaults.bin === 'application/vnd.ms-office.vbaProject') out.vbaraw = getzipdata(zip,'xl/vbaProject.bin',true); + } + return out; +} +function add_rels(rels, rId, f, type, relobj) { + if(!relobj) relobj = {}; + if(!rels['!id']) rels['!id'] = {}; + relobj.Id = 'rId' + rId; + relobj.Type = type; + relobj.Target = f; + if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId); + rels['!id'][relobj.Id] = relobj; + rels[('/' + relobj.Target).replace("//","/")] = relobj; +} + +function write_zip(wb, opts) { + if(wb && !wb.SSF) { + wb.SSF = SSF.get_table(); + } + if(wb && wb.SSF) { + make_ssf(SSF); SSF.load_table(wb.SSF); + opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0; + } + opts.rels = {}; opts.wbrels = {}; + opts.Strings = []; opts.Strings.Count = 0; opts.Strings.Unique = 0; + var wbext = opts.bookType == "xlsb" ? "bin" : "xml"; + var ct = { workbooks: [], sheets: [], calcchains: [], themes: [], styles: [], + coreprops: [], extprops: [], custprops: [], strs:[], comments: [], vba: [], + TODO:[], rels:[], xmlns: "" }; + fix_write_opts(opts = opts || {}); + var zip = new jszip(); + var f = "", rId = 0; + + opts.cellXfs = []; + get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}}); + + f = "docProps/core.xml"; + zip.file(f, write_core_props(wb.Props, opts)); + ct.coreprops.push(f); + add_rels(opts.rels, 2, f, RELS.CORE_PROPS); + + f = "docProps/app.xml"; + if(!wb.Props) wb.Props = {}; + wb.Props.SheetNames = wb.SheetNames; + wb.Props.Worksheets = wb.SheetNames.length; + zip.file(f, write_ext_props(wb.Props, opts)); + ct.extprops.push(f); + add_rels(opts.rels, 3, f, RELS.EXT_PROPS); + + if(wb.Custprops !== wb.Props && keys(wb.Custprops||{}).length > 0) { + f = "docProps/custom.xml"; + zip.file(f, write_cust_props(wb.Custprops, opts)); + ct.custprops.push(f); + add_rels(opts.rels, 4, f, RELS.CUST_PROPS); + } + + f = "xl/workbook." + wbext; + zip.file(f, write_wb(wb, f, opts)); + ct.workbooks.push(f); + add_rels(opts.rels, 1, f, RELS.WB); + + for(rId=1;rId <= wb.SheetNames.length; ++rId) { + f = "xl/worksheets/sheet" + rId + "." + wbext; + zip.file(f, write_ws(rId-1, f, opts, wb)); + ct.sheets.push(f); + add_rels(opts.wbrels, rId, "worksheets/sheet" + rId + "." + wbext, RELS.WS); + } + + if(opts.Strings != null && opts.Strings.length > 0) { + f = "xl/sharedStrings." + wbext; + zip.file(f, write_sst(opts.Strings, f, opts)); + ct.strs.push(f); + add_rels(opts.wbrels, ++rId, "sharedStrings." + wbext, RELS.SST); + } + + /* TODO: something more intelligent with themes */ + + f = "xl/theme/theme1.xml"; + zip.file(f, write_theme()); + ct.themes.push(f); + add_rels(opts.wbrels, ++rId, "theme/theme1.xml", RELS.THEME); + + /* TODO: something more intelligent with styles */ + + f = "xl/styles." + wbext; + zip.file(f, write_sty(wb, f, opts)); + ct.styles.push(f); + add_rels(opts.wbrels, ++rId, "styles." + wbext, RELS.STY); + + zip.file("[Content_Types].xml", write_ct(ct, opts)); + zip.file('_rels/.rels', write_rels(opts.rels)); + zip.file('xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels)); + return zip; +} +function firstbyte(f,o) { + switch((o||{}).type || "base64") { + case 'buffer': return f[0]; + case 'base64': return Base64.decode(f.substr(0,12)).charCodeAt(0); + case 'binary': return f.charCodeAt(0); + case 'array': return f[0]; + default: throw new Error("Unrecognized type " + o.type); + } +} + +function read_zip(data, opts) { + var zip, d = data; + var o = opts||{}; + if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64"; + switch(o.type) { + case "base64": zip = new jszip(d, { base64:true }); break; + case "binary": case "array": zip = new jszip(d, { base64:false }); break; + case "buffer": zip = new jszip(d); break; + case "file": zip=new jszip(d=_fs.readFileSync(data)); break; + default: throw new Error("Unrecognized type " + o.type); + } + return parse_zip(zip, o); +} + +function readSync(data, opts) { + var zip, d = data, isfile = false, n; + var o = opts||{}; + if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64"; + if(o.type == "file") { isfile = true; o.type = "buffer"; d = _fs.readFileSync(data); } + switch((n = firstbyte(d, o))) { + case 0xD0: + if(isfile) o.type = "file"; + return parse_xlscfb(CFB.read(data, o), o); + case 0x09: return parse_xlscfb(s2a(o.type === 'base64' ? Base64.decode(data) : data), o); + case 0x3C: return parse_xlml(d, o); + case 0x50: + if(isfile) o.type = "file"; + return read_zip(data, opts); + default: throw new Error("Unsupported file " + n); + } +} + +function readFileSync(data, opts) { + var o = opts||{}; o.type = 'file'; + return readSync(data, o); +} +function write_zip_type(wb, opts) { + var o = opts||{}; + var z = write_zip(wb, o); + switch(o.type) { + case "base64": return z.generate({type:"base64"}); + case "binary": return z.generate({type:"string"}); + case "buffer": return z.generate({type:"nodebuffer"}); + case "file": return _fs.writeFileSync(o.file, z.generate({type:"nodebuffer"})); + default: throw new Error("Unrecognized type " + o.type); + } +} + +function writeSync(wb, opts) { + var o = opts||{}; + switch(o.bookType) { + case 'xml': return write_xlml(wb, o); + default: return write_zip_type(wb, o); + } +} + +function writeFileSync(wb, filename, opts) { + var o = opts||{}; o.type = 'file'; + o.file = filename; + switch(o.file.substr(-5).toLowerCase()) { + case '.xlsx': o.bookType = 'xlsx'; break; + case '.xlsm': o.bookType = 'xlsm'; break; + case '.xlsb': o.bookType = 'xlsb'; break; + default: switch(o.file.substr(-4).toLowerCase()) { + case '.xls': o.bookType = 'xls'; break; + case '.xml': o.bookType = 'xml'; break; + }} + return writeSync(wb, o); +} + +function decode_row(rowstr) { return parseInt(unfix_row(rowstr),10) - 1; } +function encode_row(row) { return "" + (row + 1); } +function fix_row(cstr) { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); } +function unfix_row(cstr) { return cstr.replace(/\$(\d+)$/,"$1"); } + +function decode_col(colstr) { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; } +function encode_col(col) { var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; } +function fix_col(cstr) { return cstr.replace(/^([A-Z])/,"$$$1"); } +function unfix_col(cstr) { return cstr.replace(/^\$([A-Z])/,"$1"); } + +function split_cell(cstr) { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); } +function decode_cell(cstr) { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; } +function encode_cell(cell) { return encode_col(cell.c) + encode_row(cell.r); } +function fix_cell(cstr) { return fix_col(fix_row(cstr)); } +function unfix_cell(cstr) { return unfix_col(unfix_row(cstr)); } +function decode_range(range) { var x =range.split(":").map(decode_cell); return {s:x[0],e:x[x.length-1]}; } +function encode_range(cs,ce) { + if(ce === undefined || typeof ce === 'number') return encode_range(cs.s, cs.e); + if(typeof cs !== 'string') cs = encode_cell(cs); if(typeof ce !== 'string') ce = encode_cell(ce); + return cs == ce ? cs : cs + ":" + ce; +} + +function safe_decode_range(range) { + var o = {s:{c:0,r:0},e:{c:0,r:0}}; + var idx = 0, i = 0, cc = 0; + var len = range.length; + for(idx = 0; i < len; ++i) { + if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; + idx = 26*idx + cc; + } + o.s.c = --idx; + + for(idx = 0; i < len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.s.r = --idx; + + if(i === len || range.charCodeAt(++i) === 58) { o.e.c=o.s.c; o.e.r=o.s.r; return o; } + + for(idx = 0; i != len; ++i) { + if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break; + idx = 26*idx + cc; + } + o.e.c = --idx; + + for(idx = 0; i != len; ++i) { + if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break; + idx = 10*idx + cc; + } + o.e.r = --idx; + return o; +} + +function safe_format_cell(cell, v) { + if(cell.z !== undefined) try { return (cell.w = SSF.format(cell.z, v)); } catch(e) { } + if(!cell.XF) return v; + try { return (cell.w = SSF.format(cell.XF.ifmt||0, v)); } catch(e) { return ''+v; } +} + +function format_cell(cell, v) { + if(cell == null || cell.t == null) return ""; + if(cell.w !== undefined) return cell.w; + if(v === undefined) return safe_format_cell(cell, cell.v); + return safe_format_cell(cell, v); +} + +function sheet_to_json(sheet, opts){ + var val, row, range, header = 0, offset = 1, r, hdr = [], isempty, R, C, v; + var o = opts != null ? opts : {}; + var raw = o.raw; + if(sheet == null || sheet["!ref"] == null) return []; + range = o.range !== undefined ? o.range : sheet["!ref"]; + if(o.header === 1) header = 1; + else if(o.header === "A") header = 2; + else if(Array.isArray(o.header)) header = 3; + switch(typeof range) { + case 'string': r = safe_decode_range(range); break; + case 'number': r = safe_decode_range(sheet["!ref"]); r.s.r = range; break; + default: r = range; + } + if(header > 0) offset = 0; + var rr = encode_row(r.s.r); + var cols = new Array(r.e.c-r.s.c+1); + var out = new Array(r.e.r-r.s.r-offset+1); + var outi = 0; + for(C = r.s.c; C <= r.e.c; ++C) { + cols[C] = encode_col(C); + val = sheet[cols[C] + rr]; + switch(header) { + case 1: hdr[C] = C; break; + case 2: hdr[C] = cols[C]; break; + case 3: hdr[C] = o.header[C - r.s.c]; break; + default: + if(val === undefined) continue; + hdr[C] = format_cell(val); + } + } + + for (R = r.s.r + offset; R <= r.e.r; ++R) { + rr = encode_row(R); + isempty = true; + if(header === 1) row = []; + else { + row = {}; + if(Object.defineProperty) Object.defineProperty(row, '__rowNum__', {value:R, enumerable:false}); + else row.__rowNum__ = R; + } + for (C = r.s.c; C <= r.e.c; ++C) { + val = sheet[cols[C] + rr]; + if(val === undefined || val.t === undefined) continue; + v = val.v; + switch(val.t){ + case 'e': continue; + case 's': break; + case 'b': case 'n': break; + default: throw 'unrecognized type ' + val.t; + } + if(v !== undefined) { + row[hdr[C]] = raw ? v : format_cell(val,v); + isempty = false; + } + } + if(isempty === false || header === 1) out[outi++] = row; + } + out.length = outi; + return out; +} + +function sheet_to_row_object_array(sheet, opts) { return sheet_to_json(sheet, opts != null ? opts : {}); } + +function sheet_to_csv(sheet, opts) { + var out = "", txt = "", qreg = /"/g; + var o = opts == null ? {} : opts; + if(sheet == null || sheet["!ref"] == null) return ""; + var r = safe_decode_range(sheet["!ref"]); + var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0); + var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0); + var row = "", rr = "", cols = []; + var i = 0, cc = 0, val; + var R = 0, C = 0; + for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C); + for(R = r.s.r; R <= r.e.r; ++R) { + row = ""; + rr = encode_row(R); + for(C = r.s.c; C <= r.e.c; ++C) { + val = sheet[cols[C] + rr]; + txt = val !== undefined ? ''+format_cell(val) : ""; + for(i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34) { + txt = "\"" + txt.replace(qreg, '""') + "\""; break; } + row += (C === r.s.c ? "" : FS) + txt; + } + out += row + RS; + } + return out; +} +var make_csv = sheet_to_csv; + +function sheet_to_formulae(sheet) { + var cmds, y = "", x, val=""; + if(sheet == null || sheet["!ref"] == null) return ""; + var r = safe_decode_range(sheet['!ref']), rr = "", cols = [], C; + cmds = new Array((r.e.r-r.s.r+1)*(r.e.c-r.s.c+1)); + var i = 0; + for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C); + for(var R = r.s.r; R <= r.e.r; ++R) { + rr = encode_row(R); + for(C = r.s.c; C <= r.e.c; ++C) { + y = cols[C] + rr; + x = sheet[y]; + val = ""; + if(x === undefined) continue; + if(x.f != null) val = x.f; + else if(x.w !== undefined) val = "'" + x.w; + else if(x.v === undefined) continue; + else val = ""+x.v; + cmds[i++] = y + "=" + val; + } + } + cmds.length = i; + return cmds; +} + +var 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, + format_cell: format_cell, + get_formulae: sheet_to_formulae, + make_csv: sheet_to_csv, + make_json: sheet_to_json, + make_formulae: sheet_to_formulae, + sheet_to_csv: sheet_to_csv, + sheet_to_json: sheet_to_json, + sheet_to_formulae: sheet_to_formulae, + sheet_to_row_object_array: sheet_to_row_object_array +}; +XLSX.parse_xlscfb = parse_xlscfb; +XLSX.parse_zip = parse_zip; +XLSX.read = readSync; //xlsread +XLSX.readFile = readFileSync; //readFile +XLSX.readFileSync = readFileSync; +XLSX.write = writeSync; +XLSX.writeFile = writeFileSync; +XLSX.writeFileSync = writeFileSync; +XLSX.utils = utils; +XLSX.CFB = CFB; +XLSX.SSF = SSF; +})(typeof exports !== 'undefined' ? exports : XLSX); +var XLS = XLSX; diff --git a/src/Defines.ts b/src/Defines.ts new file mode 100644 index 0000000..34e8908 --- /dev/null +++ b/src/Defines.ts @@ -0,0 +1,246 @@ +/** + * 全局配置 + */ +interface GlobalCfg { + /** + * 远程的配置路径 + */ + remote?: string; + + /** + * 项目名称 + */ + project: string; + + /** + * 客户端配置导出路径 + */ + clientPath: string; + + /** + * 服务端配置导出路径 + */ + serverPath?: string; + + /** + * 服务端用于注册常量和引用的类 + */ + serverRegClass?: [string, string]; + + /** + * 客户端用于注册常量和引用的类 + */ + clientRegClass?: [string, string]; + /** + * 执行完成后调用的脚本 + */ + endScript?: string; + + /** + * 执行完成后调用的url + */ + endAction?: string; + + /** + * 屏蔽字源文件名称 + */ + dirtyName?: string; + + /** + * 保存服务端屏蔽字数据文件名称 + */ + dirtyServerName?: string; + + /** + * 保存客户端屏蔽字数据文件名称 + */ + dirtyClientName?: string; + + /** + * 客户端屏蔽字文件保存路径 + */ + dirtyClientPath?: string; + + + /** + * 名字库源文件名称 + */ + nameLib?: string; + + /** + * 保存客户端数据文件名称 + */ + nameLibClientName?: string; + + /** + * 名字库源文件保存路径 + */ + nameLibClientPath?: string; + + /** + * 是否自动更新svn + */ + isAutoSvn?: boolean; +} + +/** + * 属性定义 + */ +interface ProDefine { + + /** + * 属性名称 + */ + name: string; + + /** + * 描述 + */ + desc: string; + + /** + * 是否导出客户端数据 + * 0 不解析 + * 1 解析,并在代码生成时,生成类型对应的字段 + * 2 解析,生成代码时,在decode方法中,由临时变量记录数据,不生成方法 + */ + client: number; + + /** + * 是否导出服务端数据 + * 0 不解析 + * 1 解析,并在代码生成时,生成类型对应的字段 + * 2 解析,生成代码时,在decode方法中,由临时变量记录数据,不生成方法 + */ + server: number; + + /** + * 数据类型检查器 + */ + checker: TypeChecker; + + /** + * 数据类型服务器解析用 + */ + type: String; +} + +/** + * 检查数据是否符合类型,否则抛错 + * + * @interface TypeChecker + */ +interface TypeChecker { + + type: string; + + /** + * java类型 + */ + javaType:string; + + /** + * 类型索引值 + */ + idx: number; + + /** + * 检查并返回处理后的数据 + * + * @param {string} value 待处理的数据 + * @returns {any} + */ + check(value: string): any; + + /** + * 检查并返回处理后的服务器数据 + */ + checkServer(value: string): any; + + solveString?: string; + + solveJavaString?:string; +} + +interface IPluginData { + gcfg: GlobalCfg; + /** + * 文件名 + * @type {string} + */ + filename: string; + /**原始数据 */ + rawData: any[]; + /**服务器数据 */ + sdatas: any[]; + /**客户端数据 */ + cdatas: any[]; + /** + * 列定义 + */ + defines: ProDefine[]; + /** + * 数据起始行 + */ + dataRowStart: number; + + /** + * 行配置对应的行数 + * Key {string} 配置名称 + "程序配置内容": "cfgRow", + "前端解析": "clientRow", + "后端解析": "serverRow", + "默认值": "defaultRow", + "数据类型": "typeRow", + "描述": "desRow", + "属性名称": "nameRow" + + Value {number} 行号 + * + * @type {{ [index: string]: number }} + */ + rowCfg: { [index: string]: number }; +} + +/** + * + * 插件回调 + * @interface IPluginCallback + */ +interface IPluginCallback { + + /** + * + * + * @param {Error} [err] 错误信息 + * @param {string} [output] 输出的字符串 + * @param {any[]} [sdatas] 处理后的服务端数据 + * @param {any[]} [cdatas] 处理后的客户端数据 + */ + (err: Error, output?: string, sdatas?: any[], cdatas?: any[]): void +} + +/** + * + * 插件定义 + * @interface IPlugin + */ +interface IPlugin { + + /** + * + * 运行插件 + * @param {IPluginData} data + * @param {IPluginCallback} callback + */ + execute(data: IPluginData, callback: IPluginCallback); +} + +interface IPluginLoaderCallback { + type: string; + error?: number; + err?: Error; + output?: string; + sdatas?: any[]; + cdatas?: any[]; +} \ No newline at end of file diff --git a/src/MenualCodeHelper.ts b/src/MenualCodeHelper.ts new file mode 100644 index 0000000..a9714d7 --- /dev/null +++ b/src/MenualCodeHelper.ts @@ -0,0 +1,101 @@ +var fs = nodeRequire("fs"); +/** + * 手写代码的默认提示 + */ +const ManualCodeDefaultComment = { + /** + * 类上方提示 + */ + $area1: "!这里填写类上方的手写内容!", + /** + * 类中提示 + */ + $area2: "!这里填写类里面的手写内容!", + /** + * 类下方提示 + */ + $area3: "!这里填写类下发的手写内容!", + /** + * 处理函数提示 + */ + $decode: "!这里填写方法中的手写内容!", +} + +/** + * 生成手动代码区域的文本 + */ +function genManualAreaCode(key: string, cinfo: { [index: string]: string }) { + let yuanyou = cinfo[key]; + let tab = `\t`; + if (key == "$area2") tab += `\t`; + if (key == "$decode") tab += `\t\t`; + let desc = `${ManualCodeDefaultComment[key]}`; + return `/*-*begin ${key} ${desc}*-*/ +${tab}${yuanyou?yuanyou:""} +${tab}/*-*end ${key}*-*/` +} + +/** + * 获取手动写的代码信息 + */ +function getManualCodeInfo(file: string) { + let dict: { [index: string]: string } = {}; + if (fs.existsSync(file)) { + //读取文件内容 + let content = fs.readFileSync(file, "utf8"); + //找到手写内容 + let reg = /[/][*]-[*]begin[ ]([$]?[a-zA-Z0-9]+)[ ](.*?)[*]-[*][/]([^]*?)[/][*]-[*]end[ ]\1[*]-[*][/]/g; + while (true) { + let result = reg.exec(content); + if (result) { + let key = result[1]; + let manual = result[3].trim(); + if (!manual) {//没有注释 + continue; + } else if (key in ManualCodeDefaultComment) { + if (ManualCodeDefaultComment[key] == manual) {//类上中下的注释 + continue; + } + } + dict[key] = manual; + } else { + break; + } + } + } + return dict; +} + +function getGConfigCodeInfo(file: string, scriptName: string, sortName?: string) { + sortName = sortName ? `, "${sortName}"` : ""; + let addstr = `rP("${scriptName}", ${scriptName}Cfg${sortName});`; + if (fs.existsSync(file)) { + //读取文件内容 + let content: string = fs.readFileSync(file, "utf8"); + if (content.indexOf(`${addstr}`) != -1) return ""; + let sstr = "//begin"; + let estr = "//end"; + let si = content.indexOf(sstr); + let ei = content.indexOf(estr); + if (ei > si && si != -1){ + let fcon = content.substring(si + sstr.length, ei).replace(/\t/g, "").replace(/\r/g, ""); + let temp = fcon.split("\n");//`rP("${tempfilename}", chuanqi.${tempfilename}Cfg);` + let rarg: string[] = []; + for (let i = 0, l = temp.length; i < l; i++) { + let s = temp[i]; + if (s && s.indexOf(`rP("${scriptName}`) == -1){ + rarg.push(temp[i]); + } + } + rarg.push(addstr); + console.log(rarg); + return rarg.join("\n\t\t"); + } + return addstr; + } + else { + return addstr; + } +} + +export {genManualAreaCode, getManualCodeInfo, ManualCodeDefaultComment, getGConfigCodeInfo} \ No newline at end of file diff --git a/src/PackageData.ts b/src/PackageData.ts new file mode 100644 index 0000000..ef85358 --- /dev/null +++ b/src/PackageData.ts @@ -0,0 +1,338 @@ +/** + * 用于打包全部配置,将配置全部打包成一个文件 + * 服务端版本处理ani.json和pst.json的时候,不会打入帧数据 + */ +module pakdata +{ + + let path, fs; + let require = window["nodeRequire"]; + if (typeof require === "function") { //是Electron环境 + path = require("path"); + fs = require("fs"); + } + + const cfgsSpiltInfoName = "CfgsSpiltInfo.json"; + + + // 此处地址实际从外部传入解析 + let IP_HOST = `192.168.92.178`; + let svnRoot = `//${IP_HOST}/web/`; + let clientDir = `//${IP_HOST}/web/config/zhcn/raw/`; + let packageRoot = `//${IP_HOST}/web/config/zhcn/`; + let aniPath = `//${IP_HOST}/web/resource/zhcn/ef/`; + let pstPath = `//${IP_HOST}/web/resource/zhcn/n/a/`; + + export function initPathVars(url: string){ + let boo = true; + let reg = /\/\/(.*?)\/(.*?)\//; + if (reg.test(url)){ + let arg = reg.exec(url); + if (arg){ + IP_HOST = arg[0]; + svnRoot = `${IP_HOST}`; + clientDir = `${IP_HOST}config/zhcn/raw/`; + packageRoot = `${IP_HOST}config/zhcn/`; + aniPath = `${IP_HOST}resource/zhcn/ef/`; + pstPath = `${IP_HOST}resource/zhcn/n/a/`; + + boo = false; + } + } + if (boo){ + + clientDir = url; + packageRoot = path.join(url, ".."); + svnRoot = packageRoot; + + IP_HOST = ``; + aniPath = ``; + pstPath = ``; + + } + + console.log(`IP_HOST=${IP_HOST}`); + console.log(`svnRoot=${svnRoot}`); + console.log(`clientDir=${clientDir}`); + console.log(`packageRoot=${packageRoot}`); + console.log(`aniPath=${aniPath}`); + console.log(`pstPath=${pstPath}`); + } + + export var endCallBack; + export var traceLog; + export var traceErrorLog; + export var ifErrorCallBack; + export var isAutoSvn; + + export async function packageForClient(){ + + let aniOutFile = path.join(clientDir, "ani.json"); + let pstOutFile = path.join(clientDir, "pst.json"); + let cfgsOutFile = path.join(packageRoot, "cfgs.json"); + let firstOutFile = path.join(packageRoot, "basic.json"); + let runningOutFile = path.join(packageRoot, "running.json"); + + let p = fs.statSync(clientDir); + if (!p.isDirectory()) { + console.error("文件夹有误"); + if (ifErrorCallBack ) ifErrorCallBack(); + return; + } + // if (isAutoSvn){ + // try{ + // await svncmd.update(svnRoot); + // } catch (e) { + // log(`[error svncmdUpdate] @@@ ${svnRoot}`); + // } + // } + // ani文件夹特殊处理 + let cfgsOutData = {}; + let aniData = parseAni(aniPath); + let pstData = parsePst(pstPath); + + let cfgsSpiltInfoData = getCfgsSpiltInfo(clientDir); + console.log("++++++cfgsSpiltInfoData+++++++"); + console.log(cfgsSpiltInfoData); + console.log("++++++cfgsSpiltInfoData+++++++"); + + let firstData = {}; + let runningData = {}; + let flist = fs.readdirSync(clientDir); + let basic = cfgsSpiltInfoData.basic || []; + let firstKeys = basic.length > 0 ? basic : ["Function", "FunctionOpen", "MapLine", "TribeType"]; + let runningKeys = cfgsSpiltInfoData.running || []; + + if (aniData){ + if (firstKeys.indexOf("ani") != -1){ + firstData["ani"] = aniData; + } else if (runningKeys.indexOf("ani") != -1){ + runningData["ani"] = aniData; + } else { + cfgsOutData["ani"] = aniData; + } + } + if (pstData) { + if (firstKeys.indexOf("pst") != -1){ + firstData["pst"] = pstData; + } else if (runningKeys.indexOf("pst") != -1){ + runningData["pst"] = pstData; + } else { + cfgsOutData["pst"] = pstData; + } + } + + flist.forEach(file => { + let re = path.parse(file); + let fname = re.name; + if (re.ext != ".json") { + return; + } + if (file == "ani.json" || file == "pst.json") { + // 此2文件已添加到outData中 + return; + } + if (file == cfgsSpiltInfoName) { + return;// 配置分包信息不计入配置 + } + let data = getData(path.join(clientDir, file)); + if (data){ + if (firstKeys.indexOf(fname) != -1){ + firstData[fname] = data; + } else if (runningKeys.indexOf(fname) != -1){ + runningData[fname] = data; + } else { + cfgsOutData[fname] = data; + } + } + }); + + + // let t = JSON.stringify(cfgsOutData); + // let buf = new Buffer(t, "binary"); + // if (buf instanceof Uint8Array){ + // buf = new Buffer(buf); + // } + // console.log(buf);buf.toJSON(); + // let tempP = path.join(packageRoot, "cfgs.bin"); + // fs.writeFileSync(tempP, buf); + + // let t1 = JSON.stringify(runningData); + // let buf1 = new Buffer(t1, "binary"); + // console.log(buf1); + // let tempP1 = path.join(packageRoot, "running.bin"); + // fs.writeFileSync(tempP1, buf1); + + if (cfgsOutData) fs.writeFileSync(cfgsOutFile, JSON.stringify(cfgsOutData)); + if (aniData) fs.writeFileSync(aniOutFile, JSON.stringify(aniData)); + if (pstData) fs.writeFileSync(pstOutFile, JSON.stringify(pstData)); + if (firstData) fs.writeFileSync(firstOutFile, JSON.stringify(firstData)); + if (runningData) fs.writeFileSync(runningOutFile, JSON.stringify(runningData)); + + // if (isAutoSvn){ + // try{ + // await svncmd.add(packageRoot); + // } catch (e) { + // errorLog(`[error svncmdAdd]packageRoot:${packageRoot}`, e); + // } + + // try{ + // await svncmd.commit(packageRoot, "工具自动提交"); + // } catch (e) { + // errorLog(`[error svncmdCommit]packageRoot:${packageRoot}`, e); + // } + // } + log("PackageData 脚本执行完成"); + if( endCallBack ){ + endCallBack(); + } + } + + function log(msg) + { + if (traceLog) traceLog( msg ); + else console.log(msg); + } + + function errorLog(msg: string, err?: Error) + { + if (traceErrorLog) traceErrorLog(msg, err); + else if (err) console.error(msg, err.message, err.stack); + else console.log(msg); + } + + function getData(file) + { + if (!fs.existsSync(file) || !fs.statSync(file).isFile()) { + errorLog(`找不到文件${file}`); + return null; + } + log(`getData ${file}`); + let data; + try { + data = JSON.parse(fs.readFileSync(file, "utf8")); + } + catch (e) { + errorLog(`解析${file}数据,${file}时出错`, e); + } + return data; + } + + function getCfgsSpiltInfo(root) + { + let file = path.join(root, cfgsSpiltInfoName); + let data = getData(file); + let basic = []; + let running = []; + if (data){ + data.forEach(list=>{ + let b = list[0]; + let r = list[1]; + if (b) basic.push(b); + if (r) running.push(r); + }); + } + return { "basic": basic, "running":running }; + } + /** + * 处理ani文件夹 + * + * @param {string} aniPath ani文件处理路径 + */ + function parseAni(aniPath, saveTexture = true) + { + log(`parseAni:${aniPath}`); + if(!fs.existsSync(aniPath)){ + errorLog(`no aniPath:${aniPath}`); + return null; + } + var data = {}; + let p = fs.statSync(aniPath); + if (!p.isDirectory()) { + errorLog("给的ani路径文件夹有误"); + return null; + } + // 读取子文件夹 + let flist = fs.readdirSync(aniPath); + flist.forEach(subDir => { + //ani文件夹应该为 a0.png和d.json两个文件 + let p = path.join(aniPath, subDir); + let dp = path.join(p, "d.json"); + //检查子文件夹文件 + if (fs.existsSync(path.join(p, "a0.png")) && fs.existsSync(dp)) { + //有这两个文件,ani文件夹有效 + let aniDat; + try { + aniDat = JSON.parse(fs.readFileSync(dp, "utf8")); + } + catch (e) { + errorLog(`解析ani数据,${dp}时出错`, e); + return; + } + if (!aniDat || !Array.isArray(aniDat)) { + errorLog(`解析ani数据,${dp}数据有误,不是数组`); + return; + } + if (!saveTexture) { + aniDat.length = 1; + } + data[subDir] = aniDat; + } + }); + return data; + } + /** + * 处理pst文件夹 + * + * @param {string} pstPath pst文件处理路径 + */ + function parsePst(pstPath) + { + log(`parsePst:${pstPath}`); + if(!fs.existsSync(pstPath)){ + errorLog(`no pstPath:${pstPath}`); + return null; + } + var data = {}; + let p = fs.statSync(pstPath); + if (!p.isDirectory()) { + errorLog("给的pst路径文件夹有误"); + return null; + } + // 读取子文件夹 + let flist = fs.readdirSync(pstPath); + flist.forEach(subDir => { + //pst文件夹应该都包含 pst.json和d.json两个文件 + let p = path.join(pstPath, subDir); + let dfile = path.join(p, "d.json"); + let pfile = path.join(p, "pst.json"); + //检查子文件夹文件 + if (fs.existsSync(pfile) && fs.existsSync(dfile)) { + //有这两个文件,pst文件夹有效 + let pstDat; + try { + let temp = JSON.parse(fs.readFileSync(pfile, "utf8")); + for (let key in temp){ + pstDat = temp[key]; + } + } + catch (e) { + errorLog(`解析ani数据,${pfile}时出错`, e); + return; + } + if (!pstDat || !Array.isArray(pstDat)) { + errorLog(`解析ani数据,${pfile}数据有误,不是数组`); + return; + } + /* + if (subDir == "A10") subDir = "1_0"; + else if (subDir == "A11") subDir = "1_1"; + */ + data[subDir] = pstDat; + } + }); + return data; + } + + +} \ No newline at end of file diff --git a/src/PluginErrorType.ts b/src/PluginErrorType.ts new file mode 100644 index 0000000..006ced9 --- /dev/null +++ b/src/PluginErrorType.ts @@ -0,0 +1,14 @@ +export var PluginErrorType = { + /** + * 加载失败 + */ + LoadFailed: 1, + /** + * 初始化失败 + */ + InitFailed: 2, + /** + * 执行失败 + */ + ExecuteFailed: 3 +} \ No newline at end of file diff --git a/src/PluginLoader.ts b/src/PluginLoader.ts new file mode 100644 index 0000000..cdd6682 --- /dev/null +++ b/src/PluginLoader.ts @@ -0,0 +1,48 @@ +import {PluginErrorType} from "./PluginErrorType"; +import asyncFileLoad from "./asyncFileLoad"; +import $vm = require("vm"); +export default class PluginLoader { + private plugin: IPlugin; + private callback: { (data: IPluginLoaderCallback) }; + public constructor(pluginPath: string, m: IPluginData, callback: { (data: IPluginLoaderCallback) }) { + this.callback = callback; + var code = asyncFileLoad(pluginPath, (err, data) => { + if (err) { + this.sendError(PluginErrorType.LoadFailed, err); + return; + } + var vm: typeof $vm = nodeRequire("vm"); + let str = data.toString(); + let plugin = vm.createContext({ require: nodeRequire, console: console }); + try { + vm.runInContext(str, plugin); + } catch (err) { + this.sendError(PluginErrorType.InitFailed, err); + return; + } + this.plugin = plugin; + this.execute(m); + }); + } + + private sendError(code: number, err?: Error) { + // 插件代码有误 + this.callback({ type: "error", error: code, err: err }); + } + + private execute(m: IPluginData) { + try { + this.plugin.execute(m, (err, output, sdatas, cdatas) => { + if (err) { + this.sendError(PluginErrorType.ExecuteFailed, err); + return; + } + this.callback({ type: "success", output: output, sdatas: sdatas, cdatas: cdatas }); + }); + } catch (err) { + this.sendError(PluginErrorType.ExecuteFailed, err); + return; + } + + } +} \ No newline at end of file diff --git a/src/SvnCmd.ts b/src/SvnCmd.ts new file mode 100644 index 0000000..68247d9 --- /dev/null +++ b/src/SvnCmd.ts @@ -0,0 +1,209 @@ +module svncmd { + + let path, fs, buffer, cp; + let require = window["nodeRequire"]; + if (typeof require === "function") { //是Electron环境 + path = require("path"); + fs = require("fs"); + buffer = require("buffer"); + cp = require("child_process"); + } + + export var errorLog; + + /** + * svn update 指定目录内容 + */ + export function update(root: string) + { + return new Promise((suc, failed)=>{ + let exec = cp.exec; + exec(`svn update ${root}`, function callback(err, stdout, stderr){ + if (stderr) { + traceError("svn update failed【失败 失败 失败】" + `[${root}] __ ${stderr}`); + failed("svn update failed【失败 失败 失败】" + `[${root}] __ ${stderr}`); + } + else { + suc("svn update ok【 successful successful successful 】"); + console.log(`svn update successful`, stdout); + } + }); + }) + } + + /** + * 添加指定svn目录下所有文件到 svn 版本控制 + */ + export function add(addRoot) + { + return new Promise((suc, failed)=>{ + var exec = cp.exec; + exec(`svn status ${addRoot}`,function callback(error, stdout, stderr) { + try{ + let result: string = stdout; + if (result){ + let arg = result.split("\r\n"); + if (arg && arg.length > 0){ + let next = async ()=>{ + if (arg.length > 0){ + let temp = arg.pop().replace(/\s/g, ""); + if (temp){ + if(temp.substring(0,1)=='?'){ + try{ + let filepath = temp.substring(temp.indexOf(addRoot.substring(2, 8)) - 2); + filepath = getPathFromOldByNew(addRoot, filepath); + await realAdd(filepath); + } catch (e) { + traceError("svn status function === ", e); + } + } + } + next(); + } else { + suc("ok"); + } + } + next(); + } + } else { + suc("ok"); + } + } catch (e) { + traceError("svn add failed【失败 失败 失败】", e); + failed(e.message); + } + }) + }) + } + + /** + * 提交内容到 svn 服务器 + */ + export function commit(commitRoot, desc) + { + return new Promise((suc, failed)=>{ + var exec = cp.exec; + exec(`svn status ${commitRoot}`,function callback(error, stdout, stderr) { + console.log(error, stdout, stderr); + try{ + if (stdout){ + let result: string = stdout; + if (result){ + let arg = result.split("\r\n"); + if (arg && arg.length > 0){ + let next = async()=>{ + if (arg.length > 0){ + let temp = arg.pop().replace(/\s/g, ""); + if (temp){ + let f = temp.substring(0,1); + if (["?","!","M","A"].indexOf(f) != -1) { + let filepath = temp.substring(temp.indexOf(commitRoot.substring(2, 8)) - 2); + filepath = getPathFromOldByNew(commitRoot, filepath); + if(f=='?'){ + try{ await realAdd(filepath); } catch (e) { traceError("", e); } + } + try{ await realCommit(filepath, desc); } catch (e) { traceError("", e); } + } + } + next(); + } else { + suc("ok"); + } + } + next(); + } else { + suc("ok"); + } + } else { + suc("ok"); + } + } + else if (stderr) { + traceError("[commit]svn status stderr"+stderr); + failed("[commit]svn status stderr"+stderr); + } else { + suc("ok"); + } + } catch (e) { + traceError("failed", e); + failed(e.message); + } + }); + }) + } + + export function cleanup(root: string) + { + return new Promise((suc, failed)=>{ + let exec = cp.exec; + exec(`svn cleanup ${root}`, function callback(err, stdout, stderr){ + if (stderr) { + traceError("svn cleanup failed【失败 失败 失败】" + `[${root}] __ ${stderr}`); + failed("svn cleanup failed【失败 失败 失败】" + `[${root}] __ ${stderr}`); + } + else { + suc("svn cleanup ok【 successful successful successful 】"); + console.log(`svn cleanup successful`, stdout); + } + }); + }) + } + + function traceError(msg, e?) + { + if (errorLog) errorLog(msg, e); + else console.error(msg + ` ___ ${e?e.message:""}`); + } + + function getPathFromOldByNew(oldpath: string, newpath: string) + { + let oldNames = path.normalize(oldpath).split(path.sep); + let newNames = path.normalize(newpath).split(path.sep); + let prex = oldpath.indexOf("\\") == 0 || oldpath.indexOf("//") == 0 ? `\\\\` : ""; + let rpath = ""; + for (let i = 0, l= newNames.length; i < l; i++){ + if (!rpath) rpath = oldNames[i]; + else { + let t = oldNames[i] || newNames[i]; + rpath = path.join(rpath, t); + } + } + rpath = prex + rpath; + return rpath; + } + + function realAdd(filepath) + { + return new Promise((ssuc, sfail)=>{ + var exec = cp.exec; + exec(`svn add ${filepath}`,function callback(error, stdout, stderr) { + console.log("realAdd error:"+error); + console.log("realAdd stdout:"+stdout); + if (stderr) { + traceError("svn add failed【失败 失败 失败】" + `[${filepath}]`); + sfail("sfailed"); + } + else { + console.log("svn add ok【 successful successful successful 】"); + ssuc("sok"); + } + }); + }) + } + + function realCommit(filepath, desc) + { + return new Promise((ssuc, sfail)=>{ + var exec = cp.exec; + exec(`svn commit ${filepath} -m "${desc}`,function callback(error, stdout, stderr) { + console.log("realCommit error:"+error); + console.log("realCommit stdout:"+stdout); + if (stderr) sfail("svncommit sfail"); + else { + console.log("svn commit ok【 successful successful successful 】"); + ssuc("svncommit ok"); + } + }); + }) + } +} \ No newline at end of file diff --git a/src/TypeCheckers.ts b/src/TypeCheckers.ts new file mode 100644 index 0000000..08db3a4 --- /dev/null +++ b/src/TypeCheckers.ts @@ -0,0 +1,451 @@ +/** + * 数值类型在解析json的时候,字符串会多两个"",数值更节省 + * + * @param {*} value (description) + * @returns (description) + */ +function tryParseNumber(value: any) { + if (typeof value === "boolean") { + return value ? 1 : 0; + } + if (value == +value && value.length == (+value + "").length) { // 数值类型 + // "12132123414.12312312"==+"12132123414.12312312" + // true + // "12132123414.12312312".length==(+"12132123414.12312312"+"").length + // false + return +value; + } else { + return value; + } +} +/** + * 处理 any 类型的数据 + * + * @class AnyChecker + * @implements {TypeChecker} + */ +class AnyChecker implements TypeChecker { + get type() { + return "any"; + } + + get javaType(){ + return "String"; + } + + get idx() { + return 0; + } + + check(value: any) { + return tryParseNumber(value); + } + + checkServer(value: string){ + return this.check(value); + } +} + +/** + * 处理 string 类型的数据 + * + * @class StringChecker + * @implements {TypeChecker} + */ +class StringChecker implements TypeChecker { + get type() { + return "string"; + } + + get javaType(){ + return "String"; + } + + get idx() { + return 1; + } + + check(value: string) { + return value; + } + + checkServer(value: string){ + return value; + } +} + + +/** + * 处理 number 类型的数据 + * + * @class NumberChekcer + * @implements {TypeChecker} + */ +class IntChekcer implements TypeChecker { + get type() { + return "number"; + } + get javaType(){ + return "int"; + } + get idx() { + return 2; + } + check(value: string) { + value = value.trim(); + if (!value) { + return 0; + } + if (value.split(".").length <= 2 && (/^-?[0-9.]+e[0-9]+$/i.test(value) ||/^-?0b[01]+$/.test(value) || /^-?0x[0-9a-f]+$/i.test(value) || /^-?[0-9.]+$/.test(value))) { + return +value; + } else { + throw new ValueTypeError("number", value); + } + } + + checkServer(value: string){ + return this.check(value); + } +} + +class FloatChekcer implements TypeChecker { + get type() { + return "number"; + } + get javaType(){ + return "float"; + } + get idx() { + return 8; + } + check(value: string) { + value = value.trim(); + if (!value) { + return 0; + } + if (value.split(".").length <= 4 && (/^-?[0-9.]+e[0-9]+$/i.test(value) ||/^-?0b[01]+$/.test(value) || /^-?0x[0-9a-f]+$/i.test(value) || /^-?[0-9.]+$/.test(value))) { + return +value; + } else { + throw new ValueTypeError("number", value); + } + } + + checkServer(value: string){ + return this.check(value); + } +} + +/** + * 处理 number 类型的数据 + * + * @class NumberChekcer + * @implements {TypeChecker} + */ +class LongChekcer implements TypeChecker { + get type() { + return "number"; + } + get javaType(){ + return "long"; + } + get idx() { + return 9; + } + check(value: string) { + value = value.trim(); + if (!value) { + return 0; + } + if (value.split(".").length <= 2 && (/^-?[0-9.]+e[0-9]+$/i.test(value) ||/^-?0b[01]+$/.test(value) || /^-?0x[0-9a-f]+$/i.test(value) || /^-?[0-9.]+$/.test(value))) { + return +value; + } else { + throw new ValueTypeError("number", value); + } + } + + checkServer(value: string){ + return this.check(value); + } +} + + +/** + * 处理 boolean 类型的数据 + * + * @class BooleanChecker + * @implements {TypeChecker} + */ +class BooleanChecker implements TypeChecker { + get type() { + return "boolean"; + } + get javaType(){ + return "boolean"; + } + get idx() { + return 3; + } + solveString = `!!{value}`; + check(value: string) { + if (!value || value == "false" || value == "0") { + return 0; + } else { + return 1; + } + } + + checkServer(value: string){ + return this.check(value); + } +} + + +/** + * 处理 | 类型的数据 + * + * @class ArrayCheker + * @implements {TypeChecker} + */ +class ArrayCheker implements TypeChecker { + get type() { + return "any[]"; + } + get javaType(){ + return "String"; + } + get idx() { + return 4; + } + check(value: string) { + if (!value) return []; + if (value.indexOf(":")!=-1){ + throw new ValueTypeError("array(:)", value + "(包含中文[:]冒号)"); + } else { + let arr = value.split(":"); + arr.forEach((item, idx) => { + arr[idx] = tryParseNumber(item); + }) + return arr; + } + } + + checkServer(value: string){ + return value; + } +} + +/** + * 处理 |: 类型的二维数组的数据 + * + * @class Array2DCheker + * @implements {TypeChecker} + */ +class Array2DCheker implements TypeChecker { + get type() { + return "any[][]"; + } + get javaType(){ + return "String"; + } + get idx() { + return 5; + } + check(value: string) { + if (!value) return []; + if (value.indexOf(":")!=-1){ + throw new ValueTypeError("array(|:)", value + "(包含中文[:]冒号)"); + } else { + let arr: any[] = value.split("|"); + arr.forEach((item, idx) => { + let subArr: any[] = item.split(":"); + arr[idx] = subArr; + subArr.forEach((sitem, idx) => { + subArr[idx] = tryParseNumber(sitem); + }); + }) + return arr; + } + } + + checkServer(value: string){ + return value; + } +} + +function isLeapYear(year: number) { + return (year % 4 == 0 && year % 100 != 0) || (year % 100 == 0 && year % 400 == 0); +} + +const nday = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + +function checkDate(value: string) { + let res = /^(20[1-9][0-9])-(0\d+|1[0,1,2])-(\d+)$/.exec(value) + if (res) { + var year = +res[1]; + var month = +res[2]; + var day = +res[3]; + } else { + return false; + } + if (day < 1) { + return false; + } + let maxDay: number; + if (month == 2 && isLeapYear(year)) { + maxDay = 29; + } else { + maxDay = nday[month - 1]; + } + if (day > maxDay) { + return false; + } + return true; +} + +function checkTime(value: string) { + // let res = /^(\d{2}):(\d{2})$/.exec(value) + if (value.indexOf(":") != -1){ + value = value.trim(); + var res = value.split(":"); + var h = +res[0]; + var m = +res[1]; + var s = +res[2]; + } else { + return null; + } + if (h < 0 || h >= 24) { + return null; + } + if (m < 0 || m >= 60) { + return null; + } + if (s < 0 || s >= 60){ + return null; + } + return { h: h, m: m, s: s }; +} + +/** + * 日期检查器 yyyy-MM-dd + * + * @class DateChecker + * @implements {TypeChecker} + */ +class DateChecker implements TypeChecker { + get type() { + return "Date"; + } + get javaType(){ + return "String"; + } + get idx() { + return 6; + } + solveString = `new Date({value}*1000)`; + + check(value: string) { + if (!checkDate(value)) { + throw new ValueTypeError("yyyy-MM-dd", value); + } + // 用8位数字代替 10位字符串(JSON后变成12位) + return new Date(value).getTime() * 0.001; + // return new Date(value + " UTC").getTime() * 0.001; + } + + checkServer(value: string){ + return value; + } +} + +/** + * 时间检查器 HH:mm + * + * @class TimeChecker + * @implements {TypeChecker} + */ +class TimeChecker implements TypeChecker { + get type() { + return "TimeVO"; + } + get javaType(){ + return "String"; + } + get idx() { + return 7; + } + solveString = `new TimeVO({value})`; + check(value: string) { + let time = checkTime(value); + if (!time) { + throw new ValueTypeError("HH:mm | HH:mm:ss", value); + } + return value; + } + + checkServer(value: string){ + return value; + } +} + +/** + * 日期时间检查器 yyyy-MM-dd HH:mm + * + * @class DateTimeChecker + * @implements {TypeChecker} + */ +class DateTimeChecker implements TypeChecker { + get type() { + return "Date"; + } + get javaType(){ + return "String"; + } + get idx() { + return 8; + } + solveString = `new Date({value}*1000)`; + check(value: string) { + let t = value.split(" "); + let date = t[0]; + let time = t[1]; + if (!checkDate(date) || !checkTime(time)) { + throw new ValueTypeError("yyyy-MM-dd HH:mm | yyyy-MM-dd HH:mm:ss", value); + } + // 使用UTC时间进行存储,解析的时候,改用服务器时区 + return new Date(value).getTime() * 0.001; + // return new Date(value + " UTC").getTime() * 0.001; + } + + checkServer(value: string){ + return value; + } +} + +/** + * ValueTypeError + */ +class ValueTypeError extends Error { + constructor(type: string, value: string) { + super(); + this.message = `数据和类型不匹配,当前类型:${type},数据:${value}`; + } +} + +let checkers: { [index: string]: TypeChecker } = {}; +// number string boolean : |: yyyy-MM-dd yyyy-MM-dd HH:mm HH:mm + +checkers["any"] = new AnyChecker; +checkers["int"] = new IntChekcer; +checkers["float"] = new FloatChekcer; +checkers["long"] = new LongChekcer; +checkers["string"] = new StringChecker; +checkers["boolean"] = new BooleanChecker; +checkers[":"] = new ArrayCheker; +checkers["|:"] = new Array2DCheker; +checkers["yyyy-MM-dd"] = new DateChecker; +checkers["HH:mm"] = new TimeChecker; +checkers["yyyy-MM-dd HH:mm"] = new DateTimeChecker; + +export default TypeChecker; +export {checkers as TypeCheckers}; +export {ValueTypeError}; \ No newline at end of file diff --git a/src/asyncFileLoad.ts b/src/asyncFileLoad.ts new file mode 100644 index 0000000..f21ffd3 --- /dev/null +++ b/src/asyncFileLoad.ts @@ -0,0 +1,27 @@ +import $fs = require("fs"); +import $http = require("http"); +export default function asyncFileLoad(url: string, callback: { (err: Error, data?: Buffer) }) { + if (/^http:\/\//.test(url)) { + var http: typeof $http = nodeRequire("http"); + http.get(url, res => { + let chunks: Buffer[] = []; + res.on("data", chunk => { + chunks.push(chunk); + }); + res.on("end", () => { + callback(null, Buffer.concat(chunks)); + }); + }).on("error", (e) => { + callback(e); + }) + } else { + var fs: typeof $fs = nodeRequire("fs"); + fs.exists(url, exists => { + if (exists) { + fs.readFile(url, callback); + } else { + callback(Error(`无法找到指定文件${url}`)); + } + }) + } +} \ No newline at end of file diff --git a/src/indexJava.ts b/src/indexJava.ts new file mode 100644 index 0000000..2315e82 --- /dev/null +++ b/src/indexJava.ts @@ -0,0 +1,1140 @@ +import $path = require("path"); +import $fs = require("fs"); +import $XLSX = require("xlsx"); +declare var XLSX: typeof $XLSX; +const path: typeof $path = nodeRequire("path"); +const fs: typeof $fs = nodeRequire("fs"); +const clipboard = nodeRequire('electron').clipboard; +import { TypeCheckers } from "./TypeCheckers"; +import { genManualAreaCode, getManualCodeInfo, ManualCodeDefaultComment, getGConfigCodeInfo } from "./MenualCodeHelper"; +import asyncFileLoad from "asyncFileLoad"; +import $vm = require("vm"); + +var $g: any = (id) => { return document.getElementById(id) }; +/** + * 输出日志 + */ +function log(msg: string) { + let txtLog = $g("txtLog"); + if (txtLog) { + txtLog.innerHTML += msg + "
"; + txtLog.scrollTop = txtLog.scrollHeight; + } +} + +/** + * 输出错误 + */ +function error(msg: string, err?: Error) { + let errMsg = ""; + if (err) { + errMsg = ` +err: +${err.message} +stack: +${err.stack}` + } + log(`${msg}${errMsg}`); +} + +/** + * 给消息内网前面添加当前时间 + * @param message 消息内容 + */ +function addTimeForMessage(message){ + if (/\[[0-9]\d:[0-5]\d:[0-5]\d\]/.test(message)) return message; + return `[${new Date().toTimeString().slice(0,8)}] ${message}
`; +} + +interface FileData +{ + path: string; + + name: string; +} + +interface NetParam +{ + cmd: string; + data: string; +} + + +// var tcpClient; +var errorMessages: string[] = []; + +function endCallBack() +{ + let temp = errorMessages; + while (temp.length > 0){ + error(temp.pop()); + } + send2ServerFromEnd(); + alert("所有数据保存完成"); +} +function ifErrorCallBack() +{ + let temp = errorMessages; + while (temp.length > 0){ + error(temp.pop()); + } + send2ServerFromEnd(); + alert("执行配置合并脚本过程中未能完成"); +} + +function send2ServerFromEnd(m = "0") +{ + // try{ + // if (tcpClient){ + // tcpClient.write(encode("publish_data_tools_parse", m));// 客户端向服务器发送信息 + // } + // } catch (e) { + // alert("少年,你可能需要刷新才能继续使用,或者服务端程序已关闭"); + // } +} + +/** + * 编码 + */ +function encode(cmd: string, ...param){ + let result = {cmd, data: encodeParam(...param)}; + return JSON.stringify(result); +} + +function encodeParam(...param){ + if (param) return param.join("|"); + return ""; +} + +/** + * ExcelDataSaver + */ +export class ExcelDataSaver { + constructor() { + ready(() => { + + svncmd.errorLog = error; + + var net = nodeRequire("net"); + var isDoing = false; + + // 创建客户端 + // tcpClient = net.Socket(); + + // // 监听“服务器发来信息”事件 + // tcpClient.on('data',function(data){ + // let content: string = data.toString(); + // if (content.indexOf("alert|") != -1){ + // alert(content.substr(6)); + // } else { + // let param = content.split("|"); + // let result = param[0]; + // if (result == "0") isDoing = false; + // else if (result == "1") isDoing = true; + // log(addTimeForMessage(content)); + // log(addTimeForMessage(`isDoing=${isDoing}`)); + // } + // }); + // // tcpClient.connect(18002,'192.168.99.84',function(){ + // tcpClient.connect(18002,'client.uclub.xyz',function(){ + // log("Connect success"); + // }); + // tcpClient.on('error', function(err){ + // error('Server error:'+err.message); + // isDoing = true; + // alert("少年,你可能需要刷新才能继续使用,或者服务端程序未启动"); + // }); + + window.addEventListener("dragover", e => { + e.preventDefault(); + return false; + }); + + window.addEventListener("drop", e => { + e.preventDefault(); + if(isDoing){ + alert("少年,我是单线程操作,不好意思已经被别人占用中,稍后再试。麻烦关闭提示框,你很配合的"); + } else { + + let files = e.dataTransfer.files; + + if (!files || files.length == 0) { + alert("少年你这样操作,三亿让你请饭哦"); + return ; + } + + // try{ + // if (tcpClient){ + // tcpClient.write(encode("publish_data_tools_parse", "1"));// 客户端向服务器发送信息 + // } + // } catch (e) { + // error("socket ===== ", e); + // alert("少年,似乎请求服务器失败,刷新试试吧。"); + // return ; + // } + + isDoing = false; + this.onDrop(files); + } + return false; + }); + this.getPathCookie("txtClientPath"); + this.getPathCookie("txtServerPath"); + $g("chkClientPath").checked = cookie.getCookie("h5excel_chkClientPath") == "true"; + $g("chkServerPath").checked = cookie.getCookie("h5excel_chkServerPath") == "true"; + }); + } + + private getPathCookie(id: string) { + let sPath = cookie.getCookie("h5excel_" + id); + if (sPath) { + $g(id).value = sPath; + } + } + + private setPathCookie(id: string): string { + let v: string = $g(id).value; + v = v.trim(); + $g(id).value = v; + if (v && fs.existsSync(v)) { + let re = fs.statSync(v); + if (re.isDirectory()) { + cookie.setCookie("h5excel_" + id, v) + return v; + } + } + return undefined; + } + + private checkFiles = (rootpath, resultFiles: FileData[]) =>{ + + let basename = path.basename(rootpath); + var stat = fs.statSync(rootpath); + let self = this; + if (stat.isDirectory()){ + let temp = fs.readdirSync(rootpath); + temp.forEach(function(item, index){ + self.checkFiles(path.join(rootpath,item), resultFiles); + }) + } else { + resultFiles.push({path: rootpath, name: basename}); + } + } + + private async onDrop(files: FileList) { + if (files.length == 0) return ; + let resultFiles: FileData[] = []; + for (let i = 0, len = files.length; i < len; i++) { + this.checkFiles(files[i].path, resultFiles); + } + + let gcfg: GlobalCfg; + let cPath = this.setPathCookie("txtClientPath"); + let sPath = this.setPathCookie("txtServerPath"); + + let useClientPath = $g("chkClientPath").checked; + cookie.setCookie("h5excel_chkClientPath", useClientPath); + let useServerPath = $g("chkServerPath").checked; + cookie.setCookie("h5excel_chkServerPath", useServerPath); + if (!useClientPath) { + cPath = ""; + } + if (!useServerPath) { + sPath = ""; + } + // 清理code区 + $g("code").innerHTML = ""; + $g("txtLog").innerHTML = ""; + let xlsxRoot = ""; + let unsolved = resultFiles.concat();//Array.from(files); + // 每拖一次文件,只加载一次全局配置 + for (let i = 0, len = resultFiles.length; i < len; i++) { + let file = resultFiles[i]; + let re = path.parse(file.name); + console.log("************" + file.path); + if (re.ext == ".xlsx") { // 只处理Excel + if (!gcfg || !gcfg.project) { + // 得到全局配置路径 + let globalCfgPath = path.join(file.path, "../..", "globalConfig.json"); + gcfg = this.getGlobalCfg(globalCfgPath); + if (gcfg) { + if (gcfg.remote) { // 当前全局配置,如果配了远程路径,加载远程路径 + gcfg = this.getGlobalCfg(gcfg.remote); + } + } else { + gcfg = { + project: "common", + clientPath: "", + isAutoSvn: false + } + } + xlsxRoot = path.join(file.path, "../.."); + } + if (!gcfg.serverPath) { + gcfg.serverPath = path.join(file.path, "../..", "data", "server"); + mkdirs(gcfg.serverPath); + } + if (!gcfg.clientPath) { + gcfg.clientPath = path.join(file.path, "../..", "data", "client", "raw"); + mkdirs(gcfg.clientPath); + } + break; + } + } + if (!gcfg){ + error("没有 xlsx 配置文件 当前操作无效"); + send2ServerFromEnd(); + return ; + } + if (!("isAutoSvn" in gcfg)){ + gcfg.isAutoSvn = false; + } + console.log("clientPath", gcfg.clientPath); + console.log("serverPath", gcfg.serverPath); + + if (gcfg.isAutoSvn){ + try{ + //await svncmd.cleanup(gcfg.clientPath);// 此目录不是在每个人的本地,所以操作前执行一次cleanup,防止某些错误出现 + // await svncmd.update(gcfg.clientPath); + // await svncmd.update(gcfg.serverPath); + + // 自动更新配置文件根目录svn + await svncmd.update(xlsxRoot); + + } catch (e) { + send2ServerFromEnd(); + + alert("解析被终止,未能完成,请看日志输出信息,解决错误后再重试。优秀的你请关闭当前提示"); + + return ; + } + } + + let cb = (file: FileData, err: boolean) => { + let idx = unsolved.indexOf(file); + if (~idx) { + unsolved.splice(idx, 1); + } + if (unsolved && unsolved.length == 0) {//全部文件处理完成 + + unsolved = undefined; + + this.completeSaveAndDoAction(gcfg); + } + } + + errorMessages = []; + + // 遍历所有目录及文件 + for (let i = 0, len = resultFiles.length; i < len; i++) { + let file = resultFiles[i]; + let re = path.parse(file.name); + if (re.ext == ".xlsx") { // 只处理Excel + new XLSXDecoder(gcfg, file, cPath, sPath, i, cb); + } + } + } + + private async completeSaveAndDoAction(gcfg: GlobalCfg) + { + let self = this; + console.log("开始 Start svn 操作"); + // 分别用 try 是因为某些目录可能存在没有更新而进行操作报错, 这是为了确保每个各自的命令都能执行 + if (gcfg.isAutoSvn){ + // try{ + // await svncmd.add(gcfg.clientPath); + // } catch (e) { + // error(`add ${gcfg.clientPath}`,e); + // } + // try{ + // await svncmd.commit(gcfg.clientPath, "client工具自动提交日志"); + // } catch (e) { + // error(`commit ${gcfg.clientPath}`,e); + // } + + try{ + await svncmd.add(gcfg.serverPath); + } catch (e) { + error(`add ${gcfg.serverPath}`,e); + } + try{ + await svncmd.commit(gcfg.serverPath, "server工具自动提交日志"); + } catch (e) { + error(`commit ${gcfg.serverPath}`,e); + } + } + console.log("结束 End svn 操作"); + //检查是否有完结处理 + // if (gcfg.endScript) { + // asyncFileLoad(gcfg.endScript, (er, data) => { + // if (er) { + // error(`处理加载结束脚本出错,${gcfg.endScript}`, er); + // send2ServerFromEnd(); + // return + // } + // if (data) { + // let script = data.toString(); + // let vm: typeof $vm = nodeRequire("vm"); + // let endScript = vm.createContext({ + // ifErrorCallBack: ifErrorCallBack, + // endCallBack: endCallBack, + // require: nodeRequire, + // traceLog: log, + // console: console, + // gcfg: gcfg }); + // try { + // vm.runInContext(script, endScript); + // } catch (err1) { + // error(`处理执行结束脚本出错,${gcfg.endScript}`, err1); + // send2ServerFromEnd(); + // } + // } + // }); + // } + + // try{ + // pakdata.endCallBack = endCallBack; + // pakdata.ifErrorCallBack = ifErrorCallBack; + // pakdata.traceLog = log; + // pakdata.isAutoSvn = gcfg.isAutoSvn; + // pakdata.initPathVars(gcfg.clientPath); + // await pakdata.packageForClient(); + // } + // catch (e) { + // error(`处理执行结束脚本出错,${gcfg.endScript}`, e); + // send2ServerFromEnd(); + // } + + } + + /** + * 获取全局配置 + */ + private getGlobalCfg(globalCfgPath: string): GlobalCfg { + let cfg: GlobalCfg; + if (fs.existsSync(globalCfgPath)) { + // 加载全局配置 + let globalJSON = fs.readFileSync(globalCfgPath, "utf8"); + + try { + cfg = JSON.parse(globalJSON); + } catch (e) { + error("全局配置加载有误"); + } + } + return cfg; + } +} + +new ExcelDataSaver(); + +/** + * XLSX解析器 + */ +class XLSXDecoder { + + /** + * 创建一个代码区 + * + * @private + * @param {HTMLElement} parent (description) + * @param {string} filename (description) + * @param {number} idx (description) + * @param {string} ccode (description) + * @param {string} scode (description) + */ + private createContent(parent: HTMLElement, filename: string, idx: number, ccode: string, scode: string) { + let pane = document.createElement("div"); + pane.style.border = "#000 solid 1px"; + let idCopyClient = "btnCopyClient" + idx; + let idCopyServer = "btnCopyServer" + idx; + let template = `
${filename}
+
+ 客户端代码: + +
+
+ 服务端代码: + +
` + pane.innerHTML = template; + parent.appendChild(pane); + $g(idCopyClient).addEventListener("click", e => { + clipboard.writeText(ccode); + }); + $g(idCopyServer).addEventListener("click", e => { + clipboard.writeText(scode); + }); + + } + + constructor(gcfg: GlobalCfg, file: FileData, cPath: string, sPath: string, idx: number, cb: { (file: FileData, error: boolean) }) + { + cPath = cPath || ""; + sPath = sPath || ""; + let fre = path.parse(file.name); + let fname = fre.name; + let data = fs.readFileSync(file.path, "base64"); + let wb = XLSX.read(data); + let sheetNames = wb.SheetNames; + + let rowCfgs: { [index: string]: string } = { + // 第一列的中文: 对应后续用到的属性 + "前端解析": "clientRow", + "后端解析": "serverRow", + "数据类型": "typeRow", + "字段描述": "desRow", + "字段名称": "nameRow",//必须为配置的最后一行 + "server": "serverPkg", + "client": "clientPkg", + } + + for (let sheetName of sheetNames) { + var Regx = /(^[A-Za-z0-9]+$)/; + if (!Regx.test(sheetName)) { + continue; + } + sheetName.replace(/^\S/, function (s) { return s.toUpperCase(); }); + let list = XLSX.utils.sheet_to_json(wb.Sheets[sheetName], { header: 1 }); + let len = list.length; + fname = getJavaName(sheetName); + + let isDirty = fre.base == gcfg.dirtyName || fre.name == gcfg.dirtyName; + let isNameLib = fre.base == gcfg.nameLib || fre.name == gcfg.nameLib; + let dirtyData: string[] = []; + let nameLibData: {[key: string]: string[]} = {}; + + let cpkgtemplete = "chuanqi/module/{moduleName}/cfg"; + let cfilePackage = ""; + let sfilePackage = ""; + let sortName = ""; + let extendsName = ""; + let implementsName = ""; + /** + * 数据起始行 + */ + let dataRowStart: number = 0; + let rowCfgLines: { [index: string]: number } = {}; + // 先遍历所有行,直到得到"属性名称"行结束 + for (let i = 0; i < len; i++) { + let rowData = list[i]; + let col1 = rowData[0]; + if (col1 in rowCfgs) { + let key = rowCfgs[col1]; + if (key != null) { + rowCfgLines[key] = i; + if (key == "nameRow") { + dataRowStart = i + 1; + + if (!isDirty && !isNameLib){ + rowData = list[i + 1]; + if (rowData){ + col1 = rowData[0]; + if (col1){ + let reg = /[a-zA-Z]/; + if (reg.test(col1)){ + col1 = col1.toLowerCase(); + } else { + col1 = ""; + } + } + sfilePackage = col1 ? col1.toLowerCase() : "defaultcfg"; + cfilePackage = cpkgtemplete.replace(/{moduleName}/g, sfilePackage); + + rowData = list[i + 2]; + if (rowData){ + col1 = rowData[0] || sfilePackage; + + if (col1){ + + let reg = /[a-zA-Z]/; + if (reg.test(col1)){ + col1 = col1.toLowerCase(); + } else { + col1 = ""; + } + } + + cfilePackage = cpkgtemplete.replace(/{moduleName}/g, col1.toLowerCase()); + } + + console.log("package name =========", cfilePackage, sfilePackage); + } + // 排序字段名 + rowData = list[i + 3]; + if (rowData){ + sortName = rowData[0]; + } + + // 要继承的 类 [extend class] + rowData = list[i + 4]; + if (rowData){ + extendsName = rowData[0]; + } + + rowData = list[i + 5]; + if (rowData){ + implementsName = rowData[0]; + } + } + + break; + } + } + } + } + let defines: ProDefine[] = []; + let cdatas = []; + let sdatas = []; + /** 前端是否解析此数据 */ + let clientRow = list[rowCfgLines["clientRow"]]; + /** 后端是否解析此数据 */ + let serverRow = list[rowCfgLines["serverRow"]]; + /** 类型列 */ + let typeRow = list[rowCfgLines["typeRow"]]; + /** 描述列 */ + let desRow = list[rowCfgLines["desRow"]]; + /** 属性名称列 */ + let nameRow: any = list[rowCfgLines["nameRow"]]; + + let max = 0; + let checkers = TypeCheckers; + if (!isDirty){ + for (let key in nameRow) { + let col = +key; + if (col > 0){ + let client = +clientRow[col]; + let server = +serverRow[col]; + let type = typeRow[col] || "any"; + let checker = checkers[type]; + let desc = "" + desRow[col]; + let name = "" + nameRow[col]; + if (!checker){ + checker = checkers["any"]; + + let m = `解析${fname},第${XLSX.utils.encode_col(col)}列数据类型有误:不可识别类型为 ${type}`; + error(m); + errorMessages.push(m); + } + defines[col] = { client: client, server: server, checker: checker, name: name, desc: desc, type: "String" }; + if (col > max) { + max = col; + } + } + } + } + // 从第5行开始,是正式数据 + for (let row = dataRowStart; row < len; row++) + { + let i = 0; + let rowData = list[row]; + if (isDirty){ + let s = rowData[1]; + if (s){ + let booo = true; + for (let iii = 0, lll = dirtyData.length; iii < lll; iii++){ + let ss = dirtyData[iii]; + if (ss.indexOf(s) != -1 || ss == s || s.indexOf(ss) != -1){ + if (ss.length > s.length){ + dirtyData[iii] = s; + } + booo = false; + break; + } + } + if (booo) dirtyData.push(s); + } + continue; + } + if (isNameLib){ + let s = rowData; + if (s){ + let pa = s[2], pb = s[3], pc1= s[4], pc2= s[5]; + if (pa) { + let al = nameLibData["a"] || []; + al.push(pa); + nameLibData["a"] = al; + } + if (pb) { + let bl = nameLibData["b"] || []; + bl.push(pb); + nameLibData["b"] = bl; + } + if (pc1) { + let c1l = nameLibData["c1"] || []; + c1l.push(pc1); + nameLibData["c1"] = c1l; + } + if (pc2) { + let c2l = nameLibData["c2"] || []; + c2l.push(pc2); + nameLibData["c2"] = c2l; + } + + } + continue; + } + // 先做空行检查,减少误报信息 + // 只判断第1列(一般为id列)是否为空, 来判断是否为空行 2020-10-22 + let flag = !!rowData[1]; + // for (let col = 1; col <= max; col++) { + // let cell = rowData[col]; + // let def = defines[col]; + // // 没有def的为注释列 + // if (def && cell != void 0 && (def.client || def.server)) { + // flag = true; + // } + // } + if (flag) { + let cRow = []; + let sRow: { [index: string]: string } = {}; + for (let col = 1; col <= max; col++) { + try { + let def = defines[col]; + if (!def) { + continue; + } + let cell = rowData[col]; + if (def.client) { + let dat = def.checker.check(cell || ""); + cRow.push(dat); + } + if (def.server){ + let dat = def.checker.checkServer(cell || ""); + sRow[nameRow[col]] = dat; + } + } catch (e) { + let m = `解析${fname}第${row + 1}行,第${XLSX.utils.encode_col(col)}列数据有误:${e.message}`; + error(m); + errorMessages.push(m); + send2ServerFromEnd(m); + ifErrorCallBack(); + return; + } + } + if (cRow.length) { + cdatas.push(cRow); + } + if (sRow) { + sdatas.push(sRow); + } + } + i++; + } + + var _self = this; + if (isDirty){ + writeDirtyData(gcfg, dirtyData); + cb(file, false); + } + else if (isNameLib){ + writeNameLibData(gcfg, nameLibData); + cb(file, false); + } + else { + writeDesignData(cdatas, sdatas, sheetName, gcfg); + writeData(); + } + /** + * 写最终数据 + * @param {any[]} cdatas + * @param {any[]} sdatas + */ + function writeData() { + + let cPros = ""; + let cDecode = ""; + let sPros = ""; + let cout: string = "", sout: string = ""; + for (let define of defines) { + if (!define) { + continue; + } + let checker = define.checker; + let desc = define.desc.replace(/\r\n/g, " \n\t\t* "); + let noSymbol = getNameNoSymbol(define.name); + let pro = clientVarsTemplateCode.replace(/{desc}/g, desc).replace(/{varName}/g, define.name).replace(/{varType}/g, checker.type); + let jpro = serverVarsTemplateCode.replace(/{desc}/g, desc) + .replace(/{cfgName}/g, define.name) + .replace(/{varType}/g, checker.javaType) + .replace(/{varName}/g, noSymbol) + .replace(/{getJavaName}/g, getJavaName(noSymbol)); + let decode = ""; + let client = define.client; + let tmp: string; + if (client) { + if (checker.solveString) { + decode = `\n\t\t\t@target@.${define.name} = ${checker.solveString.substitute({ value: "data[i++]" })};`; + } else { + decode = `\n\t\t\t@target@.${define.name} = data[i++];`; + } + if (client == 1) { + cPros += pro; + tmp = decode.replace("@target@", "self"); + } else if (client == 2) { + tmp = decode.replace("@target@", "local"); + } + cDecode += tmp; + } + let server = define.server; + if (server) { + decode = `\t\t@target@.${define.name} = (${checker.javaType})data[i++];`; + sPros += jpro; + tmp = decode.replace("@target@", "this"); + } + } + let createTime = new Date().format("yyyy-MM-dd HH:mm:ss"); + let cdict = getManualCodeInfo(path.join(cPath, cfilePackage || "", fname + "Cfg.ts")); + let clientConfigOut = ""; + // 生成客户端代码 + if (cPros) { + // let clientTemplatePath = path.join(__dirname, "template", "client.template"); + // if (fs.existsSync(clientTemplatePath)) { + //读取文件内容 + let content = clientConfigTemplateCode;//fs.readFileSync(clientTemplatePath, "utf8"); + + let area1 = genManualAreaCode("$area1", cdict); + let area2 = genManualAreaCode("$area2", cdict); + let area3 = genManualAreaCode("$area3", cdict); + let decode = genManualAreaCode("$decode", cdict); + let extendsImplements = (extendsName ? ` extends ${extendsName}` : "") + (implementsName ? ` implements ${implementsName}` : ""); + + let filePath = file.path; + let indexTrunk = filePath.lastIndexOf("trunk\\"); + filePath = filePath.substring(Math.max(0, indexTrunk)); + content = content.replace(/\{filePath\}/g, filePath); + content = content.replace(/\{createTime\}/g, createTime); + content = content.replace(/\{className\}/g, getJavaName(fname)); + content = content.replace(/\{configName\}/g, fname); + content = content.replace(/\{vars\}/g, cPros); + content = content.replace(/\{area1\}/g, area1); + content = content.replace(/\{area2\}/g, area2); + content = content.replace(/\{area3\}/g, area3); + content = content.replace(/\{decode\}/g, decode); + content = content.replace(/\{decodeValue\}/g, cDecode); + content = content.replace(/\{extends_implements\}/g, extendsImplements); + + cout = content; + // } + + + let tempfilename = getJavaName(fname); + let gconfigcontent = getGConfigCodeInfo(path.join(cPath, "chuanqi", "GConfig.ts"), tempfilename, sortName); + if (gconfigcontent){ + let tempcode = clientGConfigScriptTemplateCode; + tempcode = tempcode.replace(/{content}/,gconfigcontent); + clientConfigOut = tempcode; + } + } + + // 生成服务端代码 + if (sPros) { + //template + // let serverTemplatePath = path.join(__dirname, "template", "server.template"); + // if (fs.existsSync(serverTemplatePath)) { + //读取文件内容 + let content = serverConfigTemplateCode;//fs.readFileSync(serverTemplatePath, "utf8"); + content = content.replace(/\{filePath\}/g, file.path); + content = content.replace(/\{createTime\}/g, createTime); + content = content.replace(/\{configName\}/g, fname); + content = content.replace(/\{className\}/g, getJavaName(fname)); + content = content.replace(/\{vars\}/g, sPros); + content = content.replace(/\{packageName\}/g, sfilePackage); + + sout = content; + // } + } + + // _self.createContent($g("code"), fname, idx, cout, sout); + // 尝试存储文件 + + if (sheetName != "CfgsSpiltInfo"){ + if (clientConfigOut){ + _self.saveCodeFile(cPath, "chuanqi", clientConfigOut, "GConfig"); + } + _self.saveCodeFile(cPath, cfilePackage, cout, getJavaName(fname) + "Cfg"); + _self.saveCodeFile(sPath, sfilePackage, sout, getJavaName(fname) + "TemplateGen", ".java"); + } + + cb(file, false); + } + console.log("********************************************"); + } + } + + /** + * 存储文件 + */ + private saveCodeFile(dir: string, filePackage: string, content: string, fname: string, ext = ".ts") { + if (!content) { + return; + } + if (dir) { + fname += ext; + let fullPath = filePackage ? path.join(dir, filePackage) : dir; + if (!fs.existsSync(fullPath)) { + mkdirs(fullPath); + } + if (fullPath) { + if (fs.existsSync(fullPath)) { + let re = fs.statSync(fullPath); + if (re.isDirectory()) { + let file = path.join(fullPath, fname); + try { + fs.writeFileSync(file, content); + } + catch (e) { + error(`写入文件时失败,路径:"${fullPath}",文件名:"${fname}",错误信息:${e.message}\n${e.stack}`); + return; + } + log(`生成代码成功,${file}`); + return; + } + } + } + error(`生成路径有误,无法生成,路径:"${fullPath}",文件名:"${fname}"`); + } + } +} + +/** + * 写最终数据 + * @param {any[]} cdatas + * @param {any[]} sdatas + */ +function writeDesignData(cdatas: any, sdatas: any, fname: string, gcfg: GlobalCfg) { + fname = getJavaName(fname); + console.log(fname, gcfg.clientPath, cdatas); + console.log(fname, gcfg.serverPath, sdatas); + // 导出客户端数据 + if (cdatas && cdatas.length > 0){ + writeJSONData(fname, gcfg.clientPath, cdatas); + } + if (fname != "CfgsSpiltInfo"){ + // 导出服务端数据 + writeJSONData(fname, gcfg.serverPath, sdatas); + } +} + +/** + * 向文件写入JSON数据 + * + * @export + * @param {File} file 拖入的文件 + * @param {string} directory 要存储的文件路径 + * @param {*} data 数据 + * @returns {string} 存储成功返回文件路径
+ * 存储失败返回null + */ +function writeJSONData(fname: string, directory: string, data: any) { + const path = nodeRequire("path"); + const fs = nodeRequire("fs"); + if (fs.existsSync(directory)) { + let stat = fs.statSync(directory); + if (stat.isDirectory()) { + let outpath = path.join(directory, fname + ".json"); + let b = fs.existsSync(outpath); + fs.writeFileSync(outpath, JSON.stringify(data)); + if (outpath) { + log(`文件${fname},将数据保存至:${outpath}`); + } else { + log(`文件${fname},未将数据保存到${outpath},请检查`) + } + } + } +} + +/** + * 保存屏蔽字数据 + * @param gcfg + * @param data + */ +function writeDirtyData(gcfg: GlobalCfg, data: string[]) +{ + let content = data.join(";"); + let url, name; + if (gcfg.dirtyClientPath){ + // name = gcfg.dirtyClientName ? gcfg.dirtyClientName : "dirty.js"; + // name = name.indexOf(".") == -1 ? name + ".js" : name; + // url = path.join(gcfg.dirtyClientPath, gcfg.dirtyClientName); + // fs.writeFileSync(url, `var $dirty="${content}"`); + let result = {msg: content}; + name = gcfg.dirtyClientName ? gcfg.dirtyClientName : "dirty.json"; + name = name.indexOf(".") == -1 ? name + ".json" : name; + url = path.join(gcfg.dirtyClientPath, name); + fs.writeFileSync(url, JSON.stringify(result)); + log(`将客户端【屏蔽字】数据保存至:${url}`); + } else { + alert("client 屏蔽字 保存 path 不存在"); + } + + if (gcfg.serverPath){ + name = gcfg.dirtyServerName ? gcfg.dirtyServerName : "dirty.txt"; + name = name.indexOf(".") == -1 ? name + ".txt" : name; + url = path.join(gcfg.serverPath, gcfg.dirtyServerName); + fs.writeFileSync(url, content); + log(`将服务端【屏蔽字】数据保存至:${url}`); + } else { + alert("server 屏蔽字 保存 path 不存在"); + } +} + + +/** + * 保存名字库数据 + * @param gcfg + * @param data + */ +function writeNameLibData(gcfg: GlobalCfg, data: any) +{ + let content = JSON.stringify(data); + let url, name; + if (gcfg.nameLibClientPath){ + name = gcfg.nameLibClientName ? gcfg.nameLibClientName : "namelib.json"; + name = name.indexOf(".") == -1 ? name + ".json" : name; + url = path.join(gcfg.nameLibClientPath, name); + fs.writeFileSync(url, content); + log(`将客户端【名字库】数据保存至:${url}`); + } else { + alert("client 名字库 保存 path 不存在"); + } +} + +function getJavaName(name: string) { + return name[0].toUpperCase() + name.substr(1); +} + +function getNameNoSymbol(name: string) { + let str = name.split('_'); + let ret = ''; + if (str.length == 1) { + return name; + } else { + for (let i = 0; i < str.length; i++) { + if (i > 0) { + ret += str[i].replace(/^\S/, function (s) { return s.toUpperCase(); }); + } else { + ret += str[i]; + } + } + return ret; + } +} + +function split(filePath: string): string[] { + return path.normalize(filePath).split(path.sep); +} + +function mkdirs(filePath: string) { + mkdir(split(filePath)); +} + +function mkdir(paths: string[]) { + var len = paths.length; + if (len == 0) { + throw Error("路径无效" + paths); + } + var p = paths[0] || '/'; + if (!fs.existsSync(p)) { + throw Error("没有根目录" + p); + } + for (var i = 1, len = paths.length; i < len; i++) { + p = path.join(p, paths[i]); + if (fs.existsSync(p)) { + var ret = fs.statSync(p); + if (!ret.isDirectory()) { + throw Error("无法创建文件夹" + p); + } + } else { + fs.mkdirSync(p); + } + } +} + +/////////////////////// code template ///////////////// + +var clientVarsTemplateCode = ` + /** + * {desc} + */ + public {varName}: {varType}; + +`; +var serverVarsTemplateCode = ` + @Attribute("{cfgName}") + private {varType} {varName}; + + /** + * {desc} + */ + public {varType} get{getJavaName}(){ + return {varName}; + } +`; + +var clientConfigTemplateCode = ` +module giant.chuanqi +{ + {area1} + /** + * 来自:{filePath} + **/ + export class {className}Cfg {extends_implements} + { + + {vars} + + ///////////////////// + + {area2} + + public decode(data:any[]){ + + let i = 0; + let self = this; + + {decodeValue} + + {decode} + } + } + + {area3} +} +module giant { + export interface CfgName { + {className}: { [index: number]: chuanqi.{className}Cfg }; + } +} +`; + +var clientGConfigScriptTemplateCode = ` +module giant.chuanqi { + export function initData() { + var rP = DataParser.regCommonParser.bind(DataParser); + + DataParser.regParser("maps", MapConfigParser); + DataParser.regParser("pst", PstConfigParser); + DataParser.regParser("ani", AniConfigParser); + + //begin + {content} + //end + } + +} +`; + +var serverConfigTemplateCode = ` +package com.game.resources.template.gen.{packageName}; + +import com.game.resources.annotation.Attribute; +import com.game.resources.annotation.Template; + +@Template( res = "{configName}.json") +public abstract class {className}TemplateGen { + + {vars} + +} +`; \ No newline at end of file diff --git a/src/plugins/MsgCodeParser.ts b/src/plugins/MsgCodeParser.ts new file mode 100644 index 0000000..2ce18d0 --- /dev/null +++ b/src/plugins/MsgCodeParser.ts @@ -0,0 +1,57 @@ +function writeJSONData(fname: string, directory: string, data: any): string { + const path = require("path"); + const fs = require("fs"); + if (fs.existsSync(directory)) { + let stat = fs.statSync(directory); + if (stat.isDirectory()) { + let outpath = path.join(directory + "", fname + ".json"); + fs.writeFileSync(outpath, JSON.stringify(data)); + return outpath; + } + } + return null; +} + +function execute(data: IPluginData, callback: IPluginCallback) { + let list = data.rawData; + // 检查第一行 + let cfg = { + code: 1,//默认第一列 + msg: 2//默认第二列 + } + let title: any[] = list[data.rowCfg["nameRow"]]; + let KeyFlag = 0; + for (let col = 0, len = title.length; col <= len; col++) { + let cell = title[col]; + if (cell) { + cell = cell.trim(); + } + if (cell == "code") { + cfg.code = col; + KeyFlag |= 0b1; + } else if (cell == "msg") { + cfg.msg = col; + KeyFlag |= 0b10; + } + } + if (KeyFlag != 0b11) { + callback(Error(`code码表中第一列必须有抬头"code"和"msg"`)); + return; + } + let msgDict = {}; + // 去掉第一行说明 + for (let i = data.dataRowStart, len = list.length; i < len; i++) { + let rowData = list[i]; + msgDict[rowData[cfg.code]] = rowData[cfg.msg]; + } + // 存储文件 + let output = ""; + let fname = data.filename; + let cpath = writeJSONData(fname, data.gcfg.clientPath, msgDict); + if (cpath) { + output = `处理code码文件${fname},将客户端数据保存至:${cpath}`; + } else { + output = `文件code码文件${fname},未将客户端数据保存到${cpath},请检查`; + } + callback(null, output); +} \ No newline at end of file diff --git a/testsample/0.测试数据/CeShiBiao.xlsx b/testsample/0.测试数据/CeShiBiao.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bb5896f15140dc0e6664d3fecf9f8d53728a95b8 GIT binary patch literal 11842 zcmeHtbyQr-((mBzuE8M$*AOfW?h-7x4ek&$xH}Al;1JvsoZtj^4>GuG&|pE{>+OTkrqx?zMXM+G}_Hrn`6jx~i*6MIH_wAAkrz1^@um09QVpLN6EqAQ%Avzylz| z>WVwqyMpXp4b?pzK`#1i9(J}=x$v+|IRIE_|Nmb9i&vmreMAYC6T2<_8Z+GhL-)ie z+IY?1OC9$F##-)5kXPM;&8NLX3VJiQZ@2#g$JOnZmhDMfge=L@Fv*16Yo^!ucwA)xTp8#6++yl}rM zJ*fgBYs|AYh)?_r4_IXiYtHVRM|AEwSM`>1Pw%qLDKFLN`YWAMxnknXnMmzoJC(^Cwn)L*42qxFLgC#x5Hy5Wj@!!Q%KS*EUJiH|V8F*H$Lq#KLQx{AZQC5rup7%HYj`dadVWXxA}5z%WgvIBT|qXN<;i-qG2* zUKv1%EK-zFqLZmyJ6A?7Y`W@C4wK?NZ5EpeE>)(M7HKdp{<_;FFRl>*fX7ETfXZJe zTc^Q6djZu$1t=rYpp-Rq2HCo>v;F-2FIE2+^YcHZUJh1N?&3fXJ(jr(>%W>=ipK`Z zyNk&*Q>**>%PwNo#pKbEEwwX}W2=(}!AbkI`rZvfmV{#V`>8M2dCH@3@dat?-77-h z-#WcPVrFnomU1dz>&9`L`95=*DlO;9SqfNvGRbm&LE~v?X4`Qtk=~AX|CUuLqhF1N2ltw5OuCOg=ewUyEzjvtre`-l zN>^F`$v|M#lj3El_4+$Wz(`4l@X$A+Z~y=)02#)^mi=Emad&XGF>!FP`Dxky%^4V| zd4u---+h&Xhpf9f&?T=z9)c#?oVa{cLY>Sf)Kcuyef=Gio-3Fj>H2IQ+o-)5=!mzk z=9KwzMH$fy@pG@Zrh7taL0~3}8d&ZIGPOZC?im`P4ezj&x6PzSfJ2zunbm66vQF42 zGD;H(FE$B+?OJpwKwnS^qjnOWe_oPt9B;a3GoL47qUfAhh&4IJOC>smAEp){n$$oQ z`5|uf(Wbf7nnzghej;HDjgaePycaB5nYfyl zq%A`fQM?d=2`PjsTZ11TqV-|@R!3cY8upW<+3aO9`yVg?H$ z@kwJ7sx0Ple9LX|Rw3?g{ABSe^lbHgaVx`q=0dFyvXSLZB-i@Yd8#e+a#z%&rd2;8 z<=KXe5T zwpbXMfZ5;D6KsNae*kTHox5drM zBDeApdCFrV!wP4eJp@O+Q`)SFf}B4za8U>vb}9$o3Wu$vkQtiQGeR zv)9kf_qa8c|B*sQnO#uQF5=ziqt7In#7_FA_M=0PZ$K$O$44bwx!J}~i!B-#ddU;d zq7SC#4`wGb&=g1CcuKJ&tIDM^j1i=mI(0qc)QTPU2KC{d*?4wt7I4*^wREI7Ml!_o zB^H{_S5|JdNNV*r%I4ZcRo;6fj7Z1@?#}Zx)L128xG4pVc+K4%J+aMKOi+A}%0*d%7g|KJNXXi#7xuM11^)cq_Y2Rv2==!vQK1x_rwcfTp zgU@S`ix!%i#i8oVzI^fwyIN8~YwDmYn~Gj}^ossuZ5%jl*?=>6m*R(*`Y7)`hLwS%ZcZo>TJn2R5O*&~+a7FUmVdGj@+X%IHO{ zk1UoVSjweqH=O%IEq2#+V-K2n7sx@KBL>y-#^1G647HkLWhHW7w1$acr*$YwkHq%L zMvfBzWoaZIOes^w^#}v3Uo^F2JlUl}(*s>K+B4NQY z7~VZDnyPUthN^TUeyg}%0;qmWL(QZW(<1DwsmG8oLq*-_-L|mazsKk^C4oqs8H4gP z&?(>)_tA{KI2%D%w?eeYBi0at9;ZqU(b&2W*n2xs<1bSja93gufCDR>q$QBH@VtUs zep3STv3S~_U)~y>Qx&eMxExDQAaLo`V;78hda~Ws)2N55^b2@J!j&Yy1@lL!i~M); z3fghWcS1=EgzoLMzxH((OAyG_#IwQYu;7eY?J&1dFCw>h<7k|Z1 z)2OinXL7rM2zeiWg@5l|Lk{ZL+HxG*;!FP_R6=HsnZPpL1RJtxN@V%z#Cw6YU99T) z{vtjKt5Cf06kA&woRX4UL|?o%0a{gvD&0MCmv8rcRV+$LyvX*vY=kGrz)cj{czLO{ z-I*a$ExS_PG0UcpR?rJ!wbu`au|7|P?DN`3WzNQeWd-7mL~>;W`X!If{7u9T+%L0i zd@$h)?S_ZWFH!z!1uP@ySks_~i+!@6r~W@Io2w< z$=!02uAoFlHIczJ2snetK$%IlV}Q4E@C;%#Ko%&SFFQ5YJ(O?7?wwLk9Z)N4YG@8p zh?adDLIL3)c(XC?roJGGYK^y&JtiRH=PPpA>anNvWn2UYd{&E-H1-}=Vlw{9ij+5y zY-#lK3_vzyO2k}F2~5A@+@y0!ZFQ1S8X{83U~NJI&O z3)=aMZN}{P%DY(aW0Y{d7s?G~THk-!R↱El6sfK<47GLHcqiNDBIuu7)Rj9Pyd zNO%pHk2|l{Ezl|1Uq?H8=E66dK4M;x1u+RBjlb8X1hv{YO<$+SzsOp( zlKz^Hhyq|q)fHJN6T{8bK~3j^#waZ29X z!OzroDBuq{sn+mM0;h8Tp7)24*|Dsg*)hr|%idld$6;MRuCR`M96$ni4UVJ)jBU5K ziK1TV-L{H>cI%kKdb-#{3?pv4U^YDjs`w;{3dCuY2<141LeX;a0F4wSwKP zfOJh#nB#29Ms~fNm0S6YO8j|bru)Mkoc)*K_GNQ024tq&UAz$oE$OhuJxDD=O-FN0 zL{SO3lp|W}-7xkpqiK2`6poSy%pQ$`a_SxFHwZB6Qu{M}!5jh7DFsjhk>G_Nvp}(+6O-BY_B>^jb;0@S!;is^Epw zkxRwt&EbZ9#p+|44^$lI#4Gf}P8%R0wdbc1hwH%v6utyya~7M++QE`~y3FCO62#I+ zA_umU}OMNTY4O4{H<&%iZxY&o+i9ssBFoG)~N`j)y!jAXt>qZI&2PX?$@bQTUaEd?S zMPA3gv`p(|?DSEkYtl5o5!}VQuU~PP4TFCW;a)RP76`&yn`cR^oL&h&U_PARwH7Cj zWz|_oV33O(OexN0vDhvkB~=OYns1i!_%sI}m8=Aax#VyZ4en91MXj0oN;oiI}$v=D8e>)cff1WIucQOG7ap=7p`@L8BROVkT2t63h7$kr8(aU=`SX+l~Y!k+ci z?5jr$e3sf45>i#4fK@6jcV0V6dRL)=wzSPwVXMHMzsq9RWEQ@5H)-U!uej@t?JB>z zMbIcPUf*Sf%sn~l+pu#jt6jU#jgb)Tl)cG0d5{&SIuCCJewN5{)-97Q7#E=`rmG+2 zgJ#EwqNb|+UXF$z$9C^QPOUECW!5aueUbAKj7Mm`x z=jDuA9b{JjQg~n0V>|hVaHL6;b;!}hH|@EaXFCd&Q8<+$5~T2#273&y@C+{mzh6QRUB|3#5P*^XnSyslSBJAKxz zrg4hBC+UuawIHSUv8G`69-fVf*@q$kn=J)Fs>y&1hKPB)1Nd5@E7sqJw~Hd4)lnEd zj=E$u4RS|dX82ggYXM5B4s|J9D8RwRzoaEV1G@PqD_m00mS-I6YtjuNq((ERJma=; zi#x>oIz!%=dvyuuiQf-ZbSC9!%)8m~9eY+xw8yZMy>K&UB4X#A(+meOnZIE?lq^M< zWVc0lbG&TfRr-{o#n@DIOVftL#=d8$4$q;EM31}ks5&qMxdfSn)2f_*nr#KaUh?Ey zSG^W;^=*coP&|W-e4Mal#$k>k1M46ki>JHywjKUr{7&XKb$0bV!#!8!y+bRP?NS%( z(~+f}y^KunxzjgQQ{Nj&BQGr@_Af1+<2eI3*&&haUp$Wa;Jxq+1fo;Gm!K~cjq1U# zLVc`YdK`jm3M(J~(UjF&0ku=%0RSl+0084pPu$hh7W9V;KCLb9u)&AjMzrgP?eYHm zr+k^vt)5$IqX4_Amufj$I=QwcPbcDcrTL0T-fgUn_vE5e?dnt@A=%R zS`oqQ9gNaC%uMuv~E-xdCrQB-=4^+dlSnNtpINqAlF6S+T_ zu}7<+m0a05om3UHGL|1@Y|0fHPnge)r%gO^-s200$wvL7wg`U-Zn_Nhm||8m^TT$u zIc|^jSFC3;zG5J=1vt^bF^*_hepCtw+Pf2wxYAJcp$uW(%bVr>66&A>{C;WdYl=W> z!1MF_ad(>8AW?$zu{f&hF`Sn-lLj0|0S5s%qvSUNXteKO$1DRG7{O+oG3Lx^-_FXN zIl3>vS|qOE`n1p3%3d~H=5$0Vip)(qLk^w%Cw>DV{(*ud7Wf}MB2vpGSf#V^USRX2 z6G!m!MAe@yMGJUJxO|blK#dA?#ua#JkCQF&@m;fSgOn`CYdK=U_k%v^hBXj2{z1D0 z{B;64f(x_P*%0ae!fjQE410%LUrK1l3WpfSRVsSR{HOa_h>2{e1h4g*w1rG&2e*Uw z(UpUN#n%2j8|jf~U{u~0bF0LQ;Qk2UxH?}M{_}8qu4eK($gK9k$}3@b>Nu^Xxh<@P zmkXb&VDevCz#-|_cU8Or>uX(3nIi}-mGa8|sJFnKFA)4b+md_yQe_O#r|7I;+%XSC z#PYR|H%`7;q!Ryl^9a1mtwg<`fm^?&9G>O=fjvD7yj#K8_qI+L?JC+#J|wGd%!rpA z!%uEFSYyP8*P#8te7Vq7x9!OEAv9yu^x|}Xf6UNtpP+gxnJa}DQ}UFd%kbFm&hfkM z5PMTSrzO`mM9%#6`_Otbo&7gnl)yT7jduV|~sXCnMV0v52GyvS5cyA(J z%CA(7m{|%I60MG-2Yqm0XxkWtb7(rjYY$uUTNj4ZlNYsG9FzOeS&9*}>KfKj?jHvx z8hOUysu66Vl>LA)JL8A$P=7y=2-t!mHK6%8K}G<8_-_Z2Uq_J^9Y}1R46cu%)ng~{ z{L{0~cDV1^LGOgER~%|JrfG&D>7I3+{rP zUPd#0X0glYuomB}zl(&o_vA{f+!;(4E+lzbG`2>~I(PY?yL)MHcI0urIdmVuMA^lp z&Q4OI0r_#i^@;`Wm^0Vu5!*e>(9zgeV$%ExjaC2QY^yG?yGc9e4%wHfrjBb5mF7|3d6 zIaA9Qr{+7=L9bu^#+~HlE3Y=xcBBoeNW^3awWr_E3nxJz{^NYlJk)V|VmIwJDafnS@dp>ffP;k!|6{@Cu53SXk!lpq_^!fq%fq0nCE zQw$e>_wBwPDIqaZDQ}iORK3-bV)u|!W`<>YT609SQ108y)g3as&Q z;Z#Xi7RwAQ9as0lTvM?byXQ|x$d(dGB>MtOVx%-0LnX%Si#BfDz~9!5P-~*_nl0!k z9`gry;>>&|Plq?drFO*g7)`mEUl6KaB9*|8xO;X?47@AXh;2mGij?o(ZyDM+?1ICS z9Ntd^l4Ob;WBRHFSM1h$&3eG4rh8t3_C!vT_}|KGmPnm*#Lx?Scxe*(h&3D}(#)UT zjj^4)R$R*y5U~NHOO>QeqF?whQKqd}$(@dcs|FY?^b*)5M%G(NLdtXP3?}M}Ep;_( zE0`C)64<3j@-^fh$q#HWQ)eHCesex+P%SdRQ)<1s3fqo-tB6v`YYCns>Up}V;?$Ic z^pH+4O9vO_%N{A1;}Nim|IspCy;kwrf;oZRd1Sq$B&0gmPGh3J(h{Ox`}wV|tnj^2 z(Axs}V|C?3be7xJVv8Uzfxs+;*=WK{E_2&zKE2kW;u!sqBzZ5Mj63h>_t}CWD_-%|r$Oh8BWr{Xyq1xgRzUI;SWR?z?XL{^2rOiX zu&L|Lv`v@lk;wPX?qoPK2fQ(q+85s36fbx3$i*4-vQJh=IpJWEQQ!j1vbnI4t5Z>M zV8M=~Mz+)0d#DUC^l$hD zSVeYtlL+CuR`#+w_uvOND_+uk1mzgTaOw(_&q0gXTr5l#C^**{8QjEV9)!`n*p>2# zuw4e6*t?c?KrfEN7?eHO?h2j;x{76cudsR&^6s7j!XVCR5QjTQpP~Te^!rX^q!!Md zmwc691fq=O^qq-Q95l%h-|M3nBCXXLbLi`NXh8J7lJJi+YZ=hCMuf{oe|(MJJ3YT? z)fLRY<$<25NEwhhLPBF46pDs89h&MiU`$mEMYwp)okBT`LWVen5Up$H^4emN&s%cm z?Xw-Xo3~h$WCs<7;RvrR@TPht3HwZUZO@RA!ne^AK2c*4p%=%Xv0?^2gEo0q#HpY* zKJ-E~;)aFo>e0r|%gE6iB_&yllR53<@%GZ12&;|As0~h6KF?sd9074U+Z6eq0A*~5 zQ=K59u+BF`L3?5?w!{iV9QJi1pv>=XLy%d69c5bj%uX^>MAL1Twjr0Hsm?8;KS#01 zX%QX_@F7Gm4wC1<46=c?C=Tc-GFCWJ*o+pf(}!LhC?>h@W*mQB+^4m5oKI=9XwMpF zC^Tj1CZ-g(?4?4w>LUpX?!a(HoaQ7niJs{NMpwzKA|g+{#tQ#qD*A=~m2I3av|h05 z^|xD7W|g=}hKLZb9-5WA%EDJTP7ej3qM8UKpMC~NX=z_`Er&Lxbw`~Y8$`+(N0Op2 zcVCZ1i-_XdUJY@gj*^SasIj~%^}Vi|TD(vfru(2!oJ^Y0{M+|z!HjPR) zS1hW_XKz`7`@1Bv&LW9?j7grv4q{ABd*|j%A2>8USHw+CV%siwVcIuZ8Z4)uWy*>A z3N+Kg1TIqD>{($mJKi^*o=j_~^u-l_7Omk!B&$60>Ya+(bV)Z8YD?qt$HxXkzYp!o zl|QVSTLmgu3GeUQvhH<=98hmB^)4fv0;~fuH&JHgvw+U#_=nYL)C*7K&#GyfKZuGC z2368c_K?P@sZy()u5iz!A|yGu1!;;1KGitIqHo;3CoSIi;C8~q*&f=S*tJKHb@q-q zk?T9+S1|_WQ{b7|B-Yb{#4WxuHfw{ysjy{;UT2Z@LufqrC;I%6D<#hpZqxiVt|FnI&?HLjne~$dNViSAfn91nE3< z6ZVhGwM*7W;{Ed91g@GH-MRVF@hY_nE~)s|C*mEtRf`tz;tY+58Du)Z*<@*_IC z!pCX$96=A#?_+|9X0;tZz-CK;PxThakHkM^V6$K4ged2ANjO2CvjSV1D5`+I5ft$x z1!%d{$n=3!6xfi2a3vXf>HK@QH&`m*ml&i9C&2~Lcb;(1k3RBU40e~4Io6&k7B#-A z2M0ZG!fGRpv4a#IwZ!3^bDvdt`W|IRKASp{gJtHT|LjTy+=z@;V0Ut=J2A#{Z>e}G zOrGakP-ynV-QQo%1R&Ba{OtI=ugEzj(mpI@*|eVN>DK+tp_IXedq8NQ2*$(v{^XS9 zwfXA&=rJaXD3nulVrN6&z;&X3(mJ8>4{*uQMJ<6g?0-4HrpC6W;+Do%_CJ+QD7Fd} zT6!em-RXx6@%FZ$rjf10W~sP<1KRTjn7Nn*?XHlKr3dtNq)(g+GJelxuKE;UMJ$H% zqguk3v~h*4nU={amgqfdVgMG(uv_!QGQA%rTlGF7A>4<$@4-wWDsEg!?;82z)M{)f z4)8z~n}jG5tc;6s8!#?J{xb#|aI+}thfiJ>80OAgKdCZ=j_~hJd`%I&DG>T*5!#@B z{LgH$BQzK23UYo0a&`Tg6#V^}lg-4+-oz*eouiuL(-I76XZcu1M}NlvM-(KO7NLLL zBHYLXb`nQn_~m3mXE4w^zK$CxK$V6PE_UHZ^|ArV(0>?4uFcG0CzQaMPuqS9QjJMK-jWg&-DFIm2SrWL=c z$3`B14WLuHC)3=w;E=UUQ=1m|PEY0c@;x^n#{62RM0z6jIx%67jvj^B3Js)5BJjFx z(NhYH9r84|9+9g$;3ekuhP3Us3b-c(!SGKN`eg|6(p5>#5bBWef-z_czSo7P+!EA* zO6bU6duj$nxbiDrJuRnAfsLf##|CFPeeM1MCe*CI{j%r0p~7JiHflvL+5Pm!hQ1Y} zK6)Uk4t`{p*sRzd=4`mEaqVf|MiOiOcswm9dkAL7?wbILAWOw`v@JLb#SC7myzjCq z#}oC!;1&WH9RU)nV686_Ni+4|Wr=Kva(5txD}IJ=TkkG|RJ(uZ5XI{DRV{2xRl)=b zl0BaJeV+4uaJ@P0y1d)z%C_Xa%v*=>D{7Y(Q@1?b`O^33Q7w3xpZHa9vTWE`wPZ(b zuBy8;4#o$(Q3$wi;gz)zwZ4^>w6|d#Mhu|#Dj05dTu;7~k!aL88lllu{~{hR%Teyj z^vQIwbe2`t0Hr2yy>y3foO0dj5pwP72NqF0?Umw{`uIrj%WlEIvO<&Z|6IxX@6Y`2 z`#;pRs>uHp;IDOc{}%jtuYq#uKdS707yN6j(SHigL33>X_sXN+ael8i`GrId4SoJr zee%2T?-dEZg!$3_5dK?z!tV&br$v7uKoiaX{`>z|lJs}L-?NOr0Dl%$KJ9zEfNrgH0KngTqu<4U zH*3EDLK*%T#9xfu@6x{;lwZUFoTkypZVw0{{bbalAQnm literal 0 HcmV?d00001 diff --git a/testsample/0.测试数据/CeShiBiao1.xlsx b/testsample/0.测试数据/CeShiBiao1.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..738e7a4d780068d3f3e9c943cad992c820c6c524 GIT binary patch literal 11753 zcmeHtbyQr-((hn{!{8d+-GgiJph1EK9b|BKcMC8`fB`}vSdavQ6Wl#Pf(Hne1b2rw zIrrQz_vD=S*8Bgvd#&EGcGqur?e3DUDos@+WI_NCfCc~nXaOEVhQ)pe06+u^06+jh zLo||ecJcr_d6??>x`5qHxO^NPXbO-KS@Hph@c#cj{ulp&3Y}4PL|#xE>;eb&4BP0y zEWvy=#7_tR00AQQ4tuHoI~JPrzJrVfmMofa{apR=?PHr_DdUG#Pi15&0vP?k`h+W< zJfFwe4|xN3#p4i_eG82bG-I*zNpYN$s@rrE06~6xE>yv(33H9fOZ&XT2bEo5;mKysW zN53Yp<}dF=Zgn7S?#YxUt3W7q1wYOpn?#P8CB^Vf<`3;YR`RY=c|Owht{!iH_DTwC zcksT-%XR;Ta*&**kL?o-GTUM-c1bkxl|Mq>mvVh^YMn4WvF1+k9PciG4E)SbpLpVG zxP#dPG($RY(`qamB_b13>l!kn?hlmcH7-ZCmNjlYF2}q`43v%5Q%{0$rLZ%bC;2D5 zH1f-leUwLzK1OmdS>Wiw%m-qqdFMPK*V|^Zp5k6@X={^>;2vVMNhW#$1OV>ukpP;1 z5!pIj9{LmbI(!V5NKClMn!14<+_|}ap8qSV|BL1GKUlATs%dodU`6dK-9!(ZPcJ2d zWL3Rolv-$Yf8Y0X7I)0q6%SJ_Q`H#)Vqd<`9D&}VZk#Q#ow`|VniPAOk@!axLerFRRs(< z(4JnB>prm+v3qBc=O#+$Yii}tar_9@PH-E*sh%^SO(%eV!8fkh&zOH2Y*;IBIGpR- z^ANqeeBfX(ES|db3*37BT}Ys)X*}GG_>}>zjvi)0T z5a8ww-uHj^Q2`x>^zdNGpGV$>e`<5(3)GBqwf>}?=?Du7aY++?Y=LSNxV~?%Ejrkd z>{P?6)OAi3+p-YsU3tMkO>RSErHm0);RUv|N7?Tk9;J`zuvK-)Wkf+jncbSvZ_$UO ztd*E$OU9I1gd=t@Iu~KhYev($O3VqDh;s1!_f@V z8bPwQ94Vk&4?%w!(YmlfM3X6jf@S$jEFrHjk-7{nw+09cmLJ>lZ2!pkdtT@J&Vl!{ zTT<|;|N9z3x#fTI2EHyf;EEO(-UGgd{&V#tKu4Vxc(D5SkjyQR|V}2Qg5ADV`Gg5>)vaA;(z4VaCZfsZgN=^^JYMMS6!f{5|jnj5-{`05y2&v zsKbn67U-spmjt}1Mo?0)krOACHz$+qcJZu44)87zG@C?2&-d**vMdb9u~i5F z+V}|9->C?%;Z^G!799hMdSW&<%}iGO6KgaaBvTHr5FFFcxSB;rLFtL|K_7>Y5~{V1 z{B+r|lPnj|&+qbJlJUiljx&Rl(xvr0LW{Rojx@FL4eu*;$y+Np;&ZIG8??lc!)B3J zX-k>8#za|?YMFmwDranyD#jj;!bY2v2#L18EC|;N5$CCs&LnqY@zBk7a zGgb}x);xWF`yDu=J~(wUz4Yu$P^hRtS;51HGcytr{?XLLh?7{%)pGRD?r!{j@8V%I z+{48)aa}JkxXtP3q%+<57iZlW1L@jm(kqI)1zQ=V?uhd6>8cR|^;<007~?rq$in z+zo8?#KXY>yS{5W5I#BX5233&_x8rjsZSyiKE_$!dgjgeAyNUYQ#M*;&Mxj&!qxU=Z z_0uA86|bRjTT8SKJEBF|3&NWV!=yN-98E8`M}HXEw1j=t(Tnc3a}eugdz-e%#wMAz z(Hq&IK^QaN=x7t`l$)L?@Pn<5^Wipy`n7D%OcLx=k<>8baViJUjA+CaD&^l3B5Kw* z$|OBY%FAk9UaWLWhGjN1R#5fadgmH=MtF0}-!|n!B6WBwqJv&1QrWLzXpb!(J@c$d z%v39UjvnlaXAsd^h zk>|6^j^Wcq6D;7CgyZ^RuUtv}`WBxxJ>rHgA@CK1H%Dwpj9i!CjZirR!tv^^KhU$k@!mr)6YRm~(f;~^MwFB5%bO&z1q7y zR{28OqXYt*elKUcTPNG)J|xAUU9#I6{c3z)Vm!cqKV^NvUxR4*i$BkW7ijxqE$+!+ za2X}&Uc}sR$c1IE9~`9P#F@7Evd%hie9o|UhgE4UiP&csbozngZ7yZ7^WMzmTVJfL z_57Z#X9v0T=V~eKFmLwKeZ`;(_2>Gq_Lnay31QB97fEz)aaQSRO$}U;Ik-+_ACYGQJ@MyB05_u*ON@m}*9hT(=~#eRtqL z&)F_hE&OAV5S>#z*?f|#EgMN)T_v_Z`6&@*b)*)*U!K9s zc#4k|Zy=6Grl_^t>UH}Z>w)^=q7vE$cRSAmsl}ZN+sBlS#v_zPlFcLwltc#PcaK6W zWVXG}^6Ud~kc%BhhL6wC|LG4H8_OG~!#5o36h9*Ye^@&YTd*UT`;YS)*5Zt(W{<2~z-zbXTx*_0sSz}pFNZvhaV?5!PKy}Hx_B~3 zd=<2PK5x-=VzkBCmN6gT4XDjdxRup5rWcoQP#0M67xYAll)Sd$-L^M%FVW_A1RzYD!iNmTs5-)qE z!kQv|9gkDThnY`+!wMxa%>+doUPWGZ_H@gD%12b_1IyKT7P=uIdN7pcXuZOK)ADSegW=)Yon;eC09 zp7KppMD|)dw2rL5F(b7~cp*VOp^P7?pJsu+xyS<5Com!lcZR0w*aGWi(V`>|Uvnv`akXx%p5HmbrLlZH7 zIJ(CHok|h%#;R;F9*;;B zE2&Z@9&Sa2oDzq%g@=xQFkc22_Q+$%qe^DY@NCJi6H^OV=2$(0*^!e}Qx71#W>N4r zzFcWptOVUY_!=@9x!NWlOR$$3yTX)6nOclq@DeMMIYS@ad)u|=Dw8w=q08Gx{MGku zrCcquQ!?$hZS^Bs@-)V?@BnSUEUQ5q9m@oGL~boT%`9+IBDLp)De;)-x?B56z84T8Y8gK`KUK( zu`Ih_7p9}5Z;0?{D(|svoW@2%zM9&(Uw91kNIMn zrz)AO@r?B%Rc33Ysx#G^)e8-dOTc7K>J`gd#5)JlOt0s=`0C5dsWw4hks@C-ze{iNZ}tc^l|}$xm3R+30Y-e!=@u^J=yq6qNhs zT^?1s3$+EQOmJwq#IED<0OQt&Z*e3LpiMvTutm;fCD$icMx(~EwOH&;Sl#DLRQuz3 zCt~ljqD-h%NfF`XMQ}Y~>&p(5UKI^Rnuv06XiC+LUq@t|$U9Bq$#wF*b)r zvX>a6BRmCAtA4afNb|mKHc!m~VmS%jFYf!Ic+xMe-#ihcHX5;U#P#qtGvW}tPis{w zlD>+p%->wPeykz*DtyLa$7T`2X*pWy)8zM~QYhS>snJ9)nShpvmYyl`G-`hJx}y^9 zOW^DohK!!+yF}CpWV`Rxn2D(mY6oA-&qXorJB_y{hEW`Sn9Tha$rhNZex5LvCty=0 zT0(5P9GEvc*A)H0ltj!Vsr;3#jjB$A;#znDdV=q$UI1QSi#N?jqk|#yfwWp~g1xRH zx*Wb8RZNy33S)lHHEy_#`nw%B)$HidLbF2wDzxJ< ztXt4fyh2$Y+T*0sJ?MJfu>rdsQ<1OkhE}l_9+moLDWs@Bb8KWe%tn|BUt6u+s6_Ri zB@y71XLJ)m^r|0l&xW?J(2LcCPC8^`apyrPyVQM zjVBusE|!25hs91L=aT`7ZG^d$)D91q_Jad2R zjs#`gxQCSXEJnt9E)c=y>T}O)alM>jheR%>Iz2ZO!{UV8=i=HWm;~=xGxHc2HO$Ne z_8;~?$l*lgF2hxxl#p&^J^bW)yNb!yX7HF#gSsNUW!iMCn=34pG?ueXuC}|pEP(RId<-VxI!`I2c@2g68k=kHxEsO9Tz;5G)%C?0KAfiMJY3#B`q;1xH z){@X{-gYndJ)bL3JQT#av)#o|gKtEw~ zE47*l_3nP0jf1wKD7+z5S`}ke({)nLKC?~}#kqVzgf6V>pjVLilG-XpWn67Ic{Gp0 z>Y$}F`5tNew15leWaK<3ZFxUlkdLN!H7sY2Pp~=0Rbv{Ay-zF79rZgYP~M^K46iHOq6AqdWM;JkY(c zVnKa2BQspU;it#}zrIse)=&WL%;Kz6uZRY_MZ5qoJ!_Hox-PzAz z(BD+b87}&B3-N37P+_zF<596Z{upTX!;+d3dEcR znh0Q-9G^d{#W_0EY} z8`t#*UU!ni%J@pbgrWZy{yb3*#BcBPy%f{qW@`h?;TF z1Z^z{-*JY$aat-Oh{Q)ZO#xPc;4!+WDQaEvT_DuXrSj%Lu^{yQ?f4$fRb%=dp`W`; zD~_3mHa_R!!@%3ZZ-GMCbNN(PeP`De8Qu|3rw?j-Wd3@$iQWHn+a z$!S$DP;l=CaJ$>oTwDIZr?X1vGMVmPsC{r{|lU&o4Jd^H9jIE_aG9oOvp8 z2VLV!jNPmR!9oQq6;KzMT4#);l5VGv<~j0bphS?)o_4Oy@#kjx;;aY;})31GZvr0ppWPp{`O0%Edv1eSXYCw-cqwa!g` zZXVvZEZ)dW>vXR!X+zzCG}&f#A~!kOdacM2VRtdzksJ$3f!8QVtkF}*%IeJ>I~~m( zHLZ_H20zWLR`XMPr|?h$FKv3v9%nRZ zZ;E%_dyxzf@xc5S0@U|H9$)Ob0&MPsmKHl^!SzT8#dIM7Mf3<}pH1o=7!*yT`_&Qi z$#^+HIRHV&wd{IjwS|ge$7hrErFKT2Yb!76;|ggPI-W;)x@8qI{_H+<5n(MFE*)xf z!e=!i?PBYf1-{~2kCJU>Ss7vJk$sC7C(WIWVi_yVp^6h;d>GeVtMOT9J!&O>BTCmV zYY|%bw%d}qDJ4TLPI`|*E5g9Af-jyo676IH#sixAloq;D8(NK0f{lf218-R^`N_l? zu+V(GN(e1c^+pu}Mgd7Yr^p)%`rIhO&_0O*G=|PhI^-aKevs8*S}0Ar6DbfV&e?o{u%lFgeZ(G8{TV*-9mx==#op zB$G835t?5r38u02Thxq66wT)4umz5iq2bIEPAG&w(~jYB87U^+LS?PJ0R+|6%0=p3 z^V`f9m_H{4X+7_(9khW7RL&b<+V`JE_FD1?ea&(`qsbGAma#N-A$@%abuS2w(Zd?J z>@?DMk}{?-zw`8MJ26Wt&o)UQWOS2w7JyZpC_5LiMvJcy(!ZId; z^}Lc2*jvmPjt6x68iydlSd4GFAvBJHzxi@N7d>TLG46;FomC5UP<+)VCL%3bMTu7^ z`-H#vEl%8fcbxDY0~b;OlME~c(t%iZ;Cfo-n+PBNg1rYKY1ghS_2>jPLRc|CZIvk* zr(75DN3uh5jIT*4)UL=T^`jj^d4=f5xrM26zPhLjfNXn1a`2y|gPcdER5P8Wb@XZP z@I{<5^1@3a(n`a9m?&{ml8-deS^N4}*(UW-Q94Azt2Ni3x{%gpzkq-K0v7Re@NBeS z=F492EO(Wv#2jnN$mqz%RV#^hAAr!wu#|0B`V>-w`eq$cJffiLLZr!VO)D&_l&Kf!lJx2+op!8&X1BTpJq}eHaq;#~svp$$H)pK;;u`KzOZAjsG zq|6w#Ir=#ziTFCx?-tSd{Erw7+p&(-qTfXM3>#{Krjsq28D5(E4Dea;Jd%s6PBFDf z7&U>8^9ZE|M0F+yM7h#Qav1Rf(brIyZ!{A%E4uY9*i$bkW%ct^h#FiJ3R$+xI(MMt&;iV{ zRUa5xE=OP~g@+Y^Uvcr)x<44?M~sr=1<>kqfFw&C8af7`B5?&d0=?VAI z0-#!|-8_Vm%P9A9gZ?lpu$A|c~|LyUv4WFozlruDovDpFW%jJgsl z)9cInQ9v@H91=#YcP10zy|2X6jVd9mp^-93u)wNXNuzr`VWDsnZdG1_$qb{3Xb;*Y z>)otmJB~)8{nEY)fQ^qe^Ib=veLU7Ux4A2}cMyfwhjJN7%J85fre2VDL`Z@xK&VfG zegFH~lO`GY_U_EZeh*#zuBhX=qz~WrkrGin$#1w*fM5BT;-SS3%4BLbJ^W@PftToU zrvK;w>&|r}XTaZ-!5awP;Q3NZa|cT~TXQ?7pNmfXc{K*SfasBbXYkYdbGNt{B`7N6DK$US&LF zH_0njGwi!2M_Vg&au45;VpVc77xkbHsYlg-&NsCnUX_-CYzAyi28de2%Da7s`EDfn z(^PLdx2b5)aM8ZM7=oNqSN}5)CZEw0<>6yrgg3Y!|C0w7cvjE@?Dhog;qfy)`1><2 zmxY~^g;_opPYuueB?R)$it&z)fsR3*_=O01l!31{F=iHs6L^nDq$g53BV_%P>-c3w zXtL2`WKM!t8`)dKNrnhW`s{`A^s|pQU>ie9(MPvTL#r&h}mGP)fPcR@U zy5oUd(sj(m_W07wGWSJu?DwMf4<&6lLyk(b3e0_h$~NY!NrYXKLf-KfZQ6J$q8(lf z3t_^=@(K&tkM)N*Uj_W|Wvy+H+Lvmiq)s?`D3a@`NpN$?K8y;Vo`3C;5fC}ydG>!U zIQ{n|{`>k5<)@mee+Bq!`P;t^_bTR7J>$j0FHh`1}7o{uj?cmG*=xA{VF=c8LvphGleQ zmSDaf;-`&wga8qKjkVJB6%)<*&_U7yQwq(vX`$)lR@tUh-1te2zN8d+0KFerk6_J{ z^W!ATcdo#FkvK#J-(uq<^;oO|5^N{ut7#QvR)IxJdPvbF9sM^lvPf{u+7Bxt&ElBg zX=B+EVhHwe=Tcy@kPo8TLkL%Y!96BVqlfm}DqsJ~&1pZ4gr*C_SBm8%xwCQl<;K1z z(J%3>c`AF5I~+*b`ZFa+s}Rav!O9t=)5tONBpANQJfVFj^4>Ly&&PXTH{l-6Ux{Px zkKEUIxgOq7jF2%7GJk+U=G%>he-KW6=82H;rPy4a*(69$tiO}Hz`Y9~1wZrCBbvGz z>t^r(&5;b>bQnuT2};H^xQ5KB`U6D=j4P3?rHngHDj!@X21-TiswP3$Q&;0DpvzjmII9_X~$OmVNXw6)1ba1SxsCKb8_0s!~-NC5S} zQMOTsllBz850&AJd;q7csTcy3-Co1z}w+va=s`Y+cui3NN^DH?N zl$m9V#gtowBlayjmtZccM^n3sE(lcQ941?SwO=R}vrutMEybCdYR3c@QYeET6~>j4q>(fdJ^r=gvXb&re~QgAoH*Av<26q8b^*ZQO1Co)Lt z`A9o+#DUWN_(K(hn*s(At)}?0mX-OK{9a*#jT!82%@9URKjzi>q4CK#T+a7B!*Awy z#NkW-&pm{4%cJ!QzAv`miWUd{27C|w`|e4APB<-bVh$Z5onwa`B(lvZ#8at;nv-WJ zeUSc`Lm2x!^2-CLF@xIsp@qQt-BVH7B~Pt_7kPAXGf6k8#w)oAkJUg$ZcRlF8CrZSeOD~}{Cl%{+@vKG;@Gjyrn?^$~@a;XeEDp%Al??#e z_y{!JDGF@h*6A6RoB&GtW45-(v~@QodgyIHsYow+T&v(i3HZ-j5w8)M*_1 z>9AlWSuUYp+~vW<;!B^NWCqEnOXzxpmhP?{t83yJ-dF38byTs&=UDGHYlt9+%_FZ< zmou=xBauRXhbMd0q~UrY#HUC%^LExQej^*B=dy@3PG)jX?z+4no;bi6I<0E(wJnZ_ zzGl?7UjO;+SKyrL$js^N%Ck>Fp+dYBMNgj0&54ToM^h3ZPGd6ENz*>NyYctEi-*l| zjFryC^}fL1FsEIR$m~R~LBTjoqIP*UzCgm|_~q(9FKc4Vlf(_UTEHL%00{nER(D%- zH?WnKhnt;~jr&i{(4RTxG%Z08bs_&Yd@ImpPl8c{j7YwmHCewKsb!*}E@nSDi-6fP zrHE)oDf_*qA*g|h9f2AuOW?P0%>7W<_rahmnp0A$j4EB*Zm?TtmY_R3Ekmss=bI_s z5v{%^S@4;Zc18@Jc^Q^HM7z`d+Ry4~2IF*fLtY~rH}fQj*;FN0{Kd;Oh2FWMVz;O| zV=0Xd1@V?Pl&peINpQ>U507Gm^;~??2@ZqOXbWZ!OrAJ3^SBdS%GGRz#H4AbsjiVmaXO?Q)OHln`y-{Lsb6?MGgel}u`_^SAxPB^k}e{{OG2sEBzAi_e*KiY z>g}150J#)+uIv5l=WXOrQQ*3n-5(GxT}Ee$GJID1Z`unrE-Tp|&2;Y>c$;>MR-vAr zzp4?fQr{>-La(+q1?JkIb-(H6_Jq6; zTVf);^2`Y`*8Bdx-lX0T?*jxgzJ5GT&Cf4574y)p+d$^xL^ONFQW3XmF|VD`>%6;S z6)q(_${?`WH`2EIjZ(etqvCX$W&0h`g_DP(lL7vRDVt0FYJ{tw{5dbZK)df7a85^p zD=0wsg64*!E{q35;2>=$wzTE^M(e=I1;c?oCi#sdBAUV*n#c_Lf_uPqA7tT3)brJGAJFlf`TGW6pvGjgxs z)c>ch7k1=U>VYc*DY(9;{iW;OZNXp<_rF|+KW@1G$8m^A>WS;+B#^m4x|8M4exb!0Vg5cKw4F$M+Ys+PFiyw9^QbBHwox(cPh8VeNNo@Q2$bXTo zOR`Sj+cE(`<~k;e)zJ4Z2&BzM%evy65N>$zt0J3bDSNBR}HF z-&ehYI3Am#HgKpm9V*r5Y8u?_JrAT5aVqY5Cx1K{p&*!SCRQXbI4rY&9AY84 z>wTVQABc@y>Nq}ja*qC=X2953#yB1R!LdpHGZOHJwezqAJAyg>IR7#1J%b4+@+Y89 z;xED=e>K(xs3mC%l2XR!kFFN;ig6SbgpFe{?Z(Mz4_D$g^$R3EGz^zWd{DxXSpuNH zM^wolw2R|KImUPhWwB$@sLLh!V(QSH(L!kxb#mf5+!3(l)cc+q7kb?AD2*cn@#$3Z zg)P}^I4t)(vJs#VIsM35g#OIzsg(&If+{nA)YBNpqNM(;gr2mQGlSSy zR@3L>4owe6XPj*X!x8SV%KVgDMMGPfSvHVy06nJT!{KytfsOe6@n=|c&!E0vd}y4u zf+&dFwE&E76W4PN1SclbE?6Nxw9v(o&`6^695x}OiYf_1Ju9#Z3M)w*Q}Pkb@1F^4 zjr4UqNu3;HI0cT$mc_K;muz{Jc-h(0tO7E#hZ+s5tt&-RYybk7<|Q99ipCZFtCvZ} zSVQ)Pd>1A(8?{}(qx@iT=bs}>lx@sdvWO&0zSYm_t4-HsfsJ8*3SsROimv75hfV09 zI!h3B2}L`bzN*$Wev2@WP#P}SfNk5JtCTNsmE-8YZVxbJ**apvs5gh27|P_AK{RUU zFR_Uo0k%|qai#K!+*3o;FJ18&Oe9@HxO3dlkxI5S+Zzyr&zuJWUfG`cVX3@xbpZNH_snYfiYI3ei)( z2nkAEi-b0k4z*;Y)(9*ms3uhKAPrG1(YBRXp!x(xWZ}$F)toq?7Z6b%eLH$?xhu&U z73ar$*dL3uyp_Y(awKFXx6AC)!lO*v<;KPO`J7Aa^sCe78FWYcOoTG2(RbIKr1(SQ zqET9rv{1arQywv@ex7~)lIN!0c8o2XfssyHGu<=0Q0#r7Sl-+Q75td7VH>K5#qSdb zY%^=)&EMGEzR(m>ah{N@QjfcC=!j?we2?8*iy(X$gjG3jv)LmbA!Dq>9OLnnM6UW# z%G8scsE{+Fu+H$%iMQsf;NpH63>j3htU1mdnN1=}UdtS-XD~Z5;yTJDGn z+LxMF%EaOyq{gm2PNYaJMK8+7jAY2rL-*cw?Z3(-$w27!_7N%kx+|Zn zVRlBUS=&kL+0HTny?X2r(mA!5S9mPb5=HX+F=-k%Si&!~Inb#pikwv28hIRAO|8ZK|GG zIqd;du6G3k957m2I`d#iVSmNG1c-FE5K#(u(Ju>Gu5bE^^y`7|bzkP?iQ)Iy+(mn6pr|LPI)3Z9QI z;Q?mDz6)7z!fC_mzF-gqQT3IvG@a!#t#86<+m59+za-hts6e6!*VN8Cd<*UOy3-b` zQcHGW+S+;s1x^$l&9PILuSFA~HA`7;R(5p)264~7NmjQRW2wiy@p~U_$seH19n&^b z{n#4UST|B}zCpY$Q>9I{*x;lLOzNaswYo#JcO>!n)Q-%4XEv9ZwcP6tv)0!}& zNqYqT>DBJIbUyj0t_h5zVsgW&!&G&`a1#=)W*T6!784~i4ff|xxZmmv=Z8Q+xvyU5 zJxX_>v>=fT4y_d3cRU%U-+B8bju-;88R8nV$eFHY|KLh*)Kak#i?t1F{FsSqf3oOA zYHzELpUGJ~fa5jb+FG1>uOBxkF^}g42i!*e(~g^}cXz8J0|3o<007pXR?OYQ*8%*8S3je#mQ>77(53gy zTVfeK3V@_B3^_ryD{<7ZE7h#U&g?g|lv`6yt@hik9tw*2bpH0mEx$kV7gsNVC$ zylgV`Zi0wjO~dZl&~`>z;rh^NhwKOJEVP9F?3U9=A0g2rO~X zNyi0BMPa33u~W$fq<~Tz0d{$n@84Grg99(6HMUv`_Vg#)AX2;a)GUnhrH>s^ih*1&+eBs6+?T_YbbO>kpWFY)jQ0hyvpg8Pc^$>B)ZJifnLVEHio}6GOIl zqjHWDDCCJ?p<-U`3{mx!)X7~T-G`tAgzogi=uZ6BM>h?vrjI0#Hqn-eLL+5sP!(I; zX50y77q2*K5z!RXz`!l*hp^b72UGN~c-)o_qij}9{KvruK9G3pXvtHu z_$cle3aaK9)DLsLxi6}5@w7AW25Zt?#J3naDk8jxu{t@RQk`MLh$s=GYWpk^Y1@q- zHAL0hcHJv|FBXdAzVl)KunR{h?=~0K#@;-!ZVdGn_R?lDq2IMehI$mYHsv|pKtEt{ z$ak3W5A466kArri$i5ZrXZ`5tNatcV@^bo?SHZS^poj|qQ;>r~_rUp#<&GW_au>q7tRJ*nHO6xFLn1Z>3x z{~3{fDQ%6QukzJzh&L;rY2MJ$=RskGe)aP=mv^_T!FM0WICn+C>Xo?)(cL`49_U_} zv7kX4vZR^=I}DnL?cq6;4-37YJ~}|2wS`x~rlvo4S5#Isb=|!E(E4VTMxQ=D-Rapo zKD^u8N1J?T?Vr)UrM&8ziyT(i0qJo=H$+pPlqJoeyKZS6Y?S<(7TEg(A?NLhHy1j!zyYrvH zpns~Kdvg0M9e7slAp-zF@~7(g87}(k6XMs$LzUqY6ebG_RMWW&Ejp*JsHX=iplP$T zRxN$A)*FQh_=0f_HDnQy7L_{1M8iQv?GrWpK?eF0>&j~RS*2NDcX8C()%}lBd1KB4 zO?WX)PA;A`V4q(E-qwnj9XgsQ@pyN6_1PX?oY{!aiem=dZe4LHc9s~ePV$<~mjwpG zz^=6m${p2R?$fda*Z#H(Pe!Z?TX2rFv#-+sCYqNG1C zLE8wzbDU#onH7%+BKA>8lZ90wcuXv-3t5+a2E?!+>ybS~K9r1iom z$!Rq&P;l;sar!#NoI>BO>M(5RI!{3ZdDU`rR*4^~rWcr9EUvahbCS!ful5KnoqNi0 z1YP5azPniqf`#%`%c3qn?wB(YPr98!TIeo{`ZgLbwHDd6$euin^Y%b&OL|x^a@Iw8 zsJ>kSYCWlmt~7UW!wUmKP3GQ8XUnt~qmTMB2%X5I&JEG#QXG`<9wpRc)Sx6Tyspl$ zdvL;L-Ix^M!gkq)HT_NB*#hZ7nx_lfyik=V-*dzl%-AiD1SQ5&^UV}3iEDzUX?=B_5m!asfO(1 z0c3Yw8gUlS#$ZylvP%&BH_uvCpK|p@&eo3^#BNLQm{u_hB&>`-G-miv43s1vOdqTX zK#9o<8CnNEwmg7}7&2m#Bbh-I;*y}!qQH2eNZT_`&H>L81jJpPT*M?TE0*YQw#r*KjLf7tY!DQ^~VMfX5lGc{{QkHF<})5o9Jm9Rwu+JyqnfHIjx z*^)=k=tXQY;}+ZysNbkLx6aj+2H^HuZb7873DH`o-eZ!_HmuAvOh6X5`5fc3o4_hd zuS)mb2apU9alt&7yp;F+9-r)b18nYtR+hWx!A(dAr8FS{CA0`;A5EGZ=;TbJhg1;@ zNV!-+IRHM#jqD}`m8Ggu$7j<`<#t9N8>%mx;)_-?Dm4qEI#$t1WPX6b*ZkU`jUpnPv>9%Xlft4k}Z_4IrqoK{`_R zn#X3b$ox48NaJ}=!-x%xw|ddwf&I`~hV)a?l`da6RGBUms z#C%>&0URi$561<%eU3vAq%XxY-Qu4_!Q0Ls)6Ggt@>FV6n*JpTxylvkv|hABC>KBNB!|GGoX;+*ydc|wkQ_X%bddA-j8dkvgti{_ z9iE_5MqYS%L|S>c&tnRll;mS|bf&>UCgy29RFrPP@H+KPeHW63>=*FAzl25n>^w8| zr^SjFoU6U%iZLhZl9Jj|adq-SeMca4QcMLK#zEQCpuu^E6pyI7td~5PQ7?HC@UdMD1sf7L z9ti_RLylffSt6eH?CWK8ZvSI?!!FDdmFQPdK4XUJpxI=LHoAOspJ8q*&Zp9Gbt$Gc z2@@vJNlyOMfT*72fGAfQF;*ikAo>RC>WzA$dR3pEZTb5zW1!kZTqGJY?o4)7TY*Pa z)X_a;+$5;Z?_AHmIBvL9Ce<6jFM5iiFKBvc-(M6+L@UGU)Jw zigh0tX)bGEIk|@%cH2pBfq8XWMrfA!NIf4#Z?I<{pr-y39U~UIzCkvGZ??3Uz&zQy zZ9B^RQ~-13w)ti=h+OpD#dqrK&9VxAoL6HUPM5AwIt|SqTpajhhHk^U6=@{KShY_N zA+9=#kJpr|AxJ+Ez6Du)IZTBuqnZVLan?2fA-|%lrQjxW$(N~PC4$Zpd20Y8#Rh_n z%IQwb7l);2GFvrtZ;<5tpcfw}vFnK1IlG*~gU$6{@1jg&$0emTU-?nc8+-rO?ql3N&4URVlY-6c{hv2dDc_4Y`fs)SL7dIoB(x zO2@O3b0bd#YRR;yvT@Twa1*ty^$O-7xu1&qQJv^&$&pZm!sIHCub7E5Vh4NP*t512 zbTgz_iQqR$T!UEq=Ho?e58iy?)L7?EpVF&x&)XV1s~hT);Me9D?NM7wwS}`=gko;Av#l^@& zS&)@jZbOodRHzmx7O1W+1_!OzxQ?t(Pv4rq9@A0pDe>0+>ig6^L2q|1wFuST3`>4 zpXtHh@4475?3^sj3NShAIp3@xko8nec6SeVk8s8>MbM%Qf3}G+vp}4}RUVg^O6iG^ z@=tE$krJfJMvsv^4W@Frz?7|n2i^ZePXaTWh4SI^41zNp^zR%tcX9bIh2c~7*O3G5 zfsk{7q7EZF`-=RlJQvd}8ZZXzMyLyc!mTWe21eQ}=yvt% zQWjSF4W5Xe@$=jt?ZQZ7`#c@r04=yb5ju#B8UR(Vr&_>0?}+lxKfPfsbStU0GbXVJvqW8atx>JwVztiRy$!=~!T?5$B3O85 z0`LhpaX@BVt1eNg6)OuEAMMT$yvOVQe+K&6!G+F;3y^@Hf@zWKN58#SR}D}x^kcBsr>xR}3}x-y>7 z?hgheMRz}xPP&e{+?`yRTjjWHi~U;C^|q`Nd(=^WUY21nP{GE0J&B-qn%_I#qEi!B zQK;K%X(>#gR7Q3wTUl?EtuWx5FH=La_@Q_U1!cnV6Tw_hb^MzjEMutf<@u9d2#9R( zJo|qxIQ`cm{_FZ5%1_mm{toc>^0$8p{=B|{Gv(ik;eHqVdr8p03(mtC_UTfzVU literal 0 HcmV?d00001 diff --git a/testsample/csrc/chuanqi/GConfig.ts b/testsample/csrc/chuanqi/GConfig.ts new file mode 100644 index 0000000..b9ab9ec --- /dev/null +++ b/testsample/csrc/chuanqi/GConfig.ts @@ -0,0 +1,16 @@ + +module giant.game { + export function initData() { + var rP = DataLocator.regCommonParser.bind(DataLocator); + let P = chuanqi; + //begin + rP("Ce0ShiBiao", chuanqi.Ce0ShiBiaoCfg); + rP("Ce1ShiBiao", chuanqi.Ce1ShiBiaoCfg); + rP("Ce2ShiBiao", chuanqi.Ce2ShiBiaoCfg); + rP("Ce3ShiBiao", chuanqi.Ce3ShiBiaoCfg); + rP("CeShiBiao", chuanqi.CeShiBiaoCfg); + rP("GongNeng", chuanqi.GongNengCfg); + //end + } + +} diff --git a/testsample/csrc/chuanqi/module/gongneng/cfg/GongNengCfg.ts b/testsample/csrc/chuanqi/module/gongneng/cfg/GongNengCfg.ts new file mode 100644 index 0000000..b53b358 --- /dev/null +++ b/testsample/csrc/chuanqi/module/gongneng/cfg/GongNengCfg.ts @@ -0,0 +1,78 @@ + +module giant.chuanqi +{ + /*-*begin $area1 !这里填写类上方的手写内容!*-*/ + + /*-*end $area1*-*/ + /** + * 来自:D:\workspace\cqh5\cehua\trunk\数值\功能\GongNeng.xlsx + **/ + export class GongNengCfg + { + + public constructor() { } + + + /** + * 功能标识 + */ + public id: number; + + + /** + * 是否关闭此功能(不开放) + */ + public close: number; + + + /** + * 帮助说明 + */ + public des: string; + + + /** + * 执行类型 + */ + public type: number; + + + /** + * 容器ID + */ + public containerID: number; + + + + ///////////////////// + + /*-*begin $area2 !这里填写类里面的手写内容!*-*/ + + /*-*end $area2*-*/ + + public decode(data:any[]){ + + let i = 0; + + + this.id = data[i++]; + this.close = data[i++]; + this.des = data[i++]; + this.type = data[i++]; + this.containerID = data[i++]; + + /*-*begin $decode !这里填写方法中的手写内容!*-*/ + + /*-*end $decode*-*/ + } + } + + /*-*begin $area3 !这里填写类下发的手写内容!*-*/ + + /*-*end $area3*-*/ +} +module giant { + export interface CfgName { + GongNeng: { [index: number]: chuanqi.GongNengCfg }; + } +} diff --git a/testsample/csrc/chuanqi/module/test/cfg/CeShiBiaoCfg.ts b/testsample/csrc/chuanqi/module/test/cfg/CeShiBiaoCfg.ts new file mode 100644 index 0000000..9643a1a --- /dev/null +++ b/testsample/csrc/chuanqi/module/test/cfg/CeShiBiaoCfg.ts @@ -0,0 +1,128 @@ + +module giant.chuanqi +{ + /*-*begin $area1 !这里填写类上方的手写内容!*-*/ +//这里填写类上方的手写内容 + /*-*end $area1*-*/ + /** + * 来自:D:\workspace\cqh5\cehua\trunk\数值\0.测试数据\CeShiBiao.xlsx + **/ + export class CeShiBiaoCfg + { + + public constructor() { } + + + /** + * 测试数据标识 + */ + public id: number; + + + /** + * 需求等级 + */ + public level: number; + + + /** + * 奖励物品 + */ + public items: any[][]; + + + /** + * 奖励金钱 + */ + public money: any; + + + /** + * 奖励宝石 + */ + public gold: number; + + + /** + * 展示道具 + */ + public showitems: any[]; + + + /** + * 是否可pk + */ + public pk: boolean; + + + /** + * vip特殊奖励 + */ + public vipitem: string; + + + /** + * 测试日期 + */ + public date: Date; + + + /** + * 测试时间 + */ + public datetime: Date; + + + /** + * 测试时间 + */ + public time: TimeVO; + + + /** + * 新增 + */ + public xinzeng: number; + + + + ///////////////////// + + /*-*begin $area2 !这里填写类里面的手写内容!*-*/ +//这里填写类里面的手写内容 + private thisIsTemp: number = 1; + /*-*end $area2*-*/ + + public decode(data:any[]){ + + let i = 0; + + + this.id = data[i++]; + this.level = data[i++]; + this.items = data[i++]; + this.money = data[i++]; + this.gold = data[i++]; + this.showitems = data[i++]; + this.pk = !!data[i++]; + this.vipitem = data[i++]; + this.date = new Date(data[i++]*1000); + this.datetime = new Date(data[i++]*1000); + this.time = new TimeVO(data[i++]); + this.xinzeng = data[i++]; + + /*-*begin $decode !这里填写方法中的手写内容!*-*/ +//这里填写方法中的手写内容 + /*-*end $decode*-*/ + } + } + + /*-*begin $area3 !这里填写类下发的手写内容!*-*/ +//这里填写类下发的手写内容 + /*-*end $area3*-*/ +} +module giant { + export interface CfgName { + CeShiBiao: { [index: number]: chuanqi.CeShiBiaoCfg }; + } +} diff --git a/testsample/csrc/huaqiangu/test/CeShiBiaoCfg.ts b/testsample/csrc/huaqiangu/test/CeShiBiaoCfg.ts new file mode 100644 index 0000000..d6eac9a --- /dev/null +++ b/testsample/csrc/huaqiangu/test/CeShiBiaoCfg.ts @@ -0,0 +1,103 @@ + +module giant.chuanqi +{ + /*-*begin $area1*-*/ + //这里填写类上方的手写内容 + /*-*end $area1*-*/ + /** + * 数据由工具自动生成,源文件地址:D:\workspace\bitbucket\coderesource\tools\code\DataTools\testsample\0.测试数据\CeShiBiao.xlsx + * 创建时间:2018-04-27 18:44:24 + **/ + export class CeShiBiaoCfg + { + + public constructor() + { + + } + + + /** + * 测试数据标识 + */ + public id: number; + + + /** + * 需求等级 + */ + public level: number; + + + /** + * 展示道具 + */ + public showitems: any[]; + + + /** + * 是否可pk + */ + public pk: boolean; + + + /** + * vip特殊奖励 + */ + public vipitem: string; + + + /** + * 测试日期 + */ + public date: Date; + + + /** + * 测试时间 + */ + public datetime: Date; + + + /** + * 测试时间 + */ + public time: TimeVO; + + + + ///////////////////// + + /*-*begin $area2*-*/ + //这里填写类里面的手写内容 + /*-*end $area2*-*/ + + public decode(data:any[]){ + + let i = 0; + + + this.id = data[i++]; + this.level = data[i++]; + this.showitems = data[i++]; + this.pk = !!data[i++]; + this.vipitem = data[i++]; + this.date = new Date(data[i++]*1000); + this.datetime = new Date(data[i++]*1000); + this.time = new TimeVO(data[i++]); + + /*-*begin $decode*-*/ + //这里填写方法中的手写内容 + /*-*end $decode*-*/ + } + } + + /*-*begin $area3*-*/ + //这里填写类下发的手写内容 + /*-*end $area3*-*/ +} +module giant { + export interface CfgName { + CeShiBiao: { [index: number]: chuanqi.CeShiBiaoCfg }; + } +} diff --git a/testsample/data/client/basic.json b/testsample/data/client/basic.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/testsample/data/client/basic.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/testsample/data/client/cfgs.json b/testsample/data/client/cfgs.json new file mode 100644 index 0000000..3886ff4 --- /dev/null +++ b/testsample/data/client/cfgs.json @@ -0,0 +1 @@ +{"CeShiBiao":[[123,12,[[1001,12],[1213,1]],12,12.1,[1001,1213],1,"s001",1482451200,1482506280,"23:18",1],[124,12,[[1001,12],[1213,2]],12,12.2,[1001,1214],1,"s002",1482537600,1482506340,"23:19",2],[125,12,[[1001,12],[1213,3]],12,12.3,[1001,1215],1,"s003",1482624000,1482506400,"23:20",3],[126,12,[[1001,12],[1213,4]],12,12.4,[1001,1216],1,"s004",1482710400,1482506460,"23:21",4],[127,12,[[1001,12],[1213,5]],12,12.5,[1001,1217],1,"s005",1482796800,1482506520,"23:22",5],[128,12,[[1001,12],[1213,6]],12,12.6,[1001,1218],1,"s006",1482883200,1482506580,"23:23",6],[129,12,[[1001,12],[1213,7]],12,12.7,[1001,1219],1,"s007",1482969600,1482506640,"23:24",7],[130,12,[[1001,12],[1213,8]],12,12.8,[1001,1220],1,"s008",1483056000,1482506700,"23:25",8],[131,12,[[1001,12],[1213,9]],12,12.9,[1001,1221],1,"s009",1483142400,1482506760,"23:26",9],[132,12,[[1001,12],[1213,10]],12,12.1,[1001,1222],1,"s010",1483142400,1482506820,"23:27",10]]} \ No newline at end of file diff --git a/testsample/data/client/raw/CeShiBiao.json b/testsample/data/client/raw/CeShiBiao.json new file mode 100644 index 0000000..393de7f --- /dev/null +++ b/testsample/data/client/raw/CeShiBiao.json @@ -0,0 +1 @@ +[[123,12,[[1001,12],[1213,1]],12,12.1,[1001,1213],1,"s001",1482451200,1482506280,"23:18",1],[124,12,[[1001,12],[1213,2]],12,12.2,[1001,1214],1,"s002",1482537600,1482506340,"23:19",2],[125,12,[[1001,12],[1213,3]],12,12.3,[1001,1215],1,"s003",1482624000,1482506400,"23:20",3],[126,12,[[1001,12],[1213,4]],12,12.4,[1001,1216],1,"s004",1482710400,1482506460,"23:21",4],[127,12,[[1001,12],[1213,5]],12,12.5,[1001,1217],1,"s005",1482796800,1482506520,"23:22",5],[128,12,[[1001,12],[1213,6]],12,12.6,[1001,1218],1,"s006",1482883200,1482506580,"23:23",6],[129,12,[[1001,12],[1213,7]],12,12.7,[1001,1219],1,"s007",1482969600,1482506640,"23:24",7],[130,12,[[1001,12],[1213,8]],12,12.8,[1001,1220],1,"s008",1483056000,1482506700,"23:25",8],[131,12,[[1001,12],[1213,9]],12,12.9,[1001,1221],1,"s009",1483142400,1482506760,"23:26",9],[132,12,[[1001,12],[1213,10]],12,12.1,[1001,1222],1,"s010",1483142400,1482506820,"23:27",10]] \ No newline at end of file diff --git a/testsample/data/client/running.json b/testsample/data/client/running.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/testsample/data/client/running.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/testsample/data/server/CeShiBiao.json b/testsample/data/server/CeShiBiao.json new file mode 100644 index 0000000..63ac757 --- /dev/null +++ b/testsample/data/server/CeShiBiao.json @@ -0,0 +1 @@ +[{"id":123,"level":12,"items":[[1001,12],[1213,1]],"money":12,"gold":12.1,"showitems":[1001,1213],"pk":1,"vipitem":"s001","date":148245120,"datetime":148253508,"time":"23:18","xinzeng":1},{"id":124,"level":12,"items":[[1001,12],[1213,2]],"money":12,"gold":12.2,"showitems":[1001,1214],"pk":1,"vipitem":"s002","date":148253760,"datetime":148253514,"time":"23:19","xinzeng":2},{"id":125,"level":12,"items":[[1001,12],[1213,3]],"money":12,"gold":12.3,"showitems":[1001,1215],"pk":1,"vipitem":"s003","date":148262400,"datetime":148253520,"time":"23:20","xinzeng":3},{"id":126,"level":12,"items":[[1001,12],[1213,4]],"money":12,"gold":12.4,"showitems":[1001,1216],"pk":1,"vipitem":"s004","date":148271040,"datetime":148253526,"time":"23:21","xinzeng":4},{"id":127,"level":12,"items":[[1001,12],[1213,5]],"money":12,"gold":12.5,"showitems":[1001,1217],"pk":1,"vipitem":"s005","date":148279680,"datetime":148253532,"time":"23:22","xinzeng":5},{"id":128,"level":12,"items":[[1001,12],[1213,6]],"money":12,"gold":12.6,"showitems":[1001,1218],"pk":1,"vipitem":"s006","date":148288320,"datetime":148253538,"time":"23:23","xinzeng":6},{"id":129,"level":12,"items":[[1001,12],[1213,7]],"money":12,"gold":12.7,"showitems":[1001,1219],"pk":1,"vipitem":"s007","date":148296960,"datetime":148253544,"time":"23:24","xinzeng":7},{"id":130,"level":12,"items":[[1001,12],[1213,8]],"money":12,"gold":12.8,"showitems":[1001,1220],"pk":1,"vipitem":"s008","date":148305600,"datetime":148253550,"time":"23:25","xinzeng":8},{"id":131,"level":12,"items":[[1001,12],[1213,9]],"money":12,"gold":12.9,"showitems":[1001,1221],"pk":1,"vipitem":"s009","date":148314240,"datetime":148253556,"time":"23:26","xinzeng":9},{"id":132,"level":12,"items":[[1001,12],[1213,10]],"money":12,"gold":12.1,"showitems":[1001,1222],"pk":1,"vipitem":"s010","date":148314240,"datetime":148253562,"time":"23:27","xinzeng":10}] \ No newline at end of file diff --git a/testsample/globalConfig.json b/testsample/globalConfig.json new file mode 100644 index 0000000..2e2d2be --- /dev/null +++ b/testsample/globalConfig.json @@ -0,0 +1,4 @@ +{ + "project":"chuanqi", + "clientPath":"D:/workspace/bitbucket/coderesource/tools/code/DataTools/testsample/out/client" +} \ No newline at end of file diff --git a/testsample/out/client/CeShiBiao.json b/testsample/out/client/CeShiBiao.json new file mode 100644 index 0000000..0126206 --- /dev/null +++ b/testsample/out/client/CeShiBiao.json @@ -0,0 +1 @@ +[[123,12,[[1001,12],[1213,1]],12,12.1,[1001,1213],1,"s001",148245120,148253508,"23:18",1],[124,12,[[1001,12],[1213,2]],12,12.2,[1001,1214],1,"s002",148253760,148253514,"23:19",2],[125,12,[[1001,12],[1213,3]],12,12.3,[1001,1215],1,"s003",148262400,148253520,"23:20",3],[126,12,[[1001,12],[1213,4]],12,12.4,[1001,1216],1,"s004",148271040,148253526,"23:21",4],[127,12,[[1001,12],[1213,5]],12,12.5,[1001,1217],1,"s005",148279680,148253532,"23:22",5],[128,12,[[1001,12],[1213,6]],12,12.6,[1001,1218],1,"s006",148288320,148253538,"23:23",6],[129,12,[[1001,12],[1213,7]],12,12.7,[1001,1219],1,"s007",148296960,148253544,"23:24",7],[130,12,[[1001,12],[1213,8]],12,12.8,[1001,1220],1,"s008",148305600,148253550,"23:25",8],[131,12,[[1001,12],[1213,9]],12,12.9,[1001,1221],1,"s009",148314240,148253556,"23:26",9],[132,12,[[1001,12],[1213,10]],12,12.1,[1001,1222],1,"s010",148314240,148253562,"23:27",10]] \ No newline at end of file diff --git a/testsample/out/client/CeShiBiao1.json b/testsample/out/client/CeShiBiao1.json new file mode 100644 index 0000000..524c71e --- /dev/null +++ b/testsample/out/client/CeShiBiao1.json @@ -0,0 +1 @@ +[[123,12,[1001,1213],1,"s001",148245120,148253508,"23:18"],[124,12,[1001,1214],1,"s002",148253760,148253514,"23:19"],[125,12,[1001,1215],1,"s003",148262400,148253520,"23:20"],[126,12,[1001,1216],1,"s004",148271040,148253526,"23:21"],[127,12,[1001,1217],1,"s005",148279680,148253532,"23:22"],[128,12,[1001,1218],1,"s006",148288320,148253538,"23:23"],[129,12,[1001,1219],1,"s007",148296960,148253544,"23:24"],[130,12,[1001,1220],1,"s008",148305600,148253550,"23:25"],[131,12,[1001,1221],1,"s009",148314240,148253556,"23:26"],[132,12,[1001,1222],1,"s010",148253562,"23:27"]] \ No newline at end of file diff --git a/testsample/out/client/CeShiBiao2.json b/testsample/out/client/CeShiBiao2.json new file mode 100644 index 0000000..524c71e --- /dev/null +++ b/testsample/out/client/CeShiBiao2.json @@ -0,0 +1 @@ +[[123,12,[1001,1213],1,"s001",148245120,148253508,"23:18"],[124,12,[1001,1214],1,"s002",148253760,148253514,"23:19"],[125,12,[1001,1215],1,"s003",148262400,148253520,"23:20"],[126,12,[1001,1216],1,"s004",148271040,148253526,"23:21"],[127,12,[1001,1217],1,"s005",148279680,148253532,"23:22"],[128,12,[1001,1218],1,"s006",148288320,148253538,"23:23"],[129,12,[1001,1219],1,"s007",148296960,148253544,"23:24"],[130,12,[1001,1220],1,"s008",148305600,148253550,"23:25"],[131,12,[1001,1221],1,"s009",148314240,148253556,"23:26"],[132,12,[1001,1222],1,"s010",148253562,"23:27"]] \ No newline at end of file diff --git a/testsample/out/server/CeShiBiao.json b/testsample/out/server/CeShiBiao.json new file mode 100644 index 0000000..63ac757 --- /dev/null +++ b/testsample/out/server/CeShiBiao.json @@ -0,0 +1 @@ +[{"id":123,"level":12,"items":[[1001,12],[1213,1]],"money":12,"gold":12.1,"showitems":[1001,1213],"pk":1,"vipitem":"s001","date":148245120,"datetime":148253508,"time":"23:18","xinzeng":1},{"id":124,"level":12,"items":[[1001,12],[1213,2]],"money":12,"gold":12.2,"showitems":[1001,1214],"pk":1,"vipitem":"s002","date":148253760,"datetime":148253514,"time":"23:19","xinzeng":2},{"id":125,"level":12,"items":[[1001,12],[1213,3]],"money":12,"gold":12.3,"showitems":[1001,1215],"pk":1,"vipitem":"s003","date":148262400,"datetime":148253520,"time":"23:20","xinzeng":3},{"id":126,"level":12,"items":[[1001,12],[1213,4]],"money":12,"gold":12.4,"showitems":[1001,1216],"pk":1,"vipitem":"s004","date":148271040,"datetime":148253526,"time":"23:21","xinzeng":4},{"id":127,"level":12,"items":[[1001,12],[1213,5]],"money":12,"gold":12.5,"showitems":[1001,1217],"pk":1,"vipitem":"s005","date":148279680,"datetime":148253532,"time":"23:22","xinzeng":5},{"id":128,"level":12,"items":[[1001,12],[1213,6]],"money":12,"gold":12.6,"showitems":[1001,1218],"pk":1,"vipitem":"s006","date":148288320,"datetime":148253538,"time":"23:23","xinzeng":6},{"id":129,"level":12,"items":[[1001,12],[1213,7]],"money":12,"gold":12.7,"showitems":[1001,1219],"pk":1,"vipitem":"s007","date":148296960,"datetime":148253544,"time":"23:24","xinzeng":7},{"id":130,"level":12,"items":[[1001,12],[1213,8]],"money":12,"gold":12.8,"showitems":[1001,1220],"pk":1,"vipitem":"s008","date":148305600,"datetime":148253550,"time":"23:25","xinzeng":8},{"id":131,"level":12,"items":[[1001,12],[1213,9]],"money":12,"gold":12.9,"showitems":[1001,1221],"pk":1,"vipitem":"s009","date":148314240,"datetime":148253556,"time":"23:26","xinzeng":9},{"id":132,"level":12,"items":[[1001,12],[1213,10]],"money":12,"gold":12.1,"showitems":[1001,1222],"pk":1,"vipitem":"s010","date":148314240,"datetime":148253562,"time":"23:27","xinzeng":10}] \ No newline at end of file diff --git a/testsample/out/server/CeShiBiao.xml b/testsample/out/server/CeShiBiao.xml new file mode 100644 index 0000000..2fd22e7 --- /dev/null +++ b/testsample/out/server/CeShiBiao.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsample/out/server/CeShiBiao1.json b/testsample/out/server/CeShiBiao1.json new file mode 100644 index 0000000..64ca06c --- /dev/null +++ b/testsample/out/server/CeShiBiao1.json @@ -0,0 +1 @@ +[[123,12,[[1001,12],[1213,1]],12,1,"s001",148245120,148253508,"23:18"],[124,12,[[1001,12],[1213,2]],12,1,"s002",148253760,148253514,"23:19"],[125,12,[[1001,12],[1213,3]],12,1,"s003",148262400,148253520,"23:20"],[126,12,[[1001,12],[1213,4]],12,1,"s004",148271040,148253526,"23:21"],[127,12,[[1001,12],[1213,5]],12,1,"s005",148279680,148253532,"23:22"],[128,12,[[1001,12],[1213,6]],12,1,"s006",148288320,148253538,"23:23"],[129,12,[[1001,12],[1213,7]],12,1,"s007",148296960,148253544,"23:24"],[130,12,[[1001,12],[1213,8]],12,1,"s008",148305600,148253550,"23:25"],[131,12,[[1001,12],[1213,9]],12,1,"s009",148314240,148253556,"23:26"],[132,12,[[1001,12],[1213,10]],12,1,"s010",148253562,"23:27"]] \ No newline at end of file diff --git a/testsample/out/server/CeShiBiao1.xml b/testsample/out/server/CeShiBiao1.xml new file mode 100644 index 0000000..bb79284 --- /dev/null +++ b/testsample/out/server/CeShiBiao1.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/testsample/out/server/CeShiBiao2.json b/testsample/out/server/CeShiBiao2.json new file mode 100644 index 0000000..64ca06c --- /dev/null +++ b/testsample/out/server/CeShiBiao2.json @@ -0,0 +1 @@ +[[123,12,[[1001,12],[1213,1]],12,1,"s001",148245120,148253508,"23:18"],[124,12,[[1001,12],[1213,2]],12,1,"s002",148253760,148253514,"23:19"],[125,12,[[1001,12],[1213,3]],12,1,"s003",148262400,148253520,"23:20"],[126,12,[[1001,12],[1213,4]],12,1,"s004",148271040,148253526,"23:21"],[127,12,[[1001,12],[1213,5]],12,1,"s005",148279680,148253532,"23:22"],[128,12,[[1001,12],[1213,6]],12,1,"s006",148288320,148253538,"23:23"],[129,12,[[1001,12],[1213,7]],12,1,"s007",148296960,148253544,"23:24"],[130,12,[[1001,12],[1213,8]],12,1,"s008",148305600,148253550,"23:25"],[131,12,[[1001,12],[1213,9]],12,1,"s009",148314240,148253556,"23:26"],[132,12,[[1001,12],[1213,10]],12,1,"s010",148253562,"23:27"]] \ No newline at end of file diff --git a/testsample/ssrc/huaqiangu/test/CeShiBiaoTemplate.java b/testsample/ssrc/huaqiangu/test/CeShiBiaoTemplate.java new file mode 100644 index 0000000..1124820 --- /dev/null +++ b/testsample/ssrc/huaqiangu/test/CeShiBiaoTemplate.java @@ -0,0 +1,112 @@ + +package com.game.resources.template.gen.huaqiangu.test; + +import com.game.resources.annotation.Attribute; +import com.game.resources.annotation.Template; + +@Template( res = "CeShiBiao.json") +public abstract class CeShiBiaoTemplate { + + + @Attribute("id") + private int id; + + /** + * 测试数据标识 + */ + public int getId(){ + return id; + } + + @Attribute("level") + private int level; + + /** + * 需求等级 + */ + public int getLevel(){ + return level; + } + + @Attribute("items") + private String items; + + /** + * 奖励物品 + */ + public String getItems(){ + return items; + } + + @Attribute("money") + private int money; + + /** + * 奖励金钱 + */ + public int getMoney(){ + return money; + } + + @Attribute("gold") + private int gold; + + /** + * 奖励宝石 + */ + public int getGold(){ + return gold; + } + + @Attribute("pk") + private boolean pk; + + /** + * 是否可pk + */ + public boolean getPk(){ + return pk; + } + + @Attribute("vipitem") + private String vipitem; + + /** + * vip特殊奖励 + */ + public String getVipitem(){ + return vipitem; + } + + @Attribute("date") + private String date; + + /** + * 测试日期 + */ + public String getDate(){ + return date; + } + + @Attribute("datetime") + private String datetime; + + /** + * 测试时间 + */ + public String getDatetime(){ + return datetime; + } + + @Attribute("time") + private String time; + + /** + * 测试时间 + */ + public String getTime(){ + return time; + } + + +} diff --git a/testsample/ssrc/test/CeShiBiaoTemplate.java b/testsample/ssrc/test/CeShiBiaoTemplate.java new file mode 100644 index 0000000..7deea7a --- /dev/null +++ b/testsample/ssrc/test/CeShiBiaoTemplate.java @@ -0,0 +1,132 @@ + +package com.game.resources.template.gen.test; + +import com.game.resources.annotation.Attribute; +import com.game.resources.annotation.Template; + +@Template( res = "CeShiBiao.json") +public abstract class CeShiBiaoTemplate { + + + @Attribute("id") + private int id; + + /** + * 测试数据标识 + */ + public int getId(){ + return id; + } + + @Attribute("level") + private int level; + + /** + * 需求等级 + */ + public int getLevel(){ + return level; + } + + @Attribute("items") + private String items; + + /** + * 奖励物品 + */ + public String getItems(){ + return items; + } + + @Attribute("money") + private String money; + + /** + * 奖励金钱 + */ + public String getMoney(){ + return money; + } + + @Attribute("gold") + private float gold; + + /** + * 奖励宝石 + */ + public float getGold(){ + return gold; + } + + @Attribute("showitems") + private String showitems; + + /** + * 展示道具 + */ + public String getShowitems(){ + return showitems; + } + + @Attribute("pk") + private boolean pk; + + /** + * 是否可pk + */ + public boolean getPk(){ + return pk; + } + + @Attribute("vipitem") + private String vipitem; + + /** + * vip特殊奖励 + */ + public String getVipitem(){ + return vipitem; + } + + @Attribute("date") + private String date; + + /** + * 测试日期 + */ + public String getDate(){ + return date; + } + + @Attribute("datetime") + private String datetime; + + /** + * 测试时间 + */ + public String getDatetime(){ + return datetime; + } + + @Attribute("time") + private String time; + + /** + * 测试时间 + */ + public String getTime(){ + return time; + } + + @Attribute("xinzeng") + private float xinzeng; + + /** + * 新增 + */ + public float getXinzeng(){ + return xinzeng; + } + + +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8ea4faf --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "module": "amd", + "target": "es2015", + "sourceMap": false, + "rootDir": "src", + "outDir": "dist" + }, + "exclude": [ + "node_modules", + "testsample" + ] +} \ No newline at end of file diff --git a/typings/electron.d.ts b/typings/electron.d.ts new file mode 100644 index 0000000..4590de2 --- /dev/null +++ b/typings/electron.d.ts @@ -0,0 +1,10 @@ +interface File{ + /** + * Electron环境下文件的物理路径 + */ + path : string; +} + +interface Window{ + nodeRequire:NodeRequire; +} \ No newline at end of file diff --git a/typings/node/node.d.ts b/typings/node/node.d.ts new file mode 100644 index 0000000..4c51546 --- /dev/null +++ b/typings/node/node.d.ts @@ -0,0 +1,2340 @@ +// Type definitions for Node.js v4.x +// Project: http://nodejs.org/ +// Definitions by: Microsoft TypeScript , DefinitelyTyped +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +/************************************************ +* * +* Node.js v4.x API * +* * +************************************************/ + +interface Error { + stack?: string; +} + + +// compat for TypeScript 1.8 +// if you use with --target es3 or --target es5 and use below definitions, +// use the lib.es6.d.ts that is bundled with TypeScript 1.8. +interface MapConstructor {} +interface WeakMapConstructor {} +interface SetConstructor {} +interface WeakSetConstructor {} + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: NodeJS.Global; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +interface NodeRequireFunction { + (id: string): any; +} + +interface NodeRequire extends NodeRequireFunction { + resolve(id:string): string; + cache: any; + extensions: any; + main: any; +} + +declare var require: NodeRequire; + +interface NodeModule { + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +} + +declare var module: NodeModule; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +type BufferEncoding = "ascii" | "utf8" | "utf16le" | "ucs2" | "binary" | "hex"; +interface Buffer extends NodeBuffer {} + +/** + * Raw data is stored in instances of the Buffer class. + * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. + * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + */ +declare var Buffer: { + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + new (str: string, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + new (size: number): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: Uint8Array): Buffer; + /** + * Produces a Buffer backed by the same allocated memory as + * the given {ArrayBuffer}. + * + * + * @param arrayBuffer The ArrayBuffer with which to share memory. + */ + new (arrayBuffer: ArrayBuffer): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: any[]): Buffer; + /** + * Copies the passed {buffer} data onto a new {Buffer} instance. + * + * @param buffer The buffer to copy. + */ + new (buffer: Buffer): Buffer; + prototype: Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + compare(buf1: Buffer, buf2: Buffer): number; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare namespace NodeJS { + export interface ErrnoException extends Error { + errno?: number; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } + + export interface EventEmitter { + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string|Buffer; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer|string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream {} + + export interface Events extends EventEmitter { } + + export interface Domain extends Events { + run(fn: Function): void; + add(emitter: Events): void; + remove(emitter: Events): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + } + + export interface MemoryUsage { + rss: number; + heapTotal: number; + heapUsed: number; + } + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execArgv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + openssl: string; + }; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid:number, signal?: string|number): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): MemoryUsage; + nextTick(callback: Function): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?:number[]): number[]; + domain: Domain; + + // Worker + send?(message: any, sendHandle?: any): void; + disconnect(): void; + connected: boolean; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } + + export interface Timer { + ref() : void; + unref() : void; + } +} + +/** + * @deprecated + */ +interface NodeBuffer/* extends Uint8Array*/ { + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): any; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAssert?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): Buffer; + // TODO: encoding param + indexOf(value: string | number | Buffer, byteOffset?: number): number; + // TODO: entries + // TODO: includes + // TODO: keys + // TODO: values +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; + var BuffType: typeof Buffer; + var SlowBuffType: typeof SlowBuffer; + export { BuffType as Buffer, SlowBuffType as SlowBuffer }; +} + +declare module "querystring" { + export interface StringifyOptions { + encodeURIComponent?: Function; + } + + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } + + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; +} + +declare module "events" { + export class EventEmitter implements NodeJS.EventEmitter { + static EventEmitter: EventEmitter; + static listenerCount(emitter: EventEmitter, event: string): number; // deprecated + static defaultMaxListeners: number; + + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; + } +} + +declare module "http" { + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + + export interface RequestOptions { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number; + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: { [key: string]: any }; + auth?: string; + agent?: Agent|boolean; + } + + export interface Server extends events.EventEmitter, net.Server { + setTimeout(msecs: number, callback: Function): void; + maxHeadersCount: number; + timeout: number; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + statusMessage: string; + headersSent: boolean; + setHeader(name: string, value: string | string[]): void; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + setHeader(name: string, value: string | string[]): void; + getHeader(name: string): string; + removeHeader(name: string): void; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends events.EventEmitter, stream.Readable { + httpVersion: string; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var METHODS: string[]; + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) =>void ): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import * as child from "child_process"; + import * as events from "events"; + + export interface ClusterSettings { + exec?: string; + args?: string[]; + silent?: boolean; + } + + export interface Address { + address: string; + port: number; + addressType: string; + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): void; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + } + + export var settings: ClusterSettings; + export var isMaster: boolean; + export var isWorker: boolean; + export function setupMaster(settings?: ClusterSettings): void; + export function fork(env?: any): Worker; + export function disconnect(callback?: Function): void; + export var worker: Worker; + export var workers: Worker[]; + + // Event emitter + export function addListener(event: string, listener: Function): void; + export function on(event: "disconnect", listener: (worker: Worker) => void): void; + export function on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): void; + export function on(event: "fork", listener: (worker: Worker) => void): void; + export function on(event: "listening", listener: (worker: Worker, address: any) => void): void; + export function on(event: "message", listener: (worker: Worker, message: any) => void): void; + export function on(event: "online", listener: (worker: Worker) => void): void; + export function on(event: "setup", listener: (settings: any) => void): void; + export function on(event: string, listener: Function): any; + export function once(event: string, listener: Function): void; + export function removeListener(event: string, listener: Function): void; + export function removeAllListeners(event?: string): void; + export function setMaxListeners(n: number): void; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; +} + +declare module "zlib" { + import * as stream from "stream"; + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateSync(buf: Buffer, options?: ZlibOptions): any; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gzipSync(buf: Buffer, options?: ZlibOptions): any; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; + export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateSync(buf: Buffer, options?: ZlibOptions): any; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function unzipSync(buf: Buffer, options?: ZlibOptions): any; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + }; + } + + export interface NetworkInterfaceInfo { + address: string; + netmask: string; + family: string; + mac: string; + internal: boolean; + } + + export function tmpdir(): string; + export function homedir(): string; + export function endianness(): string; + export function hostname(): string; + export function type(): string; + export function platform(): string; + export function arch(): string; + export function release(): string; + export function uptime(): number; + export function loadavg(): number[]; + export function totalmem(): number; + export function freemem(): number; + export function cpus(): CpuInfo[]; + export function networkInterfaces(): {[index: string]: NetworkInterfaceInfo[]}; + export var EOL: string; +} + +declare module "https" { + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string) => any; + } + + export interface RequestOptions extends http.RequestOptions{ + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + secureProtocol?: string; + } + + export interface Agent { + maxSockets: number; + sockets: any; + requests: any; + } + export var Agent: { + new (options?: RequestOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): number[]; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import * as stream from "stream"; + import * as events from "events"; + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + } + export function start(options: ReplOptions): events.EventEmitter; +} + +declare module "readline" { + import * as events from "events"; + import * as stream from "stream"; + + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; + close(): void; + write(data: string|Buffer, key?: Key): void; + } + + export interface Completer { + (line: string): CompleterResult; + (line: string, callback: (err: any, result: CompleterResult) => void): any; + } + + export interface CompleterResult { + completions: string[]; + line: string; + } + + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + completer?: Completer; + terminal?: boolean; + historySize?: number; + } + + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; + export function createInterface(options: ReadLineOptions): ReadLine; + + export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number|string, dy: number|string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; +} + +declare module "vm" { + export interface Context { } + export interface ScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + cachedData?: Buffer; + produceCachedData?: boolean; + } + export interface RunningScriptOptions { + filename?: string; + lineOffset?: number; + columnOffset?: number; + displayErrors?: boolean; + timeout?: number; + } + export class Script { + constructor(code: string, options?: ScriptOptions); + runInContext(contextifiedSandbox: Context, options?: RunningScriptOptions): any; + runInNewContext(sandbox?: Context, options?: RunningScriptOptions): any; + runInThisContext(options?: RunningScriptOptions): any; + } + export function createContext(sandbox?: Context): Context; + export function isContext(sandbox: Context): boolean; + export function runInContext(code: string, contextifiedSandbox: Context, options?: RunningScriptOptions): any; + export function runInDebugContext(code: string): any; + export function runInNewContext(code: string, sandbox?: Context, options?: RunningScriptOptions): any; + export function runInThisContext(code: string, options?: RunningScriptOptions): any; +} + +declare module "child_process" { + import * as events from "events"; + import * as stream from "stream"; + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + stdio: [stream.Writable, stream.Readable, stream.Readable]; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): void; + disconnect(): void; + unref(): void; + } + + export interface SpawnOptions { + cwd?: string; + env?: any; + stdio?: any; + detached?: boolean; + uid?: number; + gid?: number; + shell?: boolean | string; + } + export function spawn(command: string, args?: string[], options?: SpawnOptions): ChildProcess; + + export interface ExecOptions { + cwd?: string; + env?: any; + shell?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecOptionsWithStringEncoding extends ExecOptions { + encoding: BufferEncoding; + } + export interface ExecOptionsWithBufferEncoding extends ExecOptions { + encoding: string; // specify `null`. + } + export function exec(command: string, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + export function exec(command: string, options: ExecOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + // usage. child_process.exec("tsc", {encoding: null as string}, (err, stdout, stderr) => {}); + export function exec(command: string, options: ExecOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function exec(command: string, options: ExecOptions, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + + export interface ExecFileOptions { + cwd?: string; + env?: any; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + uid?: number; + gid?: number; + } + export interface ExecFileOptionsWithStringEncoding extends ExecFileOptions { + encoding: BufferEncoding; + } + export interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions { + encoding: string; // specify `null`. + } + export function execFile(file: string, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + export function execFile(file: string, options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + // usage. child_process.execFile("file.sh", {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithStringEncoding, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + // usage. child_process.execFile("file.sh", ["foo"], {encoding: null as string}, (err, stdout, stderr) => {}); + export function execFile(file: string, args?: string[], options?: ExecFileOptionsWithBufferEncoding, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], options?: ExecFileOptions, callback?: (error: Error, stdout: string, stderr: string) =>void ): ChildProcess; + + export interface ForkOptions { + cwd?: string; + env?: any; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + uid?: number; + gid?: number; + } + export function fork(modulePath: string, args?: string[], options?: ForkOptions): ChildProcess; + + export interface SpawnSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + shell?: boolean | string; + } + export interface SpawnSyncOptionsWithStringEncoding extends SpawnSyncOptions { + encoding: BufferEncoding; + } + export interface SpawnSyncOptionsWithBufferEncoding extends SpawnSyncOptions { + encoding: string; // specify `null`. + } + export interface SpawnSyncReturns { + pid: number; + output: string[]; + stdout: T; + stderr: T; + status: number; + signal: string; + error: Error; + } + export function spawnSync(command: string): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns; + export function spawnSync(command: string, args?: string[], options?: SpawnSyncOptions): SpawnSyncReturns; + + export interface ExecSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + shell?: string; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecSyncOptionsWithStringEncoding extends ExecSyncOptions { + encoding: BufferEncoding; + } + export interface ExecSyncOptionsWithBufferEncoding extends ExecSyncOptions { + encoding: string; // specify `null`. + } + export function execSync(command: string): Buffer; + export function execSync(command: string, options?: ExecSyncOptionsWithStringEncoding): string; + export function execSync(command: string, options?: ExecSyncOptionsWithBufferEncoding): Buffer; + export function execSync(command: string, options?: ExecSyncOptions): Buffer; + + export interface ExecFileSyncOptions { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + killSignal?: string; + maxBuffer?: number; + encoding?: string; + } + export interface ExecFileSyncOptionsWithStringEncoding extends ExecFileSyncOptions { + encoding: BufferEncoding; + } + export interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions { + encoding: string; // specify `null`. + } + export function execFileSync(command: string): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, options?: ExecFileSyncOptions): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithStringEncoding): string; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptionsWithBufferEncoding): Buffer; + export function execFileSync(command: string, args?: string[], options?: ExecFileSyncOptions): Buffer; +} + +declare module "url" { + export interface Url { + href?: string; + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: any; // string | Object + slashes?: boolean; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; + export function format(url: Url): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; +} + +declare module "net" { + import * as stream from "stream"; + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): void; + resume(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface ListenOptions { + port?: number; + host?: string; + backlog?: number; + path?: string; + exclusive?: boolean; + } + + export interface Server extends Socket { + listen(port: number, hostname?: string, backlog?: number, listeningListener?: Function): Server; + listen(port: number, hostname?: string, listeningListener?: Function): Server; + listen(port: number, backlog?: number, listeningListener?: Function): Server; + listen(port: number, listeningListener?: Function): Server; + listen(path: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, backlog?: number, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + listen(options: ListenOptions, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + getConnections(cb: (error: Error, count: number) => void): void; + ref(): Server; + unref(): Server; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) =>void ): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; + export function connect(options: { port: number, host?: string, localAddress? : string, localPort? : string, family? : number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { port: number, host?: string, localAddress? : string, localPort? : string, family? : number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import * as events from "events"; + + interface RemoteInfo { + address: string; + port: number; + size: number; + } + + interface AddressInfo { + address: string; + family: string; + port: number; + } + + export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + + interface Socket extends events.EventEmitter { + send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port: number, address?: string, callback?: () => void): void; + close(): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + } +} + +declare module "fs" { + import * as stream from "stream"; + import * as events from "events"; + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + } + + export interface ReadStream extends stream.Readable { + close(): void; + } + export interface WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + } + + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string, uid: number, gid: number): void; + export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string, mode: number): void; + export function chmodSync(path: string, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string, mode: number): void; + export function lchmodSync(path: string, mode: string): void; + export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string): Stats; + export function lstatSync(path: string): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string, dstpath: string): void; + export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; + export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string): string; + export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; + export function realpathSync(path: string, cache?: { [path: string]: string }): string; + /* + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ + export function unlinkSync(path: string): void; + /* + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ + export function rmdirSync(path: string): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string, mode?: number): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string, mode?: string): void; + export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function openSync(path: string, flags: string, mode?: number): number; + export function openSync(path: string, flags: string, mode?: string): number; + export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string, atime: number, mtime: number): void; + export function utimesSync(path: string, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number): number; + export function writeSync(fd: number, data: any, position?: number, enconding?: string): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ + export function readFileSync(filename: string, encoding: string): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; + export function exists(path: string, callback?: (exists: boolean) => void): void; + export function existsSync(path: string): boolean; + /** Constant for fs.access(). File is visible to the calling process. */ + export var F_OK: number; + /** Constant for fs.access(). File can be read by the calling process. */ + export var R_OK: number; + /** Constant for fs.access(). File can be written by the calling process. */ + export var W_OK: number; + /** Constant for fs.access(). File can be executed by the calling process. */ + export var X_OK: number; + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string, mode ?: number): void; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + autoClose?: boolean; + }): ReadStream; + export function createWriteStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: number; + mode?: number; + }): WriteStream; +} + +declare module "path" { + + /** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ + export interface ParsedPath { + /** + * The root of the path such as '/' or 'c:\' + */ + root: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base: string; + /** + * The file extension (if any) such as '.html' + */ + ext: string; + /** + * The file name without extension (if any) such as 'index' + */ + name: string; + } + + /** + * Normalize a string path, reducing '..' and '.' parts. + * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. + * + * @param p string path to normalize. + */ + export function normalize(p: string): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: any[]): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: string[]): string; + /** + * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. + * + * Starting from leftmost {from} paramter, resolves {to} to an absolute path. + * + * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. + * + * @param pathSegments string paths to join. Non-string arguments are ignored. + */ + export function resolve(...pathSegments: any[]): string; + /** + * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. + * + * @param path path to test. + */ + export function isAbsolute(path: string): boolean; + /** + * Solve the relative path from {from} to {to}. + * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to + */ + export function relative(from: string, to: string): string; + /** + * Return the directory name of a path. Similar to the Unix dirname command. + * + * @param p the path to evaluate. + */ + export function dirname(p: string): string; + /** + * Return the last portion of a path. Similar to the Unix basename command. + * Often used to extract the file name from a fully qualified path. + * + * @param p the path to evaluate. + * @param ext optionally, an extension to remove from the result. + */ + export function basename(p: string, ext?: string): string; + /** + * Return the extension of the path, from the last '.' to end of string in the last portion of the path. + * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string + * + * @param p the path to evaluate. + */ + export function extname(p: string): string; + /** + * The platform-specific file separator. '\\' or '/'. + */ + export var sep: string; + /** + * The platform-specific file delimiter. ';' or ':'. + */ + export var delimiter: string; + /** + * Returns an object from a path string - the opposite of format(). + * + * @param pathString path to evaluate. + */ + export function parse(pathString: string): ParsedPath; + /** + * Returns a path string from an object - the opposite of parse(). + * + * @param pathString path to evaluate. + */ + export function format(pathObject: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + detectIncompleteChar(buffer: Buffer): number; + } + export var StringDecoder: { + new (encoding: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface TlsOptions { + host?: string; + port?: number; + pfx?: any; //string or buffer + key?: any; //string or buffer + passphrase?: string; + cert?: any; + ca?: any; //string or buffer + crl?: any; //string or string array + ciphers?: string; + honorCipherOrder?: any; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; //array or Buffer; + SNICallback?: (servername: string) => any; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: any; //string | Buffer + key?: any; //string | Buffer + passphrase?: string; + cert?: any; //string | Buffer + ca?: any; //Array of string | Buffer + rejectUnauthorized?: boolean; + NPNProtocols?: any; //Array of string | Buffer + servername?: string; + } + + export interface Server extends net.Server { + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export interface SecureContextOptions { + pfx?: any; //string | buffer + key?: any; //string | buffer + passphrase?: string; + cert?: any; // string | buffer + ca?: any; // string | buffer + crl?: any; // string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } + + export interface SecureContext { + context: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; + export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; +} + +declare module "crypto" { + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: any; //string | string array + crl: any; //string | string array + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string): Hmac; + export function createHmac(algorithm: string, key: Buffer): Hmac; + export interface Hash { + update(data: any, input_encoding?: string): Hash; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + export interface Hmac extends NodeJS.ReadWriteStream { + update(data: any, input_encoding?: string): Hmac; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + export interface Cipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: "utf8"|"ascii"|"binary"): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: "binary"|"base64"|"hex"): string; + update(data: string, input_encoding: "utf8"|"ascii"|"binary", output_encoding: "binary"|"base64"|"hex"): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + getAuthTag(): Buffer; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + export interface Decipher extends NodeJS.ReadWriteStream { + update(data: Buffer): Buffer; + update(data: string, input_encoding: "binary"|"base64"|"hex"): Buffer; + update(data: Buffer, input_encoding: any, output_encoding: "utf8"|"ascii"|"binary"): string; + update(data: string, input_encoding: "binary"|"base64"|"hex", output_encoding: "utf8"|"ascii"|"binary"): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + setAuthTag(tag: Buffer): void; + } + export function createSign(algorithm: string): Signer; + export interface Signer extends NodeJS.WritableStream { + update(data: any): void; + sign(private_key: string, output_format: string): string; + } + export function createVerify(algorith: string): Verify; + export interface Verify extends NodeJS.WritableStream { + update(data: any): void; + verify(object: string, signature: string, signature_format?: string): boolean; + } + export function createDiffieHellman(prime_length: number): DiffieHellman; + export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; + export interface DiffieHellman { + generateKeys(encoding?: string): string; + computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; + getPrime(encoding?: string): string; + getGenerator(encoding: string): string; + getPublicKey(encoding?: string): string; + getPrivateKey(encoding?: string): string; + setPublicKey(public_key: string, encoding?: string): void; + setPrivateKey(public_key: string, encoding?: string): void; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number) : Buffer; + export function pbkdf2Sync(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, digest: string) : Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; + export interface RsaPublicKey { + key: string; + padding?: any; + } + export interface RsaPrivateKey { + key: string; + passphrase?: string, + padding?: any; + } + export function publicEncrypt(public_key: string|RsaPublicKey, buffer: Buffer): Buffer + export function privateDecrypt(private_key: string|RsaPrivateKey, buffer: Buffer): Buffer +} + +declare module "stream" { + import * as events from "events"; + + export class Stream extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + objectMode?: boolean; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + writable: boolean; + constructor(opts?: DuplexOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions {} + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: any, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform {} +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key:string): (msg:string,...param: any[])=>void; +} + +declare module "assert" { + function internal (value: any, message?: string): void; + namespace internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: {message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function}); + } + + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import * as net from "net"; + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + isTTY: boolean; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + isTTY: boolean; + } +} + +declare module "domain" { + import * as events from "events"; + + export class Domain extends events.EventEmitter implements NodeJS.Domain { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + } + + export function create(): Domain; +} + +declare module "constants" { + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; +} diff --git a/typings/tsd.d.ts b/typings/tsd.d.ts new file mode 100644 index 0000000..e0823e5 --- /dev/null +++ b/typings/tsd.d.ts @@ -0,0 +1,43 @@ +/// +/// +interface String { + /** + * 替换字符串中{0}{1}{2}{a} {b}这样的数据,用obj对应key替换,或者是数组中对应key的数据替换 + */ + substitute(...args): string; +} +interface Date { + /** + * 格式化日期 + */ + format(mask: string): string; +} + +declare function ready(hander: () => void); +declare var nodeRequire: NodeRequire; + + +interface cookiesUtils { + /** + * 设置cookie + * + * @param name + * @param value + */ + setCookie(name: string, value: string); + /** + * 获取cookie + * + * @param name + * @returns + */ + getCookie(name: string); + /** + * 删除cookie + * + * @param name + */ + delCookie(name: string); +} + +declare var cookie: cookiesUtils; \ No newline at end of file diff --git a/typings/xlsx/xlsx.d.ts b/typings/xlsx/xlsx.d.ts new file mode 100644 index 0000000..9bd98d1 --- /dev/null +++ b/typings/xlsx/xlsx.d.ts @@ -0,0 +1,148 @@ +// Type definitions for xlsx +// Project: https://github.com/SheetJS/js-xlsx +// Definitions by: themauveavenger +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare module 'xlsx' { + + export function readFile(filename:string, opts?:IParsingOptions):IWorkBook; + export function read(data:any, opts?:IParsingOptions):IWorkBook; + export var utils:IUtils; + + export interface IProperties { + LastAuthor?:string + Author?:string; + CreatedDate?:Date; + ModifiedDate?:Date + Application?:string; + AppVersion?:string; + Company?:string; + DocSecurity?:string; + Manager?:string; + HyperlinksChanged?: boolean; + SharedDoc?:boolean; + LinksUpToDate?:boolean; + ScaleCrop?:boolean; + Worksheets?:number; + SheetNames?:string[]; + } + + export interface IParsingOptions { + cellFormula?:boolean; + cellHTML?:boolean; + cellNF?:boolean; + cellStyles?:boolean; + cellDates?:boolean; + sheetStubs?:boolean; + sheetRows?:number; + bookDeps?:boolean; + bookFiles?:boolean; + bookProps?:boolean; + bookSheets?:boolean; + bookVBA?:boolean; + password?:string; + + /** + * Possible options: 'binary', 'base64', 'buffer', 'file' + */ + type?:string; + } + + export interface IWorkBook { + /** + * A dictionary of the worksheets in the workbook. + * Use SheetNames to reference these. + */ + Sheets:{[sheet:string]:IWorkSheet}; + + /** + * ordered list of the sheet names in the workbook + */ + SheetNames:string[]; + + /** + * an object storing the standard properties. wb.Custprops stores custom properties. + * Since the XLS standard properties deviate from the XLSX standard, XLS parsing stores core properties in both places. + */ + Props:IProperties; + } + + /** + * object representing the worksheet + */ + export interface IWorkSheet { + [cell:string]:IWorkSheetCell; + } + + export interface IWorkSheetCell { + /** + * The Excel Data Type of the cell. + * b Boolean, n Number, e error, s String, d Date + */ + t: string; + + /** + * The raw value of the cell. + */ + v: string; + + /** + * rich text encoding (if applicable) + */ + r?: string; + + /** + * HTML rendering of the rich text (if applicable) + */ + h?: string; + + /** + * formatted text (if applicable) + */ + w?: string; + + /** + * cell formula (if applicable) + */ + f?: string; + + /** + * comments associated with the cell ** + */ + c?: string; + + /** + * number format string associated with the cell (if requested) + */ + z?: string; + + /** + * cell hyperlink object (.Target holds link, .tooltip is tooltip) + */ + l?: string; + + /** + * the style/theme of the cell (if applicable) + */ + s?: string; + } + + + export interface IUtils { + sheet_to_json(worksheet:IWorkSheet,opts?:{ + raw?:boolean; + range?:string|number|{e:{c:number,r:number},s:{c:number,r:number}}; + header?:string[]|"A"|number; + }):T[]; + sheet_to_csv(worksheet:IWorkSheet):any; + sheet_to_formulae(worksheet:IWorkSheet):any; + /** + * + * 将列号处理为Excel的A B C D....Z AA AB...的形式 + * @param {number} col + * @returns {string} + */ + encode_col(col:number):string; + } + +} diff --git a/web.js b/web.js new file mode 100644 index 0000000..af9715a --- /dev/null +++ b/web.js @@ -0,0 +1,64 @@ +var PORT = 12345; + +var http = require('http'); +var url = require('url'); +var fs = require('fs'); +var path = require('path'); +const mime = { + "css": "text/css", + "gif": "image/gif", + "html": "text/html", + "ico": "image/x-icon", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "js": "text/javascript", + "json": "application/json", + "pdf": "application/pdf", + "png": "image/png", + "svg": "image/svg+xml", + "swf": "application/x-shockwave-flash", + "tiff": "image/tiff", + "txt": "text/plain", + "wav": "audio/x-wav", + "wma": "audio/x-ms-wma", + "wmv": "video/x-ms-wmv", + "xml": "text/xml" +}; + +var server = http.createServer(function (request, response) { + var realPath = url.parse(request.url).pathname.trim(); + if (!realPath || realPath == "/") { + realPath = "/index.html"; + } + realPath = path.join(__dirname, "dist", realPath); + console.log(realPath); + var ext = path.extname(realPath); + ext = ext ? ext.slice(1) : 'unknown'; + fs.exists(realPath, function (exists) { + if (!exists) { + response.writeHead(404, { + 'Content-Type': 'text/plain' + }); + + response.write(`无法找到文件${realPath}`); + response.end(); + } else { + fs.readFile(realPath, "binary", function (err, file) { + if (err) { + response.writeHead(500, { + 'Content-Type': 'text/plain' + }); + response.end(err); + } else { + var contentType = mime[ext] || "text/plain"; + response.writeHead(200, { + 'Content-Type': contentType + }); + response.write(file, "binary"); + response.end(); + } + }); + } + }); +}); +server.listen(PORT); \ No newline at end of file diff --git a/调试用.bat b/调试用.bat new file mode 100644 index 0000000..45f855b --- /dev/null +++ b/调试用.bat @@ -0,0 +1 @@ +electron app \ No newline at end of file