From 99b513875b1809859c50c8576ac2a0628ccbb22a Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sat, 13 May 2017 14:21:22 -0400 Subject: [PATCH] lint and type fixes - removed CFB test (fixes #654 h/t @wolfgang42) - book_append_sheet optional name (fixes #652 h/t @jomel) - strict mode compliance (h/t @simon-p-r @loongdefect @appersonj) - flow fixes (h/t @jameskraus for help with Date#getYear) - fixed minifier to generate ExtendScript-compatible code --- CHANGELOG.md | 4 + bits/00_header.js | 4 +- bits/02_codepage.js | 2 +- bits/22_xmlutils.js | 3 +- bits/25_cellutils.js | 4 +- bits/39_xlsbiff.js | 2 +- bits/40_harb.js | 23 ++-- bits/44_offcrypto.js | 6 +- bits/48_stybin.js | 8 +- bits/62_fxls.js | 12 +- bits/66_wscommon.js | 4 +- bits/67_wsxml.js | 3 +- bits/68_wsbin.js | 7 +- bits/71_wbcommon.js | 2 +- bits/72_wbxml.js | 4 +- bits/73_wbbin.js | 2 +- bits/75_xlml.js | 12 +- bits/76_xls.js | 48 ++++--- bits/79_html.js | 9 +- bits/85_parsezip.js | 5 +- bits/90_utils.js | 2 +- bits/95_api.js | 13 +- bits/97_node.js | 15 ++- demos/extendscript/.gitignore | 2 + demos/extendscript/Makefile | 3 +- demos/extendscript/README.md | 10 +- demos/extendscript/aftereffects.jsx | 2 +- demos/extendscript/estoolkit.jsx | 2 +- demos/extendscript/illustrator.jsx | 2 +- demos/extendscript/indesign.jsx | 2 +- demos/extendscript/photoshop.jsx | 2 +- demos/extendscript/test.jsx | 2 +- docbits/62_colrow.md | 4 +- misc/flow.js | 36 ++++-- misc/flowdeps.js | 77 +++++++++++ multiformat.lst | 26 ++-- package.json | 2 +- test.js | 152 ++++++++++++++-------- tests.lst | 25 +++- tests/core.js | 134 +++++++++++++------- tests/fixtures.js | 2 +- xlsx.flow.js | 190 ++++++++++++++-------------- xlsx.js | 132 +++++++++---------- 43 files changed, 620 insertions(+), 381 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8f8934..cb0470f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ but not limited to API changes and file location changes. Minor behavioral changes may not be included if they are not expected to break existing code. +## 0.10.2 (2017-05-??) + +* CSV generates numeric dates by default (aligning with XLSX cellDates behavior) + ## 0.9.10 (2017-04-08) * `--perf` renamed to `--read-only` diff --git a/bits/00_header.js b/bits/00_header.js index 634a2d1..fa858e2 100644 --- a/bits/00_header.js +++ b/bits/00_header.js @@ -1,8 +1,8 @@ /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint -W041 */ -/*jshint funcscope:true, eqnull:true */ +/*jshint funcscope:true, eqnull:true, loopfunc:true */ /*exported XLSX */ -/*global exports, module, require:false, process:false, Buffer:false */ +/*global global, exports, module, require:false, process:false, Buffer:false */ var XLSX = {}; (function make_xlsx(XLSX){ diff --git a/bits/02_codepage.js b/bits/02_codepage.js index 2d7e77e..dd94445 100644 --- a/bits/02_codepage.js +++ b/bits/02_codepage.js @@ -2,7 +2,7 @@ var current_codepage = 1200; /*:: declare var cptable:any; */ /*global cptable:true */ if(typeof module !== "undefined" && typeof require !== 'undefined') { - if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js'); + if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); } function reset_cp() { set_cp(1200); } var set_cp = function(cp) { current_codepage = cp; }; diff --git a/bits/22_xmlutils.js b/bits/22_xmlutils.js index 557729a..d5e8080 100644 --- a/bits/22_xmlutils.js +++ b/bits/22_xmlutils.js @@ -113,8 +113,7 @@ if(has_buf) { 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'); + return out.slice(0,k).toString('ucs2'); }; var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; diff --git a/bits/25_cellutils.js b/bits/25_cellutils.js index 0b0cc76..b4aaec8 100644 --- a/bits/25_cellutils.js +++ b/bits/25_cellutils.js @@ -1,5 +1,5 @@ /* XLS ranges enforced */ -function shift_cell_xls(cell, tgt/*:any*/, opts/*:?any*/) { +function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:CellAddress*/ { var out = dup(cell); if(tgt.s) { if(out.cRel) out.c += tgt.s.c; @@ -22,7 +22,7 @@ function shift_range_xls(cell, range, opts) { return out; } -function encode_cell_xls(c)/*:string*/ { +function encode_cell_xls(c/*:CellAddress*/)/*:string*/ { var s = encode_cell(c); if(c.cRel === 0) s = fix_col(s); if(c.rRel === 0) s = fix_row(s); diff --git a/bits/39_xlsbiff.js b/bits/39_xlsbiff.js index 38e3237..0d93a2c 100644 --- a/bits/39_xlsbiff.js +++ b/bits/39_xlsbiff.js @@ -274,7 +274,7 @@ function parse_Window1(blob, length) { /* 2.4.122 TODO */ function parse_Font(blob, length, opts) { - var o = { + var o/*:any*/ = { dyHeight: blob.read_shift(2), fl: blob.read_shift(2) }; diff --git a/bits/40_harb.js b/bits/40_harb.js index 8d219d8..2e8112a 100644 --- a/bits/40_harb.js +++ b/bits/40_harb.js @@ -193,7 +193,7 @@ function dbf_to_workbook(buf, opts)/*:Workbook*/ { var SYLK = (function() { /* TODO: find an actual specification */ - function sylk_to_aoa(d/*:RawData*/, opts)/*:AOA*/ { + function sylk_to_aoa(d/*:RawData*/, opts)/*:[AOA, Worksheet]*/ { switch(opts.type) { case 'base64': return sylk_to_aoa_str(Base64.decode(d), opts); case 'binary': return sylk_to_aoa_str(d, opts); @@ -202,7 +202,7 @@ var SYLK = (function() { } throw new Error("Unrecognized type " + opts.type); } - function sylk_to_aoa_str(str/*:string*/, opts)/*:AOA*/ { + function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ { var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr = []; var formats = []; var next_cell_format = null; @@ -242,7 +242,7 @@ var SYLK = (function() { next_cell_format = null; break; case 'E': - formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); + var formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); arr[R][C] = [arr[R][C], formula]; break; default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); @@ -287,13 +287,12 @@ var SYLK = (function() { } if(rowinfo.length > 0) sht['!rows'] = rowinfo; if(colinfo.length > 0) sht['!cols'] = colinfo; - arr[arr.length] = sht; - return arr; + return [arr, sht]; } function sylk_to_sheet(str/*:string*/, opts)/*:Worksheet*/ { - var aoa = sylk_to_aoa(str, opts); - var ws = aoa.pop(); + var aoasht = sylk_to_aoa(str, opts); + var aoa = aoasht[0], ws = aoasht[1]; var o = aoa_to_sheet(aoa, opts); keys(ws).forEach(function(k) { o[k] = ws[k]; }); return o; @@ -418,7 +417,7 @@ var DIF = (function() { o.push(v + "," + n); o.push('"' + s.replace(/"/g,'""') + '"'); }; - var push_value = function po(o/*:Array*/, type/*:number*/, v/*:number*/, s/*:string*/) { + var push_value = function po(o/*:Array*/, type/*:number*/, v/*:any*/, s/*:string*/) { o.push(type + "," + v); o.push(type == 1 ? '"' + s.replace(/"/g,'""') + '"' : s); }; @@ -528,8 +527,12 @@ var PRN = (function() { else if(s == "TRUE") { cell.t = 'b'; cell.v = true; } else if(s == "FALSE") { cell.t = 'b'; cell.v = false; } else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; } - else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); } - else { + else if(!isNaN(fuzzydate(s).getDate())) { + cell.z = o.dateNF || SSF._table[14]; + if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s); } + else { cell.t = 'n'; cell.v = datenum(parseDate(s)); } + cell.w = SSF.format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v); + } else { cell.t = 's'; if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"'); cell.v = s; diff --git a/bits/44_offcrypto.js b/bits/44_offcrypto.js index 3b3696b..4823fa5 100644 --- a/bits/44_offcrypto.js +++ b/bits/44_offcrypto.js @@ -6,10 +6,12 @@ function _JS2ANSI(str/*:string*/)/*:Array*/ { } /* [MS-OFFCRYPTO] 2.1.4 Version */ -function parse_CRYPTOVersion(blob, length/*:number*/) { - var o = {}; +function parse_CRYPTOVersion(blob, length/*:?number*/) { + var o/*:any*/ = {}; o.Major = blob.read_shift(2); o.Minor = blob.read_shift(2); + /*:: if(length == null) return o; */ + if(length >= 4) blob.l += length - 4; return o; } diff --git a/bits/48_stybin.js b/bits/48_stybin.js index bed89fc..d6f9a57 100644 --- a/bits/48_stybin.js +++ b/bits/48_stybin.js @@ -100,11 +100,11 @@ var XLSBFillPTNames = [ "gray125", "gray0625" ]; -var rev_XLSBFillPTNames = evert(XLSBFillPTNames); +var rev_XLSBFillPTNames/*:EvertNumType*/ = (evert(XLSBFillPTNames)/*:any*/); /* TODO: gradient fill representation */ function write_BrtFill(fill, o) { if(!o) o = new_buf(4*3 + 8*7 + 16*1); - var fls = rev_XLSBFillPTNames[fill.patternType]; + var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType]; if(fls == null) fls = 0x28; o.write_shift(4, fls); var j = 0; @@ -256,16 +256,18 @@ function parse_sty_bin(data, themes, opts) { return styles; } -function write_FMTS_bin(ba, NF) { +function write_FMTS_bin(ba, NF/*:?SSFTable*/) { if(!NF) return; var cnt = 0; [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { + /*:: if(!NF) return; */ for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt; }); if(cnt == 0) return; write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt)); [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { + /*:: if(!NF) return; */ for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i])); }); write_record(ba, "BrtEndFmts"); diff --git a/bits/62_fxls.js b/bits/62_fxls.js index a681db4..b8f9d74 100644 --- a/bits/62_fxls.js +++ b/bits/62_fxls.js @@ -693,7 +693,7 @@ var PtgBinOp = { function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, opts) { //console.log(formula); var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}}; - var stack/*:Array*/ = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname=""; + var stack/*:Array*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname=""; if(!formula[0] || !formula[0][0]) return ""; var last_sp = -1, sp = ""; //console.log("--",cell,formula[0]) @@ -764,15 +764,15 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgRef': /* 2.5.198.84 */ - type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts); + type = f[1][0]; c = shift_cell_xls((f[1][1]/*:any*/), _range, opts); stack.push(encode_cell_xls(c)); break; case 'PtgRefN': /* 2.5.198.88 */ - type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1]; + type = f[1][0]; c = cell ? shift_cell_xls((f[1][1]/*:any*/), cell, opts) : (f[1][1]/*:any*/); stack.push(encode_cell_xls(c)); break; case 'PtgRef3d': /* 2.5.198.85 */ - type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls(f[1][2], _range, opts); + type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls((f[1][2]/*:any*/), _range, opts); sname = supbooks.SheetNames[ixti]; var w = sname; /* IE9 fails on defined names */ stack.push(sname + "!" + encode_cell_xls(c)); @@ -823,7 +823,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgName': /* 2.5.97.60 TODO: revisions */ /* f[1] = type, 0, nameindex */ - nameidx = f[1][2]; + nameidx = (f[1][2]/*:any*/); var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx]; var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx); if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name]; @@ -832,7 +832,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgNameX': /* 2.5.97.61 TODO: revisions */ /* f[1] = type, ixti, nameindex */ - var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = f[1][2]; var externbook; + var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook; /* TODO: Properly handle missing values */ //console.log(bookidx, supbooks); if(opts.biff <= 5) { diff --git a/bits/66_wscommon.js b/bits/66_wscommon.js index 0e415bb..a44a7dd 100644 --- a/bits/66_wscommon.js +++ b/bits/66_wscommon.js @@ -25,7 +25,7 @@ function col_obj_w(C/*:number*/, col) { return p; } -function default_margins(margins, mode) { +function default_margins(margins/*:Margins*/, mode/*:?string*/) { if(!margins) return; var defs = [0.7, 0.7, 0.75, 0.75, 0.3, 0.3]; if(mode == 'xlml') defs = [1, 1, 1, 1, 0.5, 0.5]; @@ -60,7 +60,7 @@ function get_cell_style(styles, cell, opts) { return len; } -function safe_format(p, fmtid, fillid, opts, themes, styles) { +function safe_format(p, fmtid/*:number*/, fillid, opts, themes, styles) { if(p.t === 'z') return; if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v); try { diff --git a/bits/67_wsxml.js b/bits/67_wsxml.js index a326f83..2da4576 100644 --- a/bits/67_wsxml.js +++ b/bits/67_wsxml.js @@ -19,7 +19,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/); var data1 = "", data2 = ""; - var mtch=data.match(sheetdataregex); + var mtch/*:?any*/ =data.match(sheetdataregex); if(mtch) { data1 = data.substr(0, mtch.index); data2 = data.substr(mtch.index + mtch[0].length); @@ -490,7 +490,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ { if(ws['!drawing'].length > 0) { rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW); - ws['!drawing'].rid = rId; o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId}); } else delete ws['!drawing']; diff --git a/bits/68_wsbin.js b/bits/68_wsbin.js index 6bd2cb5..fbd2f4e 100644 --- a/bits/68_wsbin.js +++ b/bits/68_wsbin.js @@ -377,6 +377,7 @@ function write_BrtSheetProtection(sp, o) { ["pivotTables", true], // fPivotTables ["selectUnlockedCells", false] // fSelUnlockedCells ].forEach(function(n) { + /*:: if(o == null) throw "unreachable"; */ if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0); else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1); }); @@ -389,13 +390,13 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ { var opts = _opts || {}; if(!rels) rels = {'!id':{}}; if(DENSE != null && opts.dense == null) opts.dense = DENSE; - var s = opts.dense ? [] : {}; + var s/*:Worksheet*/ = (opts.dense ? [] : {}); var ref; var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} }; var pass = false, end = false; - var row, p, cf, R, C, addr, sstr, rr, cell; + var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/; var mergecells = []; opts.biff = 12; opts['!row'] = 0; @@ -511,7 +512,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ { case 0x01AA: /* 'BrtArrFmla' */ if(!opts.cellFormula) break; array_formulae.push(val); - cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]); + cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr])/*:any*/); cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts); cell.F = encode_range(val[0]); break; diff --git a/bits/71_wbcommon.js b/bits/71_wbcommon.js index 1abb5bb..627d5ad 100644 --- a/bits/71_wbcommon.js +++ b/bits/71_wbcommon.js @@ -100,7 +100,7 @@ function parse_wb_defaults(wb) { } var badchars = "][*?\/\\".split(""); -function check_ws_name(n/*:string*/, safe/*:boolean*/)/*:boolean*/ { +function check_ws_name(n/*:string*/, safe/*:?boolean*/)/*:boolean*/ { if(n.length > 31) { if(safe) return false; throw new Error("Sheet names cannot exceed 31 chars"); } var _good = true; badchars.forEach(function(c) { diff --git a/bits/72_wbxml.js b/bits/72_wbxml.js index a45302b..fac8cf5 100644 --- a/bits/72_wbxml.js +++ b/bits/72_wbxml.js @@ -7,7 +7,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { var dname = {}, dnstart = 0; /*(data.match(tagregex)||[]).forEach */ data.replace(tagregex, function xml_wb(x, idx) { - var y = parsexmltag(x); + var y/*:any*/ = parsexmltag(x); switch(strip_ns(y[0])) { case '"; if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) { - var d = {name:n.Name}; + var d/*:any*/ = {name:n.Name}; if(n.Comment) d.comment = n.Comment; if(n.Sheet != null) d.localSheetId = ""+n.Sheet; if(!n.Ref) return; diff --git a/bits/73_wbbin.js b/bits/73_wbbin.js index 23610d2..ad426dd 100644 --- a/bits/73_wbbin.js +++ b/bits/73_wbbin.js @@ -69,7 +69,7 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ { opts.biff = 12; var Names = []; - var supbooks = []; + var supbooks = ([]/*:any*/); supbooks.SheetNames = []; recordhopper(data, function hopper_wb(val, R_n, RT) { diff --git a/bits/75_xlml.js b/bits/75_xlml.js index 07fab4c..f2737fc 100644 --- a/bits/75_xlml.js +++ b/bits/75_xlml.js @@ -177,7 +177,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { var Rn; var state = [], tmp; if(DENSE != null && opts.dense == null) opts.dense = DENSE; - var sheets = {}, sheetnames = [], cursheet = (opts.dense ? [] : {}), sheetname = ""; + var sheets = {}, sheetnames = [], cursheet/*:Worksheet*/ = (opts.dense ? [] : {}), sheetname = ""; var table = {}, cell = ({}/*:any*/), row = {}; var dtag = xlml_parsexmltag(''), didx = 0; var c = 0, r = 0; @@ -190,7 +190,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { var cstys = [], csty, seencol = false; var arrayf = []; var rowinfo = [], rowobj = {}; - var Workbook = { Sheets:[] }, wsprops = {}; + var Workbook/*:WBWBProps*/ = { Sheets:[] }, wsprops = {}; xlmlregex.lastIndex = 0; str = str.replace(//mg,""); while((Rn = xlmlregex.exec(str))) switch(Rn[3]) { @@ -324,12 +324,12 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { case 'NamedRange': if(!Workbook.Names) Workbook.Names = []; var _NamedRange = parsexmltag(Rn[0]); - var _DefinedName = { + var _DefinedName/*:DefinedName*/ = ({ Name: _NamedRange.Name, Ref: rc_to_a1(_NamedRange.RefersTo.substr(1)) - }; + }/*:any*/); if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1; - Workbook.Names.push(_DefinedName); + /*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName); break; case 'NamedCell': break; @@ -1019,7 +1019,7 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo process_col(n); var w = !!n.width; var p = col_obj_w(i, n); - var k = {"ss:Index":i+1}; + var k/*:any*/ = {"ss:Index":i+1}; if(w) k['ss:Width'] = width2px(p.width); if(n.hidden) k['ss:Hidden']="1"; o.push(writextag("Column",null,k)); diff --git a/bits/76_xls.js b/bits/76_xls.js index f0f6410..1651b81 100644 --- a/bits/76_xls.js +++ b/bits/76_xls.js @@ -55,8 +55,9 @@ function slurp(R, blob, length/*:number*/, opts) { function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { if(p.t === 'z') return; if(!p.XF) return; + var fmtid = 0; try { - var fmtid = p.z || p.XF.ifmt || 0; + fmtid = p.z || p.XF.ifmt || 0; if(opts.cellNF) p.z = SSF._table[fmtid]; } catch(e) { if(opts.WTF) throw e; } if(!opts || opts.cellText !== false) try { @@ -75,7 +76,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { } catch(e) { if(opts.WTF) throw e; } } -function make_cell(val, ixfe, t)/*:any*/ { +function make_cell(val, ixfe, t)/*:Cell*/ { return ({v:val, ixfe:ixfe, t:t}/*:any*/); } @@ -84,7 +85,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { var wb = ({opts:{}}/*:any*/); var Sheets = {}; if(DENSE != null && options.dense == null) options.dense = DENSE; - var out = (options.dense ? [] : {}); + var out/*:Worksheet*/ = ((options.dense ? [] : {})/*:any*/); var Directory = {}; var found_sheet = false; var range/*:Range*/ = ({}/*:any*/); @@ -95,12 +96,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { var lastcell, last_cell = "", cc, cmnt, rng, rngC, rngR; var shared_formulae = {}; var array_formulae = []; /* TODO: something more clever */ - var temp_val; + var temp_val/*:Cell*/; var country; var cell_valid = true; var XFs = []; /* XF records */ var palette = []; - var Workbook = { Sheets:[] }, wsprops = {}; + var Workbook/*:WBWBProps*/ = ({ Sheets:[] }/*:any*/), wsprops = {}; var get_rgb = function getrgb(icv) { if(icv < 8) return XLSIcv[icv]; if(icv < 64) return palette[icv-8] || XLSIcv[icv]; @@ -179,9 +180,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { var last_Rn = ''; var file_depth = 0; /* TODO: make a real stack */ var BIFF2Fmt = 0; - var BIFF2FmtTable = []; + var BIFF2FmtTable/*:Array*/ = []; var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */ - var last_lbl; + var last_lbl/*:?DefinedName*/; /* explicit override for some broken writers */ opts.codepage = 1200; @@ -263,10 +264,10 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { break; case 'Index': break; // TODO case 'Lbl': - last_lbl = { + last_lbl = ({ Name: val.Name, Ref: stringify_formula(val.rgce,range,null,supbooks,opts) - }; + }/*:DefinedName*/); if(val.itab > 0) last_lbl.Sheet = val.itab - 1; supbooks.names.push(last_lbl); if(!supbooks[0]) supbooks[0] = []; @@ -281,7 +282,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'NameCmt': /* TODO: search for correct name */ if(opts.biff < 8) break; - last_lbl.Comment = val[1]; + if(last_lbl != null) last_lbl.Comment = val[1]; break; case 'Protect': out["!protect"] = val; break; /* for sheet or book */ @@ -307,7 +308,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { Workbook.Sheets.push(wsprops); } if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out; - out = options.dense ? [] : {}; + out = ((options.dense ? [] : {})/*:any*/); } break; case 'BOF': { if(opts.biff !== 8){/* empty */} @@ -320,7 +321,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { else if(val.BIFFVer === 0x0007) opts.biff = 2; if(file_depth++) break; cell_valid = true; - out = (options.dense ? [] : {}); + out = ((options.dense ? [] : {})/*:any*/); if(opts.biff < 5) { if(cur_sheet === "") cur_sheet = "Sheet1"; @@ -343,19 +344,19 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'Number': case 'BIFF2NUM': case 'BIFF2INT': { if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c; - temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; 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}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; 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'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:val.c, r:val.r}, temp_val, options); @@ -363,7 +364,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { 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'}; + temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:j, r:val.r}, temp_val, options); @@ -371,7 +372,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { } break; case 'Formula': { if(val.val == 'String') { last_formula = val; break; } - temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt}/*:any*/); + temp_val = make_cell(val.val, val.cell.ixfe, val.tt); temp_val.XF = XFs[temp_val.ixfe]; if(options.cellFormula) { var _f = val.formula; @@ -390,7 +391,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'String': { if(last_formula) { /* technically always true */ last_formula.val = val; - temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/); + temp_val = make_cell(val, last_formula.cell.ixfe, '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); @@ -431,7 +432,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { addcell({c:val.c, r:val.r}, temp_val, options); break; case 'Blank': if(options.sheetStubs) { - temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:val.c, r:val.r}, temp_val, options); @@ -439,7 +440,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'MulBlank': if(options.sheetStubs) { for(var _j = val.c; _j <= val.C; ++_j) { var _ixfe = val.ixfe[_j-val.c]; - temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}; + temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:_j, r:val.r}, temp_val, options); @@ -530,12 +531,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'TopMargin': case 'BottomMargin': if(!out['!margins']) default_margins(out['!margins'] = {}); - switch(Rn) { - case 'LeftMargin': out['!margins'].left = val; break; - case 'RightMargin': out['!margins'].right = val; break; - case 'TopMargin': out['!margins'].top = val; break; - case 'BottomMargin': out['!margins'].bottom = val; break; - } + out['!margins'][Rn.slice(0,-6).toLowerCase()] = val; break; case 'Setup': // TODO diff --git a/bits/79_html.js b/bits/79_html.js index 54158a9..e4794f6 100644 --- a/bits/79_html.js +++ b/bits/79_html.js @@ -75,12 +75,13 @@ var HTML_ = (function() { } return "" + oo.join("") + ""; } - function sheet_to_html(ws/*:Worksheet*/, opts)/*:string*/ { - var o/*:Array*/ = []; + function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ { + var o = opts || {}; + var out/*:Array*/ = []; var r = decode_range(ws['!ref']); o.dense = Array.isArray(ws); - for(var R = r.s.r; R <= r.e.r; ++R) o.push(make_html_row(ws, r, R, o)); - return "" + o.join("") + "
"; + for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); + return "" + out.join("") + "
"; } return { diff --git a/bits/85_parsezip.js b/bits/85_parsezip.js index 10910e3..b95c996 100644 --- a/bits/85_parsezip.js +++ b/bits/85_parsezip.js @@ -1,4 +1,4 @@ -function get_sheet_type(n) { +function get_sheet_type(n/*:string*/)/*:string*/ { if(RELS.WS.indexOf(n) > -1) return "sheet"; if(RELS.CS && n == RELS.CS) return "chart"; if(RELS.DS && n == RELS.DS) return "dialog"; @@ -181,8 +181,7 @@ function parse_xlsxcfb(cfb, opts/*:?ParseOpts*/)/*:Workbook*/ { data = cfb.find(f); if(!data) throw new Error("ECMA-376 Encrypted file missing " + f); var dsm = parse_DataSpaceMap(data.content); - if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || - dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") + if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") throw new Error("ECMA-376 Encrypted file bad " + f); f = 'StrongEncryptionDataSpace'; diff --git a/bits/90_utils.js b/bits/90_utils.js index 92128dd..3ed8bc2 100644 --- a/bits/90_utils.js +++ b/bits/90_utils.js @@ -190,7 +190,7 @@ function json_to_sheet(js/*:Array*/, opts)/*:Worksheet*/ { return ws; } -var utils = { +var utils/*:any*/ = { encode_col: encode_col, encode_row: encode_row, encode_cell: encode_cell, diff --git a/bits/95_api.js b/bits/95_api.js index fb9a68b..d771684 100644 --- a/bits/95_api.js +++ b/bits/95_api.js @@ -1,8 +1,8 @@ (function(utils) { utils.consts = utils.consts || {}; -function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } +function add_consts(R/*Array*/) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } -function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); } +function get_default(x/*:any*/, y/*:any*/, z/*:any*/)/*:any*/ { return x[y] != null ? x[y] : (x[y] = z); } /* get cell, creating a stub if necessary */ function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ { @@ -11,7 +11,7 @@ function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ { /* cell address object */ if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R)); /* R and C are 0-based indices */ - return ws_get_cell_stub(ws, encode_cell({r:R,c:C})); + return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0})); } /* find sheet index for given name / validate index */ @@ -33,7 +33,8 @@ utils.book_new = function()/*:Workbook*/ { /* add a worksheet to the end of a given workbook */ utils.book_append_sheet = function(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/) { - if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break; + if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break; + if(!name) throw new Error("Too many worksheets"); check_ws_name(name); if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!"); @@ -47,12 +48,14 @@ utils.book_set_sheet_visibility = function(wb/*:Workbook*/, sh/*:number|string*/ get_default(wb.Workbook,"Sheets",[]); var idx = wb_sheet_idx(wb, sh); + // $FlowIgnore get_default(wb.Workbook.Sheets,idx, {}); switch(vis) { case 0: case 1: case 2: break; default: throw new Error("Bad sheet visibility setting " + vis); } + // $FlowIgnore wb.Workbook.Sheets[idx].Hidden = vis; }; add_consts([ @@ -72,7 +75,7 @@ utils.cell_set_hyperlink = function(cell/*:Cell*/, target/*:string*/, tooltip/*: if(!target) { delete cell.l; } else { - cell.l = { Target: target }; + cell.l = ({ Target: target }/*:Hyperlink*/); if(tooltip) cell.l.Tooltip = tooltip; } return cell; diff --git a/bits/97_node.js b/bits/97_node.js index 6f782cf..88f1782 100644 --- a/bits/97_node.js +++ b/bits/97_node.js @@ -10,7 +10,7 @@ if(has_buf && typeof require != 'undefined') (function() { var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0); var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0); var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$"); - var row = "", cols = []; + var row/*:?string*/ = "", cols = []; o.dense = Array.isArray(sheet); for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C); var R = r.s.r; @@ -18,11 +18,12 @@ if(has_buf && typeof require != 'undefined') (function() { if(R > r.e.r) return stream.push(null); while(R <= r.e.r) { row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o); - if(row == null) { ++R; continue; } - if(o.strip) row = row.replace(endregex,""); - stream.push(row + RS); ++R; - break; + if(row != null) { + if(o.strip) row = row.replace(endregex,""); + stream.push(row + RS); + break; + } } }; return stream; @@ -31,10 +32,10 @@ if(has_buf && typeof require != 'undefined') (function() { var HTML_BEGIN = ""; var HTML_END = "
"; - var write_html_stream = function(sheet/*:Worksheet*/, opts) { + var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) { var stream = Readable(); - var o/*:Array*/ = []; + var o = opts == null ? {} : opts; var r = decode_range(sheet['!ref']), cell/*:Cell*/; o.dense = Array.isArray(sheet); stream.push(HTML_BEGIN); diff --git a/demos/extendscript/.gitignore b/demos/extendscript/.gitignore index 275d839..1c828e4 100644 --- a/demos/extendscript/.gitignore +++ b/demos/extendscript/.gitignore @@ -1,3 +1,5 @@ jszip.js shim.js xlsx.flow.js +xlsx.core.min.js +xlsx.full.min.js diff --git a/demos/extendscript/Makefile b/demos/extendscript/Makefile index 71b98ae..c94bf42 100644 --- a/demos/extendscript/Makefile +++ b/demos/extendscript/Makefile @@ -7,8 +7,7 @@ all: deps $(TARGETS) .PHONY: deps deps: cp ../../shim.js . - cp ../../jszip.js . - cp ../../xlsx.flow.js . + cp ../../dist/xlsx.core.min.js . %.base: echo "#target $*" > $@ diff --git a/demos/extendscript/README.md b/demos/extendscript/README.md index 72a9458..683f753 100644 --- a/demos/extendscript/README.md +++ b/demos/extendscript/README.md @@ -2,6 +2,10 @@ The main file is `test.jsx`. Target-specific files prepend target directives. -Copy the `test.jsx` file as well as the `shim.js`, `jszip.js` and `xlsx.flow.js` -files to wherever you want the scripts to reside. The demo shows opening a file -and converting to an array of arrays. +Copy the `test.jsx` file as well as the `shim.js` and `xlsx.core.min.js` files +to wherever you want the scripts to reside. The demo shows opening a file and +converting to an array of arrays. + +NOTE: [We forked the minifier](https://www.npmjs.com/package/@sheetjs/uglify-js) +and included a bugfix for ExtendScript's misparsing of switch statements. + diff --git a/demos/extendscript/aftereffects.jsx b/demos/extendscript/aftereffects.jsx index 9e7d248..cbc22c3 100644 --- a/demos/extendscript/aftereffects.jsx +++ b/demos/extendscript/aftereffects.jsx @@ -1,2 +1,2 @@ #target aftereffects -var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); +var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); diff --git a/demos/extendscript/estoolkit.jsx b/demos/extendscript/estoolkit.jsx index f6d83ce..ce06840 100644 --- a/demos/extendscript/estoolkit.jsx +++ b/demos/extendscript/estoolkit.jsx @@ -1,2 +1,2 @@ #target estoolkit -var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); +var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); diff --git a/demos/extendscript/illustrator.jsx b/demos/extendscript/illustrator.jsx index 866aee5..f1b348a 100644 --- a/demos/extendscript/illustrator.jsx +++ b/demos/extendscript/illustrator.jsx @@ -1,2 +1,2 @@ #target illustrator -var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); +var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); diff --git a/demos/extendscript/indesign.jsx b/demos/extendscript/indesign.jsx index 853613b..4c88636 100644 --- a/demos/extendscript/indesign.jsx +++ b/demos/extendscript/indesign.jsx @@ -1,2 +1,2 @@ #target indesign -var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); +var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); diff --git a/demos/extendscript/photoshop.jsx b/demos/extendscript/photoshop.jsx index 1c3e81b..a68b17a 100644 --- a/demos/extendscript/photoshop.jsx +++ b/demos/extendscript/photoshop.jsx @@ -1,2 +1,2 @@ #target photoshop -var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); +var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); diff --git a/demos/extendscript/test.jsx b/demos/extendscript/test.jsx index ae886ee..3c19b95 100755 --- a/demos/extendscript/test.jsx +++ b/demos/extendscript/test.jsx @@ -1 +1 @@ -var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "jszip.js"; #include "xlsx.flow.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); +var thisFile = new File($.fileName); var basePath = thisFile.path; #include "shim.js"; #include "xlsx.core.min.js"; var filename = "/sheetjs.xlsx"; var infile = File(basePath+filename); infile.open("r"); infile.encoding = "binary"; var data = infile.read(); var workbook = XLSX.read(data, {type:"binary"}); var first_sheet_name = workbook.SheetNames[0]; var first_worksheet = workbook.Sheets[first_sheet_name]; var data = XLSX.utils.sheet_to_json(first_worksheet, {header:1}); alert(data); diff --git a/docbits/62_colrow.md b/docbits/62_colrow.md index c4fcf58..609d3b5 100644 --- a/docbits/62_colrow.md +++ b/docbits/62_colrow.md @@ -10,7 +10,7 @@ type ColInfo = { /* column width is specified in one of the following ways: */ wpx?:number; // width in screen pixels - width:number; // width in Excel's "Max Digit Width", width*256 is integral + width?:number; // width in Excel's "Max Digit Width", width*256 is integral wch?:number; // width in characters /* other fields for preserving features from files */ @@ -49,7 +49,7 @@ objects which have the following properties: ```typescript type RowInfo = { /* visibility */ - hidden:?boolean; // if true, the row is hidden + hidden?:boolean; // if true, the row is hidden /* row height is specified in one of the following ways: */ hpx?:number; // height in screen pixels diff --git a/misc/flow.js b/misc/flow.js index 94d30a4..8c73aed 100644 --- a/misc/flow.js +++ b/misc/flow.js @@ -19,16 +19,13 @@ type Workbook = { Workbook?: WBWBProps; - SSF?: {[n:number]:string}; + SSF?: SSFTable; cfb?: any; }; -type WorkbookProps = { - SheetNames?: Array; -} - type WBWBProps = { Sheets: Array; + Names?: Array; }; type WBWSProp = { @@ -52,6 +49,7 @@ type Worksheet = any; type Sheet2CSVOpts = any; type Sheet2JSONOpts = any; +type Sheet2HTMLOpts = any; type ParseOpts = any; @@ -77,22 +75,44 @@ type SST = { type Comment = any; type RowInfo = { - hidden:?boolean; // if true, the row is hidden + hidden?:boolean; // if true, the row is hidden hpx?:number; // height in screen pixels hpt?:number; // height in points }; type ColInfo = { - hidden:?boolean; // if true, the column is hidden + hidden?:boolean; // if true, the column is hidden wpx?:number; // width in screen pixels - width:number; // width in Excel's "Max Digit Width", width*256 is integral + width?:number; // width in Excel's "Max Digit Width", width*256 is integral wch?:number; // width in characters MDW?:number; // Excel's "Max Digit Width" unit, always integral }; +interface Margins { + left?:number; + right?:number; + top?:number; + bottom?:number; + header?:number; + footer?:number; +}; + +interface DefinedName { + Name:string; + Ref:string; + Sheet?:number; + Comment?:string; +}; + +interface Hyperlink { + Target:string; + Tooltip?:string; +}; + +type SSFTable = any; type AOA = Array >; */ diff --git a/misc/flowdeps.js b/misc/flowdeps.js index 33cd1b2..ca01d53 100644 --- a/misc/flowdeps.js +++ b/misc/flowdeps.js @@ -11,4 +11,81 @@ declare module 'crypto' { declare var exports:any; }; declare module 'fs' { declare var exports:any; }; type ZIP = any; + +// ---------------------------------------------------------------------------- +// Note: The following override is needed because Flow is missing Date#getYear +// ---------------------------------------------------------------------------- + +type Date$LocaleOptions = { + localeMatcher?: string, + timeZone?: string, + hour12?: boolean, + formatMatcher?: string, + weekday?: string, + era?: string, + year?: string, + month?: string, + day?: string, + hour?: string, + minute?: string, + second?: string, + timeZoneName?: string, +}; + +declare class Date { + constructor(): void; + constructor(timestamp: number): void; + constructor(dateString: string): void; + constructor(year: number, month: number, day?: number, hour?: number, minute?: number, second?: number, millisecond?: number): void; + getDate(): number; + getDay(): number; + getYear(): number; + getFullYear(): number; + getHours(): number; + getMilliseconds(): number; + getMinutes(): number; + getMonth(): number; + getSeconds(): number; + getTime(): number; + getTimezoneOffset(): number; + getUTCDate(): number; + getUTCDay(): number; + getUTCFullYear(): number; + getUTCHours(): number; + getUTCMilliseconds(): number; + getUTCMinutes(): number; + getUTCMonth(): number; + getUTCSeconds(): number; + setDate(date: number): number; + setFullYear(year: number, month?: number, date?: number): number; + setHours(hours: number, min?: number, sec?: number, ms?: number): number; + setMilliseconds(ms: number): number; + setMinutes(min: number, sec?: number, ms?: number): number; + setMonth(month: number, date?: number): number; + setSeconds(sec: number, ms?: number): number; + setTime(time: number): number; + setUTCDate(date: number): number; + setUTCFullYear(year: number, month?: number, date?: number): number; + setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number; + setUTCMilliseconds(ms: number): number; + setUTCMinutes(min: number, sec?: number, ms?: number): number; + setUTCMonth(month: number, date?: number): number; + setUTCSeconds(sec: number, ms?: number): number; + toDateString(): string; + toISOString(): string; + toJSON(key?: any): string; + toLocaleDateString(locales?: string, options?: Date$LocaleOptions): string; + toLocaleString(locales?: string, options?: Date$LocaleOptions): string; + toLocaleTimeString(locales?: string, options?: Date$LocaleOptions): string; + toTimeString(): string; + toUTCString(): string; + valueOf(): number; + static ():string; + static now(): number; + static parse(s: string): number; + static UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number; + // multiple indexers not yet supported + [key: $SymbolToPrimitive]: (hint: 'string' | 'default' | 'number') => string | number; +} + */ diff --git a/multiformat.lst b/multiformat.lst index 438403c..b3e860b 100644 --- a/multiformat.lst +++ b/multiformat.lst @@ -6,33 +6,41 @@ AutoFilter .xls .xlsb .xlsx .xml # note: XLML only supports sheets, ods does not support dialog BlankSheetTypes .xls .xlsb .xlsm NumberFormatCondition .xls .xlsb .xlsm .xml -RkNumber .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#RkNumber .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +RkNumber .xls .xlsb .xlsx .xls.xml #calendar_stress_test .xls .xlsb .xlsx .xml cell_style_simple .xls .xlsb .xlsx .xml # no-csv (newline character \r vs \n) -comments_stress_test .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#comments_stress_test .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +comments_stress_test .xls .xlsb .xlsx .xls.xml # yes-csv -custom_properties .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#custom_properties .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +custom_properties .xls .xlsb .xlsx .xls.xml defined_names_simple .xls .xlsb .xlsx .xml # no-csv (randbetween) note: ODS does not support many XLSX functions -formula_stress_test .xls .xlsb .xlsx .xlsb.xml +formula_stress_test .xls .xlsb .xlsx .xls.xml # yes-csv formulae_test_simple .xls .xlsb .xlsx .xml hyperlink_stress_test_2011 .xls .xlsb .xlsx .xml #large_strings .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml -merge_cells .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#merge_cells .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +merge_cells .xls .xlsb .xlsx .xls.xml # no-formula (filename-references in XLSX encoding as [0]) -named_ranges_2011 .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#named_ranges_2011 .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +named_ranges_2011 .xls .xlsb .xlsx .xls.xml # yes-formula # no-csv (macro serialization in xml) -number_format .xls .xlsb .xlsm .xls.xml .xlsb.xml .xlsm.xml +#number_format .xls .xlsb .xlsm .xls.xml .xlsb.xml .xlsm.xml +number_format .xls .xlsb .xlsm .xls.xml # yes-csv number_format_entities .xls .xlsb .xlsx .xml pivot_table_named_range .xls .xlsb .xlsx .xml pivot_table_test .xls .xlsb .xlsm -rich_text_stress .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#rich_text_stress .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +rich_text_stress .xls .xlsb .xlsx .xls.xml smart_tags_2007 .xls .xlsb .xlsx .xml sushi .xls .xlsb .xlsx .xml text_and_numbers .xls .xlsb .xlsx .xml #time_stress_test_1 .xls .xlsb .xlsx .xml -xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +#xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml .xlsb.xml .xlsx.xml +xlsx-stream-d-date-cell .xls .xlsb .xlsx .xls.xml diff --git a/package.json b/package.json index afeba14..f6703bd 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "devDependencies": { "mocha":"", "xlsjs":"", - "uglify-js":"" + "@sheetjs/uglify-js":"" }, "repository": { "type":"git", "url":"git://github.com/SheetJS/js-xlsx.git" }, "scripts": { diff --git a/test.js b/test.js index 6e45494..99fc7ec 100644 --- a/test.js +++ b/test.js @@ -144,7 +144,7 @@ function parsetest(x, wb, full, ext) { if(fs.existsSync(sname)) it('should have the right sheet names', function() { var file = fs.readFileSync(sname, 'utf-8').replace(/\r/g,""); var names = wb.SheetNames.map(fixsheetname).join("\n") + "\n"; - if(file.length) assert.equal(names, file); + if(file.length && !x.match(/artifacts/)) assert.equal(names, file); }); }); describe(x + ext + ' should generate CSV', function() { @@ -642,6 +642,23 @@ describe('output formats', function() { }); }); +function eqarr(a,b) { + assert.equal(a.length, b.length); + a.forEach(function(x, i) { assert.equal(x, b[i]); }); +} + +describe('API', function() { + it('book_append_sheet', function() { + var wb = X.utils.book_new(); + X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]), "A"); + X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]])); + X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]])); + X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]]), "B"); + X.utils.book_append_sheet(wb, X.utils.aoa_to_sheet([[1,2,3],[4],[5]])); + eqarr(wb.SheetNames, ["A","Sheet1","Sheet2","B","Sheet3"]); + }); +}); + function coreprop(wb) { assert.equal(wb.Props.Title, 'Example with properties'); assert.equal(wb.Props.Subject, 'Test it before you code it'); @@ -1634,53 +1651,90 @@ describe('json output', function() { }); describe('csv', function() { - var data, ws; - var bef = (function() { - data = [ - [1,2,3,null], - [true, false, null, "sheetjs"], - ["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"], - [null, null, null], - ["baz", undefined, "qux"] - ]; - ws = X.utils.aoa_to_sheet(data); + describe('input', function(){ + var b = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n"; + it('should generate date numbers by default', function() { + var opts = {type:"binary"}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + assert.equal(cell.t, 'n'); + assert(typeof cell.v == "number"); + }); + it('should generate dates when requested', function() { + var opts = {type:"binary", cellDates:true}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + assert.equal(cell.t, 'd'); + assert(cell.v instanceof Date || typeof cell.v == "string"); + }); + + it('should use US date code 14 by default', function() { + var opts = {type:"binary"}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + opts.cellDates = true; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + }); + it('should honor dateNF override', function() { + var opts = {type:"binary", dateNF:"YYYY-MM-DD"}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2014-02-19'); + opts.cellDates = true; opts.dateNF = "YY-MM-DD"; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '14-02-19'); + }); + }); - if(typeof before != 'undefined') before(bef); - else it('before', bef); - it('should generate csv', function() { - var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n"; - assert.equal(baseline, X.utils.sheet_to_csv(ws)); - }); - it('should handle FS', function() { - assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws)); - assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws)); - }); - it('should handle RS', function() { - assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws)); - assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws)); - }); - it('should handle dateNF', function() { - var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n"; - var _ws = X.utils.aoa_to_sheet(data, {cellDates:true}); - delete get_cell(_ws,"C3").w; - delete get_cell(_ws,"C3").z; - assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"})); - }); - it('should handle strip', function() { - var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n"; - assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true})); - }); - it('should handle blankrows', function() { - var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n"; - assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false})); - }); - it('should handle various line endings', function() { - var data = ["1,a", "2,b", "3,c"]; - [ "\r", "\n", "\r\n" ].forEach(function(RS) { - var wb = X.read(data.join(RS), {type:'binary'}); - assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1); - assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c"); - assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3"); + describe('output', function(){ + var data, ws; + var bef = (function() { + data = [ + [1,2,3,null], + [true, false, null, "sheetjs"], + ["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"], + [null, null, null], + ["baz", undefined, "qux"] + ]; + ws = X.utils.aoa_to_sheet(data); + }); + if(typeof before != 'undefined') before(bef); + else it('before', bef); + it('should generate csv', function() { + var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n"; + assert.equal(baseline, X.utils.sheet_to_csv(ws)); + }); + it('should handle FS', function() { + assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws)); + assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws)); + }); + it('should handle RS', function() { + assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws)); + assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws)); + }); + it('should handle dateNF', function() { + var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n"; + var _ws = X.utils.aoa_to_sheet(data, {cellDates:true}); + delete get_cell(_ws,"C3").w; + delete get_cell(_ws,"C3").z; + assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"})); + }); + it('should handle strip', function() { + var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n"; + assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true})); + }); + it('should handle blankrows', function() { + var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n"; + assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false})); + }); + it('should handle various line endings', function() { + var data = ["1,a", "2,b", "3,c"]; + [ "\r", "\n", "\r\n" ].forEach(function(RS) { + var wb = X.read(data.join(RS), {type:'binary'}); + assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1); + assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c"); + assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3"); + }); }); }); }); @@ -1778,10 +1832,6 @@ describe('corner cases', function() { } }); }); - it('CFB', function() { - var cfb = X.CFB.read(paths.swcxls, {type:"file"}); - var xls = X.parse_xlscfb(cfb); - }); it('codepage', function() { X.readFile(dir + "biff5/number_format_greek.xls"); }); diff --git a/tests.lst b/tests.lst index af45ee4..34250ba 100644 --- a/tests.lst +++ b/tests.lst @@ -1371,4 +1371,27 @@ xlsx-stream-d-date-cell.xlsx.xml 2013/apachepoi_54016.xls.xlsb 2013/apachepoi_ReadOnlyRecommended.xls.xlsb 2013/apachepoi_testArraysAndTables.xls.xlsb - +artifacts/quattro/write_.csv +artifacts/quattro/write_.dif +artifacts/quattro/write_.slk +artifacts/quattro/write_57.xls +artifacts/quattro/write_6.wb2 +artifacts/quattro/write_6b.wb2 +artifacts/quattro/write_8.wb3 +artifacts/quattro/write_9.qpw +artifacts/quattro/write_97.xls +artifacts/quattro/write_L1.wks +artifacts/quattro/write_L2.wk1 +artifacts/quattro/write_L3.wk3 +artifacts/quattro/write_L45.wk4 +artifacts/quattro/write_L9.123 +artifacts/quattro/write_L97.123 +artifacts/quattro/write_Led.wke +artifacts/quattro/write_qpdos.wq1 +artifacts/quattro/write_qpw.wb1 +artifacts/wps/write.dbf +artifacts/wps/write.dif +artifacts/wps/write.et +# artifacts/wps/write.xls ## bad sheet name +artifacts/wps/write.xlsx +artifacts/wps/write.xml diff --git a/tests/core.js b/tests/core.js index db6f5a5..0117794 100644 --- a/tests/core.js +++ b/tests/core.js @@ -1636,53 +1636,90 @@ describe('json output', function() { }); describe('csv', function() { - var data, ws; - var bef = (function() { - data = [ - [1,2,3,null], - [true, false, null, "sheetjs"], - ["foo", "bar", parseDate("2014-02-19T14:30:00.000Z"), "0.3"], - [null, null, null], - ["baz", undefined, "qux"] - ]; - ws = X.utils.aoa_to_sheet(data); + describe('input', function(){ + var b = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n"; + it('should generate date numbers by default', function() { + var opts = {type:"binary"}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + assert.equal(cell.t, 'n'); + assert(typeof cell.v == "number"); + }); + it('should generate dates when requested', function() { + var opts = {type:"binary", cellDates:true}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + assert.equal(cell.t, 'd'); + assert(cell.v instanceof Date || typeof cell.v == "string"); + }); + + it('should use US date code 14 by default', function() { + var opts = {type:"binary"}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + opts.cellDates = true; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2/19/14'); + }); + it('should honor dateNF override', function() { + var opts = {type:"binary", dateNF:"YYYY-MM-DD"}; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '2014-02-19'); + opts.cellDates = true; opts.dateNF = "YY-MM-DD"; + var cell = get_cell(X.read(b, opts).Sheets.Sheet1, "C3"); + assert.equal(cell.w, '14-02-19'); + }); + }); - if(typeof before != 'undefined') before(bef); - else it('before', bef); - it('should generate csv', function() { - var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n"; - assert.equal(baseline, X.utils.sheet_to_csv(ws)); - }); - it('should handle FS', function() { - assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws)); - assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws)); - }); - it('should handle RS', function() { - assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws)); - assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws)); - }); - it('should handle dateNF', function() { - var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n"; - var _ws = X.utils.aoa_to_sheet(data, {cellDates:true}); - delete get_cell(_ws,"C3").w; - delete get_cell(_ws,"C3").z; - assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"})); - }); - it('should handle strip', function() { - var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n"; - assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true})); - }); - it('should handle blankrows', function() { - var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n"; - assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false})); - }); - it('should handle various line endings', function() { - var data = ["1,a", "2,b", "3,c"]; - [ "\r", "\n", "\r\n" ].forEach(function(RS) { - var wb = X.read(data.join(RS), {type:'binary'}); - assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1); - assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c"); - assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3"); + describe('output', function(){ + var data, ws; + var bef = (function() { + data = [ + [1,2,3,null], + [true, false, null, "sheetjs"], + ["foo", "bar", new Date("2014-02-19T14:30Z"), "0.3"], + [null, null, null], + ["baz", undefined, "qux"] + ]; + ws = X.utils.aoa_to_sheet(data); + }); + if(typeof before != 'undefined') before(bef); + else it('before', bef); + it('should generate csv', function() { + var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n,,,\nbaz,,qux,\n"; + assert.equal(baseline, X.utils.sheet_to_csv(ws)); + }); + it('should handle FS', function() { + assert.equal(X.utils.sheet_to_csv(ws, {FS:"|"}).replace(/[|]/g,","), X.utils.sheet_to_csv(ws)); + assert.equal(X.utils.sheet_to_csv(ws, {FS:";"}).replace(/[;]/g,","), X.utils.sheet_to_csv(ws)); + }); + it('should handle RS', function() { + assert.equal(X.utils.sheet_to_csv(ws, {RS:"|"}).replace(/[|]/g,"\n"), X.utils.sheet_to_csv(ws)); + assert.equal(X.utils.sheet_to_csv(ws, {RS:";"}).replace(/[;]/g,"\n"), X.utils.sheet_to_csv(ws)); + }); + it('should handle dateNF', function() { + var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,20140219,0.3\n,,,\nbaz,,qux,\n"; + var _ws = X.utils.aoa_to_sheet(data, {cellDates:true}); + delete get_cell(_ws,"C3").w; + delete get_cell(_ws,"C3").z; + assert.equal(baseline, X.utils.sheet_to_csv(_ws, {dateNF:"YYYYMMDD"})); + }); + it('should handle strip', function() { + var baseline = "1,2,3\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\n\nbaz,,qux\n"; + assert.equal(baseline, X.utils.sheet_to_csv(ws, {strip:true})); + }); + it('should handle blankrows', function() { + var baseline = "1,2,3,\nTRUE,FALSE,,sheetjs\nfoo,bar,2/19/14,0.3\nbaz,,qux,\n"; + assert.equal(baseline, X.utils.sheet_to_csv(ws, {blankrows:false})); + }); + it('should handle various line endings', function() { + var data = ["1,a", "2,b", "3,c"]; + [ "\r", "\n", "\r\n" ].forEach(function(RS) { + var wb = X.read(data.join(RS), {type:'binary'}); + assert.equal(get_cell(wb.Sheets.Sheet1, "A1").v, 1); + assert.equal(get_cell(wb.Sheets.Sheet1, "B3").v, "c"); + assert.equal(wb.Sheets.Sheet1['!ref'], "A1:B3"); + }); }); }); }); @@ -1815,14 +1852,15 @@ describe('encryption', function() { }); }); -describe.skip('multiformat tests', function() { +describe('multiformat tests', function() { var mfopts = opts; var mft = fs.readFileSync('multiformat.lst','utf-8').split("\n"); var csv = true, formulae = false; mft.forEach(function(x) { - if(x[0]!="#") describe('MFT ' + x, function() { + if(x.charAt(0)!="#") describe('MFT ' + x, function() { var fil = {}, f = [], r = x.split(/\s+/); if(r.length < 3) return; + if(!fs.existsSync(dir + r[0] + r[1])) return; it('should parse all', function() { for(var j = 1; j != r.length; ++j) f[j-1] = X.read(fs.readFileSync(dir + r[0] + r[j]), mfopts); }); diff --git a/tests/fixtures.js b/tests/fixtures.js index bcfd4b6..be3c802 100644 --- a/tests/fixtures.js +++ b/tests/fixtures.js @@ -72,6 +72,6 @@ fs['./test_files/apachepoi_SimpleWithComments.xlsx'] = 'UEsDBBQABgAIAAAAIQDfiMhb fs['./test_files/2013/apachepoi_SimpleWithComments.xlsx.xlsb'] = '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'; fs['./test_files/password_2002_40_xor.xls'] = '0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAAGQAAAAAAAAAAEAAA/v///wAAAAD+////AAAAABgAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8JCBAAAAYFAEYYzQfBgAAABgIAAIYAAAAvAAYAAAB6FK+D4QACALAEwQACAOFK4gAAAFwAcABkOOA9L7rCPQynAb6At4K5ADzk8cZTxvHlTgG+gLeCuQA85PHGU8bx5U4BvoC3grkAPOTxxlPG8eVOAb6At4K5ADzk8cZTxvHlTgG+gLeCuQA85PHGU8bx5U4BvoC3grkAPOTxxlPG8eVOAb6At4K5WwAKAIa98UiA9cKfLxhCAAIA1NdhAQIABbrAAQAAPQEGAMFKRbrks5wAAgBHvRkAAgDCVxIAAgAFuhMAAgAEOK8BAgDC9bwBAgCEsz0AEgDt1QFXsT2+LgK6hLOGvSQ467VAAAIA4UqNAAIAhr0iAAIAwlcOAAIAJbq3AQIABDjaAAIAwvUxABoA21fC9R6lF5qEs4a9BDhA1epXjPXMSim6CbMxABoA+fXCVz0a82oFuoSzhr2kGMj1jFfv9c1KiLoxABoAHTjg9T240NXhSgW6hLMmnSw4rvXvV+71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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v8AAAUBAgAAAAAAAAAAAAAAAAAAAAAAAQAAAOCFn/L5T2gQq5EIACsns9kwAAAAmAAAAAcAAAABAAAAQAAAAAQAAABIAAAACAAAAFQAAAASAAAAYAAAAAwAAAB4AAAADQAAAIQAAAATAAAAkAAAAAIAAADoBAAAHgAAAAQAAABGb28AHgAAAAQAAABGb28AHgAAABAAAABNaWNyb3NvZnQgRXhjZWwAQAAAAIAQtwtmXM8BQAAAAAB0pjNmXM8BAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7/AAAFAQIAAAAAAAAAAAAAAAAAAAAAAAEAAAAC1c3VnC4bEJOXCAArLPmuMAAAANgAAAAJAAAAAQAAAFAAAAAPAAAAWAAAABcAAABkAAAACwAAAGwAAAAQAAAAdAAAABMAAAB8AAAAFgAAAIQAAAANAAAAjAAAAAwAAAC1AAAAAgAAAOgEAAAeAAAABAAAAEJhcgADAAAAQQoKAAsAAAAAAAAACwAAAAAAAAALAAAAAAAAAAsAAAAAAAAAHhAAAAMAAAAHAAAAU2hlZXQxAAcAAABTaGVldDIABwAAAFNoZWV0MwAMEAAAAgAAAB4AAAALAAAAV29ya3NoZWV0cwADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAA/v///wkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAD+////EQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAAP7////9/////v///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////1IAbwBvAHQAIABFAG4AdAByAHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAUB//////////8CAAAAIAgCAAAAAADAAAAAAAAARgAAAAAAAAAAAAAAAACY99pnXM8B/v///wAAAAAAAAAAVwBvAHIAawBiAG8AbwBrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAgH///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAFAFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAACAQEAAAADAAAA/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAEAAAAAAAAAUARABvAGMAdQBtAGUAbgB0AFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBuAAAAAAAAAAAAAAA4AAIB////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAQAAAAAAAA'; fs[''] = ''; -fs['multiformat.lst'] = 'IyBUaGlzIGZpbGUgY29udHJvbHMgdGhlIG11bHRpZm9ybWF0IHRlc3RzCiMgdmltOiBzZXQgdHM9NDoKIyBGb3JtYXQ6IDxiYXNlbmFtZT4gPGV4dD4gPGV4dD4gW2V4dC4uXQojIHllcy1mb3JtdWxhCkF1dG9GaWx0ZXIgICAgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKIyBub3RlOiBYTE1MIG9ubHkgc3VwcG9ydHMgc2hlZXRzLCBvZHMgZG9lcyBub3Qgc3VwcG9ydCBkaWFsb2cKQmxhbmtTaGVldFR5cGVzICAgICAgICAgCS54bHMgLnhsc2IgLnhsc20KTnVtYmVyRm9ybWF0Q29uZGl0aW9uICAgCS54bHMgLnhsc2IgLnhsc20gLnhtbApSa051bWJlciAgICAgICAgICAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCiNjYWxlbmRhcl9zdHJlc3NfdGVzdCAgICAJLnhscyAueGxzYiAueGxzeCAueG1sCmNlbGxfc3R5bGVfc2ltcGxlICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKIyBuby1jc3YgKG5ld2xpbmUgY2hhcmFjdGVyIFxyIHZzIFxuKQpjb21tZW50c19zdHJlc3NfdGVzdCAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCiMgeWVzLWNzdgpjdXN0b21fcHJvcGVydGllcyAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCmRlZmluZWRfbmFtZXNfc2ltcGxlICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKIyBuby1jc3YgKHJhbmRiZXR3ZWVuKSBub3RlOiBPRFMgZG9lcyBub3Qgc3VwcG9ydCBtYW55IFhMU1ggZnVuY3Rpb25zIApmb3JtdWxhX3N0cmVzc190ZXN0ICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzYi54bWwKIyB5ZXMtY3N2CmZvcm11bGFlX3Rlc3Rfc2ltcGxlICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKaHlwZXJsaW5rX3N0cmVzc190ZXN0XzIwMTEJLnhscyAueGxzYiAueGxzeCAueG1sCiNsYXJnZV9zdHJpbmdzICAgICAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCm1lcmdlX2NlbGxzICAgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bHMueG1sIC54bHNiLnhtbCAueGxzeC54bWwKIyBuby1mb3JtdWxhIChmaWxlbmFtZS1yZWZlcmVuY2VzIGluIFhMU1ggZW5jb2RpbmcgYXMgWzBdKQpuYW1lZF9yYW5nZXNfMjAxMSAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCiMgeWVzLWZvcm11bGEKIyBuby1jc3YgKG1hY3JvIHNlcmlhbGl6YXRpb24gaW4geG1sKQpudW1iZXJfZm9ybWF0ICAgICAgICAgICAJLnhscyAueGxzYiAueGxzbSAueGxzLnhtbCAueGxzYi54bWwgLnhsc20ueG1sCiMgeWVzLWNzdgpudW1iZXJfZm9ybWF0X2VudGl0aWVzICAJLnhscyAueGxzYiAueGxzeCAueG1sCnBpdm90X3RhYmxlX25hbWVkX3JhbmdlIAkueGxzIC54bHNiIC54bHN4IC54bWwKcGl2b3RfdGFibGVfdGVzdCAgICAgICAgCS54bHMgLnhsc2IgLnhsc20KcmljaF90ZXh0X3N0cmVzcyAgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwgLnhsc2IueG1sIC54bHN4LnhtbApzbWFydF90YWdzXzIwMDcgICAgICAgICAJLnhscyAueGxzYiAueGxzeCAueG1sCnN1c2hpICAgICAgICAgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKdGV4dF9hbmRfbnVtYmVycyAgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhtbAojdGltZV9zdHJlc3NfdGVzdF8xICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhtbAp4bHN4LXN0cmVhbS1kLWRhdGUtY2VsbCAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCg=='; +fs['multiformat.lst'] = 'IyBUaGlzIGZpbGUgY29udHJvbHMgdGhlIG11bHRpZm9ybWF0IHRlc3RzCiMgdmltOiBzZXQgdHM9NDoKIyBGb3JtYXQ6IDxiYXNlbmFtZT4gPGV4dD4gPGV4dD4gW2V4dC4uXQojIHllcy1mb3JtdWxhCkF1dG9GaWx0ZXIgICAgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKIyBub3RlOiBYTE1MIG9ubHkgc3VwcG9ydHMgc2hlZXRzLCBvZHMgZG9lcyBub3Qgc3VwcG9ydCBkaWFsb2cKQmxhbmtTaGVldFR5cGVzICAgICAgICAgCS54bHMgLnhsc2IgLnhsc20KTnVtYmVyRm9ybWF0Q29uZGl0aW9uICAgCS54bHMgLnhsc2IgLnhsc20gLnhtbAojUmtOdW1iZXIgICAgICAgICAgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwgLnhsc2IueG1sIC54bHN4LnhtbApSa051bWJlciAgICAgICAgICAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbAojY2FsZW5kYXJfc3RyZXNzX3Rlc3QgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhtbApjZWxsX3N0eWxlX3NpbXBsZSAgICAgICAJLnhscyAueGxzYiAueGxzeCAueG1sCiMgbm8tY3N2IChuZXdsaW5lIGNoYXJhY3RlciBcciB2cyBcbikKI2NvbW1lbnRzX3N0cmVzc190ZXN0ICAgIAkueGxzIC54bHNiIC54bHN4IC54bHMueG1sIC54bHNiLnhtbCAueGxzeC54bWwKY29tbWVudHNfc3RyZXNzX3Rlc3QgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwKIyB5ZXMtY3N2CiNjdXN0b21fcHJvcGVydGllcyAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbCAueGxzYi54bWwgLnhsc3gueG1sCmN1c3RvbV9wcm9wZXJ0aWVzICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bHMueG1sCmRlZmluZWRfbmFtZXNfc2ltcGxlICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKIyBuby1jc3YgKHJhbmRiZXR3ZWVuKSBub3RlOiBPRFMgZG9lcyBub3Qgc3VwcG9ydCBtYW55IFhMU1ggZnVuY3Rpb25zIApmb3JtdWxhX3N0cmVzc190ZXN0ICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbAojIHllcy1jc3YKZm9ybXVsYWVfdGVzdF9zaW1wbGUgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhtbApoeXBlcmxpbmtfc3RyZXNzX3Rlc3RfMjAxMQkueGxzIC54bHNiIC54bHN4IC54bWwKI2xhcmdlX3N0cmluZ3MgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bHMueG1sIC54bHNiLnhtbCAueGxzeC54bWwKI21lcmdlX2NlbGxzICAgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bHMueG1sIC54bHNiLnhtbCAueGxzeC54bWwKbWVyZ2VfY2VsbHMgICAgICAgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwKIyBuby1mb3JtdWxhIChmaWxlbmFtZS1yZWZlcmVuY2VzIGluIFhMU1ggZW5jb2RpbmcgYXMgWzBdKQojbmFtZWRfcmFuZ2VzXzIwMTEgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwgLnhsc2IueG1sIC54bHN4LnhtbApuYW1lZF9yYW5nZXNfMjAxMSAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbAojIHllcy1mb3JtdWxhCiMgbm8tY3N2IChtYWNybyBzZXJpYWxpemF0aW9uIGluIHhtbCkKI251bWJlcl9mb3JtYXQgICAgICAgICAgIAkueGxzIC54bHNiIC54bHNtIC54bHMueG1sIC54bHNiLnhtbCAueGxzbS54bWwKbnVtYmVyX2Zvcm1hdCAgICAgICAgICAgCS54bHMgLnhsc2IgLnhsc20gLnhscy54bWwKIyB5ZXMtY3N2Cm51bWJlcl9mb3JtYXRfZW50aXRpZXMgIAkueGxzIC54bHNiIC54bHN4IC54bWwKcGl2b3RfdGFibGVfbmFtZWRfcmFuZ2UgCS54bHMgLnhsc2IgLnhsc3ggLnhtbApwaXZvdF90YWJsZV90ZXN0ICAgICAgICAJLnhscyAueGxzYiAueGxzbQojcmljaF90ZXh0X3N0cmVzcyAgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwgLnhsc2IueG1sIC54bHN4LnhtbApyaWNoX3RleHRfc3RyZXNzICAgICAgICAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbApzbWFydF90YWdzXzIwMDcgICAgICAgICAJLnhscyAueGxzYiAueGxzeCAueG1sCnN1c2hpICAgICAgICAgICAgICAgICAgIAkueGxzIC54bHNiIC54bHN4IC54bWwKdGV4dF9hbmRfbnVtYmVycyAgICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhtbAojdGltZV9zdHJlc3NfdGVzdF8xICAgICAgCS54bHMgLnhsc2IgLnhsc3ggLnhtbAojeGxzeC1zdHJlYW0tZC1kYXRlLWNlbGwgCS54bHMgLnhsc2IgLnhsc3ggLnhscy54bWwgLnhsc2IueG1sIC54bHN4LnhtbAp4bHN4LXN0cmVhbS1kLWRhdGUtY2VsbCAJLnhscyAueGxzYiAueGxzeCAueGxzLnhtbAo='; fs['./misc/ssf.json'] = 'WwogIFsiXCJmb29cIjtcImJhclwiO1wiYmF6XCI7XCJxdXhcIiIsCiAgICBbMSwgImZvbyJdLCBbLTEsICJiYXIiXSwgWzAsICJiYXoiXSwgWyJzaGVldGpzIiwgInF1eCJdCiAgXSwKICBbIlwiZm9vXCI7XCJiYXJcIjtcImJhelwiIiwKICAgIFsxLCAiZm9vIl0sIFstMSwgImJhciJdLCBbMCwgImJheiJdLCBbInNoZWV0anMiLCAic2hlZXRqcyJdCiAgXSwKICBbIlwiZm9vXCI7XCJiYXJcIjtAIiwKICAgIFsxLCAiZm9vIl0sIFstMSwgImJhciJdLCBbMCwgImZvbyJdLCBbInNoZWV0anMiLCAic2hlZXRqcyJdCiAgXSwKICBbIlwiZm9vXCI7XCJiYXJcIiIsCiAgICBbMSwgImZvbyJdLCBbLTEsICJiYXIiXSwgWzAsICJmb28iXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXQogIF0sCiAgWyJAQCIsIFsxLCAiMSJdLCBbLTEsICItMSJdLCBbMCwgIjAiXSwgWyJzaGVldGpzIiwgInNoZWV0anNzaGVldGpzIl1dLAogIFsiW0JsdWVdR2VuZXJhbCIsIFsxLCAiMSJdLCBbLTEsICItMSJdLCBbMCwgIjAiXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXV0sCiAgWyJbQmx1ZV1HM25lcmFsIiwgWzFdLCBbLTFdLCBbMF0sIFsiVE9ETyIsIlRPRE8iXV0sCiAgWyJBXCJUT0RPXCIiLCBbMSwgIkFUT0RPIl0sIFstMSwgIkFUT0RPIl0sIFswLCAiQVRPRE8iXSwgWyJUT0RPIiwiVE9ETyJdXSwKICBbInIiLCBbMSwiciJdLCBbLTEsIi1yIiwiIyJdLCBbMCwiciJdLCBbInNoZWV0anMiLCJzaGVldGpzIl1dLAogIFsiKCg7QCIsIFsxLCIoKCJdLCBbMCwiKCgiXSwgWyJmb28iLCJmb28iXV0sCiAgWyJcXHIiLCBbMSwgInIiXSwgWy0xLCAiciJdLCBbMCwgInIiXSwgWyJUT0RPIiwiVE9ETyJdXSwKICBbIl8oJCogIywjIzBfKTtfKCQqICgjLCMjMCk7XygkKiBcIi1cIl8pO18oQF8pIiwgWzEsICIgJDEgIl0sIFstMSwgIiAkKDEpIl0sIFswLCIgJC0gIl0sIFsiVE9ETyIsICIgVE9ETyAiXSwgWyIiLCIiXV0sCiAgWyIjMC4jIiwgWzAsIjAuIl0sIFsxLCIxLiJdLCBbMTIsIjEyLiJdLCBbMTIuMzQsICIxMi4zIl0sIFstMS4yMywgIi0xLjIiXV0sCiAgWyIjLCMjMC4wIiwgWzEsIjEuMCJdLCBbLTEsIi0xLjAiXSwgWzAsIjAuMCJdLCBbIlRPRE8iLCJUT0RPIl1dLAogIFsiIywjIzAuMDAiLCBbMSwiMS4wMCJdLCBbLTEsIi0xLjAwIl0sIFswLCIwLjAwIl0sIFsiVE9ETyIsIlRPRE8iXV0sCiAgWyIjLCMjMC4wMDAiLCBbMSwiMS4wMDAiXSwgWy0xLCItMS4wMDAiXSwgWzAsIjAuMDAwIl0sIFsiVE9ETyIsIlRPRE8iXV0sCiAgWyIjLCMjMC4wMDAwIiwgWzEsIjEuMDAwMCJdLCBbLTEsIi0xLjAwMDAiXSwgWzAsIjAuMDAwMCJdLCBbIlRPRE8iLCJUT0RPIl1dLAogIFsiIywjIzAuMDAwMDAiLCBbMTAwMDAwMCwgIjEsMDAwLDAwMC4wMDAwMCJdXSwKICBbIiMsIyMwLjAwMDAwMCIsIFsxMDAwMDAwLCAiMSwwMDAsMDAwLjAwMDAwMCJdXSwKICBbIiMsIyMwLjAwMDAwMDAiLCBbMTAwMDAwMCwgIjEsMDAwLDAwMC4wMDAwMDAwIl1dLAogIFsiIywjIzAuMDAwMDAwMDAiLCBbMTAwMDAwMCwgIjEsMDAwLDAwMC4wMDAwMDAwMCJdXSwKICBbIiMsIyMwLjAwMDAwMDAwMCIsIFsxMDAwMDAwLCAiMSwwMDAsMDAwLjAwMDAwMDAwMCJdXSwKICBbIiMsIyMjIiwgWzEsICIxIl0sIFstMSwgIi0xIl0sIFswLCIiXSwgWzEyMzQ1LjY3ODksICIxMiwzNDYiXSwgWyJUT0RPIiwgIlRPRE8iXV0sCiAgWyIjLiMjIiwgWzEsICIxLiJdLCBbLTEsICItMS4iXSwgWzAsIi4iXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXV0sCiAgWyIwOzAiLCBbMS4xLCAiMSJdLCBbLTEuMSwgIjEiXSwgWzAsIjAiXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXV0sCiAgWyIwLjAiLCBbMSwgIjEuMCJdLCBbLTEsICItMS4wIl0sIFswLCIwLjAiXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXV0sCiAgWyIwLjAwIiwgWzEuMDAwMSwgIjEuMDAiXSwgWy0xLCAiLTEuMDAiXSwgWzAsIjAuMDAiXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXV0sCiAgWyIwLjAwMCIsIFsxLCAiMS4wMDAiXSwgWy0xLCAiLTEuMDAwIl0sIFswLCIwLjAwMCJdLCBbInNoZWV0anMiLCAic2hlZXRqcyJdXSwKICBbIjAuMDAwMCIsIFsxLCAiMS4wMDAwIl0sIFstMSwgIi0xLjAwMDAiXSwgWzAsIjAuMDAwMCJdLCBbInNoZWV0anMiLCAic2hlZXRqcyJdXSwKICBbImhoOm1tIEFNL1BNIiwgWzAuNywgIjA0OjQ4IFBNIl1dLAogIFsiaGhoOm1tIEFNL1BNIiwgWzAuN11dLAogIFsiaGhoOm1tbTpzc3MiLCBbMC43XV0sCiAgWyJoaDptbW06c3NzIiwgWzAuN11dLAogIFsiaGg6bW06c3NzIiwgWzAuN11dLAogIFsiaGg6bW06c3MuMDAwIiwgWzAuNywiMTY6NDg6MDAuMDAwIl0sIFswLjcwNzA3LCIxNjo1ODoxMC44NDgiXV0sCiAgWyJoaC4wMDAiLCBbMC43MDcwNywgIjE2Ljg0OCJdXSwKICBbImhoIC4wMCIsIFswLjcwNzA3LCAiMTYgLjg1Il1dLAogIFsiaGggIC4wIiwgWzAuNzA3MDcsICIxNiAgLjgiXV0sCiAgWyJoaCAuMDAgLjAwMCIsIFswLjcwNzA3LCAiMTYgLjg0IC44NDgiXV0sCiAgWyJbaGhoXSIsIFswLjddXSwKICBbIlsiLCBbMC43XV0sCiAgWyJBL1AiLCBbMC43LCAiUCJdXSwKICBbImUiLCBbMC43LCAiMTkwMCJdXSwKICBbIjEyMyIsIFswLjcsICIxMjMiXSwgWzAsICIxMjMiXSwgWyJzaGVldGpzIiwgInNoZWV0anMiXV0sCiAgWyIwLiMjIiwgWzEsIjEuIl0sIFstMSwiLTEuIl0sIFswLCAiMC4iXSwgWzEuMSwgIjEuMSJdLCBbLTEuMiwgIi0xLjIiXSwgWzEwMDAwMDAwMDAwMDAuMDEsICIxMDAwMDAwMDAwMDAwLjAxIl0sIFstMTAwMC4wMSwgIi0xMDAwLjAxIl0sIFswLjEsICIwLjEiXSwgWzEuMDA3LCAiMS4wMSJdLCBbLTEuMDA4LCAiLTEuMDEiXV0sCiAgWyIqKiAjLCMjIywjMDAsMDAwLjAwLCoqIiwKICAgIFsxLjIzNDUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMCwwMDAuMDAiXSwKICAgIFsxMi4zNDUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMCwwMDAuMDEiXSwKICAgIFsxMjMuNDUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMCwwMDAuMTIiXSwKICAgIFsxMjM0LjU2LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMCwwMDEuMjMiXSwKICAgIFsxMjM0NS42NywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMCwwMTIuMzUiXSwKICAgIFsxMjM0NTYuNzgsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMCwxMjMuNDYiXSwKICAgIFsxMjM0NTY3Ljg5LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAwMSwyMzQuNTciXSwKICAgIFsxMjM0NTY4MS45LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAxMiwzNDUuNjgiXSwKICAgIFsxMjM0NTY4MjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIDEyMyw0NTYuODIiXSwKICAgIFsxMjM0NTY4MjIzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAxLDIzNCw1NjguMjIiXSwKICAgIFsxMjM0NTY4MjIzMywgICAgICAgICAgICAgICAgICAgICAgICAgICAiIDEyLDM0NSw2ODIuMjMiXSwKICAgIFsxMjM0NTY4MjIzMzMsICAgICAgICAgICAgICAgICAgICAgICAgICIgMTIzLDQ1Niw4MjIuMzMiXSwKICAgIFsxMjM0NTY4MjIzMzMzLCAgICAgICAgICAgICAgICAgICAgICAiIDEsMjM0LDU2OCwyMjMuMzMiXSwKICAgIFsxMjM0NTY4MjIzMzMzMywgICAgICAgICAgICAgICAgICAgICIgMTIsMzQ1LDY4MiwyMzMuMzMiXSwKICAgIFsxMjM0NTY4MjIzMzMzMzMsICAgICAgICAgICAgICAgICAgIiAxMjMsNDU2LDgyMiwzMzMuMzMiXSwKICAgIFsxMjM0NTY4MjIzMzMzMzMwLCAgICAgICAgICAgICAgICIgMSwyMzQsNTY4LDIyMywzMzMuMzMiXSwKICAgIFsxMjM0NTY4MjIzMzMzMzMwMCwgICAgICAgICAgICAgIiAxMiwzNDUsNjgyLDIzMywzMzMuMzAiXSwKICAgIFsxMjM0NTY4MjIzMzMzMzMwMDAsICAgICAgICAgICAiIDEyMyw0NTYsODIyLDMzMywzMzMuMDAiLCAiIyJdLAogICAgWzEyMzQ1NjgyMjMzMzMzMzAwMDAsICAgICAgICAiIDEsMjM0LDU2OCwyMjMsMzMzLDMzMC4wMCJdLAogICAgWzEyMzQ1NjgyMjMzMzMzMzAwMDAwLCAgICAgICIgMTIsMzQ1LDY4MiwyMzMsMzMzLDMwMC4wMCJdLAogICAgWzEyMzQ1NjgyMjMzMzMzMzAwMDAwMCwgICAgIiAxMjMsNDU2LDgyMiwzMzMsMzMzLDAwMC4wMCJdLAogICAgWzEyMzQ1NjgyMjMzMzMzMzAwMDAwMDAsICIgMSwyMzQsNTY4LDIyMywzMzMsMzMwLDAwMC4wMCJdCiAgXSwKICBbIjAwLDAwMC4wMCwiLCBbMTIzNDUsICIwMCwwMTIuMzUiXSBdLAogIFsiMDAsMDAwLjAwIiwgWzEyMzQ1LCAiMTIsMzQ1LjAwIl0gXSwKICBbIjAwMCMwIzAjMCMjMDAjIzAwIyMwIyMjIyMjIyMjIiwgWzEyMzQ1LCAiMDAwMDAwMDAwMDAxMjM0NSJdIF0sCiAgWyIjIzAuMEUrMCIsCiAgICBbMSwgICAgICAgICAgICIxLjBFKzAiXSwKICAgIFsxMiwgICAgICAgICAiMTIuMEUrMCJdLAogICAgWzEyMywgICAgICAgIjEyMy4wRSswIl0sCiAgICBbMTIzNCwgICAgICAgICIxLjJFKzMiXSwKICAgIFsxMjM0NSwgICAgICAiMTIuM0UrMyJdLAogICAgWzEyMzQ1NiwgICAgIjEyMy41RSszIl0sCiAgICBbMTIzNDU2NywgICAgICIxLjJFKzYiXSwKICAgIFsxMjM0NTY3OCwgICAiMTIuM0UrNiJdLAogICAgWzEyMzQ1Njc4OSwgIjEyMy41RSs2Il0KICBdLAogIFsiMCMjIyMjIyMwLiMjMCMjMCMjIyMjIzAwIyMjIyMjMCIsCiAgICBbMTIuMzQ1Njc4OSwgIjAxMi4zNDU2Nzg5MDAwIl0sCiAgICBbMTIzNDU2Nzg5LCAiMTIzNDU2Nzg5LjAwMDAwIl0KICBdLAogIFsiIyMjXFwjIyNcXCMjMC4wMCIsCiAgICBbMC4wMDEwMSwgICAgICAgICAgICAgICIjIzAuMDAiXSwKICAgIFswLjAxMDEsICAgICAgICAgICAgICAgIiMjMC4wMSJdLAogICAgWzAuMTAxLCAgICAgICAgICAgICAgICAiIyMwLjEwIl0sCiAgICBbMS4wMSwgICAgICAgICAgICAgICAgICIjIzEuMDEiXSwKICAgIFsxMC4xLCAgICAgICAgICAgICAgICAiIyMxMC4xMCJdLAogICAgWzEwMSwgICAgICAgICAgICAgICAgIiMxIzAxLjAwIl0sCiAgICBbMTAxMCwgICAgICAgICAgICAgICIjMTAjMTAuMDAiXSwKICAgIFsxMDEwMCwgICAgICAgICAgICAiMSMwMSMwMC4wMCJdLAogICAgWzEwMTAwMCwgICAgICAgICAgIjEwIzEwIzAwLjAwIl0sCiAgICBbMTAxMDAwMCwgICAgICAgICIxMDEjMDAjMDAuMDAiXSwKICAgIFsxMDEwMDAwMCwgICAgICAiMTAxMCMwMCMwMC4wMCJdLAogICAgWzEwMTAwMDAwMCwgICAgIjEwMTAwIzAwIzAwLjAwIl0sCiAgICBbMTIzNDU2Nzg5LjAxLCAgICAiMTIzNDUjNjcjODkuMDEiXQogIF0sCgogIFsiIyMjXFxcXCMjI1xcXFwjI1xcMC4wMCIsCiAgICBbMC4wMDEwMSwgICAgICAgICAgICAgICJcXFxcMC4wMCJdLAogICAgWzAuMDEwMSwgICAgICAgICAgICAgICAiXFxcXDAuMDEiXSwKICAgIFswLjEwMSwgICAgICAgICAgICAgICAgIlxcXFwwLjEwIl0sCiAgICBbMS4wMSwgICAgICAgICAgICAgICAgIlxcXFwxMC4wMSJdLAogICAgWzEwLjEsICAgICAgICAgICAgICAgIlxcXFwxMDAuMTAiXSwKICAgIFsxMDEsICAgICAgICAgICAgICAgIlxcMVxcMDEwLjAwIl0sCiAgICBbMTAxMCwgICAgICAgICAgICAgIlxcMTBcXDEwMC4wMCJdLAogICAgWzEwMTAwLCAgICAgICAgICAgIlxcMTAxXFwwMDAuMDAiXSwKICAgIFsxMDEwMDAsICAgICAgICAgIjFcXDAxMFxcMDAwLjAwIl0sCiAgICBbMTAxMDAwMCwgICAgICAgIjEwXFwxMDBcXDAwMC4wMCJdLAogICAgWzEwMTAwMDAwLCAgICAgIjEwMVxcMDAwXFwwMDAuMDAiXSwKICAgIFsxMDEwMDAwMDAsICAgIjEwMTBcXDAwMFxcMDAwLjAwIl0sCiAgICBbMTIzNDU2Nzg5LjAxLCAgICIxMjM0XFw1NjdcXDg5MC4wMSJdCiAgXSwKICBbIiMjI1xcXFwjIyNcXFxcIyNcXDAiLCBbMTIzNDUuNjc4OSwgIlxcMTIzXFw0NjAiXV0sCiAgWyIwMDAwMC0wMDAwIiwgWzk0MTA1MTYzMCwgIjk0MTA1LTE2MzAiXSwgWzEyMzQ1LjY3ODksICIwMDAwMS0yMzQ2Il1dLAogIFsiMDAwLTAwLTAwMDAiLCBbMTIzNDU2Nzg5LCAiMTIzLTQ1LTY3ODkiXV0sCiAgWyIwMDAwMFxcLTAwMDAiLCBbOTQxMDUxNjMwLCAiOTQxMDUtMTYzMCJdXSwKICBbIjAwMFxcLTAwXFwtMDAwMCIsIFsxMjM0NTY3ODksICIxMjMtNDUtNjc4OSJdXSwKICBbIj8/Lz8/IiwgWzEyLjM0NTY3ODksICIxMDAwLzgxIl0sIFswLjAwMDAxLCAiIDAvMSAiXV0sCiAgWyI/PyAvID8/IiwgWzEyLjM0NTY3ODksICIxMDAwIC8gODEiXSwgWzAuMDAwMDEsICIgMCAvIDEgIl0sIFsxMjMsICIxMjMgLyAxICJdXSwKICBbIiMgPz8vPz8iLCBbMTIuMzQ1Njc4OSwgIjEyIDI4LzgxIl1dLAogIFsiIz8/Lz8/IiwgWzEyLjM0NTY3ODksICIxMDAwLzgxIl1dLAogIFsiIzAjMDA/Py8/PyIsIFsxMi4zNDU2Nzg5LCAiMDEwMDAvODEiXV0sCiAgWyJbPD05OTk5OTk5XSMjIy0jIyMjOygjIyMpICMjIy0jIyMjIiwgWzg2NzUzMDksICI4NjctNTMwOSJdLFsyODEzMzA4MDA0LCAiKDI4MSkgMzMwLTgwMDQiXSwgWzIwMTg2NzUzMDksICIoMjAxKSA4NjctNTMwOSJdXSwKICBbIls8PTk5OTk5OTldIyMjXFwtIyMjIzsoIyMjKSAjIyNcXC0jIyMjIiwgWzg2NzUzMDksICI4NjctNTMwOSJdLFsyODEzMzA4MDA0LCAiKDI4MSkgMzMwLTgwMDQiXV0sCiAgWyJbUmVkXVs8LTI1XUdlbmVyYWw7W0JsdWVdWz4yNV1HZW5lcmFsO1tHcmVlbl1HZW5lcmFsO1tZZWxsb3ddR2VuZXJhbCIsIFs1MCwgIjUwIl0sWzI2LCAiMjYiXSxbMjUsIjI1Il0sWzEsIjEiXSxbMCwiMCJdLFstMSwiLTEiXSxbLTI1LCItMjUiXSxbLTI2LCIyNiIsIiMiXSxbLTUwLjEsIjUwIiwiIyJdLCBbImZvbyIsImZvbyJdLFsiYmFyIiwiYmFyIl1dLAogIFsiW1JlZF1bPD0tMjVdR2VuZXJhbDtbQmx1ZV1bPj0yNV1HZW5lcmFsO1tHcmVlbl1HZW5lcmFsO1tZZWxsb3ddR2VuZXJhbCIsIFs1MCwgIjUwIl0sWzI2LCAiMjYiXSxbMjUsIjI1Il0sWzEsIjEiXSxbMCwiMCJdLFstMSwiLTEiXSxbLTI1LCItMjUiXSxbLTI2LjEsIjI2IiwiIyJdLFstNTAsIjUwIiwiIyJdLCBbImZvbyIsImZvbyJdLFsiYmFyIiwiYmFyIl1dLAogIFsiW1JlZF1HZW5lcmFsIDtbQmx1ZV1HZW5lcmFsXFwgO1tHcmVlbl1HZW5lcmFscDtbWWVsbG93XUdlbmVyYWwnIiwgWzUwLCAiNTAgIl0sWzAsIjBwIl0sWy0yNSwiLTI1ICJdLFsiZm9vIiwiZm9vJyJdXSwKICBbIltSZWRdWz01MF1HZW5lcmFsO1tCbHVlXTAwMCIsIFs1MCwgIjUwIl0sIFs1MSwgIjA1MSJdLCBbNDksICIwNDkiXV0sCiAgWyJbUmVkXVs8PjUwXUdlbmVyYWw7W0JsdWVdMDAwIiwgWzUwLCAiMDUwIl0sIFs1MSwgIjUxIl0sIFs0OSwgIjQ5Il1dLAogIFsiYiIsIFsxLCI0MyJdLCBbMTAwMCwiNDUiXSwgWzEwMDAwLCI3MCJdXSwKICBbIkIyeXl5eW1tZGQiLCBbMCwiMTMxNzA4MjkiXSwgWzEwMDAsIjEzMjAwNjI0IiwiIyJdLCBbMTAwMDAsIjEzNDUxMTE3IiwiIyJdXSwKICBbIuKYgyIsIFswXSwgWzFdLCBbLTFdXSwKICBbIiMwIyMjIyMjIyIsIFsxMjM0NSwgIjAxMjM0NSJdLCBbMTIzNDUuNDMyMSwgIjAxMjM0NSJdLCBbMTIzNDUuNjc4OSwgIjAxMjM0NiJdXSwKICBbIiMjLCMjIiwgWzEyMzQ1LCAiMTIsMzQ1IiwgIiJdLCBbMTIzNDUuNDMyMSwgIjEyLDM0NSIsICIiXSwgWzEyMzQ1LjY3ODksICIxMiwzNDYiLCAiIl1dLAogIFswLCBbMTIzNDUsIjEyMzQ1Il0sIFs0Mjk0OTY3Mjk2LjUsICI0Mjk0OTY3Mjk3Il1dLAogIFsiXCJScy5cIiMsIyMwLjAwIiwgWy01MTk2ODI4NywgIi1Scy41MSw5NjgsMjg3LjAwIl0sIFsyMDAwMDAwLCAiUnMuMiwwMDAsMDAwLjAwIl1dLAogIFsiJCMuMDAiLCBbMy4xNDE1OSwgIiQzLjE0Il0sIFstMy4xNDE1OSwgIi0kMy4xNCJdXSwKICBbIlwiVGhpcyBpcyBhIFwiLjAwXCJ0ZXN0XCIwMDAiLCBbLTMuMTQxNTksICItVGhpcyBpcyBhIDMuMTR0ZXN0MTU5Il0sIFszLjE0MTU5LCAiVGhpcyBpcyBhIDMuMTR0ZXN0MTU5Il1dLAogIFsiWyRJTlJdXFwgIywjIzAuMDAiLCBbMy4xNDE1OSwgIklOUiAzLjE0Il0sIFstMy4xNDE1OSwgIi1JTlIgMy4xNCJdXSwKICBbIlsk4oK5LTQwMDldXFwgIywjIzAuMDAiLCBbMy4xNDE1OSwgIuKCuSAzLjE0Il0sIFstMy4xNDE1OSwgIi3igrkgMy4xNCJdXSwKICBbIlskwqMtODA5XSMsIyMwLjAwMDA7XFwtWyTCoy04MDldIywjIzAuMDAwMCIsIFszLjE0MTU5LCAiwqMzLjE0MTYiXSwgWy0zLjE0MTU5LCAiLcKjMy4xNDE2Il1dLAogIFsiXCItXCIwLjAwIiwgWzMuMTQxNTksICItMy4xNCJdLCBbLTMuMTQxNTksICItLTMuMTQiXV0sCiAgWyJbJC00MDldbW1tXFwteXkiLCBbMTIzNDUsICJPY3QtMzMiXV0sCiAgWyJcImZvb1wiO1wiYmFyXCI7XCJiYXpcIjtcInF1eFwiO1wiZm9vYmFyXCIiLCBbMV0sIFswXSwgWy0xXSwgWyJzaGVldGpzIl1dCl0K'; fs['./test_files/biff5/number_format_greek.xls'] = '0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAEAAASgAAAAEAAAD+////AAAAAAAAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////9////TQAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAAoAAAAKQAAACoAAAArAAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAABAAAAAQQAAAEIAAABDAAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAA/v////7///9MAAAA/v////7//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////1IAbwBvAHQAIABFAG4AdAByAHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAUA//////////8CAAAAEAgCAAAAAADAAAAAAAAARgAAAAAAAAAAAAAAAMC8HH0Jm88BSwAAAAADAAAAAAAAQgBvAG8AawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAgH/////BAAAAP////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAUo8AAAAAAAAFAFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAACAQEAAAADAAAA/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAQAAAAAAAAUARABvAGMAdQBtAGUAbgB0AFMAdQBtAG0AYQByAHkASQBuAGYAbwByAG0AYQB0AGkAbwBuAAAAAAAAAAAAAAA4AAIB////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAACABAAAAAAAACQgIAAAFBQAEPc0H4QAAAMEAAgAAAL8AAADAAAAA4gAAAFwAcAACICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQgACAOUEnAACABEAGAATAA4AAAUAAAAAAAAAAAAARG9mbXQYABQADgAABgAAAAAAAAAAAABOdW1GbXQZAAIAAAASAAIAAAATAAIAAAA9ABIAoAAAAKRb+C84AAAAAAABAPQBQAACAAAAjQACAAAAIgAC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AADgABAAAAAQAAEAIATAIAAAAAAAAOAAEAAAABEAAQAgBMAgAAAAAAAA4AAQAAAAEgABACAEwCAAAAAAAADgABAAAAATAAEAIATAIAAAAAAAAOAAEAAAADEAAQAgBMAgAAAAAAAA4AAQAAAAMAABACAEwCAAAAAAAADgABAAAACvAAEAIATAIAAAAAAAAOAAEAAAAC4AAQAgBMAgAAAAAAAA4AAQAAAALQABACAEwCAAAAAAAADgABAAAACwAAEAIATAIAAAAAAAAOAAEAAAALEAAQAgBMAgAAAAAAAA4AAQAAAAFAABACAEwCAAAAAAAADgABAAAAAVAAEAIATAIAAAAAAAAOAAEAAAALIAAQAgBMAgAAAAAAAA4AAQAAAAswABACAEwCAAAAAAAADgABAAAAC0AAEAIATAIAAAAAAAAOAAEAAAALUAAQAgBMAgAAAAAAAA4AAQAAAAtgABACAEwCAAAAAAAADgABAAAAC3AAEAIATAIAAAAAAAAOAAEAAAALgAAQAgBMAgAAAAAAAA4AAQAAAAuQABACAEwCAAAAAAAADgABAAAAC6AAEAIATAIAAAAAAAAOAAEAAAALsAAQAgBMAgAAAAAAAA4AAQAAAAvAABACAEwCAAAAAAAADgABAAAAC9AAEAIATAIAAAAAAAAOAAEAAAAL4AAQAgBMAgAAAAAAAA4AAQAAAAvwABACAEwCAAAAAAAADgABAAAAAAAAEAIATAIAAAAAAAAOAAEAAAAAAAAQAgBMAgAAAAAAAA4AAQAAAAAAABACAEwCAAAAAAAADgABAAAAAAAAEAIATAIAAAAAAAAOAAEAAAAAAAAQAgBMAgAAAAAAAA4AAQAAAAqgABACAEwCAAAAAAAADgABAAAAAAAAEAIATAIAAAAAAAAOAAEAAAAAAAAQAgBMAgAAAAAAAA4AAQAAAAxwABACAEwCAAAAAAAADgABAAAADIAAEAIATAIAAAAAAAAOAAEAAAAMkAAQAgBMAgAAAAAAAA4AAQAAAAygABACAEwCAAAAAAAADgABAAAADLAAEAIATAIAAAAAAAAOAAEAAAAMwAAQAgBMAgAAAAAAAA4AAQAAAAzQABACAEwCAAAAAAAADgABAAAADOAAEAIATAIAAAAAAAAOAAEAAAAM8AAQAgBMAgAAAAAAAA4AAQAAAA0AABACAEwCAAAAAA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AIIAggCCAIIAAACWAIIAggCCAIIAggAAAJgAggCCAAAAkgCCAIIAggCCAAgCEAAgAAAACwA2AQAAAACAAYoACAIQACEAAAALADYBAAAAAIABiwAIAhAAIgAAAAsANgEAAAAAgAGMAAgCEAAjAAAACwA2AQAAAACAAY0ACAIQACQAAAALADYBAAAAAIABjgAIAhAAJQAAAAsANgEAAAAAgAGDAAgCEAAmAAAACwA2AQAAAACAAYQACAIQACcAAAALADYBAAAAAIABjwAIAhAAKAAAAAsANgEAAAAAgAGQAAgCEAApAAAACwA2AQAAAACAAZEACAIQACoAAAALADYBAAAAAIABkgAIAhAAKwAAAAsANgEAAAAAgAFuAAgCEAAsAAAACwA2AQAAAACAAXwACAIQAC0AAAALADYBAAAAAIABfgAIAhAALgAAAAsANgEAAAAAgAF9AAgCEAAvAAAACwA2AQAAAACAAX8ACAIQADAAAAALADYBAAAAAIABgAAIAhAAMQAAAAsANgEAAAAAgAGBAAgCEAAyAAAACwA2AQAAAACAAYIACAIQADMAAAALADYBAAAAAIABgwAIAhAANAAAAAsANgEAAAAAgAGEAAgCEAA1AAAACwA2AQAAAACAAYQACAIQADYAAAALADYBAAAAAIABbwAIAhAANwAAAAsANgEAAAAAgAFvAAgCEAA4AAAACwA2AQAAAACAAUgACAIQADkAAAALADYBAAAAAIABSQAIAhAAOgAAAAsANgEAAAAAgAFwAAgCEAA7AAAACwA2AQAAAACAAXEACAIQADwAAAALADYBAAAAAIABcgAIAhAAPQAAAAsANgEAAAAAgAF0AAgCEAA+AAAACwA2AQAAAACAAXMACAIQAD8AAAALADYBAAAAAIABdQC9ACQAIAABAIoAAADwP4oAAQBewIoAATiTQIoAAUiTwIoAgRzIQAUAAwIOACAABgCKAHe+nxov3V7AAwIOACAABwCKAFTjpZtESpNAAwIOACAACACKAK36XG1FSpPAAwIOACAACQCKAKH4MebWHMhAAwIOACAACgCKAHfbhebWHMjAvQAkACEAAQCLAAAA8D+LAAEAXsCLAAE4k0CLAAFIk8CLAIEcyEAFAAMCDgAhAAYAiwB3vp8aL91ewAMCDgAhAAcAiwBU46WbREqTQAMCDgAhAAgAiwCt+lxtRUqTwAMCDgAhAAkAiwCh+DHm1hzIQAMCDgAhAAoAiwB324Xm1hzIwL0AJAAiAAEAjAAAAPA/jAABAF7AjAABOJNAjAABSJPAjACBHMhABQADAg4AIgAGAIwAd76fGi/dXsADAg4AIgAHAIwAVOOlm0RKk0ADAg4AIgAIAIwArfpcbUVKk8ADAg4AIgAJAIwAofgx5tYcyEADAg4AIgAKAIwAd9uF5tYcyMC9ACQAIwABAI0AAADwP40AAQBewI0AATiTQI0AAUiTwI0AgRzIQAUAAwIOACMABgCNAHe+nxov3V7AAwIOACMABwCNAFTjpZtESpNAAwIOACMACACNAK36XG1FSpPAAwIOACMACQCNAKH4MebWHMhAAwIOACMACgCNAHfbhebWHMjAvQAkACQAAQCOAAAA8D+OAAEAXsCOAAE4k0COAAFIk8COAIEcyEAFAAMCDgAkAAYAjgB3vp8aL91ewAMCDgAkAAcAjgBU46WbREqTQAMCDgAkAAgAjgCt+lxtRUqTwAMCDgAkAAkAjgCh+DHm1hzIQAMCDgAkAAoAjgB324Xm1hzIwL0AJAAlAAEAgwAAAPA/gwABAF7AgwABOJNAgwABSJPAgwCBHMhABQADAg4AJQAGAIMAd76fGi/dXsADAg4AJQAHAIMAVOOlm0RKk0ADAg4AJQAIAIMArfpcbUVKk8ADAg4AJQAJAIMAofgx5tYcyEADAg4AJQAKAIMAd9uF5tYcyMC9ACQAJgABAIQAAADwP4QAAQBewIQAATiTQIQAAUiTwIQAgRzIQAUAAwIOACYABgCEAHe+nxov3V7AAwIOACYABwCEAFTjpZtESpNAAwIOACYACACEAK36XG1FSpPAAwIOACYACQCEAKH4MebWHMhAAwIOACYACgCEAHfbhebWHMjAvQAkACcAAQCPAAAA8D+PAAEAXsCPAAE4k0CPAAFIk8CPAIEcyEAFAAMCDgAnAAYAjwB3vp8aL91ewAMCDgAnAAcAjwBU46WbREqTQAMCDgAnAAgAjwCt+lxtRUqTwAMCDgAnAAkAjwCh+DHm1hzIQAMCDgAnAAoAjwB324Xm1hzIwL0AJAAoAAEAkAAAAPA/kAABAF7AkAABOJNAkAABSJPAkACBHMhABQADAg4AKAAGAJAAd76fGi/dXsADAg4AKAAHAJAAVOOlm0RKk0ADAg4AKAAIAJAArfpcbUVKk8ADAg4AKAAJAJAAofgx5tYcyEADAg4AKAAKAJAAd9uF5tYcyMC9ACQAKQABAJEAAADwP5EAAQBewJEAATiTQJEAAUiTwJEAgRzIQAUAAwIOACkABgCRAHe+nxov3V7AAwIOACkABwCRAFTjpZtESpNAAwIOACkACACRAK36XG1FSpPAAwIOACkACQCRAKH4MebWHMhAAwIOACkACgCRAHfbhebWHMjAvQAkACoAAQCSAAAA8D+SAAEAXsCSAAE4k0CSAAFIk8CSAIEcyEAFAAMCDgAqAAYAkgB3vp8aL91ewAMCDgAqAAcAkgBU46WbREqTQAMCDgAqAAgAkgCt+lxtRUqTwAMCDgAqAAkAkgCh+DHm1hzIQAMCDgAqAAoAkgB324Xm1hzIwAQCDAAsAAAAfAAEAFRpbWW9ACQALAABAHwAAADwP3wAAQBewHwAATiTQHwAAUiTwHwAgRzIQAUAAwIOACwABgB8AHe+nxov3V7AAwIOACwABwB8AFTjpZtESpNAAwIOACwACAB8AK36XG1FSpPAAwIOACwACQB8AKH4MebWHMhAAwIOACwACgB8AHfbhebWHMjAvQAkAC0AAQB+AAAA8D9+AAEAXsB+AAE4k0B+AAFIk8B+AIEcyEAFAAMCDgAtAAYAfgB3vp8aL91ewAMCDgAtAAcAfgBU46WbREqTQAMCDgAtAAgAfgCt+lxtRUqTwAMCDgAtAAkAfgCh+DHm1hzIQAMCDgAtAAoAfgB324Xm1hzIwL0AJAAuAAEAfQAAAPA/fQABAF7AfQABOJNAfQABSJPAfQCBHMhABQADAg4ALgAGAH0Ad76fGi/dXsADAg4ALgAHAH0AVOOlm0RKk0ADAg4ALgAIAH0ArfpcbUVKk8ADAg4ALgAJAH0Aofgx5tYcyEADAg4ALgAKAH0Ad9uF5tYcyMC9ACQALwABAH8AAADwP38AAQBewH8AATiTQH8AAUiTwH8AgRzIQAUAAwIOAC8ABgB/AHe+nxov3V7AAwIOAC8ABwB/AFTjpZtESpNAAwIOAC8ACAB/AK36XG1FSpPAAwIOAC8ACQB/AKH4MebWHMhAAwIOAC8ACgB/AHfbhebWHMjAvQAkADAAAQCAAAAA8D+AAAEAXsCAAAE4k0CAAAFIk8CAAIEcyEAFAAMCDgAwAAYAgAB3vp8aL91ewAMCDgAwAAcAgABU46WbREqTQAMCDgAwAAgAgACt+lxtRUqTwAMCDgAwAAkAgACh+DHm1hzIQAMCDgAwAAoAgAB324Xm1hzIwL0AJAAxAAEAgQAAAPA/gQABAF7AgQABOJNAgQABSJPAgQCBHMhABQADAg4AMQAGAIEAd76fGi/dXsADAg4AMQAHAIEAVOOlm0RKk0ADAg4AMQAIAIEArfpcbUVKk8ADAg4AMQAJAIEAofgx5tYcyEADAg4AMQAKAIEAd9uF5tYcyMC9ACQAMgABAIIAAADwP4IAAQBewIIAATiTQIIAAUiTwIIAgRzIQAUAAwIOADIABgCCAHe+nxov3V7AAwIOADIABwCCAFTjpZtESpNAAwIOADIACACCAK36XG1FSpPAAwIOADIACQCCAKH4MebWHMhAAwIOADIACgCCAHfbhebWHMjAvQAkADMAAQCDAAAA8D+DAAEAXsCDAAE4k0CDAAFIk8CDAIEcyEAFAAMCDgAzAAYAgwB3vp8aL91ewAMCDgAzAAcAgwBU46WbREqTQAMCDgAzAAgAgwCt+lxtRUqTwAMCDgAzAAkAgwCh+DHm1hzIQAMCDgAzAAoAgwB324Xm1hzIwL0AJAA0AAEAhAAAAPA/hAABAF7AhAABOJNAhAABSJPAhACBHMhABQADAg4ANAAGAIQAd76fGi/dXsADAg4ANAAHAIQAVOOlm0RKk0ADAg4ANAAIAIQArfpcbUVKk8ADAg4ANAAJAIQAofgx5tYcyEADAg4ANAAKAIQAd9uF5tYcyMAEAhIANgAAAG8ACgBQZXJjZW50YWdlvQAkADYAAQBvAAAA8D9vAAEAXsBvAAE4k0BvAAFIk8BvAIEcyEAFAAMCDgA2AAYAbwB3vp8aL91ewAMCDgA2AAcAbwBU46WbREqTQAMCDgA2AAgAbwCt+lxtRUqTwAMCDgA2AAkAbwCh+DHm1hzIQAMCDgA2AAoAbwB324Xm1hzIwAQCEAA4AAAASAAIAEZyYWN0aW9uvQAkADgAAQBIAAAA8D9IAAEAXsBIAAE4k0BIAAFIk8BIAIEcyEAFAAMCDgA4AAYASAB3vp8aL91ewAMCDgA4AAcASABU46WbREqTQAMCDgA4AAgASACt+lxtRUqTwAMCDgA4AAkASACh+DHm1hzIQAMCDgA4AAoASAB324Xm1hzIwL0AJAA5AAEASQAAAPA/SQABAF7ASQABOJNASQABSJPASQCBHMhABQADAg4AOQAGAEkAd76fGi/dXsADAg4AOQAHAEkAVOOlm0RKk0ADAg4AOQAIAEkArfpcbUVKk8ADAg4AOQAJAEkAofgx5tYcyEADAg4AOQAKAEkAd9uF5tYcyMC9ACQAOgABAHAAAADwP3AAAQBewHAAATiTQHAAAUiTwHAAgRzIQAUAAwIOADoABgBwAHe+nxov3V7AAwIOADoABwBwAFTjpZtESpNAAwIOADoACABwAK36XG1FSpPAAwIOADoACQBwAKH4MebWHMhAAwIOADoACgBwAHfbhebWHMjAvQAkADsAAQBxAAAA8D9xAAEAXsBxAAE4k0BxAAFIk8BxAIEcyEAFAAMCDgA7AAYAcQB3vp8aL91ewAMCDgA7AAcAcQBU46WbREqTQAMCDgA7AAgAcQCt+lxtRUqTwAMCDgA7AAkAcQCh+DHm1hzIQAMCDgA7AAoAcQB324Xm1hzIwL0AJAA8AAEAcgAAAPA/cgABAF7AcgABOJNAcgABSJPAcgCBHMhABQADAg4APAAGAHIAd76fGi/dXsADAg4APAAHAHIAVOOlm0RKk0ADAg4APAAIAHIArfpcbUVKk8ADAg4APAAJAHIAofgx5tYcyEADAg4APAAKAHIAd9uF5tYcyMC9ACQAPQABAHQAAADwP3QAAQBewHQAATiTQHQAAUiTwHQAgRzIQAUAAwIOAD0ABgB0AHe+nxov3V7AAwIOAD0ABwB0AFTjpZtESpNAAwIOAD0ACAB0AK36XG1FSpPAAwIOAD0ACQB0AKH4MebWHMhAAwIOAD0ACgB0AHfbhebWHMjAvQAkAD4AAQBzAAAA8D9zAAEAXsBzAAE4k0BzAAFIk8BzAIEcyEAFAAMCDgA+AAYAcwB3vp8aL91ewAMCDgA+AAcAcwBU46WbREqTQAMCDgA+AAgAcwCt+lxtRUqTwAMCDgA+AAkAcwCh+DHm1hzIQAMCDgA+AAoAcwB324Xm1hzIwL0AJAA/AAEAdQAAAPA/dQABAF7AdQABOJNAdQABSJPAdQCBHMhABQADAg4APwAGAHUAd76fGi/dXsADAg4APwAHAHUAVOOlm0RKk0ADAg4APwAIAHUArfpcbUVKk8ADAg4APwAJAHUAofgx5tYcyEADAg4APwAKAHUAd9uF5tYcyMDXAEQAdBEAAGwCggCCAIIAggCCAIIAggCCAIIAggCCAAAAkgCCAIIAggCCAIIAggCCAIIAAACYAAAAlgCCAIIAggCCAIIAggAIAhAAQAAAAAsANgEAAAAAgAF2AAgCEABBAAAACwA2AQAAAACAAXYACAIQAEIAAAALADYBAAAAAIABdwAIAhAAQwAAAAsANgEAAAAAgAF3AAgCEABEAAAACwA2AQAAAACAAVAACAIQAEUAAAALADYBAAAAAIABUAAIAhAARgAAAAsANgEAAAAAgAF4AAgCEABHAAAACwA2AQAAAACAAXkACAIQAEgAAAALADYBAAAAAIABegAIAhAASQAAAAsANgEAAAAAgAF7AL0AJABAAAEAdgAAAPA/dgABAF7AdgABOJNAdgABSJPAdgCBHMhABQADAg4AQAAGAHYAd76fGi/dXsADAg4AQAAHAHYAVOOlm0RKk0ADAg4AQAAIAHYArfpcbUVKk8ADAg4AQAAJAHYAofgx5tYcyEADAg4AQAAKAHYAd9uF5tYcyMAEAhIAQgAAAHcACgBTY2llbnRpZmljvQAkAEIAAQB3AAAA8D93AAEAXsB3AAE4k0B3AAFIk8B3AIEcyEAFAAMCDgBCAAYAdwB3vp8aL91ewAMCDgBCAAcAdwBU46WbREqTQAMCDgBCAAgAdwCt+lxtRUqTwAMCDgBCAAkAdwCh+DHm1hzIQAMCDgBCAAoAdwB324Xm1hzIwAQCDABEAAAAUAAEAFRleHS9ACQARAABAFAAAADwP1AAAQBewFAAATiTQFAAAUiTwFAAgRzIQAUAAwIOAEQABgBQAHe+nxov3V7AAwIOAEQABwBQAFTjpZtESpNAAwIOAEQACABQAK36XG1FSpPAAwIOAEQACQBQAKH4MebWHMhAAwIOAEQACgBQAHfbhebWHMjABAIPAEYAAAB4AAcAU3BlY2lhbL0AJABGAAEAeAAAAPA/eAABAF7AeAABOJNAeAABSJPAeACBHMhABQADAg4ARgAGAHgAd76fGi/dXsADAg4ARgAHAHgAVOOlm0RKk0ADAg4ARgAIAHgArfpcbUVKk8ADAg4ARgAJAHgAofgx5tYcyEADAg4ARgAKAHgAd9uF5tYcyMC9ACQARwABAHkAAADwP3kAAQBewHkAATiTQHkAAUiTwHkAgRzIQAUAAwIOAEcABgB5AHe+nxov3V7AAwIOAEcABwB5AFTjpZtESpNAAwIOAEcACAB5AK36XG1FSpPAAwIOAEcACQB5AKH4MebWHMhAAwIOAEcACgB5AHfbhebWHMjAvQAkAEgAAQB6AAAA8D96AAEAXsB6AAE4k0B6AAFIk8B6AIEcyEAFAAMCDgBIAAYAegB3vp8aL91ewAMCDgBIAAcAegBU46WbREqTQAMCDgBIAAgAegCt+lxtRUqTwAMCDgBIAAkAegCh+DHm1hzIQAMCDgBIAAoAegB324Xm1hzIwL0AJABJAAEAewAAAPA/ewABAF7AewABOJNAewABSJPAewCBHMhABQADAg4ASQAGAHsAd76fGi/dXsADAg4ASQAHAHsAVOOlm0RKk0ADAg4ASQAIAHsArfpcbUVKk8ADAg4ASQAJAHsAofgx5tYcyEADAg4ASQAKAHsAd9uF5tYcyMDXABgAjwQAALQAggAAAJgAAACSAAAAlQCCAIIAPQASAKAAAACkW/gvOAAAAAAAAQD0AT4CCgC2AAAAAAAAAAAAHQAPAAMAAAAAAAABAAAAAAAA/6sAIgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAkICAAABhAABD3NBwsCEAAAAAAAAAAPAFuCAAB/hAAADQACAAEADAACAGQADwACAAEAEQACAAAAEAAIAPyp8dJNYlA/XwACAAEAKgACAAAAKwACAAAAggACAAEAgAAIAAAAAAAAAAAAJQIEAAAANgGMAAQAAQAeAIEAAgDBBBQAAAAVAAAAgwACAAAAhAACAAAAJgAIAAAAAAAAAOg/JwAIAAAAAAAAAOg/KAAIAAAAAAAAAPA/KQAIAAAAAAAAAPA/oQAiAAAAHgABAAEAAQAEAAAA/wAAAAAAAADgPwAAAAAAAOA/ewBVAAIACAB9AAwAAAAAAAALDwAAAAQAfQAMAAEAAAGqCg8AAAAEAAACCgAAAA8AAAACAAAACAIQAAAAAAACADYBAAAAAAABDwAIAhAAAQAAAAIANgEAAAAAAAEPAAgCEAACAAAAAgA2AQAAAAAAAQ8ACAIQAAMAAAACADYBAAAAAAABDwAIAhAABAAAAAIANgEAAAAAAAEPAAgCEAAFAAAAAgA2AQAAAAAAAQ8ACAIQAAYAAAACADYBAAAAAAABDwAIAhAABwAAAAIANgEAAAAAAAEPAAgCEAAIAAAAAgA2AQAAAAAAAQ8ACAIQAAkAAAACADYBAAAAAAABDwAIAhAACgAAAAIANgEAAAAAAAEPAAgCEAALAAAAAgA2AQAAAAAAAQ8ACAIQAAwAAAACADYBAAAAAAABDwAIAhAADQAAAAIANgEAAAAAAAEPAAgCEAAOAAAAAgA2AQAAAAAAAQ8AfgIKAAAAAAA/AAAA8D9+AgoAAQAAAD8AAADwP34CCgACAAAAPwAAACRAfgIKAAMAAAA/AAAAWUB+AgoABAAAAD8AAECPQAECBgAEAAEAPgB+AgoABQAAAD8AAIjDQH4CCgAGAAAAPwAAavhAfgIKAAcAAAA/AICELkF+AgoACAAAAD8A0BJjQQECBgAJAAAAPwABAgYACgAAAD8AAQIGAAsAAAA/AAECBgAMAAAAPwABAgYADQAAAD8AAQIGAA4AAAA/ANcAIgDwAQAAGAEOAA4ADgAOABgADgAOAA4ADgAKAAoACgAKAAoAPQASAKAAAACkW/gvOAAAAAAAAQD0AT4CCgC2AAEAAAAAAAAAHQAPAAMCAAAAAAABAAIAAgAAAKsAIgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAkICAAABhAABD3NBwsCEAAAAAAAAAAMAO6FAADRjgAADQACAAEADAACAGQADwACAAEAEQACAAAAEAAIAPyp8dJNYlA/XwACAAEAKgACAAAAKwACAAAAggACAAEAgAAIAAAAAAAAAAAAJQIEAAAANgGMAAQAAQAeAIEAAgDBBBQAAAAVAAAAgwACAAAAhAACAAAAJgAIAAAAAAAAAOg/JwAIAAAAAAAAAOg/KAAIAAAAAAAAAPA/KQAIAAAAAAAAAPA/oQAiAAEAZAABAAEAAQACAPz//P8AAAAAAADgPwAAAAAAAOA/AQBVAAIACAB9AAwAAAAAAKoKDwAAAAIAfQAMAAEAAQDVCw8AAAACAH0ADAACAAIAgAwPAAAAAgB9AAwAAwADANUMDwAAAAIAfQAMAAQABACADQ8AAAACAH0ADAAFAAUA1Q0PAAAAAgB9AAwABgAGAIAODwAAAAIAfQAMAAcABwBVDw8AAAACAH0ADAAIAAgAABAPAAAAAgB9AAwACQAJAIAQDwAAAAIAfQAMAAoACgAAEQ8AAAACAH0ADAALAAABqgoPAAAAAgAAAgoAAAAMAAAACwAAAAgCEAAAAAAACwA2AQAAAAAAAQ8ACAIQAAEAAAALADYBAAAAAAABDwAIAhAAAgAAAAsANgEAAAAAAAEPAAgCEAADAAAACwA2AQAAAAAAAQ8ACAIQAAQAAAALADYBAAAAAAABDwAIAhAABQAAAAsANgEAAAAAAAEPAAgCEAAGAAAACwA2AQAAAAAAAQ8ACAIQAAcAAAALADYBAAAAAAABDwAIAhAACAAAAAsANgEAAAAAAAEPAAgCEAAJAAAACwA2AQAAAAAAAQ8ACAIQAAoAAAALADYBAAAAAAABDwAIAhAACwAAAAsANgEAAAAAAAEPAAQCDwAAAAAADwAHAEdlbmVyYWy9ACQAAAABAA8AAADwPw8AAQBewA8AATiTQA8AAUiTwA8AgRzIQAUAAwIOAAAABgAPAHe+nxov3V7AAwIOAAAABwAPAFTjpZtESpNAAwIOAAAACAAPAK36XG1FSpPAAwIOAAAACQAPAKH4MebWHMhAAwIOAAAACgAPAHfbhebWHMjABAIQAAEAAAAPAAgAIyMwLjBFKzC9ACQAAQABAFEAAADwP1EAAQBewFEAATiTQFEAAUiTwFEAgRzIQAUAAwIOAAEABgBRAHe+nxov3V7AAwIOAAEABwBRAFTjpZtESpNAAwIOAAEACABRAK36XG1FSpPAAwIOAAEACQBRAKH4MebWHMhAAwIOAAEACgBRAHfbhebWHMjABAINAAIAAAAPAAUAIywjIzC9ACQAAgABAEIAAADwP0IAAQBewEIAATiTQEIAAUiTwEIAgRzIQAUAAwIOAAIABgBCAHe+nxov3V7AAwIOAAIABwBCAFTjpZtESpNAAwIOAAIACABCAK36XG1FSpPAAwIOAAIACQBCAKH4MebWHMhAAwIOAAIACgBCAHfbhebWHMjABAIPAAMAAAAPAAcAIywjIzAuML0AJAADAAEAYgAAAPA/YgABAF7AYgABOJNAYgABSJPAYgCBHMhABQADAg4AAwAGAGIAd76fGi/dXsADAg4AAwAHAGIAVOOlm0RKk0ADAg4AAwAIAGIArfpcbUVKk8ADAg4AAwAJAGIAofgx5tYcyEADAg4AAwAKAGIAd9uF5tYcyMAEAhAABAAAAA8ACAAjLCMjMC4wML0AJAAEAAEARAAAAPA/RAABAF7ARAABOJNARAABSJPARACBHMhABQADAg4ABAAGAEQAd76fGi/dXsADAg4ABAAHAEQAVOOlm0RKk0ADAg4ABAAIAEQArfpcbUVKk8ADAg4ABAAJAEQAofgx5tYcyEADAg4ABAAKAEQAd9uF5tYcyMAEAhEABQAAAA8ACQAjLCMjMC4wMDC9ACQABQABAJwAAADwP5wAAQBewJwAATiTQJwAAUiTwJwAgRzIQAUAAwIOAAUABgCcAHe+nxov3V7AAwIOAAUABwCcAFTjpZtESpNAAwIOAAUACACcAK36XG1FSpPAAwIOAAUACQCcAKH4MebWHMhAAwIOAAUACgCcAHfbhebWHMjABAISAAYAAAAPAAoAIywjIzAuMDAwML0AJAAGAAEAmwAAAPA/mwABAF7AmwABOJNAmwABSJPAmwCBHMhABQADAg4ABgAGAJsAd76fGi/dXsADAg4ABgAHAJsAVOOlm0RKk0ADAg4ABgAIAJsArfpcbUVKk8ADAg4ABgAJAJsAofgx5tYcyEADAg4ABgAKAJsAd9uF5tYcyMAEAhMABwAAAA8ACwAjLCMjMC4wMDAwML0AJAAHAAEAmgAAAPA/mgABAF7AmgABOJNAmgABSJPAmgCBHMhABQADAg4ABwAGAJoAd76fGi/dXsADAg4ABwAHAJoAVOOlm0RKk0ADAg4ABwAIAJoArfpcbUVKk8ADAg4ABwAJAJoAofgx5tYcyEADAg4ABwAKAJoAd9uF5tYcyMAEAhQACAAAAA8ADAAjLCMjMC4wMDAwMDC9ACQACAABAJkAAADwP5kAAQBewJkAATiTQJkAAUiTwJkAgRzIQAUAAwIOAAgABgCZAHe+nxov3V7AAwIOAAgABwCZAFTjpZtESpNAAwIOAAgACACZAK36XG1FSpPAAwIOAAgACQCZAKH4MebWHMhAAwIOAAgACgCZAHfbhebWHMjABAIVAAkAAAAPAA0AIywjIzAuMDAwMDAwML0AJAAJAAEAmAAAAPA/mAABAF7AmAABOJNAmAABSJPAmACBHMhABQADAg4ACQAGAJgAd76fGi/dXsADAg4ACQAHAJgAVOOlm0RKk0ADAg4ACQAIAJgArfpcbUVKk8ADAg4ACQAJAJgAofgx5tYcyEADAg4ACQAKAJgAd9uF5tYcyMAEAhYACgAAAA8ADgAjLCMjMC4wMDAwMDAwML0AJAAKAAEAlwAAAPA/lwABAF7AlwABOJNAlwABSJPAlwCBHMhABQADAg4ACgAGAJcAd76fGi/dXsADAg4ACgAHAJcAVOOlm0RKk0ADAg4ACgAIAJcArfpcbUVKk8ADAg4ACgAJAJcAofgx5tYcyEADAg4ACgAKAJcAd9uF5tYcyMAEAhcACwAAAA8ADwAjLCMjMC4wMDAwMDAwMDC9ACQACwABAJYAAADwP5YAAQBewJYAATiTQJYAAUiTwJYAgRzIQAUAAwIOAAsABgCWAHe+nxov3V7AAwIOAAsABwCWAFTjpZtESpNAAwIOAAsACACWAK36XG1FSpPAAwIOAAsACQCWAKH4MebWHMhAAwIOAAsACgCWAHfbhebWHMjA1wAcAA8IAADcAJUAlgCTAJUAlgCXAJgAmQCaAJsAnAA9ABIAoAAAAKRb+C84AAAAAAABAPQBPgIKALYAAAAAAAAAAAAdAA8AAwwAAAAAAAEADAAMAAAAqwAiACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAABAAAAP7///8GAAAABwAAAAgAAAAJAAAA/v///wsAAAD+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+/wAABgECAAAAAAAAAAAAAAAAAAAAAAABAAAA4IWf8vlPaBCrkQgAKyez2TAAAAD0AAAACwAAAAEAAABgAAAAAgAAAGgAAAADAAAAdAAAAAQAAACAAAAABQAAAIwAAAAGAAAAmAAAAAgAAACkAAAAEgAAALAAAAAMAAAA1AAAAA0AAADgAAAAEwAAAOwAAAACAAAA5QQAAB4AAAAEAAAAAAAAAB4AAAAEAAAAAAAAAB4AAAAEAAAAAAAAAB4AAAAEAAAAAAAAAB4AAAAEAAAAAAAAAB4AAAAEAAAAAAAAAB4AAAAcAAAATWljcm9zb2Z0IE1hY2ludG9zaCBFeGNlbAAAAEAAAACwzkrZok7OAUAAAACAve18CZvPAQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7/AAAGAQIAAAAAAAAAAAAAAAAAAAAAAAEAAAAC1c3VnC4bEJOXCAArLPmuMAAAAPAAAAAIAAAAAQAAAEgAAAACAAAAUAAAAA4AAABcAAAADwAAAGgAAAALAAAAdAAAABAAAAB8AAAADQAAAIQAAAAMAAAAzAAAAAIAAADlBAAAHgAAAAQAAAAAAAAAHgAAAAQAAAAAAAAAHgAAAAQAAAAAAAAACwAAAAAAAAALAAAAAAAAAB4QAAAFAAAACAAAAEltcGxpZWQAEAAAAEltcGxpZWROZWdhdGl2ZQAFAAAAMjAxMQALAAAATWlzY2VsbGFueQAEAAAAU1NGAAwQAAACAAAAHgAAAAsAAABXb3Jrc2hlZXRzAAMAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQD+/wMKAAD/////EAgCAAAAAADAAAAAAAAARh8AAABNaWNyb3NvZnQgRXhjZWwgMjAwMyBXb3Jrc2hlZXQABgAAAEJpZmY4AA4AAABFeGNlbC5TaGVldC44APQ5snEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQBDAG8AbQBwAE8AYgBqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAgD///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAawAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; diff --git a/xlsx.flow.js b/xlsx.flow.js index 302b032..477a77b 100644 --- a/xlsx.flow.js +++ b/xlsx.flow.js @@ -1,9 +1,9 @@ /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint -W041 */ -/*jshint funcscope:true, eqnull:true */ +/*jshint funcscope:true, eqnull:true, loopfunc:true */ /*exported XLSX */ -/*global exports, module, require:false, process:false, Buffer:false */ +/*global global, exports, module, require:false, process:false, Buffer:false */ var XLSX = {}; (function make_xlsx(XLSX){ XLSX.version = '0.10.1'; @@ -11,7 +11,7 @@ var current_codepage = 1200; /*:: declare var cptable:any; */ /*global cptable:true */ if(typeof module !== "undefined" && typeof require !== 'undefined') { - if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js'); + if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); } function reset_cp() { set_cp(1200); } var set_cp = function(cp) { current_codepage = cp; }; @@ -1713,8 +1713,7 @@ if(has_buf) { 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'); + return out.slice(0,k).toString('ucs2'); }; var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; @@ -2075,7 +2074,7 @@ function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?numbe if(/*:: length != null &&*/length > 0 && is_buf(payload)) ba.push(payload); } /* XLS ranges enforced */ -function shift_cell_xls(cell, tgt/*:any*/, opts/*:?any*/) { +function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:CellAddress*/ { var out = dup(cell); if(tgt.s) { if(out.cRel) out.c += tgt.s.c; @@ -2098,7 +2097,7 @@ function shift_range_xls(cell, range, opts) { return out; } -function encode_cell_xls(c)/*:string*/ { +function encode_cell_xls(c/*:CellAddress*/)/*:string*/ { var s = encode_cell(c); if(c.cRel === 0) s = fix_col(s); if(c.rRel === 0) s = fix_row(s); @@ -4294,7 +4293,7 @@ function parse_Window1(blob, length) { /* 2.4.122 TODO */ function parse_Font(blob, length, opts) { - var o = { + var o/*:any*/ = { dyHeight: blob.read_shift(2), fl: blob.read_shift(2) }; @@ -5330,7 +5329,7 @@ function dbf_to_workbook(buf, opts)/*:Workbook*/ { var SYLK = (function() { /* TODO: find an actual specification */ - function sylk_to_aoa(d/*:RawData*/, opts)/*:AOA*/ { + function sylk_to_aoa(d/*:RawData*/, opts)/*:[AOA, Worksheet]*/ { switch(opts.type) { case 'base64': return sylk_to_aoa_str(Base64.decode(d), opts); case 'binary': return sylk_to_aoa_str(d, opts); @@ -5339,7 +5338,7 @@ var SYLK = (function() { } throw new Error("Unrecognized type " + opts.type); } - function sylk_to_aoa_str(str/*:string*/, opts)/*:AOA*/ { + function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ { var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr = []; var formats = []; var next_cell_format = null; @@ -5379,7 +5378,7 @@ var SYLK = (function() { next_cell_format = null; break; case 'E': - formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); + var formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); arr[R][C] = [arr[R][C], formula]; break; default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); @@ -5424,13 +5423,12 @@ var SYLK = (function() { } if(rowinfo.length > 0) sht['!rows'] = rowinfo; if(colinfo.length > 0) sht['!cols'] = colinfo; - arr[arr.length] = sht; - return arr; + return [arr, sht]; } function sylk_to_sheet(str/*:string*/, opts)/*:Worksheet*/ { - var aoa = sylk_to_aoa(str, opts); - var ws = aoa.pop(); + var aoasht = sylk_to_aoa(str, opts); + var aoa = aoasht[0], ws = aoasht[1]; var o = aoa_to_sheet(aoa, opts); keys(ws).forEach(function(k) { o[k] = ws[k]; }); return o; @@ -5555,7 +5553,7 @@ var DIF = (function() { o.push(v + "," + n); o.push('"' + s.replace(/"/g,'""') + '"'); }; - var push_value = function po(o/*:Array*/, type/*:number*/, v/*:number*/, s/*:string*/) { + var push_value = function po(o/*:Array*/, type/*:number*/, v/*:any*/, s/*:string*/) { o.push(type + "," + v); o.push(type == 1 ? '"' + s.replace(/"/g,'""') + '"' : s); }; @@ -5665,8 +5663,12 @@ var PRN = (function() { else if(s == "TRUE") { cell.t = 'b'; cell.v = true; } else if(s == "FALSE") { cell.t = 'b'; cell.v = false; } else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; } - else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); } - else { + else if(!isNaN(fuzzydate(s).getDate())) { + cell.z = o.dateNF || SSF._table[14]; + if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s); } + else { cell.t = 'n'; cell.v = datenum(parseDate(s)); } + cell.w = SSF.format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v); + } else { cell.t = 's'; if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"'); cell.v = s; @@ -6365,10 +6367,12 @@ function _JS2ANSI(str/*:string*/)/*:Array*/ { } /* [MS-OFFCRYPTO] 2.1.4 Version */ -function parse_CRYPTOVersion(blob, length/*:number*/) { - var o = {}; +function parse_CRYPTOVersion(blob, length/*:?number*/) { + var o/*:any*/ = {}; o.Major = blob.read_shift(2); o.Minor = blob.read_shift(2); + /*:: if(length == null) return o; */ + if(length >= 4) blob.l += length - 4; return o; } @@ -7253,11 +7257,11 @@ var XLSBFillPTNames = [ "gray125", "gray0625" ]; -var rev_XLSBFillPTNames = evert(XLSBFillPTNames); +var rev_XLSBFillPTNames/*:EvertNumType*/ = (evert(XLSBFillPTNames)/*:any*/); /* TODO: gradient fill representation */ function write_BrtFill(fill, o) { if(!o) o = new_buf(4*3 + 8*7 + 16*1); - var fls = rev_XLSBFillPTNames[fill.patternType]; + var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType]; if(fls == null) fls = 0x28; o.write_shift(4, fls); var j = 0; @@ -7409,16 +7413,18 @@ function parse_sty_bin(data, themes, opts) { return styles; } -function write_FMTS_bin(ba, NF) { +function write_FMTS_bin(ba, NF/*:?SSFTable*/) { if(!NF) return; var cnt = 0; [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { + /*:: if(!NF) return; */ for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt; }); if(cnt == 0) return; write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt)); [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { + /*:: if(!NF) return; */ for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i])); }); write_record(ba, "BrtEndFmts"); @@ -8956,7 +8962,7 @@ var PtgBinOp = { function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, opts) { //console.log(formula); var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}}; - var stack/*:Array*/ = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname=""; + var stack/*:Array*/ = [], e1, e2, type, c/*:CellAddress*/, ixti=0, nameidx=0, r, sname=""; if(!formula[0] || !formula[0][0]) return ""; var last_sp = -1, sp = ""; //console.log("--",cell,formula[0]) @@ -9027,15 +9033,15 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgRef': /* 2.5.198.84 */ - type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts); + type = f[1][0]; c = shift_cell_xls((f[1][1]/*:any*/), _range, opts); stack.push(encode_cell_xls(c)); break; case 'PtgRefN': /* 2.5.198.88 */ - type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1]; + type = f[1][0]; c = cell ? shift_cell_xls((f[1][1]/*:any*/), cell, opts) : (f[1][1]/*:any*/); stack.push(encode_cell_xls(c)); break; case 'PtgRef3d': /* 2.5.198.85 */ - type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls(f[1][2], _range, opts); + type = f[1][0]; ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls((f[1][2]/*:any*/), _range, opts); sname = supbooks.SheetNames[ixti]; var w = sname; /* IE9 fails on defined names */ stack.push(sname + "!" + encode_cell_xls(c)); @@ -9086,7 +9092,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgName': /* 2.5.97.60 TODO: revisions */ /* f[1] = type, 0, nameindex */ - nameidx = f[1][2]; + nameidx = (f[1][2]/*:any*/); var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx]; var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx); if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name]; @@ -9095,7 +9101,7 @@ function stringify_formula(formula/*Array*/, range, cell/*:any*/, supbooks, case 'PtgNameX': /* 2.5.97.61 TODO: revisions */ /* f[1] = type, ixti, nameindex */ - var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = f[1][2]; var externbook; + var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook; /* TODO: Properly handle missing values */ //console.log(bookidx, supbooks); if(opts.biff <= 5) { @@ -10562,7 +10568,7 @@ function col_obj_w(C/*:number*/, col) { return p; } -function default_margins(margins, mode) { +function default_margins(margins/*:Margins*/, mode/*:?string*/) { if(!margins) return; var defs = [0.7, 0.7, 0.75, 0.75, 0.3, 0.3]; if(mode == 'xlml') defs = [1, 1, 1, 1, 0.5, 0.5]; @@ -10597,7 +10603,7 @@ function get_cell_style(styles, cell, opts) { return len; } -function safe_format(p, fmtid, fillid, opts, themes, styles) { +function safe_format(p, fmtid/*:number*/, fillid, opts, themes, styles) { if(p.t === 'z') return; if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v); try { @@ -10654,7 +10660,7 @@ function parse_ws_xml(data/*:?string*/, opts, rels, wb, themes, styles)/*:Worksh var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/); var data1 = "", data2 = ""; - var mtch=data.match(sheetdataregex); + var mtch/*:?any*/ =data.match(sheetdataregex); if(mtch) { data1 = data.substr(0, mtch.index); data2 = data.substr(mtch.index + mtch[0].length); @@ -11125,7 +11131,6 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ { if(ws['!drawing'].length > 0) { rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW); - ws['!drawing'].rid = rId; o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId}); } else delete ws['!drawing']; @@ -11526,6 +11531,7 @@ function write_BrtSheetProtection(sp, o) { ["pivotTables", true], // fPivotTables ["selectUnlockedCells", false] // fSelUnlockedCells ].forEach(function(n) { + /*:: if(o == null) throw "unreachable"; */ if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0); else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1); }); @@ -11538,13 +11544,13 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ { var opts = _opts || {}; if(!rels) rels = {'!id':{}}; if(DENSE != null && opts.dense == null) opts.dense = DENSE; - var s = opts.dense ? [] : {}; + var s/*:Worksheet*/ = (opts.dense ? [] : {}); var ref; var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} }; var pass = false, end = false; - var row, p, cf, R, C, addr, sstr, rr, cell; + var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/; var mergecells = []; opts.biff = 12; opts['!row'] = 0; @@ -11660,7 +11666,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles)/*:Worksheet*/ { case 0x01AA: /* 'BrtArrFmla' */ if(!opts.cellFormula) break; array_formulae.push(val); - cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]); + cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr])/*:any*/); cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts); cell.F = encode_range(val[0]); break; @@ -12200,7 +12206,7 @@ function parse_wb_defaults(wb) { } var badchars = "][*?\/\\".split(""); -function check_ws_name(n/*:string*/, safe/*:boolean*/)/*:boolean*/ { +function check_ws_name(n/*:string*/, safe/*:?boolean*/)/*:boolean*/ { if(n.length > 31) { if(safe) return false; throw new Error("Sheet names cannot exceed 31 chars"); } var _good = true; badchars.forEach(function(c) { @@ -12230,7 +12236,7 @@ function parse_wb_xml(data, opts)/*:WorkbookFile*/ { var dname = {}, dnstart = 0; /*(data.match(tagregex)||[]).forEach */ data.replace(tagregex, function xml_wb(x, idx) { - var y = parsexmltag(x); + var y/*:any*/ = parsexmltag(x); switch(strip_ns(y[0])) { case '"; if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) { - var d = {name:n.Name}; + var d/*:any*/ = {name:n.Name}; if(n.Comment) d.comment = n.Comment; if(n.Sheet != null) d.localSheetId = ""+n.Sheet; if(!n.Ref) return; @@ -12507,7 +12513,7 @@ function parse_wb_bin(data, opts)/*:WorkbookFile*/ { opts.biff = 12; var Names = []; - var supbooks = []; + var supbooks = ([]/*:any*/); supbooks.SheetNames = []; recordhopper(data, function hopper_wb(val, R_n, RT) { @@ -12944,7 +12950,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { var Rn; var state = [], tmp; if(DENSE != null && opts.dense == null) opts.dense = DENSE; - var sheets = {}, sheetnames = [], cursheet = (opts.dense ? [] : {}), sheetname = ""; + var sheets = {}, sheetnames = [], cursheet/*:Worksheet*/ = (opts.dense ? [] : {}), sheetname = ""; var table = {}, cell = ({}/*:any*/), row = {}; var dtag = xlml_parsexmltag(''), didx = 0; var c = 0, r = 0; @@ -12957,7 +12963,7 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { var cstys = [], csty, seencol = false; var arrayf = []; var rowinfo = [], rowobj = {}; - var Workbook = { Sheets:[] }, wsprops = {}; + var Workbook/*:WBWBProps*/ = { Sheets:[] }, wsprops = {}; xlmlregex.lastIndex = 0; str = str.replace(//mg,""); while((Rn = xlmlregex.exec(str))) switch(Rn[3]) { @@ -13091,12 +13097,12 @@ function parse_xlml_xml(d, opts)/*:Workbook*/ { case 'NamedRange': if(!Workbook.Names) Workbook.Names = []; var _NamedRange = parsexmltag(Rn[0]); - var _DefinedName = { + var _DefinedName/*:DefinedName*/ = ({ Name: _NamedRange.Name, Ref: rc_to_a1(_NamedRange.RefersTo.substr(1)) - }; + }/*:any*/); if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1; - Workbook.Names.push(_DefinedName); + /*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName); break; case 'NamedCell': break; @@ -13786,7 +13792,7 @@ function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbo process_col(n); var w = !!n.width; var p = col_obj_w(i, n); - var k = {"ss:Index":i+1}; + var k/*:any*/ = {"ss:Index":i+1}; if(w) k['ss:Width'] = width2px(p.width); if(n.hidden) k['ss:Hidden']="1"; o.push(writextag("Column",null,k)); @@ -13901,8 +13907,9 @@ function slurp(R, blob, length/*:number*/, opts) { function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { if(p.t === 'z') return; if(!p.XF) return; + var fmtid = 0; try { - var fmtid = p.z || p.XF.ifmt || 0; + fmtid = p.z || p.XF.ifmt || 0; if(opts.cellNF) p.z = SSF._table[fmtid]; } catch(e) { if(opts.WTF) throw e; } if(!opts || opts.cellText !== false) try { @@ -13921,7 +13928,7 @@ function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) { } catch(e) { if(opts.WTF) throw e; } } -function make_cell(val, ixfe, t)/*:any*/ { +function make_cell(val, ixfe, t)/*:Cell*/ { return ({v:val, ixfe:ixfe, t:t}/*:any*/); } @@ -13930,7 +13937,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { var wb = ({opts:{}}/*:any*/); var Sheets = {}; if(DENSE != null && options.dense == null) options.dense = DENSE; - var out = (options.dense ? [] : {}); + var out/*:Worksheet*/ = ((options.dense ? [] : {})/*:any*/); var Directory = {}; var found_sheet = false; var range/*:Range*/ = ({}/*:any*/); @@ -13941,12 +13948,12 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { var lastcell, last_cell = "", cc, cmnt, rng, rngC, rngR; var shared_formulae = {}; var array_formulae = []; /* TODO: something more clever */ - var temp_val; + var temp_val/*:Cell*/; var country; var cell_valid = true; var XFs = []; /* XF records */ var palette = []; - var Workbook = { Sheets:[] }, wsprops = {}; + var Workbook/*:WBWBProps*/ = ({ Sheets:[] }/*:any*/), wsprops = {}; var get_rgb = function getrgb(icv) { if(icv < 8) return XLSIcv[icv]; if(icv < 64) return palette[icv-8] || XLSIcv[icv]; @@ -14025,9 +14032,9 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { var last_Rn = ''; var file_depth = 0; /* TODO: make a real stack */ var BIFF2Fmt = 0; - var BIFF2FmtTable = []; + var BIFF2FmtTable/*:Array*/ = []; var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */ - var last_lbl; + var last_lbl/*:?DefinedName*/; /* explicit override for some broken writers */ opts.codepage = 1200; @@ -14109,10 +14116,10 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { break; case 'Index': break; // TODO case 'Lbl': - last_lbl = { + last_lbl = ({ Name: val.Name, Ref: stringify_formula(val.rgce,range,null,supbooks,opts) - }; + }/*:DefinedName*/); if(val.itab > 0) last_lbl.Sheet = val.itab - 1; supbooks.names.push(last_lbl); if(!supbooks[0]) supbooks[0] = []; @@ -14127,7 +14134,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'NameCmt': /* TODO: search for correct name */ if(opts.biff < 8) break; - last_lbl.Comment = val[1]; + if(last_lbl != null) last_lbl.Comment = val[1]; break; case 'Protect': out["!protect"] = val; break; /* for sheet or book */ @@ -14153,7 +14160,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { Workbook.Sheets.push(wsprops); } if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out; - out = options.dense ? [] : {}; + out = ((options.dense ? [] : {})/*:any*/); } break; case 'BOF': { if(opts.biff !== 8){/* empty */} @@ -14166,7 +14173,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { else if(val.BIFFVer === 0x0007) opts.biff = 2; if(file_depth++) break; cell_valid = true; - out = (options.dense ? [] : {}); + out = ((options.dense ? [] : {})/*:any*/); if(opts.biff < 5) { if(cur_sheet === "") cur_sheet = "Sheet1"; @@ -14189,19 +14196,19 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'Number': case 'BIFF2NUM': case 'BIFF2INT': { if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c; - temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; 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}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; 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'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:val.c, r:val.r}, temp_val, options); @@ -14209,7 +14216,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { 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'}; + temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:j, r:val.r}, temp_val, options); @@ -14217,7 +14224,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { } break; case 'Formula': { if(val.val == 'String') { last_formula = val; break; } - temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt}/*:any*/); + temp_val = make_cell(val.val, val.cell.ixfe, val.tt); temp_val.XF = XFs[temp_val.ixfe]; if(options.cellFormula) { var _f = val.formula; @@ -14236,7 +14243,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'String': { if(last_formula) { /* technically always true */ last_formula.val = val; - temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'}/*:any*/); + temp_val = make_cell(val, last_formula.cell.ixfe, '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); @@ -14277,7 +14284,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { addcell({c:val.c, r:val.r}, temp_val, options); break; case 'Blank': if(options.sheetStubs) { - temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:val.c, r:val.r}, temp_val, options); @@ -14285,7 +14292,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'MulBlank': if(options.sheetStubs) { for(var _j = val.c; _j <= val.C; ++_j) { var _ixfe = val.ixfe[_j-val.c]; - temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}; + temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:_j, r:val.r}, temp_val, options); @@ -14376,12 +14383,7 @@ function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ { case 'TopMargin': case 'BottomMargin': if(!out['!margins']) default_margins(out['!margins'] = {}); - switch(Rn) { - case 'LeftMargin': out['!margins'].left = val; break; - case 'RightMargin': out['!margins'].right = val; break; - case 'TopMargin': out['!margins'].top = val; break; - case 'BottomMargin': out['!margins'].bottom = val; break; - } + out['!margins'][Rn.slice(0,-6).toLowerCase()] = val; break; case 'Setup': // TODO @@ -16121,12 +16123,13 @@ var HTML_ = (function() { } return "" + oo.join("") + ""; } - function sheet_to_html(ws/*:Worksheet*/, opts)/*:string*/ { - var o/*:Array*/ = []; + function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ { + var o = opts || {}; + var out/*:Array*/ = []; var r = decode_range(ws['!ref']); o.dense = Array.isArray(ws); - for(var R = r.s.r; R <= r.e.r; ++R) o.push(make_html_row(ws, r, R, o)); - return "" + o.join("") + "
"; + for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); + return "" + out.join("") + "
"; } return { @@ -16882,7 +16885,7 @@ var fix_write_opts = fix_opts_func([ ['WTF', false] /* WTF mode (throws errors) */ ]); -function get_sheet_type(n) { +function get_sheet_type(n/*:string*/)/*:string*/ { if(RELS.WS.indexOf(n) > -1) return "sheet"; if(RELS.CS && n == RELS.CS) return "chart"; if(RELS.DS && n == RELS.DS) return "dialog"; @@ -17065,8 +17068,7 @@ function parse_xlsxcfb(cfb, opts/*:?ParseOpts*/)/*:Workbook*/ { data = cfb.find(f); if(!data) throw new Error("ECMA-376 Encrypted file missing " + f); var dsm = parse_DataSpaceMap(data.content); - if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || - dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") + if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") throw new Error("ECMA-376 Encrypted file bad " + f); f = 'StrongEncryptionDataSpace'; @@ -17600,7 +17602,7 @@ function json_to_sheet(js/*:Array*/, opts)/*:Worksheet*/ { return ws; } -var utils = { +var utils/*:any*/ = { encode_col: encode_col, encode_row: encode_row, encode_cell: encode_cell, @@ -17627,9 +17629,9 @@ var utils = { (function(utils) { utils.consts = utils.consts || {}; -function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } +function add_consts(R/*Array*/) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } -function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); } +function get_default(x/*:any*/, y/*:any*/, z/*:any*/)/*:any*/ { return x[y] != null ? x[y] : (x[y] = z); } /* get cell, creating a stub if necessary */ function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ { @@ -17638,7 +17640,7 @@ function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ { /* cell address object */ if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R)); /* R and C are 0-based indices */ - return ws_get_cell_stub(ws, encode_cell({r:R,c:C})); + return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0})); } /* find sheet index for given name / validate index */ @@ -17660,7 +17662,8 @@ utils.book_new = function()/*:Workbook*/ { /* add a worksheet to the end of a given workbook */ utils.book_append_sheet = function(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/) { - if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break; + if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break; + if(!name) throw new Error("Too many worksheets"); check_ws_name(name); if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!"); @@ -17674,12 +17677,14 @@ utils.book_set_sheet_visibility = function(wb/*:Workbook*/, sh/*:number|string*/ get_default(wb.Workbook,"Sheets",[]); var idx = wb_sheet_idx(wb, sh); + // $FlowIgnore get_default(wb.Workbook.Sheets,idx, {}); switch(vis) { case 0: case 1: case 2: break; default: throw new Error("Bad sheet visibility setting " + vis); } + // $FlowIgnore wb.Workbook.Sheets[idx].Hidden = vis; }; add_consts([ @@ -17699,7 +17704,7 @@ utils.cell_set_hyperlink = function(cell/*:Cell*/, target/*:string*/, tooltip/*: if(!target) { delete cell.l; } else { - cell.l = { Target: target }; + cell.l = ({ Target: target }/*:Hyperlink*/); if(tooltip) cell.l.Tooltip = tooltip; } return cell; @@ -17740,7 +17745,7 @@ if(has_buf && typeof require != 'undefined') (function() { var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0); var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0); var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$"); - var row = "", cols = []; + var row/*:?string*/ = "", cols = []; o.dense = Array.isArray(sheet); for(var C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C); var R = r.s.r; @@ -17748,11 +17753,12 @@ if(has_buf && typeof require != 'undefined') (function() { if(R > r.e.r) return stream.push(null); while(R <= r.e.r) { row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o); - if(row == null) { ++R; continue; } - if(o.strip) row = row.replace(endregex,""); - stream.push(row + RS); ++R; - break; + if(row != null) { + if(o.strip) row = row.replace(endregex,""); + stream.push(row + RS); + break; + } } }; return stream; @@ -17761,10 +17767,10 @@ if(has_buf && typeof require != 'undefined') (function() { var HTML_BEGIN = ""; var HTML_END = "
"; - var write_html_stream = function(sheet/*:Worksheet*/, opts) { + var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) { var stream = Readable(); - var o/*:Array*/ = []; + var o = opts == null ? {} : opts; var r = decode_range(sheet['!ref']), cell/*:Cell*/; o.dense = Array.isArray(sheet); stream.push(HTML_BEGIN); diff --git a/xlsx.js b/xlsx.js index a172bd0..2492535 100644 --- a/xlsx.js +++ b/xlsx.js @@ -1,16 +1,16 @@ /* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */ /* vim: set ts=2: */ /*jshint -W041 */ -/*jshint funcscope:true, eqnull:true */ +/*jshint funcscope:true, eqnull:true, loopfunc:true */ /*exported XLSX */ -/*global exports, module, require:false, process:false, Buffer:false */ +/*global global, exports, module, require:false, process:false, Buffer:false */ var XLSX = {}; (function make_xlsx(XLSX){ XLSX.version = '0.10.1'; var current_codepage = 1200; /*global cptable:true */ if(typeof module !== "undefined" && typeof require !== 'undefined') { - if(typeof cptable === 'undefined') cptable = require('./dist/cpexcel.js'); + if(typeof cptable === 'undefined') global.cptable = require('./dist/cpexcel.js'); } function reset_cp() { set_cp(1200); } var set_cp = function(cp) { current_codepage = cp; }; @@ -1662,8 +1662,7 @@ if(has_buf) { 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'); + return out.slice(0,k).toString('ucs2'); }; var corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; if(utf8read(corpus) == utf8readb(corpus)) utf8read = utf8readb; @@ -5318,7 +5317,7 @@ var SYLK = (function() { next_cell_format = null; break; case 'E': - formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); + var formula = rc_to_a1(record[rj].substr(1), {r:R,c:C}); arr[R][C] = [arr[R][C], formula]; break; default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr); @@ -5363,13 +5362,12 @@ var SYLK = (function() { } if(rowinfo.length > 0) sht['!rows'] = rowinfo; if(colinfo.length > 0) sht['!cols'] = colinfo; - arr[arr.length] = sht; - return arr; + return [arr, sht]; } function sylk_to_sheet(str, opts) { - var aoa = sylk_to_aoa(str, opts); - var ws = aoa.pop(); + var aoasht = sylk_to_aoa(str, opts); + var aoa = aoasht[0], ws = aoasht[1]; var o = aoa_to_sheet(aoa, opts); keys(ws).forEach(function(k) { o[k] = ws[k]; }); return o; @@ -5604,8 +5602,12 @@ var PRN = (function() { else if(s == "TRUE") { cell.t = 'b'; cell.v = true; } else if(s == "FALSE") { cell.t = 'b'; cell.v = false; } else if(!isNaN(v = +s)) { cell.t = 'n'; cell.w = s; cell.v = v; } - else if(!isNaN(fuzzydate(s).getDate())) { cell.t = 'd'; cell.v = parseDate(s); } - else { + else if(!isNaN(fuzzydate(s).getDate())) { + cell.z = o.dateNF || SSF._table[14]; + if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s); } + else { cell.t = 'n'; cell.v = datenum(parseDate(s)); } + cell.w = SSF.format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v); + } else { cell.t = 's'; if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"'); cell.v = s; @@ -6308,6 +6310,7 @@ function parse_CRYPTOVersion(blob, length) { var o = {}; o.Major = blob.read_shift(2); o.Minor = blob.read_shift(2); +if(length >= 4) blob.l += length - 4; return o; } @@ -7192,7 +7195,7 @@ var XLSBFillPTNames = [ "gray125", "gray0625" ]; -var rev_XLSBFillPTNames = evert(XLSBFillPTNames); +var rev_XLSBFillPTNames = (evert(XLSBFillPTNames)); /* TODO: gradient fill representation */ function write_BrtFill(fill, o) { if(!o) o = new_buf(4*3 + 8*7 + 16*1); @@ -7352,13 +7355,13 @@ function write_FMTS_bin(ba, NF) { if(!NF) return; var cnt = 0; [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { - for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt; +for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt; }); if(cnt == 0) return; write_record(ba, "BrtBeginFmts", write_UInt32LE(cnt)); [[5,8],[23,26],[41,44],[/*63*/57,/*66],[164,*/392]].forEach(function(r) { - for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i])); +for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, "BrtFmt", write_BrtFmt(i, NF[i])); }); write_record(ba, "BrtEndFmts"); } @@ -8965,15 +8968,15 @@ function stringify_formula(formula/*Array*/, range, cell, supbooks, opts) { case 'PtgRef': /* 2.5.198.84 */ - type = f[1][0]; c = shift_cell_xls(f[1][1], _range, opts); + type = f[1][0]; c = shift_cell_xls((f[1][1]), _range, opts); stack.push(encode_cell_xls(c)); break; case 'PtgRefN': /* 2.5.198.88 */ - type = f[1][0]; c = cell ? shift_cell_xls(f[1][1], cell, opts) : f[1][1]; + type = f[1][0]; c = cell ? shift_cell_xls((f[1][1]), cell, opts) : (f[1][1]); stack.push(encode_cell_xls(c)); break; case 'PtgRef3d': /* 2.5.198.85 */ - type = f[1][0]; ixti = f[1][1]; c = shift_cell_xls(f[1][2], _range, opts); + type = f[1][0]; ixti = f[1][1]; c = shift_cell_xls((f[1][2]), _range, opts); sname = supbooks.SheetNames[ixti]; var w = sname; /* IE9 fails on defined names */ stack.push(sname + "!" + encode_cell_xls(c)); @@ -9024,7 +9027,7 @@ function stringify_formula(formula/*Array*/, range, cell, supbooks, opts) { case 'PtgName': /* 2.5.97.60 TODO: revisions */ /* f[1] = type, 0, nameindex */ - nameidx = f[1][2]; + nameidx = (f[1][2]); var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx]; var name = lbl ? lbl.Name : "**MISSING**" + String(nameidx); if(name in XLSXFutureFunctions) name = XLSXFutureFunctions[name]; @@ -9033,7 +9036,7 @@ function stringify_formula(formula/*Array*/, range, cell, supbooks, opts) { case 'PtgNameX': /* 2.5.97.61 TODO: revisions */ /* f[1] = type, ixti, nameindex */ - var bookidx = (f[1][1]); nameidx = f[1][2]; var externbook; + var bookidx = (f[1][1]); nameidx = (f[1][2]); var externbook; /* TODO: Properly handle missing values */ //console.log(bookidx, supbooks); if(opts.biff <= 5) { @@ -10592,7 +10595,7 @@ function parse_ws_xml(data, opts, rels, wb, themes, styles) { var refguess = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }); var data1 = "", data2 = ""; - var mtch=data.match(sheetdataregex); + var mtch =data.match(sheetdataregex); if(mtch) { data1 = data.substr(0, mtch.index); data2 = data.substr(mtch.index + mtch[0].length); @@ -11063,7 +11066,6 @@ function write_ws_xml(idx, opts, wb, rels) { if(ws['!drawing'].length > 0) { rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW); - ws['!drawing'].rid = rId; o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId}); } else delete ws['!drawing']; @@ -11464,7 +11466,7 @@ function write_BrtSheetProtection(sp, o) { ["pivotTables", true], // fPivotTables ["selectUnlockedCells", false] // fSelUnlockedCells ].forEach(function(n) { - if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0); +if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0); else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1); }); return o; @@ -11476,7 +11478,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) { var opts = _opts || {}; if(!rels) rels = {'!id':{}}; if(DENSE != null && opts.dense == null) opts.dense = DENSE; - var s = opts.dense ? [] : {}; + var s = (opts.dense ? [] : {}); var ref; var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} }; @@ -11598,7 +11600,7 @@ function parse_ws_bin(data, _opts, rels, wb, themes, styles) { case 0x01AA: /* 'BrtArrFmla' */ if(!opts.cellFormula) break; array_formulae.push(val); - cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]); + cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr])); cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts); cell.F = encode_range(val[0]); break; @@ -12445,7 +12447,7 @@ function parse_wb_bin(data, opts) { opts.biff = 12; var Names = []; - var supbooks = []; + var supbooks = ([]); supbooks.SheetNames = []; recordhopper(data, function hopper_wb(val, R_n, RT) { @@ -13026,12 +13028,12 @@ for(var cma = c; cma <= cc; ++cma) { case 'NamedRange': if(!Workbook.Names) Workbook.Names = []; var _NamedRange = parsexmltag(Rn[0]); - var _DefinedName = { + var _DefinedName = ({ Name: _NamedRange.Name, Ref: rc_to_a1(_NamedRange.RefersTo.substr(1)) - }; + }); if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1; - Workbook.Names.push(_DefinedName); +Workbook.Names.push(_DefinedName); break; case 'NamedCell': break; @@ -13835,8 +13837,9 @@ function slurp(R, blob, length, opts) { function safe_format_xf(p, opts, date1904) { if(p.t === 'z') return; if(!p.XF) return; + var fmtid = 0; try { - var fmtid = p.z || p.XF.ifmt || 0; + fmtid = p.z || p.XF.ifmt || 0; if(opts.cellNF) p.z = SSF._table[fmtid]; } catch(e) { if(opts.WTF) throw e; } if(!opts || opts.cellText !== false) try { @@ -13864,7 +13867,7 @@ function parse_workbook(blob, options) { var wb = ({opts:{}}); var Sheets = {}; if(DENSE != null && options.dense == null) options.dense = DENSE; - var out = (options.dense ? [] : {}); + var out = ((options.dense ? [] : {})); var Directory = {}; var found_sheet = false; var range = ({}); @@ -13880,7 +13883,7 @@ function parse_workbook(blob, options) { var cell_valid = true; var XFs = []; /* XF records */ var palette = []; - var Workbook = { Sheets:[] }, wsprops = {}; + var Workbook = ({ Sheets:[] }), wsprops = {}; var get_rgb = function getrgb(icv) { if(icv < 8) return XLSIcv[icv]; if(icv < 64) return palette[icv-8] || XLSIcv[icv]; @@ -14043,10 +14046,10 @@ function parse_workbook(blob, options) { break; case 'Index': break; // TODO case 'Lbl': - last_lbl = { + last_lbl = ({ Name: val.Name, Ref: stringify_formula(val.rgce,range,null,supbooks,opts) - }; + }); if(val.itab > 0) last_lbl.Sheet = val.itab - 1; supbooks.names.push(last_lbl); if(!supbooks[0]) supbooks[0] = []; @@ -14061,7 +14064,7 @@ function parse_workbook(blob, options) { case 'NameCmt': /* TODO: search for correct name */ if(opts.biff < 8) break; - last_lbl.Comment = val[1]; + if(last_lbl != null) last_lbl.Comment = val[1]; break; case 'Protect': out["!protect"] = val; break; /* for sheet or book */ @@ -14087,7 +14090,7 @@ function parse_workbook(blob, options) { Workbook.Sheets.push(wsprops); } if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out; - out = options.dense ? [] : {}; + out = ((options.dense ? [] : {})); } break; case 'BOF': { if(opts.biff !== 8){/* empty */} @@ -14100,7 +14103,7 @@ function parse_workbook(blob, options) { else if(val.BIFFVer === 0x0007) opts.biff = 2; if(file_depth++) break; cell_valid = true; - out = (options.dense ? [] : {}); + out = ((options.dense ? [] : {})); if(opts.biff < 5) { if(cur_sheet === "") cur_sheet = "Sheet1"; @@ -14123,19 +14126,19 @@ function parse_workbook(blob, options) { case 'Number': case 'BIFF2NUM': case 'BIFF2INT': { if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c; - temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; 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}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; 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'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:val.c, r:val.r}, temp_val, options); @@ -14143,7 +14146,7 @@ function parse_workbook(blob, options) { 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'}; + temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:j, r:val.r}, temp_val, options); @@ -14151,7 +14154,7 @@ function parse_workbook(blob, options) { } break; case 'Formula': { if(val.val == 'String') { last_formula = val; break; } - temp_val = ({v:val.val, ixfe:val.cell.ixfe, t:val.tt}); + temp_val = make_cell(val.val, val.cell.ixfe, val.tt); temp_val.XF = XFs[temp_val.ixfe]; if(options.cellFormula) { var _f = val.formula; @@ -14170,7 +14173,7 @@ function parse_workbook(blob, options) { case 'String': { if(last_formula) { /* technically always true */ last_formula.val = val; - temp_val = ({v:val, ixfe:last_formula.cell.ixfe, t:'s'}); + temp_val = make_cell(val, last_formula.cell.ixfe, '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); @@ -14211,7 +14214,7 @@ function parse_workbook(blob, options) { addcell({c:val.c, r:val.r}, temp_val, options); break; case 'Blank': if(options.sheetStubs) { - temp_val = {ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}; + temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:val.c, r:val.r}, temp_val, options); @@ -14219,7 +14222,7 @@ function parse_workbook(blob, options) { case 'MulBlank': if(options.sheetStubs) { for(var _j = val.c; _j <= val.C; ++_j) { var _ixfe = val.ixfe[_j-val.c]; - temp_val= {ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}; + temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}); if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x1F]; safe_format_xf(temp_val, options, wb.opts.Date1904); addcell({c:_j, r:val.r}, temp_val, options); @@ -14310,12 +14313,7 @@ function parse_workbook(blob, options) { case 'TopMargin': case 'BottomMargin': if(!out['!margins']) default_margins(out['!margins'] = {}); - switch(Rn) { - case 'LeftMargin': out['!margins'].left = val; break; - case 'RightMargin': out['!margins'].right = val; break; - case 'TopMargin': out['!margins'].top = val; break; - case 'BottomMargin': out['!margins'].bottom = val; break; - } + out['!margins'][Rn.slice(0,-6).toLowerCase()] = val; break; case 'Setup': // TODO @@ -16056,11 +16054,12 @@ var HTML_ = (function() { return "" + oo.join("") + ""; } function sheet_to_html(ws, opts) { - var o = []; + var o = opts || {}; + var out = []; var r = decode_range(ws['!ref']); o.dense = Array.isArray(ws); - for(var R = r.s.r; R <= r.e.r; ++R) o.push(make_html_row(ws, r, R, o)); - return "" + o.join("") + "
"; + for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o)); + return "" + out.join("") + "
"; } return { @@ -16998,8 +16997,7 @@ function parse_xlsxcfb(cfb, opts) { data = cfb.find(f); if(!data) throw new Error("ECMA-376 Encrypted file missing " + f); var dsm = parse_DataSpaceMap(data.content); - if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || - dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") + if(dsm.length != 1 || dsm[0].comps.length != 1 || dsm[0].comps[0].t != 0 || dsm[0].name != "StrongEncryptionDataSpace" || dsm[0].comps[0].v != "EncryptedPackage") throw new Error("ECMA-376 Encrypted file bad " + f); f = 'StrongEncryptionDataSpace'; @@ -17557,7 +17555,7 @@ var utils = { (function(utils) { utils.consts = utils.consts || {}; -function add_consts(R) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } +function add_consts(R/*Array*/) { R.forEach(function(a){ utils.consts[a[0]] = a[1]; }); } function get_default(x, y, z) { return x[y] != null ? x[y] : (x[y] = z); } @@ -17568,7 +17566,7 @@ function ws_get_cell_stub(ws, R, C) { /* cell address object */ if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R)); /* R and C are 0-based indices */ - return ws_get_cell_stub(ws, encode_cell({r:R,c:C})); + return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0})); } /* find sheet index for given name / validate index */ @@ -17590,7 +17588,8 @@ utils.book_new = function() { /* add a worksheet to the end of a given workbook */ utils.book_append_sheet = function(wb, ws, name) { - if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf("Sheet" + i) == -1) break; + if(!name) for(var i = 1; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break; + if(!name) throw new Error("Too many worksheets"); check_ws_name(name); if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!"); @@ -17604,12 +17603,14 @@ utils.book_set_sheet_visibility = function(wb, sh, vis) { get_default(wb.Workbook,"Sheets",[]); var idx = wb_sheet_idx(wb, sh); + // $FlowIgnore get_default(wb.Workbook.Sheets,idx, {}); switch(vis) { case 0: case 1: case 2: break; default: throw new Error("Bad sheet visibility setting " + vis); } + // $FlowIgnore wb.Workbook.Sheets[idx].Hidden = vis; }; add_consts([ @@ -17629,7 +17630,7 @@ utils.cell_set_hyperlink = function(cell, target, tooltip) { if(!target) { delete cell.l; } else { - cell.l = { Target: target }; + cell.l = ({ Target: target }); if(tooltip) cell.l.Tooltip = tooltip; } return cell; @@ -17678,11 +17679,12 @@ if(has_buf && typeof require != 'undefined') (function() { if(R > r.e.r) return stream.push(null); while(R <= r.e.r) { row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o); - if(row == null) { ++R; continue; } - if(o.strip) row = row.replace(endregex,""); - stream.push(row + RS); ++R; - break; + if(row != null) { + if(o.strip) row = row.replace(endregex,""); + stream.push(row + RS); + break; + } } }; return stream; @@ -17694,7 +17696,7 @@ if(has_buf && typeof require != 'undefined') (function() { var write_html_stream = function(sheet, opts) { var stream = Readable(); - var o = []; + var o = opts == null ? {} : opts; var r = decode_range(sheet['!ref']), cell; o.dense = Array.isArray(sheet); stream.push(HTML_BEGIN);