From 99b513875b1809859c50c8576ac2a0628ccbb22a Mon Sep 17 00:00:00 2001
From: SheetJS <dev@sheetjs.com>
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<string>*/, type/*:number*/, v/*:number*/, s/*:string*/) {
+		var push_value = function po(o/*:Array<string>*/, 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<number>*/ {
 }
 
 /* [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<any>*/, 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<string>*/ = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname="";
+	var stack/*:Array<string>*/ = [], 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<any>*/, 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<any>*/, 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<any>*/, 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 '<?xml': break;
 
@@ -190,7 +190,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
 	if(write_names) {
 		o[o.length] = "<definedNames>";
 		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('<Data ss:Type="String">'), 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(/<!--([^\u2603]*?)-->/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<string>*/ = [];
 	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 "<tr>" + oo.join("") + "</tr>";
 	}
-	function sheet_to_html(ws/*:Worksheet*/, opts)/*:string*/ {
-		var o/*:Array<string>*/ = [];
+	function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ {
+		var o = opts || {};
+		var out/*:Array<string>*/ = [];
 		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 "<html><body><table>" + o.join("") + "</table></body></html>";
+		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
+		return "<html><body><table>" + out.join("") + "</table></body></html>";
 	}
 
 	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<any>*/, 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<any>*/) { 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 = "<html><body><table>";
 	var HTML_END = "</table></body></html>";
 
-	var write_html_stream = function(sheet/*:Worksheet*/, opts) {
+	var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
 		var stream = Readable();
 
-		var o/*:Array<string>*/ = [];
+		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<string>;
-}
-
 type WBWBProps = {
 	Sheets: Array<WBWSProp>;
+	Names?: Array<any>;
 };
 
 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<Array<any> >;
 */
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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MC4wMDAwMDAwML0AJAAKAAEAlwAAAPA/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<string>*/, type/*:number*/, v/*:number*/, s/*:string*/) {
+		var push_value = function po(o/*:Array<string>*/, 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<number>*/ {
 }
 
 /* [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<any>*/, 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<string>*/ = [], e1, e2, type, c, ixti=0, nameidx=0, r, sname="";
+	var stack/*:Array<string>*/ = [], 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<any>*/, 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<any>*/, 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<any>*/, 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 '<?xml': break;
 
@@ -12413,7 +12419,7 @@ function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
 	if(write_names) {
 		o[o.length] = "<definedNames>";
 		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('<Data ss:Type="String">'), 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(/<!--([^\u2603]*?)-->/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<string>*/ = [];
 	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 "<tr>" + oo.join("") + "</tr>";
 	}
-	function sheet_to_html(ws/*:Worksheet*/, opts)/*:string*/ {
-		var o/*:Array<string>*/ = [];
+	function sheet_to_html(ws/*:Worksheet*/, opts/*:Sheet2HTMLOpts*/)/*:string*/ {
+		var o = opts || {};
+		var out/*:Array<string>*/ = [];
 		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 "<html><body><table>" + o.join("") + "</table></body></html>";
+		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
+		return "<html><body><table>" + out.join("") + "</table></body></html>";
 	}
 
 	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<any>*/, 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<any>*/) { 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 = "<html><body><table>";
 	var HTML_END = "</table></body></html>";
 
-	var write_html_stream = function(sheet/*:Worksheet*/, opts) {
+	var write_html_stream = function(sheet/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
 		var stream = Readable();
 
-		var o/*:Array<string>*/ = [];
+		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<any>*/, 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<any>*/, 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<any>*/, 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 "<tr>" + oo.join("") + "</tr>";
 	}
 	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 "<html><body><table>" + o.join("") + "</table></body></html>";
+		for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
+		return "<html><body><table>" + out.join("") + "</table></body></html>";
 	}
 
 	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<any>*/) { 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);