UNPKG

896 kBJavaScriptView Raw
1/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
2/* vim: set ts=2: */
3/*exported XLSX */
4/*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
5var XLSX = {};
6XLSX.version = '0.18.5';
7var current_codepage = 1200, current_ansi = 1252;
8
9var VALID_ANSI = [ 874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000 ];
10/* ECMA-376 Part I 18.4.1 charset to codepage mapping */
11var CS2CP = ({
12 /*::[*/0/*::]*/: 1252, /* ANSI */
13 /*::[*/1/*::]*/: 65001, /* DEFAULT */
14 /*::[*/2/*::]*/: 65001, /* SYMBOL */
15 /*::[*/77/*::]*/: 10000, /* MAC */
16 /*::[*/128/*::]*/: 932, /* SHIFTJIS */
17 /*::[*/129/*::]*/: 949, /* HANGUL */
18 /*::[*/130/*::]*/: 1361, /* JOHAB */
19 /*::[*/134/*::]*/: 936, /* GB2312 */
20 /*::[*/136/*::]*/: 950, /* CHINESEBIG5 */
21 /*::[*/161/*::]*/: 1253, /* GREEK */
22 /*::[*/162/*::]*/: 1254, /* TURKISH */
23 /*::[*/163/*::]*/: 1258, /* VIETNAMESE */
24 /*::[*/177/*::]*/: 1255, /* HEBREW */
25 /*::[*/178/*::]*/: 1256, /* ARABIC */
26 /*::[*/186/*::]*/: 1257, /* BALTIC */
27 /*::[*/204/*::]*/: 1251, /* RUSSIAN */
28 /*::[*/222/*::]*/: 874, /* THAI */
29 /*::[*/238/*::]*/: 1250, /* EASTEUROPE */
30 /*::[*/255/*::]*/: 1252, /* OEM */
31 /*::[*/69/*::]*/: 6969 /* MISC */
32}/*:any*/);
33
34var set_ansi = function(cp/*:number*/) { if(VALID_ANSI.indexOf(cp) == -1) return; current_ansi = CS2CP[0] = cp; };
35function reset_ansi() { set_ansi(1252); }
36
37var set_cp = function(cp/*:number*/) { current_codepage = cp; set_ansi(cp); };
38function reset_cp() { set_cp(1200); reset_ansi(); }
39
40function char_codes(data/*:string*/)/*:Array<number>*/ { var o/*:Array<number>*/ = []; for(var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i); return o; }
41
42function utf16leread(data/*:string*/)/*:string*/ {
43 var o/*:Array<string>*/ = [];
44 for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i) + (data.charCodeAt(2*i+1)<<8));
45 return o.join("");
46}
47function utf16beread(data/*:string*/)/*:string*/ {
48 var o/*:Array<string>*/ = [];
49 for(var i = 0; i < (data.length>>1); ++i) o[i] = String.fromCharCode(data.charCodeAt(2*i+1) + (data.charCodeAt(2*i)<<8));
50 return o.join("");
51}
52
53var debom = function(data/*:string*/)/*:string*/ {
54 var c1 = data.charCodeAt(0), c2 = data.charCodeAt(1);
55 if(c1 == 0xFF && c2 == 0xFE) return utf16leread(data.slice(2));
56 if(c1 == 0xFE && c2 == 0xFF) return utf16beread(data.slice(2));
57 if(c1 == 0xFEFF) return data.slice(1);
58 return data;
59};
60
61var _getchar = function _gc1(x/*:number*/)/*:string*/ { return String.fromCharCode(x); };
62var _getansi = function _ga1(x/*:number*/)/*:string*/ { return String.fromCharCode(x); };
63
64var $cptable;
65function set_cptable(cptable) {
66 $cptable = cptable;
67 set_cp = function(cp/*:number*/) { current_codepage = cp; set_ansi(cp); };
68 debom = function(data/*:string*/) {
69 if(data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) { return $cptable.utils.decode(1200, char_codes(data.slice(2))); }
70 return data;
71 };
72 _getchar = function _gc2(x/*:number*/)/*:string*/ {
73 if(current_codepage === 1200) return String.fromCharCode(x);
74 return $cptable.utils.decode(current_codepage, [x&255,x>>8])[0];
75 };
76 _getansi = function _ga2(x/*:number*/)/*:string*/ {
77 return $cptable.utils.decode(current_ansi, [x])[0];
78 };
79 cpdoit();
80}
81export { set_cptable };
82var DENSE = null;
83var DIF_XL = true;
84var Base64_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
85function Base64_encode(input) {
86 var o = "";
87 var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
88 for (var i = 0; i < input.length; ) {
89 c1 = input.charCodeAt(i++);
90 e1 = c1 >> 2;
91 c2 = input.charCodeAt(i++);
92 e2 = (c1 & 3) << 4 | c2 >> 4;
93 c3 = input.charCodeAt(i++);
94 e3 = (c2 & 15) << 2 | c3 >> 6;
95 e4 = c3 & 63;
96 if (isNaN(c2)) {
97 e3 = e4 = 64;
98 } else if (isNaN(c3)) {
99 e4 = 64;
100 }
101 o += Base64_map.charAt(e1) + Base64_map.charAt(e2) + Base64_map.charAt(e3) + Base64_map.charAt(e4);
102 }
103 return o;
104}
105function Base64_decode(input) {
106 var o = "";
107 var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
108 input = input.replace(/[^\w\+\/\=]/g, "");
109 for (var i = 0; i < input.length; ) {
110 e1 = Base64_map.indexOf(input.charAt(i++));
111 e2 = Base64_map.indexOf(input.charAt(i++));
112 c1 = e1 << 2 | e2 >> 4;
113 o += String.fromCharCode(c1);
114 e3 = Base64_map.indexOf(input.charAt(i++));
115 c2 = (e2 & 15) << 4 | e3 >> 2;
116 if (e3 !== 64) {
117 o += String.fromCharCode(c2);
118 }
119 e4 = Base64_map.indexOf(input.charAt(i++));
120 c3 = (e3 & 3) << 6 | e4;
121 if (e4 !== 64) {
122 o += String.fromCharCode(c3);
123 }
124 }
125 return o;
126}
127var has_buf = /*#__PURE__*/(function() { return typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && !!process.versions.node; })();
128
129var Buffer_from = /*#__PURE__*/(function() {
130 if(typeof Buffer !== 'undefined') {
131 var nbfs = !Buffer.from;
132 if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; }
133 return nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer);
134 }
135 return function() {};
136})();
137
138
139function new_raw_buf(len/*:number*/) {
140 /* jshint -W056 */
141 if(has_buf) return Buffer.alloc ? Buffer.alloc(len) : new Buffer(len);
142 return typeof Uint8Array != "undefined" ? new Uint8Array(len) : new Array(len);
143 /* jshint +W056 */
144}
145
146function new_unsafe_buf(len/*:number*/) {
147 /* jshint -W056 */
148 if(has_buf) return Buffer.allocUnsafe ? Buffer.allocUnsafe(len) : new Buffer(len);
149 return typeof Uint8Array != "undefined" ? new Uint8Array(len) : new Array(len);
150 /* jshint +W056 */
151}
152
153var s2a = function s2a(s/*:string*/)/*:any*/ {
154 if(has_buf) return Buffer_from(s, "binary");
155 return s.split("").map(function(x/*:string*/)/*:number*/{ return x.charCodeAt(0) & 0xff; });
156};
157
158function s2ab(s/*:string*/)/*:any*/ {
159 if(typeof ArrayBuffer === 'undefined') return s2a(s);
160 var buf = new ArrayBuffer(s.length), view = new Uint8Array(buf);
161 for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
162 return buf;
163}
164
165function a2s(data/*:any*/)/*:string*/ {
166 if(Array.isArray(data)) return data.map(function(c) { return String.fromCharCode(c); }).join("");
167 var o/*:Array<string>*/ = []; for(var i = 0; i < data.length; ++i) o[i] = String.fromCharCode(data[i]); return o.join("");
168}
169
170function a2u(data/*:Array<number>*/)/*:Uint8Array*/ {
171 if(typeof Uint8Array === 'undefined') throw new Error("Unsupported");
172 return new Uint8Array(data);
173}
174
175function ab2a(data/*:ArrayBuffer|Uint8Array*/)/*:Array<number>*/ {
176 if(typeof ArrayBuffer == 'undefined') throw new Error("Unsupported");
177 if(data instanceof ArrayBuffer) return ab2a(new Uint8Array(data));
178 /*:: if(data instanceof ArrayBuffer) throw new Error("unreachable"); */
179 var o = new Array(data.length);
180 for(var i = 0; i < data.length; ++i) o[i] = data[i];
181 return o;
182}
183
184var bconcat = has_buf ? function(bufs) { return Buffer.concat(bufs.map(function(buf) { return Buffer.isBuffer(buf) ? buf : Buffer_from(buf); })); } : function(bufs) {
185 if(typeof Uint8Array !== "undefined") {
186 var i = 0, maxlen = 0;
187 for(i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;
188 var o = new Uint8Array(maxlen);
189 var len = 0;
190 for(i = 0, maxlen = 0; i < bufs.length; maxlen += len, ++i) {
191 len = bufs[i].length;
192 if(bufs[i] instanceof Uint8Array) o.set(bufs[i], maxlen);
193 else if(typeof bufs[i] == "string") { throw "wtf"; }
194 else o.set(new Uint8Array(bufs[i]), maxlen);
195 }
196 return o;
197 }
198 return [].concat.apply([], bufs.map(function(buf) { return Array.isArray(buf) ? buf : [].slice.call(buf); }));
199};
200
201function utf8decode(content/*:string*/) {
202 var out = [], widx = 0, L = content.length + 250;
203 var o = new_raw_buf(content.length + 255);
204 for(var ridx = 0; ridx < content.length; ++ridx) {
205 var c = content.charCodeAt(ridx);
206 if(c < 0x80) o[widx++] = c;
207 else if(c < 0x800) {
208 o[widx++] = (192|((c>>6)&31));
209 o[widx++] = (128|(c&63));
210 } else if(c >= 0xD800 && c < 0xE000) {
211 c = (c&1023)+64;
212 var d = content.charCodeAt(++ridx)&1023;
213 o[widx++] = (240|((c>>8)&7));
214 o[widx++] = (128|((c>>2)&63));
215 o[widx++] = (128|((d>>6)&15)|((c&3)<<4));
216 o[widx++] = (128|(d&63));
217 } else {
218 o[widx++] = (224|((c>>12)&15));
219 o[widx++] = (128|((c>>6)&63));
220 o[widx++] = (128|(c&63));
221 }
222 if(widx > L) {
223 out.push(o.slice(0, widx));
224 widx = 0;
225 o = new_raw_buf(65535);
226 L = 65530;
227 }
228 }
229 out.push(o.slice(0, widx));
230 return bconcat(out);
231}
232
233var chr0 = /\u0000/g, chr1 = /[\u0001-\u0006]/g;
234/*::
235declare type Block = any;
236declare type BufArray = {
237 newblk(sz:number):Block;
238 next(sz:number):Block;
239 end():any;
240 push(buf:Block):void;
241};
242
243type RecordHopperCB = {(d:any, Rn:string, RT:number):?boolean;};
244
245type EvertType = {[string]:string};
246type EvertNumType = {[string]:number};
247type EvertArrType = {[string]:Array<string>};
248
249type StringConv = {(string):string};
250
251*/
252/* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */
253/*jshint -W041 */
254function _strrev(x/*:string*/)/*:string*/ { var o = "", i = x.length-1; while(i>=0) o += x.charAt(i--); return o; }
255function pad0(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
256function pad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v;return t.length>=d?t:fill(' ',d-t.length)+t;}
257function rpad_(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:t+fill(' ',d-t.length);}
258function pad0r1(v/*:any*/,d/*:number*/)/*:string*/{var t=""+Math.round(v); return t.length>=d?t:fill('0',d-t.length)+t;}
259function pad0r2(v/*:any*/,d/*:number*/)/*:string*/{var t=""+v; return t.length>=d?t:fill('0',d-t.length)+t;}
260var p2_32 = /*#__PURE__*/Math.pow(2,32);
261function pad0r(v/*:any*/,d/*:number*/)/*:string*/{if(v>p2_32||v<-p2_32) return pad0r1(v,d); var i = Math.round(v); return pad0r2(i,d); }
262/* yes, in 2022 this is still faster than string compare */
263function SSF_isgeneral(s/*:string*/, i/*:?number*/)/*:boolean*/ { i = i || 0; return s.length >= 7 + i && (s.charCodeAt(i)|32) === 103 && (s.charCodeAt(i+1)|32) === 101 && (s.charCodeAt(i+2)|32) === 110 && (s.charCodeAt(i+3)|32) === 101 && (s.charCodeAt(i+4)|32) === 114 && (s.charCodeAt(i+5)|32) === 97 && (s.charCodeAt(i+6)|32) === 108; }
264var days/*:Array<Array<string> >*/ = [
265 ['Sun', 'Sunday'],
266 ['Mon', 'Monday'],
267 ['Tue', 'Tuesday'],
268 ['Wed', 'Wednesday'],
269 ['Thu', 'Thursday'],
270 ['Fri', 'Friday'],
271 ['Sat', 'Saturday']
272];
273var months/*:Array<Array<string> >*/ = [
274 ['J', 'Jan', 'January'],
275 ['F', 'Feb', 'February'],
276 ['M', 'Mar', 'March'],
277 ['A', 'Apr', 'April'],
278 ['M', 'May', 'May'],
279 ['J', 'Jun', 'June'],
280 ['J', 'Jul', 'July'],
281 ['A', 'Aug', 'August'],
282 ['S', 'Sep', 'September'],
283 ['O', 'Oct', 'October'],
284 ['N', 'Nov', 'November'],
285 ['D', 'Dec', 'December']
286];
287function SSF_init_table(t/*:any*/) {
288 if(!t) t = {};
289 t[0]= 'General';
290 t[1]= '0';
291 t[2]= '0.00';
292 t[3]= '#,##0';
293 t[4]= '#,##0.00';
294 t[9]= '0%';
295 t[10]= '0.00%';
296 t[11]= '0.00E+00';
297 t[12]= '# ?/?';
298 t[13]= '# ??/??';
299 t[14]= 'm/d/yy';
300 t[15]= 'd-mmm-yy';
301 t[16]= 'd-mmm';
302 t[17]= 'mmm-yy';
303 t[18]= 'h:mm AM/PM';
304 t[19]= 'h:mm:ss AM/PM';
305 t[20]= 'h:mm';
306 t[21]= 'h:mm:ss';
307 t[22]= 'm/d/yy h:mm';
308 t[37]= '#,##0 ;(#,##0)';
309 t[38]= '#,##0 ;[Red](#,##0)';
310 t[39]= '#,##0.00;(#,##0.00)';
311 t[40]= '#,##0.00;[Red](#,##0.00)';
312 t[45]= 'mm:ss';
313 t[46]= '[h]:mm:ss';
314 t[47]= 'mmss.0';
315 t[48]= '##0.0E+0';
316 t[49]= '@';
317 t[56]= '"上午/下午 "hh"時"mm"分"ss"秒 "';
318 return t;
319}
320/* repeated to satiate webpack */
321var table_fmt = {
322 0: 'General',
323 1: '0',
324 2: '0.00',
325 3: '#,##0',
326 4: '#,##0.00',
327 9: '0%',
328 10: '0.00%',
329 11: '0.00E+00',
330 12: '# ?/?',
331 13: '# ??/??',
332 14: 'm/d/yy',
333 15: 'd-mmm-yy',
334 16: 'd-mmm',
335 17: 'mmm-yy',
336 18: 'h:mm AM/PM',
337 19: 'h:mm:ss AM/PM',
338 20: 'h:mm',
339 21: 'h:mm:ss',
340 22: 'm/d/yy h:mm',
341 37: '#,##0 ;(#,##0)',
342 38: '#,##0 ;[Red](#,##0)',
343 39: '#,##0.00;(#,##0.00)',
344 40: '#,##0.00;[Red](#,##0.00)',
345 45: 'mm:ss',
346 46: '[h]:mm:ss',
347 47: 'mmss.0',
348 48: '##0.0E+0',
349 49: '@',
350 56: '"上午/下午 "hh"時"mm"分"ss"秒 "'
351};
352
353/* Defaults determined by systematically testing in Excel 2019 */
354
355/* These formats appear to default to other formats in the table */
356var SSF_default_map = {
357 5: 37, 6: 38, 7: 39, 8: 40, // 5 -> 37 ... 8 -> 40
358
359 23: 0, 24: 0, 25: 0, 26: 0, // 23 -> 0 ... 26 -> 0
360
361 27: 14, 28: 14, 29: 14, 30: 14, 31: 14, // 27 -> 14 ... 31 -> 14
362
363 50: 14, 51: 14, 52: 14, 53: 14, 54: 14, // 50 -> 14 ... 58 -> 14
364 55: 14, 56: 14, 57: 14, 58: 14,
365 59: 1, 60: 2, 61: 3, 62: 4, // 59 -> 1 ... 62 -> 4
366
367 67: 9, 68: 10, // 67 -> 9 ... 68 -> 10
368 69: 12, 70: 13, 71: 14, // 69 -> 12 ... 71 -> 14
369 72: 14, 73: 15, 74: 16, 75: 17, // 72 -> 14 ... 75 -> 17
370 76: 20, 77: 21, 78: 22, // 76 -> 20 ... 78 -> 22
371 79: 45, 80: 46, 81: 47, // 79 -> 45 ... 81 -> 47
372 82: 0 // 82 -> 0 ... 65536 -> 0 (omitted)
373};
374
375
376/* These formats technically refer to Accounting formats with no equivalent */
377var SSF_default_str = {
378 // 5 -- Currency, 0 decimal, black negative
379 5: '"$"#,##0_);\\("$"#,##0\\)',
380 63: '"$"#,##0_);\\("$"#,##0\\)',
381
382 // 6 -- Currency, 0 decimal, red negative
383 6: '"$"#,##0_);[Red]\\("$"#,##0\\)',
384 64: '"$"#,##0_);[Red]\\("$"#,##0\\)',
385
386 // 7 -- Currency, 2 decimal, black negative
387 7: '"$"#,##0.00_);\\("$"#,##0.00\\)',
388 65: '"$"#,##0.00_);\\("$"#,##0.00\\)',
389
390 // 8 -- Currency, 2 decimal, red negative
391 8: '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
392 66: '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
393
394 // 41 -- Accounting, 0 decimal, No Symbol
395 41: '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)',
396
397 // 42 -- Accounting, 0 decimal, $ Symbol
398 42: '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)',
399
400 // 43 -- Accounting, 2 decimal, No Symbol
401 43: '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)',
402
403 // 44 -- Accounting, 2 decimal, $ Symbol
404 44: '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'
405};
406
407function SSF_frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
408 var sgn = x < 0 ? -1 : 1;
409 var B = x * sgn;
410 var P_2 = 0, P_1 = 1, P = 0;
411 var Q_2 = 1, Q_1 = 0, Q = 0;
412 var A = Math.floor(B);
413 while(Q_1 < D) {
414 A = Math.floor(B);
415 P = A * P_1 + P_2;
416 Q = A * Q_1 + Q_2;
417 if((B - A) < 0.00000005) break;
418 B = 1 / (B - A);
419 P_2 = P_1; P_1 = P;
420 Q_2 = Q_1; Q_1 = Q;
421 }
422 if(Q > D) { if(Q_1 > D) { Q = Q_2; P = P_2; } else { Q = Q_1; P = P_1; } }
423 if(!mixed) return [0, sgn * P, Q];
424 var q = Math.floor(sgn * P/Q);
425 return [q, sgn*P - q*Q, Q];
426}
427function SSF_parse_date_code(v/*:number*/,opts/*:?any*/,b2/*:?boolean*/) {
428 if(v > 2958465 || v < 0) return null;
429 var date = (v|0), time = Math.floor(86400 * (v - date)), dow=0;
430 var dout=[];
431 var out={D:date, T:time, u:86400*(v-date)-time,y:0,m:0,d:0,H:0,M:0,S:0,q:0};
432 if(Math.abs(out.u) < 1e-6) out.u = 0;
433 if(opts && opts.date1904) date += 1462;
434 if(out.u > 0.9999) {
435 out.u = 0;
436 if(++time == 86400) { out.T = time = 0; ++date; ++out.D; }
437 }
438 if(date === 60) {dout = b2 ? [1317,10,29] : [1900,2,29]; dow=3;}
439 else if(date === 0) {dout = b2 ? [1317,8,29] : [1900,1,0]; dow=6;}
440 else {
441 if(date > 60) --date;
442 /* 1 = Jan 1 1900 in Gregorian */
443 var d = new Date(1900, 0, 1);
444 d.setDate(d.getDate() + date - 1);
445 dout = [d.getFullYear(), d.getMonth()+1,d.getDate()];
446 dow = d.getDay();
447 if(date < 60) dow = (dow + 6) % 7;
448 if(b2) dow = SSF_fix_hijri(d, dout);
449 }
450 out.y = dout[0]; out.m = dout[1]; out.d = dout[2];
451 out.S = time % 60; time = Math.floor(time / 60);
452 out.M = time % 60; time = Math.floor(time / 60);
453 out.H = time;
454 out.q = dow;
455 return out;
456}
457var SSFbasedate = /*#__PURE__*/new Date(1899, 11, 31, 0, 0, 0);
458var SSFdnthresh = /*#__PURE__*/SSFbasedate.getTime();
459var SSFbase1904 = /*#__PURE__*/new Date(1900, 2, 1, 0, 0, 0);
460function datenum_local(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
461 var epoch = /*#__PURE__*/v.getTime();
462 if(date1904) epoch -= 1461*24*60*60*1000;
463 else if(v >= SSFbase1904) epoch += 24*60*60*1000;
464 return (epoch - (SSFdnthresh + (/*#__PURE__*/v.getTimezoneOffset() - /*#__PURE__*/SSFbasedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000);
465}
466/* ECMA-376 18.8.30 numFmt*/
467/* Note: `toPrecision` uses standard form when prec > E and E >= -6 */
468/* exponent >= -9 and <= 9 */
469function SSF_strip_decimal(o/*:string*/)/*:string*/ {
470 return (o.indexOf(".") == -1) ? o : o.replace(/(?:\.0*|(\.\d*[1-9])0+)$/, "$1");
471}
472
473/* General Exponential always shows 2 digits exp and trims the mantissa */
474function SSF_normalize_exp(o/*:string*/)/*:string*/ {
475 if(o.indexOf("E") == -1) return o;
476 return o.replace(/(?:\.0*|(\.\d*[1-9])0+)[Ee]/,"$1E").replace(/(E[+-])(\d)$/,"$10$2");
477}
478
479/* exponent >= -9 and <= 9 */
480function SSF_small_exp(v/*:number*/)/*:string*/ {
481 var w = (v<0?12:11);
482 var o = SSF_strip_decimal(v.toFixed(12)); if(o.length <= w) return o;
483 o = v.toPrecision(10); if(o.length <= w) return o;
484 return v.toExponential(5);
485}
486
487/* exponent >= 11 or <= -10 likely exponential */
488function SSF_large_exp(v/*:number*/)/*:string*/ {
489 var o = SSF_strip_decimal(v.toFixed(11));
490 return (o.length > (v<0?12:11) || o === "0" || o === "-0") ? v.toPrecision(6) : o;
491}
492
493function SSF_general_num(v/*:number*/)/*:string*/ {
494 var V = Math.floor(Math.log(Math.abs(v))*Math.LOG10E), o;
495
496 if(V >= -4 && V <= -1) o = v.toPrecision(10+V);
497 else if(Math.abs(V) <= 9) o = SSF_small_exp(v);
498 else if(V === 10) o = v.toFixed(10).substr(0,12);
499 else o = SSF_large_exp(v);
500
501 return SSF_strip_decimal(SSF_normalize_exp(o.toUpperCase()));
502}
503
504
505/*
506 "General" rules:
507 - text is passed through ("@")
508 - booleans are rendered as TRUE/FALSE
509 - "up to 11 characters" displayed for numbers
510 - Default date format (code 14) used for Dates
511
512 The longest 32-bit integer text is "-2147483648", exactly 11 chars
513 TODO: technically the display depends on the width of the cell
514*/
515function SSF_general(v/*:any*/, opts/*:any*/) {
516 switch(typeof v) {
517 case 'string': return v;
518 case 'boolean': return v ? "TRUE" : "FALSE";
519 case 'number': return (v|0) === v ? v.toString(10) : SSF_general_num(v);
520 case 'undefined': return "";
521 case 'object':
522 if(v == null) return "";
523 if(v instanceof Date) return SSF_format(14, datenum_local(v, opts && opts.date1904), opts);
524 }
525 throw new Error("unsupported value in General format: " + v);
526}
527
528function SSF_fix_hijri(date/*:Date*/, o/*:[number, number, number]*/) {
529 /* TODO: properly adjust y/m/d and */
530 o[0] -= 581;
531 var dow = date.getDay();
532 if(date < 60) dow = (dow + 6) % 7;
533 return dow;
534}
535//var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
536function SSF_write_date(type/*:number*/, fmt/*:string*/, val, ss0/*:?number*/)/*:string*/ {
537 var o="", ss=0, tt=0, y = val.y, out, outl = 0;
538 switch(type) {
539 case 98: /* 'b' buddhist year */
540 y = val.y + 543;
541 /* falls through */
542 case 121: /* 'y' year */
543 switch(fmt.length) {
544 case 1: case 2: out = y % 100; outl = 2; break;
545 default: out = y % 10000; outl = 4; break;
546 } break;
547 case 109: /* 'm' month */
548 switch(fmt.length) {
549 case 1: case 2: out = val.m; outl = fmt.length; break;
550 case 3: return months[val.m-1][1];
551 case 5: return months[val.m-1][0];
552 default: return months[val.m-1][2];
553 } break;
554 case 100: /* 'd' day */
555 switch(fmt.length) {
556 case 1: case 2: out = val.d; outl = fmt.length; break;
557 case 3: return days[val.q][0];
558 default: return days[val.q][1];
559 } break;
560 case 104: /* 'h' 12-hour */
561 switch(fmt.length) {
562 case 1: case 2: out = 1+(val.H+11)%12; outl = fmt.length; break;
563 default: throw 'bad hour format: ' + fmt;
564 } break;
565 case 72: /* 'H' 24-hour */
566 switch(fmt.length) {
567 case 1: case 2: out = val.H; outl = fmt.length; break;
568 default: throw 'bad hour format: ' + fmt;
569 } break;
570 case 77: /* 'M' minutes */
571 switch(fmt.length) {
572 case 1: case 2: out = val.M; outl = fmt.length; break;
573 default: throw 'bad minute format: ' + fmt;
574 } break;
575 case 115: /* 's' seconds */
576 if(fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000') throw 'bad second format: ' + fmt;
577 if(val.u === 0 && (fmt == "s" || fmt == "ss")) return pad0(val.S, fmt.length);
578 /*::if(!ss0) ss0 = 0; */
579 if(ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;
580 else tt = ss0 === 1 ? 10 : 1;
581 ss = Math.round((tt)*(val.S + val.u));
582 if(ss >= 60*tt) ss = 0;
583 if(fmt === 's') return ss === 0 ? "0" : ""+ss/tt;
584 o = pad0(ss,2 + ss0);
585 if(fmt === 'ss') return o.substr(0,2);
586 return "." + o.substr(2,fmt.length-1);
587 case 90: /* 'Z' absolute time */
588 switch(fmt) {
589 case '[h]': case '[hh]': out = val.D*24+val.H; break;
590 case '[m]': case '[mm]': out = (val.D*24+val.H)*60+val.M; break;
591 case '[s]': case '[ss]': out = ((val.D*24+val.H)*60+val.M)*60+Math.round(val.S+val.u); break;
592 default: throw 'bad abstime format: ' + fmt;
593 } outl = fmt.length === 3 ? 1 : 2; break;
594 case 101: /* 'e' era */
595 out = y; outl = 1; break;
596 }
597 var outstr = outl > 0 ? pad0(out, outl) : "";
598 return outstr;
599}
600
601
602/*jshint -W086 */
603/*jshint +W086 */
604function commaify(s/*:string*/)/*:string*/ {
605 var w = 3;
606 if(s.length <= w) return s;
607 var j = (s.length % w), o = s.substr(0,j);
608 for(; j!=s.length; j+=w) o+=(o.length > 0 ? "," : "") + s.substr(j,w);
609 return o;
610}
611var pct1 = /%/g;
612function write_num_pct(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/{
613 var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length;
614 return write_num(type, sfmt, val * Math.pow(10,2*mul)) + fill("%",mul);
615}
616
617function write_num_cm(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/{
618 var idx = fmt.length - 1;
619 while(fmt.charCodeAt(idx-1) === 44) --idx;
620 return write_num(type, fmt.substr(0,idx), val / Math.pow(10,3*(fmt.length-idx)));
621}
622
623function write_num_exp(fmt/*:string*/, val/*:number*/)/*:string*/{
624 var o/*:string*/;
625 var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
626 if(fmt.match(/^#+0.0E\+0$/)) {
627 if(val == 0) return "0.0E+0";
628 else if(val < 0) return "-" + write_num_exp(fmt, -val);
629 var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
630 var ee = Math.floor(Math.log(val)*Math.LOG10E)%period;
631 if(ee < 0) ee += period;
632 o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
633 if(o.indexOf("e") === -1) {
634 var fakee = Math.floor(Math.log(val)*Math.LOG10E);
635 if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
636 else o += "E+" + (fakee - ee);
637 while(o.substr(0,2) === "0.") {
638 o = o.charAt(0) + o.substr(2,period) + "." + o.substr(2+period);
639 o = o.replace(/^0+([1-9])/,"$1").replace(/^0+\./,"0.");
640 }
641 o = o.replace(/\+-/,"-");
642 }
643 o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
644 } else o = val.toExponential(idx);
645 if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o.charAt(o.length-1);
646 if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
647 return o.replace("e","E");
648}
649var frac1 = /# (\?+)( ?)\/( ?)(\d+)/;
650function write_num_f1(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:string*/ {
651 var den = parseInt(r[4],10), rr = Math.round(aval * den), base = Math.floor(rr/den);
652 var myn = (rr - base*den), myd = den;
653 return sign + (base === 0 ? "" : ""+base) + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad_(myn,r[1].length) + r[2] + "/" + r[3] + pad0(myd,r[4].length));
654}
655function write_num_f2(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:string*/ {
656 return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
657}
658var dec1 = /^#*0*\.([0#]+)/;
659var closeparen = /\).*[0#]/;
660var phone = /\(###\) ###\\?-####/;
661function hashq(str/*:string*/)/*:string*/ {
662 var o = "", cc;
663 for(var i = 0; i != str.length; ++i) switch((cc=str.charCodeAt(i))) {
664 case 35: break;
665 case 63: o+= " "; break;
666 case 48: o+= "0"; break;
667 default: o+= String.fromCharCode(cc);
668 }
669 return o;
670}
671function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); }
672function dec(val/*:number*/, d/*:number*/)/*:number*/ {
673 var _frac = val - Math.floor(val), dd = Math.pow(10,d);
674 if (d < ('' + Math.round(_frac * dd)).length) return 0;
675 return Math.round(_frac * dd);
676}
677function carry(val/*:number*/, d/*:number*/)/*:number*/ {
678 if (d < ('' + Math.round((val-Math.floor(val))*Math.pow(10,d))).length) {
679 return 1;
680 }
681 return 0;
682}
683function flr(val/*:number*/)/*:string*/ {
684 if(val < 2147483647 && val > -2147483648) return ""+(val >= 0 ? (val|0) : (val-1|0));
685 return ""+Math.floor(val);
686}
687function write_num_flt(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ {
688 if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
689 var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
690 if(val >= 0) return write_num_flt('n', ffmt, val);
691 return '(' + write_num_flt('n', ffmt, -val) + ')';
692 }
693 if(fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm(type, fmt, val);
694 if(fmt.indexOf('%') !== -1) return write_num_pct(type, fmt, val);
695 if(fmt.indexOf('E') !== -1) return write_num_exp(fmt, val);
696 if(fmt.charCodeAt(0) === 36) return "$"+write_num_flt(type,fmt.substr(fmt.charAt(1)==' '?2:1),val);
697 var o;
698 var r/*:?Array<string>*/, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
699 if(fmt.match(/^00+$/)) return sign + pad0r(aval,fmt.length);
700 if(fmt.match(/^[#?]+$/)) {
701 o = pad0r(val,0); if(o === "0") o = "";
702 return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o;
703 }
704 if((r = fmt.match(frac1))) return write_num_f1(r, aval, sign);
705 if(fmt.match(/^#+0+$/)) return sign + pad0r(aval,fmt.length - fmt.indexOf("0"));
706 if((r = fmt.match(dec1))) {
707 o = rnd(val, r[1].length).replace(/^([^\.]+)$/,"$1."+hashq(r[1])).replace(/\.$/,"."+hashq(r[1])).replace(/\.(\d*)$/,function($$, $1) { return "." + $1 + fill("0", hashq(/*::(*/r/*::||[""])*/[1]).length-$1.length); });
708 return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
709 }
710 fmt = fmt.replace(/^#+([0.])/, "$1");
711 if((r = fmt.match(/^(0*)\.(#*)$/))) {
712 return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
713 }
714 if((r = fmt.match(/^#{1,3},##0(\.?)$/))) return sign + commaify(pad0r(aval,0));
715 if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
716 return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(""+(Math.floor(val) + carry(val, r[1].length))) + "." + pad0(dec(val, r[1].length),r[1].length);
717 }
718 if((r = fmt.match(/^#,#*,#0/))) return write_num_flt(type,fmt.replace(/^#,#*,/,""),val);
719 if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/))) {
720 o = _strrev(write_num_flt(type, fmt.replace(/[\\-]/g,""), val));
721 ri = 0;
722 return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o.charAt(ri++):x==='0'?'0':"";}));
723 }
724 if(fmt.match(phone)) {
725 o = write_num_flt(type, "##########", val);
726 return "(" + o.substr(0,3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
727 }
728 var oa = "";
729 if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))) {
730 ri = Math.min(/*::String(*/r[4]/*::)*/.length,7);
731 ff = SSF_frac(aval, Math.pow(10,ri)-1, false);
732 o = "" + sign;
733 oa = write_num("n", /*::String(*/r[1]/*::)*/, ff[1]);
734 if(oa.charAt(oa.length-1) == " ") oa = oa.substr(0,oa.length-1) + "0";
735 o += oa + /*::String(*/r[2]/*::)*/ + "/" + /*::String(*/r[3]/*::)*/;
736 oa = rpad_(ff[2],ri);
737 if(oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length-oa.length)) + oa;
738 o += oa;
739 return o;
740 }
741 if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/))) {
742 ri = Math.min(Math.max(r[1].length, r[4].length),7);
743 ff = SSF_frac(aval, Math.pow(10,ri)-1, true);
744 return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1],ri) + r[2] + "/" + r[3] + rpad_(ff[2],ri): fill(" ", 2*ri+1 + r[2].length + r[3].length));
745 }
746 if((r = fmt.match(/^[#0?]+$/))) {
747 o = pad0r(val, 0);
748 if(fmt.length <= o.length) return o;
749 return hashq(fmt.substr(0,fmt.length-o.length)) + o;
750 }
751 if((r = fmt.match(/^([#0?]+)\.([#0]+)$/))) {
752 o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
753 ri = o.indexOf(".");
754 var lres = fmt.indexOf(".") - ri, rres = fmt.length - o.length - lres;
755 return hashq(fmt.substr(0,lres) + o + fmt.substr(fmt.length-rres));
756 }
757 if((r = fmt.match(/^00,000\.([#0]*0)$/))) {
758 ri = dec(val, r[1].length);
759 return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(ri,r[1].length);
760 }
761 switch(fmt) {
762 case "###,##0.00": return write_num_flt(type, "#,##0.00", val);
763 case "###,###":
764 case "##,###":
765 case "#,###": var x = commaify(pad0r(aval,0)); return x !== "0" ? sign + x : "";
766 case "###,###.00": return write_num_flt(type, "###,##0.00",val).replace(/^0\./,".");
767 case "#,###.00": return write_num_flt(type, "#,##0.00",val).replace(/^0\./,".");
768 default:
769 }
770 throw new Error("unsupported format |" + fmt + "|");
771}
772function write_num_cm2(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/{
773 var idx = fmt.length - 1;
774 while(fmt.charCodeAt(idx-1) === 44) --idx;
775 return write_num(type, fmt.substr(0,idx), val / Math.pow(10,3*(fmt.length-idx)));
776}
777function write_num_pct2(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/{
778 var sfmt = fmt.replace(pct1,""), mul = fmt.length - sfmt.length;
779 return write_num(type, sfmt, val * Math.pow(10,2*mul)) + fill("%",mul);
780}
781function write_num_exp2(fmt/*:string*/, val/*:number*/)/*:string*/{
782 var o/*:string*/;
783 var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
784 if(fmt.match(/^#+0.0E\+0$/)) {
785 if(val == 0) return "0.0E+0";
786 else if(val < 0) return "-" + write_num_exp2(fmt, -val);
787 var period = fmt.indexOf("."); if(period === -1) period=fmt.indexOf('E');
788 var ee = Math.floor(Math.log(val)*Math.LOG10E)%period;
789 if(ee < 0) ee += period;
790 o = (val/Math.pow(10,ee)).toPrecision(idx+1+(period+ee)%period);
791 if(!o.match(/[Ee]/)) {
792 var fakee = Math.floor(Math.log(val)*Math.LOG10E);
793 if(o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length+ee);
794 else o += "E+" + (fakee - ee);
795 o = o.replace(/\+-/,"-");
796 }
797 o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/,function($$,$1,$2,$3) { return $1 + $2 + $3.substr(0,(period+ee)%period) + "." + $3.substr(ee) + "E"; });
798 } else o = val.toExponential(idx);
799 if(fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0,o.length-1) + "0" + o.charAt(o.length-1);
800 if(fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/,"e");
801 return o.replace("e","E");
802}
803function write_num_int(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ {
804 if(type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
805 var ffmt = fmt.replace(/\( */,"").replace(/ \)/,"").replace(/\)/,"");
806 if(val >= 0) return write_num_int('n', ffmt, val);
807 return '(' + write_num_int('n', ffmt, -val) + ')';
808 }
809 if(fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm2(type, fmt, val);
810 if(fmt.indexOf('%') !== -1) return write_num_pct2(type, fmt, val);
811 if(fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val);
812 if(fmt.charCodeAt(0) === 36) return "$"+write_num_int(type,fmt.substr(fmt.charAt(1)==' '?2:1),val);
813 var o;
814 var r/*:?Array<string>*/, ri, ff, aval = Math.abs(val), sign = val < 0 ? "-" : "";
815 if(fmt.match(/^00+$/)) return sign + pad0(aval,fmt.length);
816 if(fmt.match(/^[#?]+$/)) {
817 o = (""+val); if(val === 0) o = "";
818 return o.length > fmt.length ? o : hashq(fmt.substr(0,fmt.length-o.length)) + o;
819 }
820 if((r = fmt.match(frac1))) return write_num_f2(r, aval, sign);
821 if(fmt.match(/^#+0+$/)) return sign + pad0(aval,fmt.length - fmt.indexOf("0"));
822 if((r = fmt.match(dec1))) {
823 /*:: if(!Array.isArray(r)) throw new Error("unreachable"); */
824 o = (""+val).replace(/^([^\.]+)$/,"$1."+hashq(r[1])).replace(/\.$/,"."+hashq(r[1]));
825 o = o.replace(/\.(\d*)$/,function($$, $1) {
826 /*:: if(!Array.isArray(r)) throw new Error("unreachable"); */
827 return "." + $1 + fill("0", hashq(r[1]).length-$1.length); });
828 return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./,".");
829 }
830 fmt = fmt.replace(/^#+([0.])/, "$1");
831 if((r = fmt.match(/^(0*)\.(#*)$/))) {
832 return sign + (""+aval).replace(/\.(\d*[1-9])0*$/,".$1").replace(/^(-?\d*)$/,"$1.").replace(/^0\./,r[1].length?"0.":".");
833 }
834 if((r = fmt.match(/^#{1,3},##0(\.?)$/))) return sign + commaify((""+aval));
835 if((r = fmt.match(/^#,##0\.([#0]*0)$/))) {
836 return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify((""+val)) + "." + fill('0',r[1].length);
837 }
838 if((r = fmt.match(/^#,#*,#0/))) return write_num_int(type,fmt.replace(/^#,#*,/,""),val);
839 if((r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/))) {
840 o = _strrev(write_num_int(type, fmt.replace(/[\\-]/g,""), val));
841 ri = 0;
842 return _strrev(_strrev(fmt.replace(/\\/g,"")).replace(/[0#]/g,function(x){return ri<o.length?o.charAt(ri++):x==='0'?'0':"";}));
843 }
844 if(fmt.match(phone)) {
845 o = write_num_int(type, "##########", val);
846 return "(" + o.substr(0,3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
847 }
848 var oa = "";
849 if((r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/))) {
850 ri = Math.min(/*::String(*/r[4]/*::)*/.length,7);
851 ff = SSF_frac(aval, Math.pow(10,ri)-1, false);
852 o = "" + sign;
853 oa = write_num("n", /*::String(*/r[1]/*::)*/, ff[1]);
854 if(oa.charAt(oa.length-1) == " ") oa = oa.substr(0,oa.length-1) + "0";
855 o += oa + /*::String(*/r[2]/*::)*/ + "/" + /*::String(*/r[3]/*::)*/;
856 oa = rpad_(ff[2],ri);
857 if(oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length-oa.length)) + oa;
858 o += oa;
859 return o;
860 }
861 if((r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/))) {
862 ri = Math.min(Math.max(r[1].length, r[4].length),7);
863 ff = SSF_frac(aval, Math.pow(10,ri)-1, true);
864 return sign + (ff[0]||(ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1],ri) + r[2] + "/" + r[3] + rpad_(ff[2],ri): fill(" ", 2*ri+1 + r[2].length + r[3].length));
865 }
866 if((r = fmt.match(/^[#0?]+$/))) {
867 o = "" + val;
868 if(fmt.length <= o.length) return o;
869 return hashq(fmt.substr(0,fmt.length-o.length)) + o;
870 }
871 if((r = fmt.match(/^([#0]+)\.([#0]+)$/))) {
872 o = "" + val.toFixed(Math.min(r[2].length,10)).replace(/([^0])0+$/,"$1");
873 ri = o.indexOf(".");
874 var lres = fmt.indexOf(".") - ri, rres = fmt.length - o.length - lres;
875 return hashq(fmt.substr(0,lres) + o + fmt.substr(fmt.length-rres));
876 }
877 if((r = fmt.match(/^00,000\.([#0]*0)$/))) {
878 return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify(""+val).replace(/^\d,\d{3}$/,"0$&").replace(/^\d*$/,function($$) { return "00," + ($$.length < 3 ? pad0(0,3-$$.length) : "") + $$; }) + "." + pad0(0,r[1].length);
879 }
880 switch(fmt) {
881 case "###,###":
882 case "##,###":
883 case "#,###": var x = commaify(""+aval); return x !== "0" ? sign + x : "";
884 default:
885 if(fmt.match(/\.[0#?]*$/)) return write_num_int(type, fmt.slice(0,fmt.lastIndexOf(".")), val) + hashq(fmt.slice(fmt.lastIndexOf(".")));
886 }
887 throw new Error("unsupported format |" + fmt + "|");
888}
889function write_num(type/*:string*/, fmt/*:string*/, val/*:number*/)/*:string*/ {
890 return (val|0) === val ? write_num_int(type, fmt, val) : write_num_flt(type, fmt, val);
891}
892function SSF_split_fmt(fmt/*:string*/)/*:Array<string>*/ {
893 var out/*:Array<string>*/ = [];
894 var in_str = false/*, cc*/;
895 for(var i = 0, j = 0; i < fmt.length; ++i) switch((/*cc=*/fmt.charCodeAt(i))) {
896 case 34: /* '"' */
897 in_str = !in_str; break;
898 case 95: case 42: case 92: /* '_' '*' '\\' */
899 ++i; break;
900 case 59: /* ';' */
901 out[out.length] = fmt.substr(j,i-j);
902 j = i+1;
903 }
904 out[out.length] = fmt.substr(j);
905 if(in_str === true) throw new Error("Format |" + fmt + "| unterminated string ");
906 return out;
907}
908
909var SSF_abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/;
910function fmt_is_date(fmt/*:string*/)/*:boolean*/ {
911 var i = 0, /*cc = 0,*/ c = "", o = "";
912 while(i < fmt.length) {
913 switch((c = fmt.charAt(i))) {
914 case 'G': if(SSF_isgeneral(fmt, i)) i+= 6; i++; break;
915 case '"': for(;(/*cc=*/fmt.charCodeAt(++i)) !== 34 && i < fmt.length;){/*empty*/} ++i; break;
916 case '\\': i+=2; break;
917 case '_': i+=2; break;
918 case '@': ++i; break;
919 case 'B': case 'b':
920 if(fmt.charAt(i+1) === "1" || fmt.charAt(i+1) === "2") return true;
921 /* falls through */
922 case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E':
923 /* falls through */
924 case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g': return true;
925 case 'A': case 'a': case '上':
926 if(fmt.substr(i, 3).toUpperCase() === "A/P") return true;
927 if(fmt.substr(i, 5).toUpperCase() === "AM/PM") return true;
928 if(fmt.substr(i, 5).toUpperCase() === "上午/下午") return true;
929 ++i; break;
930 case '[':
931 o = c;
932 while(fmt.charAt(i++) !== ']' && i < fmt.length) o += fmt.charAt(i);
933 if(o.match(SSF_abstime)) return true;
934 break;
935 case '.':
936 /* falls through */
937 case '0': case '#':
938 while(i < fmt.length && ("0#?.,E+-%".indexOf(c=fmt.charAt(++i)) > -1 || (c=='\\' && fmt.charAt(i+1) == "-" && "0#".indexOf(fmt.charAt(i+2))>-1))){/* empty */}
939 break;
940 case '?': while(fmt.charAt(++i) === c){/* empty */} break;
941 case '*': ++i; if(fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i; break;
942 case '(': case ')': ++i; break;
943 case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
944 while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1){/* empty */} break;
945 case ' ': ++i; break;
946 default: ++i; break;
947 }
948 }
949 return false;
950}
951
952function eval_fmt(fmt/*:string*/, v/*:any*/, opts/*:any*/, flen/*:number*/) {
953 var out = [], o = "", i = 0, c = "", lst='t', dt, j, cc;
954 var hr='H';
955 /* Tokenize */
956 while(i < fmt.length) {
957 switch((c = fmt.charAt(i))) {
958 case 'G': /* General */
959 if(!SSF_isgeneral(fmt, i)) throw new Error('unrecognized character ' + c + ' in ' +fmt);
960 out[out.length] = {t:'G', v:'General'}; i+=7; break;
961 case '"': /* Literal text */
962 for(o="";(cc=fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) o += String.fromCharCode(cc);
963 out[out.length] = {t:'t', v:o}; ++i; break;
964 case '\\': var w = fmt.charAt(++i), t = (w === "(" || w === ")") ? w : 't';
965 out[out.length] = {t:t, v:w}; ++i; break;
966 case '_': out[out.length] = {t:'t', v:" "}; i+=2; break;
967 case '@': /* Text Placeholder */
968 out[out.length] = {t:'T', v:v}; ++i; break;
969 case 'B': case 'b':
970 if(fmt.charAt(i+1) === "1" || fmt.charAt(i+1) === "2") {
971 if(dt==null) { dt=SSF_parse_date_code(v, opts, fmt.charAt(i+1) === "2"); if(dt==null) return ""; }
972 out[out.length] = {t:'X', v:fmt.substr(i,2)}; lst = c; i+=2; break;
973 }
974 /* falls through */
975 case 'M': case 'D': case 'Y': case 'H': case 'S': case 'E':
976 c = c.toLowerCase();
977 /* falls through */
978 case 'm': case 'd': case 'y': case 'h': case 's': case 'e': case 'g':
979 if(v < 0) return "";
980 if(dt==null) { dt=SSF_parse_date_code(v, opts); if(dt==null) return ""; }
981 o = c; while(++i < fmt.length && fmt.charAt(i).toLowerCase() === c) o+=c;
982 if(c === 'm' && lst.toLowerCase() === 'h') c = 'M';
983 if(c === 'h') c = hr;
984 out[out.length] = {t:c, v:o}; lst = c; break;
985 case 'A': case 'a': case '上':
986 var q={t:c, v:c};
987 if(dt==null) dt=SSF_parse_date_code(v, opts);
988 if(fmt.substr(i, 3).toUpperCase() === "A/P") { if(dt!=null) q.v = dt.H >= 12 ? "P" : "A"; q.t = 'T'; hr='h';i+=3;}
989 else if(fmt.substr(i,5).toUpperCase() === "AM/PM") { if(dt!=null) q.v = dt.H >= 12 ? "PM" : "AM"; q.t = 'T'; i+=5; hr='h'; }
990 else if(fmt.substr(i,5).toUpperCase() === "上午/下午") { if(dt!=null) q.v = dt.H >= 12 ? "下午" : "上午"; q.t = 'T'; i+=5; hr='h'; }
991 else { q.t = "t"; ++i; }
992 if(dt==null && q.t === 'T') return "";
993 out[out.length] = q; lst = c; break;
994 case '[':
995 o = c;
996 while(fmt.charAt(i++) !== ']' && i < fmt.length) o += fmt.charAt(i);
997 if(o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
998 if(o.match(SSF_abstime)) {
999 if(dt==null) { dt=SSF_parse_date_code(v, opts); if(dt==null) return ""; }
1000 out[out.length] = {t:'Z', v:o.toLowerCase()};
1001 lst = o.charAt(1);
1002 } else if(o.indexOf("$") > -1) {
1003 o = (o.match(/\$([^-\[\]]*)/)||[])[1]||"$";
1004 if(!fmt_is_date(fmt)) out[out.length] = {t:'t',v:o};
1005 }
1006 break;
1007 /* Numbers */
1008 case '.':
1009 if(dt != null) {
1010 o = c; while(++i < fmt.length && (c=fmt.charAt(i)) === "0") o += c;
1011 out[out.length] = {t:'s', v:o}; break;
1012 }
1013 /* falls through */
1014 case '0': case '#':
1015 o = c; while(++i < fmt.length && "0#?.,E+-%".indexOf(c=fmt.charAt(i)) > -1) o += c;
1016 out[out.length] = {t:'n', v:o}; break;
1017 case '?':
1018 o = c; while(fmt.charAt(++i) === c) o+=c;
1019 out[out.length] = {t:c, v:o}; lst = c; break;
1020 case '*': ++i; if(fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i; break; // **
1021 case '(': case ')': out[out.length] = {t:(flen===1?'t':c), v:c}; ++i; break;
1022 case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
1023 o = c; while(i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o+=fmt.charAt(i);
1024 out[out.length] = {t:'D', v:o}; break;
1025 case ' ': out[out.length] = {t:c, v:c}; ++i; break;
1026 case '$': out[out.length] = {t:'t', v:'$'}; ++i; break;
1027 default:
1028 if(",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);
1029 out[out.length] = {t:'t', v:c}; ++i; break;
1030 }
1031 }
1032
1033 /* Scan for date/time parts */
1034 var bt = 0, ss0 = 0, ssm;
1035 for(i=out.length-1, lst='t'; i >= 0; --i) {
1036 switch(out[i].t) {
1037 case 'h': case 'H': out[i].t = hr; lst='h'; if(bt < 1) bt = 1; break;
1038 case 's':
1039 if((ssm=out[i].v.match(/\.0+$/))) ss0=Math.max(ss0,ssm[0].length-1);
1040 if(bt < 3) bt = 3;
1041 /* falls through */
1042 case 'd': case 'y': case 'M': case 'e': lst=out[i].t; break;
1043 case 'm': if(lst === 's') { out[i].t = 'M'; if(bt < 2) bt = 2; } break;
1044 case 'X': /*if(out[i].v === "B2");*/
1045 break;
1046 case 'Z':
1047 if(bt < 1 && out[i].v.match(/[Hh]/)) bt = 1;
1048 if(bt < 2 && out[i].v.match(/[Mm]/)) bt = 2;
1049 if(bt < 3 && out[i].v.match(/[Ss]/)) bt = 3;
1050 }
1051 }
1052 /* time rounding depends on presence of minute / second / usec fields */
1053 switch(bt) {
1054 case 0: break;
1055 case 1:
1056 /*::if(!dt) break;*/
1057 if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
1058 if(dt.S >= 60) { dt.S = 0; ++dt.M; }
1059 if(dt.M >= 60) { dt.M = 0; ++dt.H; }
1060 break;
1061 case 2:
1062 /*::if(!dt) break;*/
1063 if(dt.u >= 0.5) { dt.u = 0; ++dt.S; }
1064 if(dt.S >= 60) { dt.S = 0; ++dt.M; }
1065 break;
1066 }
1067
1068 /* replace fields */
1069 var nstr = "", jj;
1070 for(i=0; i < out.length; ++i) {
1071 switch(out[i].t) {
1072 case 't': case 'T': case ' ': case 'D': break;
1073 case 'X': out[i].v = ""; out[i].t = ";"; break;
1074 case 'd': case 'm': case 'y': case 'h': case 'H': case 'M': case 's': case 'e': case 'b': case 'Z':
1075 /*::if(!dt) throw "unreachable"; */
1076 out[i].v = SSF_write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
1077 out[i].t = 't'; break;
1078 case 'n': case '?':
1079 jj = i+1;
1080 while(out[jj] != null && (
1081 (c=out[jj].t) === "?" || c === "D" ||
1082 ((c === " " || c === "t") && out[jj+1] != null && (out[jj+1].t === '?' || out[jj+1].t === "t" && out[jj+1].v === '/')) ||
1083 (out[i].t === '(' && (c === ' ' || c === 'n' || c === ')')) ||
1084 (c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj+1] != null && out[jj+1].t == '?'))
1085 )) {
1086 out[i].v += out[jj].v;
1087 out[jj] = {v:"", t:";"}; ++jj;
1088 }
1089 nstr += out[i].v;
1090 i = jj-1; break;
1091 case 'G': out[i].t = 't'; out[i].v = SSF_general(v,opts); break;
1092 }
1093 }
1094 var vv = "", myv, ostr;
1095 if(nstr.length > 0) {
1096 if(nstr.charCodeAt(0) == 40) /* '(' */ {
1097 myv = (v<0&&nstr.charCodeAt(0) === 45 ? -v : v);
1098 ostr = write_num('n', nstr, myv);
1099 } else {
1100 myv = (v<0 && flen > 1 ? -v : v);
1101 ostr = write_num('n', nstr, myv);
1102 if(myv < 0 && out[0] && out[0].t == 't') {
1103 ostr = ostr.substr(1);
1104 out[0].v = "-" + out[0].v;
1105 }
1106 }
1107 jj=ostr.length-1;
1108 var decpt = out.length;
1109 for(i=0; i < out.length; ++i) if(out[i] != null && out[i].t != 't' && out[i].v.indexOf(".") > -1) { decpt = i; break; }
1110 var lasti=out.length;
1111 if(decpt === out.length && ostr.indexOf("E") === -1) {
1112 for(i=out.length-1; i>= 0;--i) {
1113 if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;
1114 if(jj>=out[i].v.length-1) { jj -= out[i].v.length; out[i].v = ostr.substr(jj+1, out[i].v.length); }
1115 else if(jj < 0) out[i].v = "";
1116 else { out[i].v = ostr.substr(0, jj+1); jj = -1; }
1117 out[i].t = 't';
1118 lasti = i;
1119 }
1120 if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
1121 }
1122 else if(decpt !== out.length && ostr.indexOf("E") === -1) {
1123 jj = ostr.indexOf(".")-1;
1124 for(i=decpt; i>= 0; --i) {
1125 if(out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;
1126 j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")-1:out[i].v.length-1;
1127 vv = out[i].v.substr(j+1);
1128 for(; j>=0; --j) {
1129 if(jj>=0 && (out[i].v.charAt(j) === "0" || out[i].v.charAt(j) === "#")) vv = ostr.charAt(jj--) + vv;
1130 }
1131 out[i].v = vv;
1132 out[i].t = 't';
1133 lasti = i;
1134 }
1135 if(jj>=0 && lasti<out.length) out[lasti].v = ostr.substr(0,jj+1) + out[lasti].v;
1136 jj = ostr.indexOf(".")+1;
1137 for(i=decpt; i<out.length; ++i) {
1138 if(out[i] == null || ('n?('.indexOf(out[i].t) === -1 && i !== decpt)) continue;
1139 j=out[i].v.indexOf(".")>-1&&i===decpt?out[i].v.indexOf(".")+1:0;
1140 vv = out[i].v.substr(0,j);
1141 for(; j<out[i].v.length; ++j) {
1142 if(jj<ostr.length) vv += ostr.charAt(jj++);
1143 }
1144 out[i].v = vv;
1145 out[i].t = 't';
1146 lasti = i;
1147 }
1148 }
1149 }
1150 for(i=0; i<out.length; ++i) if(out[i] != null && 'n?'.indexOf(out[i].t)>-1) {
1151 myv = (flen >1 && v < 0 && i>0 && out[i-1].v === "-" ? -v:v);
1152 out[i].v = write_num(out[i].t, out[i].v, myv);
1153 out[i].t = 't';
1154 }
1155 var retval = "";
1156 for(i=0; i !== out.length; ++i) if(out[i] != null) retval += out[i].v;
1157 return retval;
1158}
1159
1160var cfregex2 = /\[(=|>[=]?|<[>=]?)(-?\d+(?:\.\d*)?)\]/;
1161function chkcond(v, rr) {
1162 if(rr == null) return false;
1163 var thresh = parseFloat(rr[2]);
1164 switch(rr[1]) {
1165 case "=": if(v == thresh) return true; break;
1166 case ">": if(v > thresh) return true; break;
1167 case "<": if(v < thresh) return true; break;
1168 case "<>": if(v != thresh) return true; break;
1169 case ">=": if(v >= thresh) return true; break;
1170 case "<=": if(v <= thresh) return true; break;
1171 }
1172 return false;
1173}
1174function choose_fmt(f/*:string*/, v/*:any*/) {
1175 var fmt = SSF_split_fmt(f);
1176 var l = fmt.length, lat = fmt[l-1].indexOf("@");
1177 if(l<4 && lat>-1) --l;
1178 if(fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
1179 if(typeof v !== "number") return [4, fmt.length === 4 || lat>-1?fmt[fmt.length-1]:"@"];
1180 switch(fmt.length) {
1181 case 1: fmt = lat>-1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"]; break;
1182 case 2: fmt = lat>-1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"]; break;
1183 case 3: fmt = lat>-1 ? [fmt[0], fmt[1], fmt[0], fmt[2]] : [fmt[0], fmt[1], fmt[2], "@"]; break;
1184 case 4: break;
1185 }
1186 var ff = v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2];
1187 if(fmt[0].indexOf("[") === -1 && fmt[1].indexOf("[") === -1) return [l, ff];
1188 if(fmt[0].match(/\[[=<>]/) != null || fmt[1].match(/\[[=<>]/) != null) {
1189 var m1 = fmt[0].match(cfregex2);
1190 var m2 = fmt[1].match(cfregex2);
1191 return chkcond(v, m1) ? [l, fmt[0]] : chkcond(v, m2) ? [l, fmt[1]] : [l, fmt[m1 != null && m2 != null ? 2 : 1]];
1192 }
1193 return [l, ff];
1194}
1195function SSF_format(fmt/*:string|number*/,v/*:any*/,o/*:?any*/) {
1196 if(o == null) o = {};
1197 var sfmt = "";
1198 switch(typeof fmt) {
1199 case "string":
1200 if(fmt == "m/d/yy" && o.dateNF) sfmt = o.dateNF;
1201 else sfmt = fmt;
1202 break;
1203 case "number":
1204 if(fmt == 14 && o.dateNF) sfmt = o.dateNF;
1205 else sfmt = (o.table != null ? (o.table/*:any*/) : table_fmt)[fmt];
1206 if(sfmt == null) sfmt = (o.table && o.table[SSF_default_map[fmt]]) || table_fmt[SSF_default_map[fmt]];
1207 if(sfmt == null) sfmt = SSF_default_str[fmt] || "General";
1208 break;
1209 }
1210 if(SSF_isgeneral(sfmt,0)) return SSF_general(v, o);
1211 if(v instanceof Date) v = datenum_local(v, o.date1904);
1212 var f = choose_fmt(sfmt, v);
1213 if(SSF_isgeneral(f[1])) return SSF_general(v, o);
1214 if(v === true) v = "TRUE"; else if(v === false) v = "FALSE";
1215 else if(v === "" || v == null) return "";
1216 return eval_fmt(f[1], v, o, f[0]);
1217}
1218function SSF_load(fmt/*:string*/, idx/*:?number*/)/*:number*/ {
1219 if(typeof idx != 'number') {
1220 idx = +idx || -1;
1221/*::if(typeof idx != 'number') return 0x188; */
1222 for(var i = 0; i < 0x0188; ++i) {
1223/*::if(typeof idx != 'number') return 0x188; */
1224 if(table_fmt[i] == undefined) { if(idx < 0) idx = i; continue; }
1225 if(table_fmt[i] == fmt) { idx = i; break; }
1226 }
1227/*::if(typeof idx != 'number') return 0x188; */
1228 if(idx < 0) idx = 0x187;
1229 }
1230/*::if(typeof idx != 'number') return 0x188; */
1231 table_fmt[idx] = fmt;
1232 return idx;
1233}
1234function SSF_load_table(tbl/*:SSFTable*/)/*:void*/ {
1235 for(var i=0; i!=0x0188; ++i)
1236 if(tbl[i] !== undefined) SSF_load(tbl[i], i);
1237}
1238
1239function make_ssf() {
1240 table_fmt = SSF_init_table();
1241}
1242
1243var SSF = {
1244 format: SSF_format,
1245 load: SSF_load,
1246 _table: table_fmt,
1247 load_table: SSF_load_table,
1248 parse_date_code: SSF_parse_date_code,
1249 is_date: fmt_is_date,
1250 get_table: function get_table() { return SSF._table = table_fmt; }
1251};
1252
1253var SSFImplicit/*{[number]:string}*/ = ({
1254 "5": '"$"#,##0_);\\("$"#,##0\\)',
1255 "6": '"$"#,##0_);[Red]\\("$"#,##0\\)',
1256 "7": '"$"#,##0.00_);\\("$"#,##0.00\\)',
1257 "8": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
1258 "23": 'General', "24": 'General', "25": 'General', "26": 'General',
1259 "27": 'm/d/yy', "28": 'm/d/yy', "29": 'm/d/yy', "30": 'm/d/yy', "31": 'm/d/yy',
1260 "32": 'h:mm:ss', "33": 'h:mm:ss', "34": 'h:mm:ss', "35": 'h:mm:ss',
1261 "36": 'm/d/yy',
1262 "41": '_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)',
1263 "42": '_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)',
1264 "43": '_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)',
1265 "44": '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
1266 "50": 'm/d/yy', "51": 'm/d/yy', "52": 'm/d/yy', "53": 'm/d/yy', "54": 'm/d/yy',
1267 "55": 'm/d/yy', "56": 'm/d/yy', "57": 'm/d/yy', "58": 'm/d/yy',
1268 "59": '0',
1269 "60": '0.00',
1270 "61": '#,##0',
1271 "62": '#,##0.00',
1272 "63": '"$"#,##0_);\\("$"#,##0\\)',
1273 "64": '"$"#,##0_);[Red]\\("$"#,##0\\)',
1274 "65": '"$"#,##0.00_);\\("$"#,##0.00\\)',
1275 "66": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
1276 "67": '0%',
1277 "68": '0.00%',
1278 "69": '# ?/?',
1279 "70": '# ??/??',
1280 "71": 'm/d/yy',
1281 "72": 'm/d/yy',
1282 "73": 'd-mmm-yy',
1283 "74": 'd-mmm',
1284 "75": 'mmm-yy',
1285 "76": 'h:mm',
1286 "77": 'h:mm:ss',
1287 "78": 'm/d/yy h:mm',
1288 "79": 'mm:ss',
1289 "80": '[h]:mm:ss',
1290 "81": 'mmss.0'
1291}/*:any*/);
1292
1293/* dateNF parse TODO: move to SSF */
1294var dateNFregex = /[dD]+|[mM]+|[yYeE]+|[Hh]+|[Ss]+/g;
1295function dateNF_regex(dateNF/*:string|number*/)/*:RegExp*/ {
1296 var fmt = typeof dateNF == "number" ? table_fmt[dateNF] : dateNF;
1297 fmt = fmt.replace(dateNFregex, "(\\d+)");
1298 return new RegExp("^" + fmt + "$");
1299}
1300function dateNF_fix(str/*:string*/, dateNF/*:string*/, match/*:Array<string>*/)/*:string*/ {
1301 var Y = -1, m = -1, d = -1, H = -1, M = -1, S = -1;
1302 (dateNF.match(dateNFregex)||[]).forEach(function(n, i) {
1303 var v = parseInt(match[i+1], 10);
1304 switch(n.toLowerCase().charAt(0)) {
1305 case 'y': Y = v; break; case 'd': d = v; break;
1306 case 'h': H = v; break; case 's': S = v; break;
1307 case 'm': if(H >= 0) M = v; else m = v; break;
1308 }
1309 });
1310 if(S >= 0 && M == -1 && m >= 0) { M = m; m = -1; }
1311 var datestr = (("" + (Y>=0?Y: new Date().getFullYear())).slice(-4) + "-" + ("00" + (m>=1?m:1)).slice(-2) + "-" + ("00" + (d>=1?d:1)).slice(-2));
1312 if(datestr.length == 7) datestr = "0" + datestr;
1313 if(datestr.length == 8) datestr = "20" + datestr;
1314 var timestr = (("00" + (H>=0?H:0)).slice(-2) + ":" + ("00" + (M>=0?M:0)).slice(-2) + ":" + ("00" + (S>=0?S:0)).slice(-2));
1315 if(H == -1 && M == -1 && S == -1) return datestr;
1316 if(Y == -1 && m == -1 && d == -1) return timestr;
1317 return datestr + "T" + timestr;
1318}
1319
1320/*::
1321declare var ReadShift:any;
1322declare var CheckField:any;
1323declare var prep_blob:any;
1324declare var __readUInt32LE:any;
1325declare var __readInt32LE:any;
1326declare var __toBuffer:any;
1327declare var __utf16le:any;
1328declare var bconcat:any;
1329declare var s2a:any;
1330declare var chr0:any;
1331declare var chr1:any;
1332declare var has_buf:boolean;
1333declare var new_buf:any;
1334declare var new_raw_buf:any;
1335declare var new_unsafe_buf:any;
1336declare var Buffer_from:any;
1337*/
1338/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
1339/* vim: set ts=2: */
1340/*jshint eqnull:true */
1341/*exported CFB */
1342/*global Uint8Array:false, Uint16Array:false */
1343
1344/*::
1345type SectorEntry = {
1346 name?:string;
1347 nodes?:Array<number>;
1348 data:RawBytes;
1349};
1350type SectorList = {
1351 [k:string|number]:SectorEntry;
1352 name:?string;
1353 fat_addrs:Array<number>;
1354 ssz:number;
1355}
1356type CFBFiles = {[n:string]:CFBEntry};
1357*/
1358/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */
1359/* vim: set ts=2: */
1360/*exported CRC32 */
1361var CRC32 = /*#__PURE__*/(function() {
1362var CRC32 = {};
1363CRC32.version = '1.2.0';
1364/* see perf/crc32table.js */
1365/*global Int32Array */
1366function signed_crc_table()/*:any*/ {
1367 var c = 0, table/*:Array<number>*/ = new Array(256);
1368
1369 for(var n =0; n != 256; ++n){
1370 c = n;
1371 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1372 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1373 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1374 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1375 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1376 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1377 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1378 c = ((c&1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
1379 table[n] = c;
1380 }
1381
1382 return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
1383}
1384
1385var T0 = signed_crc_table();
1386function slice_by_16_tables(T) {
1387 var c = 0, v = 0, n = 0, table/*:Array<number>*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096) ;
1388
1389 for(n = 0; n != 256; ++n) table[n] = T[n];
1390 for(n = 0; n != 256; ++n) {
1391 v = T[n];
1392 for(c = 256 + n; c < 4096; c += 256) v = table[c] = (v >>> 8) ^ T[v & 0xFF];
1393 }
1394 var out = [];
1395 for(n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256);
1396 return out;
1397}
1398var TT = slice_by_16_tables(T0);
1399var T1 = TT[0], T2 = TT[1], T3 = TT[2], T4 = TT[3], T5 = TT[4];
1400var T6 = TT[5], T7 = TT[6], T8 = TT[7], T9 = TT[8], Ta = TT[9];
1401var Tb = TT[10], Tc = TT[11], Td = TT[12], Te = TT[13], Tf = TT[14];
1402function crc32_bstr(bstr/*:string*/, seed/*:number*/)/*:number*/ {
1403 var C = seed/*:: ? 0 : 0 */ ^ -1;
1404 for(var i = 0, L = bstr.length; i < L;) C = (C>>>8) ^ T0[(C^bstr.charCodeAt(i++))&0xFF];
1405 return ~C;
1406}
1407
1408function crc32_buf(B/*:Uint8Array|Array<number>*/, seed/*:number*/)/*:number*/ {
1409 var C = seed/*:: ? 0 : 0 */ ^ -1, L = B.length - 15, i = 0;
1410 for(; i < L;) C =
1411 Tf[B[i++] ^ (C & 255)] ^
1412 Te[B[i++] ^ ((C >> 8) & 255)] ^
1413 Td[B[i++] ^ ((C >> 16) & 255)] ^
1414 Tc[B[i++] ^ (C >>> 24)] ^
1415 Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^
1416 T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^
1417 T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]];
1418 L += 15;
1419 while(i < L) C = (C>>>8) ^ T0[(C^B[i++])&0xFF];
1420 return ~C;
1421}
1422
1423function crc32_str(str/*:string*/, seed/*:number*/)/*:number*/ {
1424 var C = seed ^ -1;
1425 for(var i = 0, L = str.length, c = 0, d = 0; i < L;) {
1426 c = str.charCodeAt(i++);
1427 if(c < 0x80) {
1428 C = (C>>>8) ^ T0[(C^c)&0xFF];
1429 } else if(c < 0x800) {
1430 C = (C>>>8) ^ T0[(C ^ (192|((c>>6)&31)))&0xFF];
1431 C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF];
1432 } else if(c >= 0xD800 && c < 0xE000) {
1433 c = (c&1023)+64; d = str.charCodeAt(i++)&1023;
1434 C = (C>>>8) ^ T0[(C ^ (240|((c>>8)&7)))&0xFF];
1435 C = (C>>>8) ^ T0[(C ^ (128|((c>>2)&63)))&0xFF];
1436 C = (C>>>8) ^ T0[(C ^ (128|((d>>6)&15)|((c&3)<<4)))&0xFF];
1437 C = (C>>>8) ^ T0[(C ^ (128|(d&63)))&0xFF];
1438 } else {
1439 C = (C>>>8) ^ T0[(C ^ (224|((c>>12)&15)))&0xFF];
1440 C = (C>>>8) ^ T0[(C ^ (128|((c>>6)&63)))&0xFF];
1441 C = (C>>>8) ^ T0[(C ^ (128|(c&63)))&0xFF];
1442 }
1443 }
1444 return ~C;
1445}
1446CRC32.table = T0;
1447CRC32.bstr = crc32_bstr;
1448CRC32.buf = crc32_buf;
1449CRC32.str = crc32_str;
1450return CRC32;
1451})();
1452/* [MS-CFB] v20171201 */
1453var CFB = /*#__PURE__*/(function _CFB(){
1454var exports = {};
1455exports.version = '1.2.1';
1456/* [MS-CFB] 2.6.4 */
1457function namecmp(l/*:string*/, r/*:string*/)/*:number*/ {
1458 var L = l.split("/"), R = r.split("/");
1459 for(var i = 0, c = 0, Z = Math.min(L.length, R.length); i < Z; ++i) {
1460 if((c = L[i].length - R[i].length)) return c;
1461 if(L[i] != R[i]) return L[i] < R[i] ? -1 : 1;
1462 }
1463 return L.length - R.length;
1464}
1465function dirname(p/*:string*/)/*:string*/ {
1466 if(p.charAt(p.length - 1) == "/") return (p.slice(0,-1).indexOf("/") === -1) ? p : dirname(p.slice(0, -1));
1467 var c = p.lastIndexOf("/");
1468 return (c === -1) ? p : p.slice(0, c+1);
1469}
1470
1471function filename(p/*:string*/)/*:string*/ {
1472 if(p.charAt(p.length - 1) == "/") return filename(p.slice(0, -1));
1473 var c = p.lastIndexOf("/");
1474 return (c === -1) ? p : p.slice(c+1);
1475}
1476/* -------------------------------------------------------------------------- */
1477/* DOS Date format:
1478 high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low
1479 add 1980 to stored year
1480 stored second should be doubled
1481*/
1482
1483/* write JS date to buf as a DOS date */
1484function write_dos_date(buf/*:CFBlob*/, date/*:Date|string*/) {
1485 if(typeof date === "string") date = new Date(date);
1486 var hms/*:number*/ = date.getHours();
1487 hms = hms << 6 | date.getMinutes();
1488 hms = hms << 5 | (date.getSeconds()>>>1);
1489 buf.write_shift(2, hms);
1490 var ymd/*:number*/ = (date.getFullYear() - 1980);
1491 ymd = ymd << 4 | (date.getMonth()+1);
1492 ymd = ymd << 5 | date.getDate();
1493 buf.write_shift(2, ymd);
1494}
1495
1496/* read four bytes from buf and interpret as a DOS date */
1497function parse_dos_date(buf/*:CFBlob*/)/*:Date*/ {
1498 var hms = buf.read_shift(2) & 0xFFFF;
1499 var ymd = buf.read_shift(2) & 0xFFFF;
1500 var val = new Date();
1501 var d = ymd & 0x1F; ymd >>>= 5;
1502 var m = ymd & 0x0F; ymd >>>= 4;
1503 val.setMilliseconds(0);
1504 val.setFullYear(ymd + 1980);
1505 val.setMonth(m-1);
1506 val.setDate(d);
1507 var S = hms & 0x1F; hms >>>= 5;
1508 var M = hms & 0x3F; hms >>>= 6;
1509 val.setHours(hms);
1510 val.setMinutes(M);
1511 val.setSeconds(S<<1);
1512 return val;
1513}
1514function parse_extra_field(blob/*:CFBlob*/)/*:any*/ {
1515 prep_blob(blob, 0);
1516 var o = /*::(*/{}/*:: :any)*/;
1517 var flags = 0;
1518 while(blob.l <= blob.length - 4) {
1519 var type = blob.read_shift(2);
1520 var sz = blob.read_shift(2), tgt = blob.l + sz;
1521 var p = {};
1522 switch(type) {
1523 /* UNIX-style Timestamps */
1524 case 0x5455: {
1525 flags = blob.read_shift(1);
1526 if(flags & 1) p.mtime = blob.read_shift(4);
1527 /* for some reason, CD flag corresponds to LFH */
1528 if(sz > 5) {
1529 if(flags & 2) p.atime = blob.read_shift(4);
1530 if(flags & 4) p.ctime = blob.read_shift(4);
1531 }
1532 if(p.mtime) p.mt = new Date(p.mtime*1000);
1533 }
1534 break;
1535 }
1536 blob.l = tgt;
1537 o[type] = p;
1538 }
1539 return o;
1540}
1541var fs/*:: = require('fs'); */;
1542function get_fs() { return fs || (fs = {}); }
1543function parse(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
1544if(file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options);
1545if((file[0] | 0x20) == 0x6d && (file[1]|0x20) == 0x69) return parse_mad(file, options);
1546if(file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
1547var mver = 3;
1548var ssz = 512;
1549var nmfs = 0; // number of mini FAT sectors
1550var difat_sec_cnt = 0;
1551var dir_start = 0;
1552var minifat_start = 0;
1553var difat_start = 0;
1554
1555var fat_addrs/*:Array<number>*/ = []; // locations of FAT sectors
1556
1557/* [MS-CFB] 2.2 Compound File Header */
1558var blob/*:CFBlob*/ = /*::(*/file.slice(0,512)/*:: :any)*/;
1559prep_blob(blob, 0);
1560
1561/* major version */
1562var mv = check_get_mver(blob);
1563mver = mv[0];
1564switch(mver) {
1565 case 3: ssz = 512; break; case 4: ssz = 4096; break;
1566 case 0: if(mv[1] == 0) return parse_zip(file, options);
1567 /* falls through */
1568 default: throw new Error("Major Version: Expected 3 or 4 saw " + mver);
1569}
1570
1571/* reprocess header */
1572if(ssz !== 512) { blob = /*::(*/file.slice(0,ssz)/*:: :any)*/; prep_blob(blob, 28 /* blob.l */); }
1573/* Save header for final object */
1574var header/*:RawBytes*/ = file.slice(0,ssz);
1575
1576check_shifts(blob, mver);
1577
1578// Number of Directory Sectors
1579var dir_cnt/*:number*/ = blob.read_shift(4, 'i');
1580if(mver === 3 && dir_cnt !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + dir_cnt);
1581
1582// Number of FAT Sectors
1583blob.l += 4;
1584
1585// First Directory Sector Location
1586dir_start = blob.read_shift(4, 'i');
1587
1588// Transaction Signature
1589blob.l += 4;
1590
1591// Mini Stream Cutoff Size
1592blob.chk('00100000', 'Mini Stream Cutoff Size: ');
1593
1594// First Mini FAT Sector Location
1595minifat_start = blob.read_shift(4, 'i');
1596
1597// Number of Mini FAT Sectors
1598nmfs = blob.read_shift(4, 'i');
1599
1600// First DIFAT sector location
1601difat_start = blob.read_shift(4, 'i');
1602
1603// Number of DIFAT Sectors
1604difat_sec_cnt = blob.read_shift(4, 'i');
1605
1606// Grab FAT Sector Locations
1607for(var q = -1, j = 0; j < 109; ++j) { /* 109 = (512 - blob.l)>>>2; */
1608 q = blob.read_shift(4, 'i');
1609 if(q<0) break;
1610 fat_addrs[j] = q;
1611}
1612
1613/** Break the file up into sectors */
1614var sectors/*:Array<RawBytes>*/ = sectorify(file, ssz);
1615
1616sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);
1617
1618/** Chains */
1619var sector_list/*:SectorList*/ = make_sector_list(sectors, dir_start, fat_addrs, ssz);
1620
1621sector_list[dir_start].name = "!Directory";
1622if(nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
1623sector_list[fat_addrs[0]].name = "!FAT";
1624sector_list.fat_addrs = fat_addrs;
1625sector_list.ssz = ssz;
1626
1627/* [MS-CFB] 2.6.1 Compound File Directory Entry */
1628var files/*:CFBFiles*/ = {}, Paths/*:Array<string>*/ = [], FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = [];
1629read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, minifat_start);
1630
1631build_full_paths(FileIndex, FullPaths, Paths);
1632Paths.shift();
1633
1634var o = {
1635 FileIndex: FileIndex,
1636 FullPaths: FullPaths
1637};
1638
1639// $FlowIgnore
1640if(options && options.raw) o.raw = {header: header, sectors: sectors};
1641return o;
1642} // parse
1643
1644/* [MS-CFB] 2.2 Compound File Header -- read up to major version */
1645function check_get_mver(blob/*:CFBlob*/)/*:[number, number]*/ {
1646 if(blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0];
1647 // header signature 8
1648 blob.chk(HEADER_SIGNATURE, 'Header Signature: ');
1649
1650 // clsid 16
1651 //blob.chk(HEADER_CLSID, 'CLSID: ');
1652 blob.l += 16;
1653
1654 // minor version 2
1655 var mver/*:number*/ = blob.read_shift(2, 'u');
1656
1657 return [blob.read_shift(2,'u'), mver];
1658}
1659function check_shifts(blob/*:CFBlob*/, mver/*:number*/)/*:void*/ {
1660 var shift = 0x09;
1661
1662 // Byte Order
1663 //blob.chk('feff', 'Byte Order: '); // note: some writers put 0xffff
1664 blob.l += 2;
1665
1666 // Sector Shift
1667 switch((shift = blob.read_shift(2))) {
1668 case 0x09: if(mver != 3) throw new Error('Sector Shift: Expected 9 saw ' + shift); break;
1669 case 0x0c: if(mver != 4) throw new Error('Sector Shift: Expected 12 saw ' + shift); break;
1670 default: throw new Error('Sector Shift: Expected 9 or 12 saw ' + shift);
1671 }
1672
1673 // Mini Sector Shift
1674 blob.chk('0600', 'Mini Sector Shift: ');
1675
1676 // Reserved
1677 blob.chk('000000000000', 'Reserved: ');
1678}
1679
1680/** Break the file up into sectors */
1681function sectorify(file/*:RawBytes*/, ssz/*:number*/)/*:Array<RawBytes>*/ {
1682 var nsectors = Math.ceil(file.length/ssz)-1;
1683 var sectors/*:Array<RawBytes>*/ = [];
1684 for(var i=1; i < nsectors; ++i) sectors[i-1] = file.slice(i*ssz,(i+1)*ssz);
1685 sectors[nsectors-1] = file.slice(nsectors*ssz);
1686 return sectors;
1687}
1688
1689/* [MS-CFB] 2.6.4 Red-Black Tree */
1690function build_full_paths(FI/*:CFBFileIndex*/, FP/*:Array<string>*/, Paths/*:Array<string>*/)/*:void*/ {
1691 var i = 0, L = 0, R = 0, C = 0, j = 0, pl = Paths.length;
1692 var dad/*:Array<number>*/ = [], q/*:Array<number>*/ = [];
1693
1694 for(; i < pl; ++i) { dad[i]=q[i]=i; FP[i]=Paths[i]; }
1695
1696 for(; j < q.length; ++j) {
1697 i = q[j];
1698 L = FI[i].L; R = FI[i].R; C = FI[i].C;
1699 if(dad[i] === i) {
1700 if(L !== -1 /*NOSTREAM*/ && dad[L] !== L) dad[i] = dad[L];
1701 if(R !== -1 && dad[R] !== R) dad[i] = dad[R];
1702 }
1703 if(C !== -1 /*NOSTREAM*/) dad[C] = i;
1704 if(L !== -1 && i != dad[i]) { dad[L] = dad[i]; if(q.lastIndexOf(L) < j) q.push(L); }
1705 if(R !== -1 && i != dad[i]) { dad[R] = dad[i]; if(q.lastIndexOf(R) < j) q.push(R); }
1706 }
1707 for(i=1; i < pl; ++i) if(dad[i] === i) {
1708 if(R !== -1 /*NOSTREAM*/ && dad[R] !== R) dad[i] = dad[R];
1709 else if(L !== -1 && dad[L] !== L) dad[i] = dad[L];
1710 }
1711
1712 for(i=1; i < pl; ++i) {
1713 if(FI[i].type === 0 /* unknown */) continue;
1714 j = i;
1715 if(j != dad[j]) do {
1716 j = dad[j];
1717 FP[i] = FP[j] + "/" + FP[i];
1718 } while (j !== 0 && -1 !== dad[j] && j != dad[j]);
1719 dad[i] = -1;
1720 }
1721
1722 FP[0] += "/";
1723 for(i=1; i < pl; ++i) {
1724 if(FI[i].type !== 2 /* stream */) FP[i] += "/";
1725 }
1726}
1727
1728function get_mfat_entry(entry/*:CFBEntry*/, payload/*:RawBytes*/, mini/*:?RawBytes*/)/*:CFBlob*/ {
1729 var start = entry.start, size = entry.size;
1730 //return (payload.slice(start*MSSZ, start*MSSZ + size)/*:any*/);
1731 var o = [];
1732 var idx = start;
1733 while(mini && size > 0 && idx >= 0) {
1734 o.push(payload.slice(idx * MSSZ, idx * MSSZ + MSSZ));
1735 size -= MSSZ;
1736 idx = __readInt32LE(mini, idx * 4);
1737 }
1738 if(o.length === 0) return (new_buf(0)/*:any*/);
1739 return (bconcat(o).slice(0, entry.size)/*:any*/);
1740}
1741
1742/** Chase down the rest of the DIFAT chain to build a comprehensive list
1743 DIFAT chains by storing the next sector number as the last 32 bits */
1744function sleuth_fat(idx/*:number*/, cnt/*:number*/, sectors/*:Array<RawBytes>*/, ssz/*:number*/, fat_addrs)/*:void*/ {
1745 var q/*:number*/ = ENDOFCHAIN;
1746 if(idx === ENDOFCHAIN) {
1747 if(cnt !== 0) throw new Error("DIFAT chain shorter than expected");
1748 } else if(idx !== -1 /*FREESECT*/) {
1749 var sector = sectors[idx], m = (ssz>>>2)-1;
1750 if(!sector) return;
1751 for(var i = 0; i < m; ++i) {
1752 if((q = __readInt32LE(sector,i*4)) === ENDOFCHAIN) break;
1753 fat_addrs.push(q);
1754 }
1755 sleuth_fat(__readInt32LE(sector,ssz-4),cnt - 1, sectors, ssz, fat_addrs);
1756 }
1757}
1758
1759/** Follow the linked list of sectors for a given starting point */
1760function get_sector_list(sectors/*:Array<RawBytes>*/, start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/, chkd/*:?Array<boolean>*/)/*:SectorEntry*/ {
1761 var buf/*:Array<number>*/ = [], buf_chain/*:Array<any>*/ = [];
1762 if(!chkd) chkd = [];
1763 var modulus = ssz - 1, j = 0, jj = 0;
1764 for(j=start; j>=0;) {
1765 chkd[j] = true;
1766 buf[buf.length] = j;
1767 buf_chain.push(sectors[j]);
1768 var addr = fat_addrs[Math.floor(j*4/ssz)];
1769 jj = ((j*4) & modulus);
1770 if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz);
1771 if(!sectors[addr]) break;
1772 j = __readInt32LE(sectors[addr], jj);
1773 }
1774 return {nodes: buf, data:__toBuffer([buf_chain])};
1775}
1776
1777/** Chase down the sector linked lists */
1778function make_sector_list(sectors/*:Array<RawBytes>*/, dir_start/*:number*/, fat_addrs/*:Array<number>*/, ssz/*:number*/)/*:SectorList*/ {
1779 var sl = sectors.length, sector_list/*:SectorList*/ = ([]/*:any*/);
1780 var chkd/*:Array<boolean>*/ = [], buf/*:Array<number>*/ = [], buf_chain/*:Array<RawBytes>*/ = [];
1781 var modulus = ssz - 1, i=0, j=0, k=0, jj=0;
1782 for(i=0; i < sl; ++i) {
1783 buf = ([]/*:Array<number>*/);
1784 k = (i + dir_start); if(k >= sl) k-=sl;
1785 if(chkd[k]) continue;
1786 buf_chain = [];
1787 var seen = [];
1788 for(j=k; j>=0;) {
1789 seen[j] = true;
1790 chkd[j] = true;
1791 buf[buf.length] = j;
1792 buf_chain.push(sectors[j]);
1793 var addr/*:number*/ = fat_addrs[Math.floor(j*4/ssz)];
1794 jj = ((j*4) & modulus);
1795 if(ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 "+ssz);
1796 if(!sectors[addr]) break;
1797 j = __readInt32LE(sectors[addr], jj);
1798 if(seen[j]) break;
1799 }
1800 sector_list[k] = ({nodes: buf, data:__toBuffer([buf_chain])}/*:SectorEntry*/);
1801 }
1802 return sector_list;
1803}
1804
1805/* [MS-CFB] 2.6.1 Compound File Directory Entry */
1806function read_directory(dir_start/*:number*/, sector_list/*:SectorList*/, sectors/*:Array<RawBytes>*/, Paths/*:Array<string>*/, nmfs, files, FileIndex, mini) {
1807 var minifat_store = 0, pl = (Paths.length?2:0);
1808 var sector = sector_list[dir_start].data;
1809 var i = 0, namelen = 0, name;
1810 for(; i < sector.length; i+= 128) {
1811 var blob/*:CFBlob*/ = /*::(*/sector.slice(i, i+128)/*:: :any)*/;
1812 prep_blob(blob, 64);
1813 namelen = blob.read_shift(2);
1814 name = __utf16le(blob,0,namelen-pl);
1815 Paths.push(name);
1816 var o/*:CFBEntry*/ = ({
1817 name: name,
1818 type: blob.read_shift(1),
1819 color: blob.read_shift(1),
1820 L: blob.read_shift(4, 'i'),
1821 R: blob.read_shift(4, 'i'),
1822 C: blob.read_shift(4, 'i'),
1823 clsid: blob.read_shift(16),
1824 state: blob.read_shift(4, 'i'),
1825 start: 0,
1826 size: 0
1827 });
1828 var ctime/*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
1829 if(ctime !== 0) o.ct = read_date(blob, blob.l-8);
1830 var mtime/*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
1831 if(mtime !== 0) o.mt = read_date(blob, blob.l-8);
1832 o.start = blob.read_shift(4, 'i');
1833 o.size = blob.read_shift(4, 'i');
1834 if(o.size < 0 && o.start < 0) { o.size = o.type = 0; o.start = ENDOFCHAIN; o.name = ""; }
1835 if(o.type === 5) { /* root */
1836 minifat_store = o.start;
1837 if(nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";
1838 /*minifat_size = o.size;*/
1839 } else if(o.size >= 4096 /* MSCSZ */) {
1840 o.storage = 'fat';
1841 if(sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz);
1842 sector_list[o.start].name = o.name;
1843 o.content = (sector_list[o.start].data.slice(0,o.size)/*:any*/);
1844 } else {
1845 o.storage = 'minifat';
1846 if(o.size < 0) o.size = 0;
1847 else if(minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
1848 o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini]||{}).data);
1849 }
1850 }
1851 if(o.content) prep_blob(o.content, 0);
1852 files[name] = o;
1853 FileIndex.push(o);
1854 }
1855}
1856
1857function read_date(blob/*:RawBytes|CFBlob*/, offset/*:number*/)/*:Date*/ {
1858 return new Date(( ( (__readUInt32LE(blob,offset+4)/1e7)*Math.pow(2,32)+__readUInt32LE(blob,offset)/1e7 ) - 11644473600)*1000);
1859}
1860
1861function read_file(filename/*:string*/, options/*:CFBReadOpts*/) {
1862 get_fs();
1863 return parse(fs.readFileSync(filename), options);
1864}
1865
1866function read(blob/*:RawBytes|string*/, options/*:CFBReadOpts*/) {
1867 var type = options && options.type;
1868 if(!type) {
1869 if(has_buf && Buffer.isBuffer(blob)) type = "buffer";
1870 }
1871 switch(type || "base64") {
1872 case "file": /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */return read_file(blob, options);
1873 case "base64": /*:: if(typeof blob !== 'string') throw "Must pass a base64-encoded binary string when type='file'"; */return parse(s2a(Base64_decode(blob)), options);
1874 case "binary": /*:: if(typeof blob !== 'string') throw "Must pass a binary string when type='file'"; */return parse(s2a(blob), options);
1875 }
1876 return parse(/*::typeof blob == 'string' ? new Buffer(blob, 'utf-8') : */blob, options);
1877}
1878
1879function init_cfb(cfb/*:CFBContainer*/, opts/*:?any*/)/*:void*/ {
1880 var o = opts || {}, root = o.root || "Root Entry";
1881 if(!cfb.FullPaths) cfb.FullPaths = [];
1882 if(!cfb.FileIndex) cfb.FileIndex = [];
1883 if(cfb.FullPaths.length !== cfb.FileIndex.length) throw new Error("inconsistent CFB structure");
1884 if(cfb.FullPaths.length === 0) {
1885 cfb.FullPaths[0] = root + "/";
1886 cfb.FileIndex[0] = ({ name: root, type: 5 }/*:any*/);
1887 }
1888 if(o.CLSID) cfb.FileIndex[0].clsid = o.CLSID;
1889 seed_cfb(cfb);
1890}
1891function seed_cfb(cfb/*:CFBContainer*/)/*:void*/ {
1892 var nm = "\u0001Sh33tJ5";
1893 if(CFB.find(cfb, "/" + nm)) return;
1894 var p = new_buf(4); p[0] = 55; p[1] = p[3] = 50; p[2] = 54;
1895 cfb.FileIndex.push(({ name: nm, type: 2, content:p, size:4, L:69, R:69, C:69 }/*:any*/));
1896 cfb.FullPaths.push(cfb.FullPaths[0] + nm);
1897 rebuild_cfb(cfb);
1898}
1899function rebuild_cfb(cfb/*:CFBContainer*/, f/*:?boolean*/)/*:void*/ {
1900 init_cfb(cfb);
1901 var gc = false, s = false;
1902 for(var i = cfb.FullPaths.length - 1; i >= 0; --i) {
1903 var _file = cfb.FileIndex[i];
1904 switch(_file.type) {
1905 case 0:
1906 if(s) gc = true;
1907 else { cfb.FileIndex.pop(); cfb.FullPaths.pop(); }
1908 break;
1909 case 1: case 2: case 5:
1910 s = true;
1911 if(isNaN(_file.R * _file.L * _file.C)) gc = true;
1912 if(_file.R > -1 && _file.L > -1 && _file.R == _file.L) gc = true;
1913 break;
1914 default: gc = true; break;
1915 }
1916 }
1917 if(!gc && !f) return;
1918
1919 var now = new Date(1987, 1, 19), j = 0;
1920 // Track which names exist
1921 var fullPaths = Object.create ? Object.create(null) : {};
1922 var data/*:Array<[string, CFBEntry]>*/ = [];
1923 for(i = 0; i < cfb.FullPaths.length; ++i) {
1924 fullPaths[cfb.FullPaths[i]] = true;
1925 if(cfb.FileIndex[i].type === 0) continue;
1926 data.push([cfb.FullPaths[i], cfb.FileIndex[i]]);
1927 }
1928 for(i = 0; i < data.length; ++i) {
1929 var dad = dirname(data[i][0]);
1930 s = fullPaths[dad];
1931 if(!s) {
1932 data.push([dad, ({
1933 name: filename(dad).replace("/",""),
1934 type: 1,
1935 clsid: HEADER_CLSID,
1936 ct: now, mt: now,
1937 content: null
1938 }/*:any*/)]);
1939 // Add name to set
1940 fullPaths[dad] = true;
1941 }
1942 }
1943
1944 data.sort(function(x,y) { return namecmp(x[0], y[0]); });
1945 cfb.FullPaths = []; cfb.FileIndex = [];
1946 for(i = 0; i < data.length; ++i) { cfb.FullPaths[i] = data[i][0]; cfb.FileIndex[i] = data[i][1]; }
1947 for(i = 0; i < data.length; ++i) {
1948 var elt = cfb.FileIndex[i];
1949 var nm = cfb.FullPaths[i];
1950
1951 elt.name = filename(nm).replace("/","");
1952 elt.L = elt.R = elt.C = -(elt.color = 1);
1953 elt.size = elt.content ? elt.content.length : 0;
1954 elt.start = 0;
1955 elt.clsid = (elt.clsid || HEADER_CLSID);
1956 if(i === 0) {
1957 elt.C = data.length > 1 ? 1 : -1;
1958 elt.size = 0;
1959 elt.type = 5;
1960 } else if(nm.slice(-1) == "/") {
1961 for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==nm) break;
1962 elt.C = j >= data.length ? -1 : j;
1963 for(j=i+1;j < data.length; ++j) if(dirname(cfb.FullPaths[j])==dirname(nm)) break;
1964 elt.R = j >= data.length ? -1 : j;
1965 elt.type = 1;
1966 } else {
1967 if(dirname(cfb.FullPaths[i+1]||"") == dirname(nm)) elt.R = i + 1;
1968 elt.type = 2;
1969 }
1970 }
1971
1972}
1973
1974function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|string*/ {
1975 var _opts = options || {};
1976 /* MAD is order-sensitive, skip rebuild and sort */
1977 if(_opts.fileType == 'mad') return write_mad(cfb, _opts);
1978 rebuild_cfb(cfb);
1979 switch(_opts.fileType) {
1980 case 'zip': return write_zip(cfb, _opts);
1981 //case 'mad': return write_mad(cfb, _opts);
1982 }
1983 var L = (function(cfb/*:CFBContainer*/)/*:Array<number>*/{
1984 var mini_size = 0, fat_size = 0;
1985 for(var i = 0; i < cfb.FileIndex.length; ++i) {
1986 var file = cfb.FileIndex[i];
1987 if(!file.content) continue;
1988 /*:: if(file.content == null) throw new Error("unreachable"); */
1989 var flen = file.content.length;
1990 if(flen > 0){
1991 if(flen < 0x1000) mini_size += (flen + 0x3F) >> 6;
1992 else fat_size += (flen + 0x01FF) >> 9;
1993 }
1994 }
1995 var dir_cnt = (cfb.FullPaths.length +3) >> 2;
1996 var mini_cnt = (mini_size + 7) >> 3;
1997 var mfat_cnt = (mini_size + 0x7F) >> 7;
1998 var fat_base = mini_cnt + fat_size + dir_cnt + mfat_cnt;
1999 var fat_cnt = (fat_base + 0x7F) >> 7;
2000 var difat_cnt = fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);
2001 while(((fat_base + fat_cnt + difat_cnt + 0x7F) >> 7) > fat_cnt) difat_cnt = ++fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt-109)/0x7F);
2002 var L = [1, difat_cnt, fat_cnt, mfat_cnt, dir_cnt, fat_size, mini_size, 0];
2003 cfb.FileIndex[0].size = mini_size << 6;
2004 L[7] = (cfb.FileIndex[0].start=L[0]+L[1]+L[2]+L[3]+L[4]+L[5])+((L[6]+7) >> 3);
2005 return L;
2006 })(cfb);
2007 var o = new_buf(L[7] << 9);
2008 var i = 0, T = 0;
2009 {
2010 for(i = 0; i < 8; ++i) o.write_shift(1, HEADER_SIG[i]);
2011 for(i = 0; i < 8; ++i) o.write_shift(2, 0);
2012 o.write_shift(2, 0x003E);
2013 o.write_shift(2, 0x0003);
2014 o.write_shift(2, 0xFFFE);
2015 o.write_shift(2, 0x0009);
2016 o.write_shift(2, 0x0006);
2017 for(i = 0; i < 3; ++i) o.write_shift(2, 0);
2018 o.write_shift(4, 0);
2019 o.write_shift(4, L[2]);
2020 o.write_shift(4, L[0] + L[1] + L[2] + L[3] - 1);
2021 o.write_shift(4, 0);
2022 o.write_shift(4, 1<<12);
2023 o.write_shift(4, L[3] ? L[0] + L[1] + L[2] - 1: ENDOFCHAIN);
2024 o.write_shift(4, L[3]);
2025 o.write_shift(-4, L[1] ? L[0] - 1: ENDOFCHAIN);
2026 o.write_shift(4, L[1]);
2027 for(i = 0; i < 109; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
2028 }
2029 if(L[1]) {
2030 for(T = 0; T < L[1]; ++T) {
2031 for(; i < 236 + T * 127; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
2032 o.write_shift(-4, T === L[1] - 1 ? ENDOFCHAIN : T + 1);
2033 }
2034 }
2035 var chainit = function(w/*:number*/)/*:void*/ {
2036 for(T += w; i<T-1; ++i) o.write_shift(-4, i+1);
2037 if(w) { ++i; o.write_shift(-4, ENDOFCHAIN); }
2038 };
2039 T = i = 0;
2040 for(T+=L[1]; i<T; ++i) o.write_shift(-4, consts.DIFSECT);
2041 for(T+=L[2]; i<T; ++i) o.write_shift(-4, consts.FATSECT);
2042 chainit(L[3]);
2043 chainit(L[4]);
2044 var j/*:number*/ = 0, flen/*:number*/ = 0;
2045 var file/*:CFBEntry*/ = cfb.FileIndex[0];
2046 for(; j < cfb.FileIndex.length; ++j) {
2047 file = cfb.FileIndex[j];
2048 if(!file.content) continue;
2049 /*:: if(file.content == null) throw new Error("unreachable"); */
2050 flen = file.content.length;
2051 if(flen < 0x1000) continue;
2052 file.start = T;
2053 chainit((flen + 0x01FF) >> 9);
2054 }
2055 chainit((L[6] + 7) >> 3);
2056 while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
2057 T = i = 0;
2058 for(j = 0; j < cfb.FileIndex.length; ++j) {
2059 file = cfb.FileIndex[j];
2060 if(!file.content) continue;
2061 /*:: if(file.content == null) throw new Error("unreachable"); */
2062 flen = file.content.length;
2063 if(!flen || flen >= 0x1000) continue;
2064 file.start = T;
2065 chainit((flen + 0x3F) >> 6);
2066 }
2067 while(o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
2068 for(i = 0; i < L[4]<<2; ++i) {
2069 var nm = cfb.FullPaths[i];
2070 if(!nm || nm.length === 0) {
2071 for(j = 0; j < 17; ++j) o.write_shift(4, 0);
2072 for(j = 0; j < 3; ++j) o.write_shift(4, -1);
2073 for(j = 0; j < 12; ++j) o.write_shift(4, 0);
2074 continue;
2075 }
2076 file = cfb.FileIndex[i];
2077 if(i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
2078 var _nm/*:string*/ = (i === 0 && _opts.root) || file.name;
2079 flen = 2*(_nm.length+1);
2080 o.write_shift(64, _nm, "utf16le");
2081 o.write_shift(2, flen);
2082 o.write_shift(1, file.type);
2083 o.write_shift(1, file.color);
2084 o.write_shift(-4, file.L);
2085 o.write_shift(-4, file.R);
2086 o.write_shift(-4, file.C);
2087 if(!file.clsid) for(j = 0; j < 4; ++j) o.write_shift(4, 0);
2088 else o.write_shift(16, file.clsid, "hex");
2089 o.write_shift(4, file.state || 0);
2090 o.write_shift(4, 0); o.write_shift(4, 0);
2091 o.write_shift(4, 0); o.write_shift(4, 0);
2092 o.write_shift(4, file.start);
2093 o.write_shift(4, file.size); o.write_shift(4, 0);
2094 }
2095 for(i = 1; i < cfb.FileIndex.length; ++i) {
2096 file = cfb.FileIndex[i];
2097 /*:: if(!file.content) throw new Error("unreachable"); */
2098 if(file.size >= 0x1000) {
2099 o.l = (file.start+1) << 9;
2100 if (has_buf && Buffer.isBuffer(file.content)) {
2101 file.content.copy(o, o.l, 0, file.size);
2102 // o is a 0-filled Buffer so just set next offset
2103 o.l += (file.size + 511) & -512;
2104 } else {
2105 for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
2106 for(; j & 0x1FF; ++j) o.write_shift(1, 0);
2107 }
2108 }
2109 }
2110 for(i = 1; i < cfb.FileIndex.length; ++i) {
2111 file = cfb.FileIndex[i];
2112 /*:: if(!file.content) throw new Error("unreachable"); */
2113 if(file.size > 0 && file.size < 0x1000) {
2114 if (has_buf && Buffer.isBuffer(file.content)) {
2115 file.content.copy(o, o.l, 0, file.size);
2116 // o is a 0-filled Buffer so just set next offset
2117 o.l += (file.size + 63) & -64;
2118 } else {
2119 for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
2120 for(; j & 0x3F; ++j) o.write_shift(1, 0);
2121 }
2122 }
2123 }
2124 if (has_buf) {
2125 o.l = o.length;
2126 } else {
2127 // When using Buffer, already 0-filled
2128 while(o.l < o.length) o.write_shift(1, 0);
2129 }
2130 return o;
2131}
2132/* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
2133function find(cfb/*:CFBContainer*/, path/*:string*/)/*:?CFBEntry*/ {
2134 var UCFullPaths/*:Array<string>*/ = cfb.FullPaths.map(function(x) { return x.toUpperCase(); });
2135 var UCPaths/*:Array<string>*/ = UCFullPaths.map(function(x) { var y = x.split("/"); return y[y.length - (x.slice(-1) == "/" ? 2 : 1)]; });
2136 var k/*:boolean*/ = false;
2137 if(path.charCodeAt(0) === 47 /* "/" */) { k = true; path = UCFullPaths[0].slice(0, -1) + path; }
2138 else k = path.indexOf("/") !== -1;
2139 var UCPath/*:string*/ = path.toUpperCase();
2140 var w/*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
2141 if(w !== -1) return cfb.FileIndex[w];
2142
2143 var m = !UCPath.match(chr1);
2144 UCPath = UCPath.replace(chr0,'');
2145 if(m) UCPath = UCPath.replace(chr1,'!');
2146 for(w = 0; w < UCFullPaths.length; ++w) {
2147 if((m ? UCFullPaths[w].replace(chr1,'!') : UCFullPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
2148 if((m ? UCPaths[w].replace(chr1,'!') : UCPaths[w]).replace(chr0,'') == UCPath) return cfb.FileIndex[w];
2149 }
2150 return null;
2151}
2152/** CFB Constants */
2153var MSSZ = 64; /* Mini Sector Size = 1<<6 */
2154//var MSCSZ = 4096; /* Mini Stream Cutoff Size */
2155/* 2.1 Compound File Sector Numbers and Types */
2156var ENDOFCHAIN = -2;
2157/* 2.2 Compound File Header */
2158var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1';
2159var HEADER_SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
2160var HEADER_CLSID = '00000000000000000000000000000000';
2161var consts = {
2162 /* 2.1 Compund File Sector Numbers and Types */
2163 MAXREGSECT: -6,
2164 DIFSECT: -4,
2165 FATSECT: -3,
2166 ENDOFCHAIN: ENDOFCHAIN,
2167 FREESECT: -1,
2168 /* 2.2 Compound File Header */
2169 HEADER_SIGNATURE: HEADER_SIGNATURE,
2170 HEADER_MINOR_VERSION: '3e00',
2171 MAXREGSID: -6,
2172 NOSTREAM: -1,
2173 HEADER_CLSID: HEADER_CLSID,
2174 /* 2.6.1 Compound File Directory Entry */
2175 EntryTypes: ['unknown','storage','stream','lockbytes','property','root']
2176};
2177
2178function write_file(cfb/*:CFBContainer*/, filename/*:string*/, options/*:CFBWriteOpts*/)/*:void*/ {
2179 get_fs();
2180 var o = _write(cfb, options);
2181 /*:: if(typeof Buffer == 'undefined' || !Buffer.isBuffer(o) || !(o instanceof Buffer)) throw new Error("unreachable"); */
2182 fs.writeFileSync(filename, o);
2183}
2184
2185function a2s(o/*:RawBytes*/)/*:string*/ {
2186 var out = new Array(o.length);
2187 for(var i = 0; i < o.length; ++i) out[i] = String.fromCharCode(o[i]);
2188 return out.join("");
2189}
2190
2191function write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|string*/ {
2192 var o = _write(cfb, options);
2193 switch(options && options.type || "buffer") {
2194 case "file": get_fs(); fs.writeFileSync(options.filename, (o/*:any*/)); return o;
2195 case "binary": return typeof o == "string" ? o : a2s(o);
2196 case "base64": return Base64_encode(typeof o == "string" ? o : a2s(o));
2197 case "buffer": if(has_buf) return Buffer.isBuffer(o) ? o : Buffer_from(o);
2198 /* falls through */
2199 case "array": return typeof o == "string" ? s2a(o) : o;
2200 }
2201 return o;
2202}
2203/* node < 8.1 zlib does not expose bytesRead, so default to pure JS */
2204var _zlib;
2205function use_zlib(zlib) { try {
2206 var InflateRaw = zlib.InflateRaw;
2207 var InflRaw = new InflateRaw();
2208 InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag);
2209 if(InflRaw.bytesRead) _zlib = zlib;
2210 else throw new Error("zlib does not expose bytesRead");
2211} catch(e) {console.error("cannot use native zlib: " + (e.message || e)); } }
2212
2213function _inflateRawSync(payload, usz) {
2214 if(!_zlib) return _inflate(payload, usz);
2215 var InflateRaw = _zlib.InflateRaw;
2216 var InflRaw = new InflateRaw();
2217 var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag);
2218 payload.l += InflRaw.bytesRead;
2219 return out;
2220}
2221
2222function _deflateRawSync(payload) {
2223 return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload);
2224}
2225var CLEN_ORDER = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
2226
2227/* LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */
2228var LEN_LN = [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13 , 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 ];
2229
2230/* DST_ID = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ]; */
2231var DST_LN = [ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 ];
2232
2233function bit_swap_8(n) { var t = (((((n<<1)|(n<<11)) & 0x22110) | (((n<<5)|(n<<15)) & 0x88440))); return ((t>>16) | (t>>8) |t)&0xFF; }
2234
2235var use_typed_arrays = typeof Uint8Array !== 'undefined';
2236
2237var bitswap8 = use_typed_arrays ? new Uint8Array(1<<8) : [];
2238for(var q = 0; q < (1<<8); ++q) bitswap8[q] = bit_swap_8(q);
2239
2240function bit_swap_n(n, b) {
2241 var rev = bitswap8[n & 0xFF];
2242 if(b <= 8) return rev >>> (8-b);
2243 rev = (rev << 8) | bitswap8[(n>>8)&0xFF];
2244 if(b <= 16) return rev >>> (16-b);
2245 rev = (rev << 8) | bitswap8[(n>>16)&0xFF];
2246 return rev >>> (24-b);
2247}
2248
2249/* helpers for unaligned bit reads */
2250function read_bits_2(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 6 ? 0 : buf[h+1]<<8))>>>w)& 0x03; }
2251function read_bits_3(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 5 ? 0 : buf[h+1]<<8))>>>w)& 0x07; }
2252function read_bits_4(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 4 ? 0 : buf[h+1]<<8))>>>w)& 0x0F; }
2253function read_bits_5(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 3 ? 0 : buf[h+1]<<8))>>>w)& 0x1F; }
2254function read_bits_7(buf, bl) { var w = (bl&7), h = (bl>>>3); return ((buf[h]|(w <= 1 ? 0 : buf[h+1]<<8))>>>w)& 0x7F; }
2255
2256/* works up to n = 3 * 8 + 1 = 25 */
2257function read_bits_n(buf, bl, n) {
2258 var w = (bl&7), h = (bl>>>3), f = ((1<<n)-1);
2259 var v = buf[h] >>> w;
2260 if(n < 8 - w) return v & f;
2261 v |= buf[h+1]<<(8-w);
2262 if(n < 16 - w) return v & f;
2263 v |= buf[h+2]<<(16-w);
2264 if(n < 24 - w) return v & f;
2265 v |= buf[h+3]<<(24-w);
2266 return v & f;
2267}
2268
2269/* helpers for unaligned bit writes */
2270function write_bits_3(buf, bl, v) { var w = bl & 7, h = bl >>> 3;
2271 if(w <= 5) buf[h] |= (v & 7) << w;
2272 else {
2273 buf[h] |= (v << w) & 0xFF;
2274 buf[h+1] = (v&7) >> (8-w);
2275 }
2276 return bl + 3;
2277}
2278
2279function write_bits_1(buf, bl, v) {
2280 var w = bl & 7, h = bl >>> 3;
2281 v = (v&1) << w;
2282 buf[h] |= v;
2283 return bl + 1;
2284}
2285function write_bits_8(buf, bl, v) {
2286 var w = bl & 7, h = bl >>> 3;
2287 v <<= w;
2288 buf[h] |= v & 0xFF; v >>>= 8;
2289 buf[h+1] = v;
2290 return bl + 8;
2291}
2292function write_bits_16(buf, bl, v) {
2293 var w = bl & 7, h = bl >>> 3;
2294 v <<= w;
2295 buf[h] |= v & 0xFF; v >>>= 8;
2296 buf[h+1] = v & 0xFF;
2297 buf[h+2] = v >>> 8;
2298 return bl + 16;
2299}
2300
2301/* until ArrayBuffer#realloc is a thing, fake a realloc */
2302function realloc(b, sz/*:number*/) {
2303 var L = b.length, M = 2*L > sz ? 2*L : sz + 5, i = 0;
2304 if(L >= sz) return b;
2305 if(has_buf) {
2306 var o = new_unsafe_buf(M);
2307 // $FlowIgnore
2308 if(b.copy) b.copy(o);
2309 else for(; i < b.length; ++i) o[i] = b[i];
2310 return o;
2311 } else if(use_typed_arrays) {
2312 var a = new Uint8Array(M);
2313 if(a.set) a.set(b);
2314 else for(; i < L; ++i) a[i] = b[i];
2315 return a;
2316 }
2317 b.length = M;
2318 return b;
2319}
2320
2321/* zero-filled arrays for older browsers */
2322function zero_fill_array(n) {
2323 var o = new Array(n);
2324 for(var i = 0; i < n; ++i) o[i] = 0;
2325 return o;
2326}
2327
2328/* build tree (used for literals and lengths) */
2329function build_tree(clens, cmap, MAX/*:number*/)/*:number*/ {
2330 var maxlen = 1, w = 0, i = 0, j = 0, ccode = 0, L = clens.length;
2331
2332 var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
2333 for(i = 0; i < 32; ++i) bl_count[i] = 0;
2334
2335 for(i = L; i < MAX; ++i) clens[i] = 0;
2336 L = clens.length;
2337
2338 var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // []
2339
2340 /* build code tree */
2341 for(i = 0; i < L; ++i) {
2342 bl_count[(w = clens[i])]++;
2343 if(maxlen < w) maxlen = w;
2344 ctree[i] = 0;
2345 }
2346 bl_count[0] = 0;
2347 for(i = 1; i <= maxlen; ++i) bl_count[i+16] = (ccode = (ccode + bl_count[i-1])<<1);
2348 for(i = 0; i < L; ++i) {
2349 ccode = clens[i];
2350 if(ccode != 0) ctree[i] = bl_count[ccode+16]++;
2351 }
2352
2353 /* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */
2354 var cleni = 0;
2355 for(i = 0; i < L; ++i) {
2356 cleni = clens[i];
2357 if(cleni != 0) {
2358 ccode = bit_swap_n(ctree[i], maxlen)>>(maxlen-cleni);
2359 for(j = (1<<(maxlen + 4 - cleni)) - 1; j>=0; --j)
2360 cmap[ccode|(j<<cleni)] = (cleni&15) | (i<<4);
2361 }
2362 }
2363 return maxlen;
2364}
2365
2366/* Fixed Huffman */
2367var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512);
2368var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
2369if(!use_typed_arrays) {
2370 for(var i = 0; i < 512; ++i) fix_lmap[i] = 0;
2371 for(i = 0; i < 32; ++i) fix_dmap[i] = 0;
2372}
2373(function() {
2374 var dlens/*:Array<number>*/ = [];
2375 var i = 0;
2376 for(;i<32; i++) dlens.push(5);
2377 build_tree(dlens, fix_dmap, 32);
2378
2379 var clens/*:Array<number>*/ = [];
2380 i = 0;
2381 for(; i<=143; i++) clens.push(8);
2382 for(; i<=255; i++) clens.push(9);
2383 for(; i<=279; i++) clens.push(7);
2384 for(; i<=287; i++) clens.push(8);
2385 build_tree(clens, fix_lmap, 288);
2386})();var _deflateRaw = /*#__PURE__*/(function _deflateRawIIFE() {
2387 var DST_LN_RE = use_typed_arrays ? new Uint8Array(0x8000) : [];
2388 var j = 0, k = 0;
2389 for(; j < DST_LN.length - 1; ++j) {
2390 for(; k < DST_LN[j+1]; ++k) DST_LN_RE[k] = j;
2391 }
2392 for(;k < 32768; ++k) DST_LN_RE[k] = 29;
2393
2394 var LEN_LN_RE = use_typed_arrays ? new Uint8Array(0x103) : [];
2395 for(j = 0, k = 0; j < LEN_LN.length - 1; ++j) {
2396 for(; k < LEN_LN[j+1]; ++k) LEN_LN_RE[k] = j;
2397 }
2398
2399 function write_stored(data, out) {
2400 var boff = 0;
2401 while(boff < data.length) {
2402 var L = Math.min(0xFFFF, data.length - boff);
2403 var h = boff + L == data.length;
2404 out.write_shift(1, +h);
2405 out.write_shift(2, L);
2406 out.write_shift(2, (~L) & 0xFFFF);
2407 while(L-- > 0) out[out.l++] = data[boff++];
2408 }
2409 return out.l;
2410 }
2411
2412 /* Fixed Huffman */
2413 function write_huff_fixed(data, out) {
2414 var bl = 0;
2415 var boff = 0;
2416 var addrs = use_typed_arrays ? new Uint16Array(0x8000) : [];
2417 while(boff < data.length) {
2418 var L = /* data.length - boff; */ Math.min(0xFFFF, data.length - boff);
2419
2420 /* write a stored block for short data */
2421 if(L < 10) {
2422 bl = write_bits_3(out, bl, +!!(boff + L == data.length)); // jshint ignore:line
2423 if(bl & 7) bl += 8 - (bl & 7);
2424 out.l = (bl / 8) | 0;
2425 out.write_shift(2, L);
2426 out.write_shift(2, (~L) & 0xFFFF);
2427 while(L-- > 0) out[out.l++] = data[boff++];
2428 bl = out.l * 8;
2429 continue;
2430 }
2431
2432 bl = write_bits_3(out, bl, +!!(boff + L == data.length) + 2); // jshint ignore:line
2433 var hash = 0;
2434 while(L-- > 0) {
2435 var d = data[boff];
2436 hash = ((hash << 5) ^ d) & 0x7FFF;
2437
2438 var match = -1, mlen = 0;
2439
2440 if((match = addrs[hash])) {
2441 match |= boff & ~0x7FFF;
2442 if(match > boff) match -= 0x8000;
2443 if(match < boff) while(data[match + mlen] == data[boff + mlen] && mlen < 250) ++mlen;
2444 }
2445
2446 if(mlen > 2) {
2447 /* Copy Token */
2448 d = LEN_LN_RE[mlen];
2449 if(d <= 22) bl = write_bits_8(out, bl, bitswap8[d+1]>>1) - 1;
2450 else {
2451 write_bits_8(out, bl, 3);
2452 bl += 5;
2453 write_bits_8(out, bl, bitswap8[d-23]>>5);
2454 bl += 3;
2455 }
2456 var len_eb = (d < 8) ? 0 : ((d - 4)>>2);
2457 if(len_eb > 0) {
2458 write_bits_16(out, bl, mlen - LEN_LN[d]);
2459 bl += len_eb;
2460 }
2461
2462 d = DST_LN_RE[boff - match];
2463 bl = write_bits_8(out, bl, bitswap8[d]>>3);
2464 bl -= 3;
2465
2466 var dst_eb = d < 4 ? 0 : (d-2)>>1;
2467 if(dst_eb > 0) {
2468 write_bits_16(out, bl, boff - match - DST_LN[d]);
2469 bl += dst_eb;
2470 }
2471 for(var q = 0; q < mlen; ++q) {
2472 addrs[hash] = boff & 0x7FFF;
2473 hash = ((hash << 5) ^ data[boff]) & 0x7FFF;
2474 ++boff;
2475 }
2476 L-= mlen - 1;
2477 } else {
2478 /* Literal Token */
2479 if(d <= 143) d = d + 48;
2480 else bl = write_bits_1(out, bl, 1);
2481 bl = write_bits_8(out, bl, bitswap8[d]);
2482 addrs[hash] = boff & 0x7FFF;
2483 ++boff;
2484 }
2485 }
2486
2487 bl = write_bits_8(out, bl, 0) - 1;
2488 }
2489 out.l = ((bl + 7)/8)|0;
2490 return out.l;
2491 }
2492 return function _deflateRaw(data, out) {
2493 if(data.length < 8) return write_stored(data, out);
2494 return write_huff_fixed(data, out);
2495 };
2496})();
2497
2498function _deflate(data) {
2499 var buf = new_buf(50+Math.floor(data.length*1.1));
2500 var off = _deflateRaw(data, buf);
2501 return buf.slice(0, off);
2502}
2503/* modified inflate function also moves original read head */
2504
2505var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
2506var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
2507var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128);
2508var dyn_len_1 = 1, dyn_len_2 = 1;
2509
2510/* 5.5.3 Expanding Huffman Codes */
2511function dyn(data, boff/*:number*/) {
2512 /* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */
2513 var _HLIT = read_bits_5(data, boff) + 257; boff += 5;
2514 var _HDIST = read_bits_5(data, boff) + 1; boff += 5;
2515 var _HCLEN = read_bits_4(data, boff) + 4; boff += 4;
2516 var w = 0;
2517
2518 /* grab and store code lengths */
2519 var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19);
2520 var ctree = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
2521 var maxlen = 1;
2522 var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
2523 var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
2524 var L = clens.length; /* 19 */
2525 for(var i = 0; i < _HCLEN; ++i) {
2526 clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff);
2527 if(maxlen < w) maxlen = w;
2528 bl_count[w]++;
2529 boff += 3;
2530 }
2531
2532 /* build code tree */
2533 var ccode = 0;
2534 bl_count[0] = 0;
2535 for(i = 1; i <= maxlen; ++i) next_code[i] = ccode = (ccode + bl_count[i-1])<<1;
2536 for(i = 0; i < L; ++i) if((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++;
2537 /* cmap[7 bits from stream] = (off&7) + (lit<<3) */
2538 var cleni = 0;
2539 for(i = 0; i < L; ++i) {
2540 cleni = clens[i];
2541 if(cleni != 0) {
2542 ccode = bitswap8[ctree[i]]>>(8-cleni);
2543 for(var j = (1<<(7-cleni))-1; j>=0; --j) dyn_cmap[ccode|(j<<cleni)] = (cleni&7) | (i<<3);
2544 }
2545 }
2546
2547 /* read literal and dist codes at once */
2548 var hcodes/*:Array<number>*/ = [];
2549 maxlen = 1;
2550 for(; hcodes.length < _HLIT + _HDIST;) {
2551 ccode = dyn_cmap[read_bits_7(data, boff)];
2552 boff += ccode & 7;
2553 switch((ccode >>>= 3)) {
2554 case 16:
2555 w = 3 + read_bits_2(data, boff); boff += 2;
2556 ccode = hcodes[hcodes.length - 1];
2557 while(w-- > 0) hcodes.push(ccode);
2558 break;
2559 case 17:
2560 w = 3 + read_bits_3(data, boff); boff += 3;
2561 while(w-- > 0) hcodes.push(0);
2562 break;
2563 case 18:
2564 w = 11 + read_bits_7(data, boff); boff += 7;
2565 while(w -- > 0) hcodes.push(0);
2566 break;
2567 default:
2568 hcodes.push(ccode);
2569 if(maxlen < ccode) maxlen = ccode;
2570 break;
2571 }
2572 }
2573
2574 /* build literal / length trees */
2575 var h1 = hcodes.slice(0, _HLIT), h2 = hcodes.slice(_HLIT);
2576 for(i = _HLIT; i < 286; ++i) h1[i] = 0;
2577 for(i = _HDIST; i < 30; ++i) h2[i] = 0;
2578 dyn_len_1 = build_tree(h1, dyn_lmap, 286);
2579 dyn_len_2 = build_tree(h2, dyn_dmap, 30);
2580 return boff;
2581}
2582
2583/* return [ data, bytesRead ] */
2584function inflate(data, usz/*:number*/) {
2585 /* shortcircuit for empty buffer [0x03, 0x00] */
2586 if(data[0] == 3 && !(data[1] & 0x3)) { return [new_raw_buf(usz), 2]; }
2587
2588 /* bit offset */
2589 var boff = 0;
2590
2591 /* header includes final bit and type bits */
2592 var header = 0;
2593
2594 var outbuf = new_unsafe_buf(usz ? usz : (1<<18));
2595 var woff = 0;
2596 var OL = outbuf.length>>>0;
2597 var max_len_1 = 0, max_len_2 = 0;
2598
2599 while((header&1) == 0) {
2600 header = read_bits_3(data, boff); boff += 3;
2601 if((header >>> 1) == 0) {
2602 /* Stored block */
2603 if(boff & 7) boff += 8 - (boff&7);
2604 /* 2 bytes sz, 2 bytes bit inverse */
2605 var sz = data[boff>>>3] | data[(boff>>>3)+1]<<8;
2606 boff += 32;
2607 /* push sz bytes */
2608 if(sz > 0) {
2609 if(!usz && OL < woff + sz) { outbuf = realloc(outbuf, woff + sz); OL = outbuf.length; }
2610 while(sz-- > 0) { outbuf[woff++] = data[boff>>>3]; boff += 8; }
2611 }
2612 continue;
2613 } else if((header >> 1) == 1) {
2614 /* Fixed Huffman */
2615 max_len_1 = 9; max_len_2 = 5;
2616 } else {
2617 /* Dynamic Huffman */
2618 boff = dyn(data, boff);
2619 max_len_1 = dyn_len_1; max_len_2 = dyn_len_2;
2620 }
2621 for(;;) { // while(true) is apparently out of vogue in modern JS circles
2622 if(!usz && (OL < woff + 32767)) { outbuf = realloc(outbuf, woff + 32767); OL = outbuf.length; }
2623 /* ingest code and move read head */
2624 var bits = read_bits_n(data, boff, max_len_1);
2625 var code = (header>>>1) == 1 ? fix_lmap[bits] : dyn_lmap[bits];
2626 boff += code & 15; code >>>= 4;
2627 /* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */
2628 if(((code>>>8)&0xFF) === 0) outbuf[woff++] = code;
2629 else if(code == 256) break;
2630 else {
2631 code -= 257;
2632 var len_eb = (code < 8) ? 0 : ((code-4)>>2); if(len_eb > 5) len_eb = 0;
2633 var tgt = woff + LEN_LN[code];
2634 /* length extra bits */
2635 if(len_eb > 0) {
2636 tgt += read_bits_n(data, boff, len_eb);
2637 boff += len_eb;
2638 }
2639
2640 /* dist code */
2641 bits = read_bits_n(data, boff, max_len_2);
2642 code = (header>>>1) == 1 ? fix_dmap[bits] : dyn_dmap[bits];
2643 boff += code & 15; code >>>= 4;
2644 var dst_eb = (code < 4 ? 0 : (code-2)>>1);
2645 var dst = DST_LN[code];
2646 /* dist extra bits */
2647 if(dst_eb > 0) {
2648 dst += read_bits_n(data, boff, dst_eb);
2649 boff += dst_eb;
2650 }
2651
2652 /* in the common case, manual byte copy is faster than TA set / Buffer copy */
2653 if(!usz && OL < tgt) { outbuf = realloc(outbuf, tgt + 100); OL = outbuf.length; }
2654 while(woff < tgt) { outbuf[woff] = outbuf[woff - dst]; ++woff; }
2655 }
2656 }
2657 }
2658 if(usz) return [outbuf, (boff+7)>>>3];
2659 return [outbuf.slice(0, woff), (boff+7)>>>3];
2660}
2661
2662function _inflate(payload, usz) {
2663 var data = payload.slice(payload.l||0);
2664 var out = inflate(data, usz);
2665 payload.l += out[1];
2666 return out[0];
2667}
2668
2669function warn_or_throw(wrn, msg) {
2670 if(wrn) { if(typeof console !== 'undefined') console.error(msg); }
2671 else throw new Error(msg);
2672}
2673
2674function parse_zip(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
2675 var blob/*:CFBlob*/ = /*::(*/file/*:: :any)*/;
2676 prep_blob(blob, 0);
2677
2678 var FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = [];
2679 var o = {
2680 FileIndex: FileIndex,
2681 FullPaths: FullPaths
2682 };
2683 init_cfb(o, { root: options.root });
2684
2685 /* find end of central directory, start just after signature */
2686 var i = blob.length - 4;
2687 while((blob[i] != 0x50 || blob[i+1] != 0x4b || blob[i+2] != 0x05 || blob[i+3] != 0x06) && i >= 0) --i;
2688 blob.l = i + 4;
2689
2690 /* parse end of central directory */
2691 blob.l += 4;
2692 var fcnt = blob.read_shift(2);
2693 blob.l += 6;
2694 var start_cd = blob.read_shift(4);
2695
2696 /* parse central directory */
2697 blob.l = start_cd;
2698
2699 for(i = 0; i < fcnt; ++i) {
2700 /* trust local file header instead of CD entry */
2701 blob.l += 20;
2702 var csz = blob.read_shift(4);
2703 var usz = blob.read_shift(4);
2704 var namelen = blob.read_shift(2);
2705 var efsz = blob.read_shift(2);
2706 var fcsz = blob.read_shift(2);
2707 blob.l += 8;
2708 var offset = blob.read_shift(4);
2709 var EF = parse_extra_field(/*::(*/blob.slice(blob.l+namelen, blob.l+namelen+efsz)/*:: :any)*/);
2710 blob.l += namelen + efsz + fcsz;
2711
2712 var L = blob.l;
2713 blob.l = offset + 4;
2714 parse_local_file(blob, csz, usz, o, EF);
2715 blob.l = L;
2716 }
2717 return o;
2718}
2719
2720
2721/* head starts just after local file header signature */
2722function parse_local_file(blob/*:CFBlob*/, csz/*:number*/, usz/*:number*/, o/*:CFBContainer*/, EF) {
2723 /* [local file header] */
2724 blob.l += 2;
2725 var flags = blob.read_shift(2);
2726 var meth = blob.read_shift(2);
2727 var date = parse_dos_date(blob);
2728
2729 if(flags & 0x2041) throw new Error("Unsupported ZIP encryption");
2730 var crc32 = blob.read_shift(4);
2731 var _csz = blob.read_shift(4);
2732 var _usz = blob.read_shift(4);
2733
2734 var namelen = blob.read_shift(2);
2735 var efsz = blob.read_shift(2);
2736
2737 // TODO: flags & (1<<11) // UTF8
2738 var name = ""; for(var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]);
2739 if(efsz) {
2740 var ef = parse_extra_field(/*::(*/blob.slice(blob.l, blob.l + efsz)/*:: :any)*/);
2741 if((ef[0x5455]||{}).mt) date = ef[0x5455].mt;
2742 if(((EF||{})[0x5455]||{}).mt) date = EF[0x5455].mt;
2743 }
2744 blob.l += efsz;
2745
2746 /* [encryption header] */
2747
2748 /* [file data] */
2749 var data = blob.slice(blob.l, blob.l + _csz);
2750 switch(meth) {
2751 case 8: data = _inflateRawSync(blob, _usz); break;
2752 case 0: break; // TODO: scan for magic number
2753 default: throw new Error("Unsupported ZIP Compression method " + meth);
2754 }
2755
2756 /* [data descriptor] */
2757 var wrn = false;
2758 if(flags & 8) {
2759 crc32 = blob.read_shift(4);
2760 if(crc32 == 0x08074b50) { crc32 = blob.read_shift(4); wrn = true; }
2761 _csz = blob.read_shift(4);
2762 _usz = blob.read_shift(4);
2763 }
2764
2765 if(_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz);
2766 if(_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz);
2767 //var _crc32 = CRC32.buf(data, 0);
2768 //if((crc32>>0) != (_crc32>>0)) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32);
2769 cfb_add(o, name, data, {unsafe: true, mt: date});
2770}
2771function write_zip(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes*/ {
2772 var _opts = options || {};
2773 var out = [], cdirs = [];
2774 var o/*:CFBlob*/ = new_buf(1);
2775 var method = (_opts.compression ? 8 : 0), flags = 0;
2776 var desc = false;
2777 if(desc) flags |= 8;
2778 var i = 0, j = 0;
2779
2780 var start_cd = 0, fcnt = 0;
2781 var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0];
2782 var crcs = [];
2783 var sz_cd = 0;
2784
2785 for(i = 1; i < cfb.FullPaths.length; ++i) {
2786 fp = cfb.FullPaths[i].slice(root.length); fi = cfb.FileIndex[i];
2787 if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
2788 var start = start_cd;
2789
2790 /* TODO: CP437 filename */
2791 var namebuf = new_buf(fp.length);
2792 for(j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
2793 namebuf = namebuf.slice(0, namebuf.l);
2794 crcs[fcnt] = CRC32.buf(/*::((*/fi.content/*::||[]):any)*/, 0);
2795
2796 var outbuf = fi.content/*::||[]*/;
2797 if(method == 8) outbuf = _deflateRawSync(outbuf);
2798
2799 /* local file header */
2800 o = new_buf(30);
2801 o.write_shift(4, 0x04034b50);
2802 o.write_shift(2, 20);
2803 o.write_shift(2, flags);
2804 o.write_shift(2, method);
2805 /* TODO: last mod file time/date */
2806 if(fi.mt) write_dos_date(o, fi.mt);
2807 else o.write_shift(4, 0);
2808 o.write_shift(-4, (flags & 8) ? 0 : crcs[fcnt]);
2809 o.write_shift(4, (flags & 8) ? 0 : outbuf.length);
2810 o.write_shift(4, (flags & 8) ? 0 : /*::(*/fi.content/*::||[])*/.length);
2811 o.write_shift(2, namebuf.length);
2812 o.write_shift(2, 0);
2813
2814 start_cd += o.length;
2815 out.push(o);
2816 start_cd += namebuf.length;
2817 out.push(namebuf);
2818
2819 /* TODO: extra fields? */
2820
2821 /* TODO: encryption header ? */
2822
2823 start_cd += outbuf.length;
2824 out.push(outbuf);
2825
2826 /* data descriptor */
2827 if(flags & 8) {
2828 o = new_buf(12);
2829 o.write_shift(-4, crcs[fcnt]);
2830 o.write_shift(4, outbuf.length);
2831 o.write_shift(4, /*::(*/fi.content/*::||[])*/.length);
2832 start_cd += o.l;
2833 out.push(o);
2834 }
2835
2836 /* central directory */
2837 o = new_buf(46);
2838 o.write_shift(4, 0x02014b50);
2839 o.write_shift(2, 0);
2840 o.write_shift(2, 20);
2841 o.write_shift(2, flags);
2842 o.write_shift(2, method);
2843 o.write_shift(4, 0); /* TODO: last mod file time/date */
2844 o.write_shift(-4, crcs[fcnt]);
2845
2846 o.write_shift(4, outbuf.length);
2847 o.write_shift(4, /*::(*/fi.content/*::||[])*/.length);
2848 o.write_shift(2, namebuf.length);
2849 o.write_shift(2, 0);
2850 o.write_shift(2, 0);
2851 o.write_shift(2, 0);
2852 o.write_shift(2, 0);
2853 o.write_shift(4, 0);
2854 o.write_shift(4, start);
2855
2856 sz_cd += o.l;
2857 cdirs.push(o);
2858 sz_cd += namebuf.length;
2859 cdirs.push(namebuf);
2860 ++fcnt;
2861 }
2862
2863 /* end of central directory */
2864 o = new_buf(22);
2865 o.write_shift(4, 0x06054b50);
2866 o.write_shift(2, 0);
2867 o.write_shift(2, 0);
2868 o.write_shift(2, fcnt);
2869 o.write_shift(2, fcnt);
2870 o.write_shift(4, sz_cd);
2871 o.write_shift(4, start_cd);
2872 o.write_shift(2, 0);
2873
2874 return bconcat(([bconcat((out/*:any*/)), bconcat(cdirs), o]/*:any*/));
2875}
2876var ContentTypeMap = ({
2877 "htm": "text/html",
2878 "xml": "text/xml",
2879
2880 "gif": "image/gif",
2881 "jpg": "image/jpeg",
2882 "png": "image/png",
2883
2884 "mso": "application/x-mso",
2885 "thmx": "application/vnd.ms-officetheme",
2886 "sh33tj5": "application/octet-stream"
2887}/*:any*/);
2888
2889function get_content_type(fi/*:CFBEntry*/, fp/*:string*/)/*:string*/ {
2890 if(fi.ctype) return fi.ctype;
2891
2892 var ext = fi.name || "", m = ext.match(/\.([^\.]+)$/);
2893 if(m && ContentTypeMap[m[1]]) return ContentTypeMap[m[1]];
2894
2895 if(fp) {
2896 m = (ext = fp).match(/[\.\\]([^\.\\])+$/);
2897 if(m && ContentTypeMap[m[1]]) return ContentTypeMap[m[1]];
2898 }
2899
2900 return "application/octet-stream";
2901}
2902
2903/* 76 character chunks TODO: intertwine encoding */
2904function write_base64_76(bstr/*:string*/)/*:string*/ {
2905 var data = Base64_encode(bstr);
2906 var o = [];
2907 for(var i = 0; i < data.length; i+= 76) o.push(data.slice(i, i+76));
2908 return o.join("\r\n") + "\r\n";
2909}
2910
2911/*
2912Rules for QP:
2913 - escape =## applies for all non-display characters and literal "="
2914 - space or tab at end of line must be encoded
2915 - \r\n newlines can be preserved, but bare \r and \n must be escaped
2916 - lines must not exceed 76 characters, use soft breaks =\r\n
2917
2918TODO: Some files from word appear to write line extensions with bare equals:
2919
2920```
2921<table class=3DMsoTableGrid border=3D1 cellspacing=3D0 cellpadding=3D0 width=
2922="70%"
2923```
2924*/
2925function write_quoted_printable(text/*:string*/)/*:string*/ {
2926 var encoded = text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF=]/g, function(c) {
2927 var w = c.charCodeAt(0).toString(16).toUpperCase();
2928 return "=" + (w.length == 1 ? "0" + w : w);
2929 });
2930
2931 encoded = encoded.replace(/ $/mg, "=20").replace(/\t$/mg, "=09");
2932
2933 if(encoded.charAt(0) == "\n") encoded = "=0D" + encoded.slice(1);
2934 encoded = encoded.replace(/\r(?!\n)/mg, "=0D").replace(/\n\n/mg, "\n=0A").replace(/([^\r\n])\n/mg, "$1=0A");
2935
2936 var o/*:Array<string>*/ = [], split = encoded.split("\r\n");
2937 for(var si = 0; si < split.length; ++si) {
2938 var str = split[si];
2939 if(str.length == 0) { o.push(""); continue; }
2940 for(var i = 0; i < str.length;) {
2941 var end = 76;
2942 var tmp = str.slice(i, i + end);
2943 if(tmp.charAt(end - 1) == "=") end --;
2944 else if(tmp.charAt(end - 2) == "=") end -= 2;
2945 else if(tmp.charAt(end - 3) == "=") end -= 3;
2946 tmp = str.slice(i, i + end);
2947 i += end;
2948 if(i < str.length) tmp += "=";
2949 o.push(tmp);
2950 }
2951 }
2952
2953 return o.join("\r\n");
2954}
2955function parse_quoted_printable(data/*:Array<string>*/)/*:RawBytes*/ {
2956 var o = [];
2957
2958 /* unify long lines */
2959 for(var di = 0; di < data.length; ++di) {
2960 var line = data[di];
2961 while(di <= data.length && line.charAt(line.length - 1) == "=") line = line.slice(0, line.length - 1) + data[++di];
2962 o.push(line);
2963 }
2964
2965 /* decode */
2966 for(var oi = 0; oi < o.length; ++oi) o[oi] = o[oi].replace(/[=][0-9A-Fa-f]{2}/g, function($$) { return String.fromCharCode(parseInt($$.slice(1), 16)); });
2967 return s2a(o.join("\r\n"));
2968}
2969
2970
2971function parse_mime(cfb/*:CFBContainer*/, data/*:Array<string>*/, root/*:string*/)/*:void*/ {
2972 var fname = "", cte = "", ctype = "", fdata;
2973 var di = 0;
2974 for(;di < 10; ++di) {
2975 var line = data[di];
2976 if(!line || line.match(/^\s*$/)) break;
2977 var m = line.match(/^(.*?):\s*([^\s].*)$/);
2978 if(m) switch(m[1].toLowerCase()) {
2979 case "content-location": fname = m[2].trim(); break;
2980 case "content-type": ctype = m[2].trim(); break;
2981 case "content-transfer-encoding": cte = m[2].trim(); break;
2982 }
2983 }
2984 ++di;
2985 switch(cte.toLowerCase()) {
2986 case 'base64': fdata = s2a(Base64_decode(data.slice(di).join(""))); break;
2987 case 'quoted-printable': fdata = parse_quoted_printable(data.slice(di)); break;
2988 default: throw new Error("Unsupported Content-Transfer-Encoding " + cte);
2989 }
2990 var file = cfb_add(cfb, fname.slice(root.length), fdata, {unsafe: true});
2991 if(ctype) file.ctype = ctype;
2992}
2993
2994function parse_mad(file/*:RawBytes*/, options/*:CFBReadOpts*/)/*:CFBContainer*/ {
2995 if(a2s(file.slice(0,13)).toLowerCase() != "mime-version:") throw new Error("Unsupported MAD header");
2996 var root = (options && options.root || "");
2997 // $FlowIgnore
2998 var data = (has_buf && Buffer.isBuffer(file) ? file.toString("binary") : a2s(file)).split("\r\n");
2999 var di = 0, row = "";
3000
3001 /* if root is not specified, scan for the common prefix */
3002 for(di = 0; di < data.length; ++di) {
3003 row = data[di];
3004 if(!/^Content-Location:/i.test(row)) continue;
3005 row = row.slice(row.indexOf("file"));
3006 if(!root) root = row.slice(0, row.lastIndexOf("/") + 1);
3007 if(row.slice(0, root.length) == root) continue;
3008 while(root.length > 0) {
3009 root = root.slice(0, root.length - 1);
3010 root = root.slice(0, root.lastIndexOf("/") + 1);
3011 if(row.slice(0,root.length) == root) break;
3012 }
3013 }
3014
3015 var mboundary = (data[1] || "").match(/boundary="(.*?)"/);
3016 if(!mboundary) throw new Error("MAD cannot find boundary");
3017 var boundary = "--" + (mboundary[1] || "");
3018
3019 var FileIndex/*:CFBFileIndex*/ = [], FullPaths/*:Array<string>*/ = [];
3020 var o = {
3021 FileIndex: FileIndex,
3022 FullPaths: FullPaths
3023 };
3024 init_cfb(o);
3025 var start_di, fcnt = 0;
3026 for(di = 0; di < data.length; ++di) {
3027 var line = data[di];
3028 if(line !== boundary && line !== boundary + "--") continue;
3029 if(fcnt++) parse_mime(o, data.slice(start_di, di), root);
3030 start_di = di;
3031 }
3032 return o;
3033}
3034
3035function write_mad(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:string*/ {
3036 var opts = options || {};
3037 var boundary = opts.boundary || "SheetJS";
3038 boundary = '------=' + boundary;
3039
3040 var out = [
3041 'MIME-Version: 1.0',
3042 'Content-Type: multipart/related; boundary="' + boundary.slice(2) + '"',
3043 '',
3044 '',
3045 ''
3046 ];
3047
3048 var root = cfb.FullPaths[0], fp = root, fi = cfb.FileIndex[0];
3049 for(var i = 1; i < cfb.FullPaths.length; ++i) {
3050 fp = cfb.FullPaths[i].slice(root.length);
3051 fi = cfb.FileIndex[i];
3052 if(!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
3053
3054 /* Normalize filename */
3055 fp = fp.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF]/g, function(c) {
3056 return "_x" + c.charCodeAt(0).toString(16) + "_";
3057 }).replace(/[\u0080-\uFFFF]/g, function(u) {
3058 return "_u" + u.charCodeAt(0).toString(16) + "_";
3059 });
3060
3061 /* Extract content as binary string */
3062 var ca = fi.content;
3063 // $FlowIgnore
3064 var cstr = has_buf && Buffer.isBuffer(ca) ? ca.toString("binary") : a2s(ca);
3065
3066 /* 4/5 of first 1024 chars ascii -> quoted printable, else base64 */
3067 var dispcnt = 0, L = Math.min(1024, cstr.length), cc = 0;
3068 for(var csl = 0; csl <= L; ++csl) if((cc=cstr.charCodeAt(csl)) >= 0x20 && cc < 0x80) ++dispcnt;
3069 var qp = dispcnt >= L * 4 / 5;
3070
3071 out.push(boundary);
3072 out.push('Content-Location: ' + (opts.root || 'file:///C:/SheetJS/') + fp);
3073 out.push('Content-Transfer-Encoding: ' + (qp ? 'quoted-printable' : 'base64'));
3074 out.push('Content-Type: ' + get_content_type(fi, fp));
3075 out.push('');
3076
3077 out.push(qp ? write_quoted_printable(cstr) : write_base64_76(cstr));
3078 }
3079 out.push(boundary + '--\r\n');
3080 return out.join("\r\n");
3081}
3082function cfb_new(opts/*:?any*/)/*:CFBContainer*/ {
3083 var o/*:CFBContainer*/ = ({}/*:any*/);
3084 init_cfb(o, opts);
3085 return o;
3086}
3087
3088function cfb_add(cfb/*:CFBContainer*/, name/*:string*/, content/*:?RawBytes*/, opts/*:?any*/)/*:CFBEntry*/ {
3089 var unsafe = opts && opts.unsafe;
3090 if(!unsafe) init_cfb(cfb);
3091 var file = !unsafe && CFB.find(cfb, name);
3092 if(!file) {
3093 var fpath/*:string*/ = cfb.FullPaths[0];
3094 if(name.slice(0, fpath.length) == fpath) fpath = name;
3095 else {
3096 if(fpath.slice(-1) != "/") fpath += "/";
3097 fpath = (fpath + name).replace("//","/");
3098 }
3099 file = ({name: filename(name), type: 2}/*:any*/);
3100 cfb.FileIndex.push(file);
3101 cfb.FullPaths.push(fpath);
3102 if(!unsafe) CFB.utils.cfb_gc(cfb);
3103 }
3104 /*:: if(!file) throw new Error("unreachable"); */
3105 file.content = (content/*:any*/);
3106 file.size = content ? content.length : 0;
3107 if(opts) {
3108 if(opts.CLSID) file.clsid = opts.CLSID;
3109 if(opts.mt) file.mt = opts.mt;
3110 if(opts.ct) file.ct = opts.ct;
3111 }
3112 return file;
3113}
3114
3115function cfb_del(cfb/*:CFBContainer*/, name/*:string*/)/*:boolean*/ {
3116 init_cfb(cfb);
3117 var file = CFB.find(cfb, name);
3118 if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {
3119 cfb.FileIndex.splice(j, 1);
3120 cfb.FullPaths.splice(j, 1);
3121 return true;
3122 }
3123 return false;
3124}
3125
3126function cfb_mov(cfb/*:CFBContainer*/, old_name/*:string*/, new_name/*:string*/)/*:boolean*/ {
3127 init_cfb(cfb);
3128 var file = CFB.find(cfb, old_name);
3129 if(file) for(var j = 0; j < cfb.FileIndex.length; ++j) if(cfb.FileIndex[j] == file) {
3130 cfb.FileIndex[j].name = filename(new_name);
3131 cfb.FullPaths[j] = new_name;
3132 return true;
3133 }
3134 return false;
3135}
3136
3137function cfb_gc(cfb/*:CFBContainer*/)/*:void*/ { rebuild_cfb(cfb, true); }
3138
3139exports.find = find;
3140exports.read = read;
3141exports.parse = parse;
3142exports.write = write;
3143exports.writeFile = write_file;
3144exports.utils = {
3145 cfb_new: cfb_new,
3146 cfb_add: cfb_add,
3147 cfb_del: cfb_del,
3148 cfb_mov: cfb_mov,
3149 cfb_gc: cfb_gc,
3150 ReadShift: ReadShift,
3151 CheckField: CheckField,
3152 prep_blob: prep_blob,
3153 bconcat: bconcat,
3154 use_zlib: use_zlib,
3155 _deflateRaw: _deflate,
3156 _inflateRaw: _inflate,
3157 consts: consts
3158};
3159
3160return exports;
3161})();
3162
3163let _fs = void 0;
3164function set_fs(fs) { _fs = fs; }
3165export { set_fs };
3166
3167/* normalize data for blob ctor */
3168function blobify(data) {
3169 if(typeof data === "string") return s2ab(data);
3170 if(Array.isArray(data)) return a2u(data);
3171 return data;
3172}
3173/* write or download file */
3174function write_dl(fname/*:string*/, payload/*:any*/, enc/*:?string*/) {
3175 /*global IE_SaveFile, Blob, navigator, saveAs, document, File, chrome */
3176 if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
3177 if(typeof Deno !== 'undefined') {
3178 /* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
3179 if(enc && typeof payload == "string") switch(enc) {
3180 case "utf8": payload = new TextEncoder(enc).encode(payload); break;
3181 case "binary": payload = s2ab(payload); break;
3182 /* TODO: binary equivalent */
3183 default: throw new Error("Unsupported encoding " + enc);
3184 }
3185 return Deno.writeFileSync(fname, payload);
3186 }
3187 var data = (enc == "utf8") ? utf8write(payload) : payload;
3188 /*:: declare var IE_SaveFile: any; */
3189 if(typeof IE_SaveFile !== 'undefined') return IE_SaveFile(data, fname);
3190 if(typeof Blob !== 'undefined') {
3191 var blob = new Blob([blobify(data)], {type:"application/octet-stream"});
3192 /*:: declare var navigator: any; */
3193 if(typeof navigator !== 'undefined' && navigator.msSaveBlob) return navigator.msSaveBlob(blob, fname);
3194 /*:: declare var saveAs: any; */
3195 if(typeof saveAs !== 'undefined') return saveAs(blob, fname);
3196 if(typeof URL !== 'undefined' && typeof document !== 'undefined' && document.createElement && URL.createObjectURL) {
3197 var url = URL.createObjectURL(blob);
3198 /*:: declare var chrome: any; */
3199 if(typeof chrome === 'object' && typeof (chrome.downloads||{}).download == "function") {
3200 if(URL.revokeObjectURL && typeof setTimeout !== 'undefined') setTimeout(function() { URL.revokeObjectURL(url); }, 60000);
3201 return chrome.downloads.download({ url: url, filename: fname, saveAs: true});
3202 }
3203 var a = document.createElement("a");
3204 if(a.download != null) {
3205 /*:: if(document.body == null) throw new Error("unreachable"); */
3206 a.download = fname; a.href = url; document.body.appendChild(a); a.click();
3207 /*:: if(document.body == null) throw new Error("unreachable"); */ document.body.removeChild(a);
3208 if(URL.revokeObjectURL && typeof setTimeout !== 'undefined') setTimeout(function() { URL.revokeObjectURL(url); }, 60000);
3209 return url;
3210 }
3211 }
3212 }
3213 // $FlowIgnore
3214 if(typeof $ !== 'undefined' && typeof File !== 'undefined' && typeof Folder !== 'undefined') try { // extendscript
3215 // $FlowIgnore
3216 var out = File(fname); out.open("w"); out.encoding = "binary";
3217 if(Array.isArray(payload)) payload = a2s(payload);
3218 out.write(payload); out.close(); return payload;
3219 } catch(e) { if(!e.message || !e.message.match(/onstruct/)) throw e; }
3220 throw new Error("cannot save file " + fname);
3221}
3222
3223/* read binary data from file */
3224function read_binary(path/*:string*/) {
3225 if(typeof _fs !== 'undefined') return _fs.readFileSync(path);
3226 if(typeof Deno !== 'undefined') return Deno.readFileSync(path);
3227 // $FlowIgnore
3228 if(typeof $ !== 'undefined' && typeof File !== 'undefined' && typeof Folder !== 'undefined') try { // extendscript
3229 // $FlowIgnore
3230 var infile = File(path); infile.open("r"); infile.encoding = "binary";
3231 var data = infile.read(); infile.close();
3232 return data;
3233 } catch(e) { if(!e.message || !e.message.match(/onstruct/)) throw e; }
3234 throw new Error("Cannot access file " + path);
3235}
3236function keys(o/*:any*/)/*:Array<any>*/ {
3237 var ks = Object.keys(o), o2 = [];
3238 for(var i = 0; i < ks.length; ++i) if(Object.prototype.hasOwnProperty.call(o, ks[i])) o2.push(ks[i]);
3239 return o2;
3240}
3241
3242function evert_key(obj/*:any*/, key/*:string*/)/*:EvertType*/ {
3243 var o = ([]/*:any*/), K = keys(obj);
3244 for(var i = 0; i !== K.length; ++i) if(o[obj[K[i]][key]] == null) o[obj[K[i]][key]] = K[i];
3245 return o;
3246}
3247
3248function evert(obj/*:any*/)/*:EvertType*/ {
3249 var o = ([]/*:any*/), K = keys(obj);
3250 for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = K[i];
3251 return o;
3252}
3253
3254function evert_num(obj/*:any*/)/*:EvertNumType*/ {
3255 var o = ([]/*:any*/), K = keys(obj);
3256 for(var i = 0; i !== K.length; ++i) o[obj[K[i]]] = parseInt(K[i],10);
3257 return o;
3258}
3259
3260function evert_arr(obj/*:any*/)/*:EvertArrType*/ {
3261 var o/*:EvertArrType*/ = ([]/*:any*/), K = keys(obj);
3262 for(var i = 0; i !== K.length; ++i) {
3263 if(o[obj[K[i]]] == null) o[obj[K[i]]] = [];
3264 o[obj[K[i]]].push(K[i]);
3265 }
3266 return o;
3267}
3268
3269var basedate = /*#__PURE__*/new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
3270function datenum(v/*:Date*/, date1904/*:?boolean*/)/*:number*/ {
3271 var epoch = /*#__PURE__*/v.getTime();
3272 if(date1904) epoch -= 1462*24*60*60*1000;
3273 var dnthresh = /*#__PURE__*/basedate.getTime() + (/*#__PURE__*/v.getTimezoneOffset() - /*#__PURE__*/basedate.getTimezoneOffset()) * 60000;
3274 return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
3275}
3276var refdate = /*#__PURE__*/new Date();
3277var dnthresh = /*#__PURE__*/basedate.getTime() + (/*#__PURE__*/refdate.getTimezoneOffset() - /*#__PURE__*/basedate.getTimezoneOffset()) * 60000;
3278var refoffset = /*#__PURE__*/refdate.getTimezoneOffset();
3279function numdate(v/*:number*/)/*:Date*/ {
3280 var out = new Date();
3281 out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh);
3282 if (out.getTimezoneOffset() !== refoffset) {
3283 out.setTime(out.getTime() + (out.getTimezoneOffset() - refoffset) * 60000);
3284 }
3285 return out;
3286}
3287
3288/* ISO 8601 Duration */
3289function parse_isodur(s) {
3290 var sec = 0, mt = 0, time = false;
3291 var m = s.match(/P([0-9\.]+Y)?([0-9\.]+M)?([0-9\.]+D)?T([0-9\.]+H)?([0-9\.]+M)?([0-9\.]+S)?/);
3292 if(!m) throw new Error("|" + s + "| is not an ISO8601 Duration");
3293 for(var i = 1; i != m.length; ++i) {
3294 if(!m[i]) continue;
3295 mt = 1;
3296 if(i > 3) time = true;
3297 switch(m[i].slice(m[i].length-1)) {
3298 case 'Y':
3299 throw new Error("Unsupported ISO Duration Field: " + m[i].slice(m[i].length-1));
3300 case 'D': mt *= 24;
3301 /* falls through */
3302 case 'H': mt *= 60;
3303 /* falls through */
3304 case 'M':
3305 if(!time) throw new Error("Unsupported ISO Duration Field: M");
3306 else mt *= 60;
3307 /* falls through */
3308 case 'S': break;
3309 }
3310 sec += mt * parseInt(m[i], 10);
3311 }
3312 return sec;
3313}
3314
3315var good_pd_date_1 = /*#__PURE__*/new Date('2017-02-19T19:06:09.000Z');
3316var good_pd_date = /*#__PURE__*/isNaN(/*#__PURE__*/good_pd_date_1.getFullYear()) ? /*#__PURE__*/new Date('2/19/17') : good_pd_date_1;
3317var good_pd = /*#__PURE__*/good_pd_date.getFullYear() == 2017;
3318/* parses a date as a local date */
3319function parseDate(str/*:string|Date*/, fixdate/*:?number*/)/*:Date*/ {
3320 var d = new Date(str);
3321 if(good_pd) {
3322 /*:: if(fixdate == null) fixdate = 0; */
3323 if(fixdate > 0) d.setTime(d.getTime() + d.getTimezoneOffset() * 60 * 1000);
3324 else if(fixdate < 0) d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000);
3325 return d;
3326 }
3327 if(str instanceof Date) return str;
3328 if(good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
3329 var s = d.getFullYear();
3330 if(str.indexOf("" + s) > -1) return d;
3331 d.setFullYear(d.getFullYear() + 100); return d;
3332 }
3333 var n = str.match(/\d+/g)||["2017","2","19","0","0","0"];
3334 var out = new Date(+n[0], +n[1] - 1, +n[2], (+n[3]||0), (+n[4]||0), (+n[5]||0));
3335 if(str.indexOf("Z") > -1) out = new Date(out.getTime() - out.getTimezoneOffset() * 60 * 1000);
3336 return out;
3337}
3338
3339function cc2str(arr/*:Array<number>*/, debomit)/*:string*/ {
3340 if(has_buf && Buffer.isBuffer(arr)) {
3341 if(debomit) {
3342 if(arr[0] == 0xFF && arr[1] == 0xFE) return utf8write(arr.slice(2).toString("utf16le"));
3343 if(arr[1] == 0xFE && arr[2] == 0xFF) return utf8write(utf16beread(arr.slice(2).toString("binary")));
3344 }
3345 return arr.toString("binary");
3346 }
3347
3348 if(typeof TextDecoder !== "undefined") try {
3349 if(debomit) {
3350 if(arr[0] == 0xFF && arr[1] == 0xFE) return utf8write(new TextDecoder("utf-16le").decode(arr.slice(2)));
3351 if(arr[0] == 0xFE && arr[1] == 0xFF) return utf8write(new TextDecoder("utf-16be").decode(arr.slice(2)));
3352 }
3353 var rev = {
3354 "\u20ac": "\x80", "\u201a": "\x82", "\u0192": "\x83", "\u201e": "\x84",
3355 "\u2026": "\x85", "\u2020": "\x86", "\u2021": "\x87", "\u02c6": "\x88",
3356 "\u2030": "\x89", "\u0160": "\x8a", "\u2039": "\x8b", "\u0152": "\x8c",
3357 "\u017d": "\x8e", "\u2018": "\x91", "\u2019": "\x92", "\u201c": "\x93",
3358 "\u201d": "\x94", "\u2022": "\x95", "\u2013": "\x96", "\u2014": "\x97",
3359 "\u02dc": "\x98", "\u2122": "\x99", "\u0161": "\x9a", "\u203a": "\x9b",
3360 "\u0153": "\x9c", "\u017e": "\x9e", "\u0178": "\x9f"
3361 };
3362 if(Array.isArray(arr)) arr = new Uint8Array(arr);
3363 return new TextDecoder("latin1").decode(arr).replace(/[€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ]/g, function(c) { return rev[c] || c; });
3364 } catch(e) {}
3365
3366 var o = [];
3367 for(var i = 0; i != arr.length; ++i) o.push(String.fromCharCode(arr[i]));
3368 return o.join("");
3369}
3370
3371function dup(o/*:any*/)/*:any*/ {
3372 if(typeof JSON != 'undefined' && !Array.isArray(o)) return JSON.parse(JSON.stringify(o));
3373 if(typeof o != 'object' || o == null) return o;
3374 if(o instanceof Date) return new Date(o.getTime());
3375 var out = {};
3376 for(var k in o) if(Object.prototype.hasOwnProperty.call(o, k)) out[k] = dup(o[k]);
3377 return out;
3378}
3379
3380function fill(c/*:string*/,l/*:number*/)/*:string*/ { var o = ""; while(o.length < l) o+=c; return o; }
3381
3382/* TODO: stress test */
3383function fuzzynum(s/*:string*/)/*:number*/ {
3384 var v/*:number*/ = Number(s);
3385 if(!isNaN(v)) return isFinite(v) ? v : NaN;
3386 if(!/\d/.test(s)) return v;
3387 var wt = 1;
3388 var ss = s.replace(/([\d]),([\d])/g,"$1$2").replace(/[$]/g,"").replace(/[%]/g, function() { wt *= 100; return "";});
3389 if(!isNaN(v = Number(ss))) return v / wt;
3390 ss = ss.replace(/[(](.*)[)]/,function($$, $1) { wt = -wt; return $1;});
3391 if(!isNaN(v = Number(ss))) return v / wt;
3392 return v;
3393}
3394var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
3395function fuzzydate(s/*:string*/)/*:Date*/ {
3396 var o = new Date(s), n = new Date(NaN);
3397 var y = o.getYear(), m = o.getMonth(), d = o.getDate();
3398 if(isNaN(d)) return n;
3399 var lower = s.toLowerCase();
3400 if(lower.match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) {
3401 lower = lower.replace(/[^a-z]/g,"").replace(/([^a-z]|^)[ap]m?([^a-z]|$)/,"");
3402 if(lower.length > 3 && lower_months.indexOf(lower) == -1) return n;
3403 } else if(lower.match(/[a-z]/)) return n;
3404 if(y < 0 || y > 8099) return n;
3405 if((m > 0 || d > 1) && y != 101) return o;
3406 if(s.match(/[^-0-9:,\/\\]/)) return n;
3407 return o;
3408}
3409
3410var split_regex = /*#__PURE__*/(function() {
3411 var safe_split_regex = "abacaba".split(/(:?b)/i).length == 5;
3412 return function split_regex(str/*:string*/, re, def/*:string*/)/*:Array<string>*/ {
3413 if(safe_split_regex || typeof re == "string") return str.split(re);
3414 var p = str.split(re), o = [p[0]];
3415 for(var i = 1; i < p.length; ++i) { o.push(def); o.push(p[i]); }
3416 return o;
3417 };
3418})();
3419function getdatastr(data)/*:?string*/ {
3420 if(!data) return null;
3421 if(data.content && data.type) return cc2str(data.content, true);
3422 if(data.data) return debom(data.data);
3423 if(data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
3424 if(data.asBinary) return debom(data.asBinary());
3425 if(data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(),0)));
3426 return null;
3427}
3428
3429function getdatabin(data) {
3430 if(!data) return null;
3431 if(data.data) return char_codes(data.data);
3432 if(data.asNodeBuffer && has_buf) return data.asNodeBuffer();
3433 if(data._data && data._data.getContent) {
3434 var o = data._data.getContent();
3435 if(typeof o == "string") return char_codes(o);
3436 return Array.prototype.slice.call(o);
3437 }
3438 if(data.content && data.type) return data.content;
3439 return null;
3440}
3441
3442function getdata(data) { return (data && data.name.slice(-4) === ".bin") ? getdatabin(data) : getdatastr(data); }
3443
3444/* Part 2 Section 10.1.2 "Mapping Content Types" Names are case-insensitive */
3445/* OASIS does not comment on filename case sensitivity */
3446function safegetzipfile(zip, file/*:string*/) {
3447 var k = zip.FullPaths || keys(zip.files);
3448 var f = file.toLowerCase().replace(/[\/]/g, '\\'), g = f.replace(/\\/g,'\/');
3449 for(var i=0; i<k.length; ++i) {
3450 var n = k[i].replace(/^Root Entry[\/]/,"").toLowerCase();
3451 if(f == n || g == n) return zip.files ? zip.files[k[i]] : zip.FileIndex[i];
3452 }
3453 return null;
3454}
3455
3456function getzipfile(zip, file/*:string*/) {
3457 var o = safegetzipfile(zip, file);
3458 if(o == null) throw new Error("Cannot find file " + file + " in zip");
3459 return o;
3460}
3461
3462function getzipdata(zip, file/*:string*/, safe/*:?boolean*/)/*:any*/ {
3463 if(!safe) return getdata(getzipfile(zip, file));
3464 if(!file) return null;
3465 try { return getzipdata(zip, file); } catch(e) { return null; }
3466}
3467
3468function getzipstr(zip, file/*:string*/, safe/*:?boolean*/)/*:?string*/ {
3469 if(!safe) return getdatastr(getzipfile(zip, file));
3470 if(!file) return null;
3471 try { return getzipstr(zip, file); } catch(e) { return null; }
3472}
3473
3474function getzipbin(zip, file/*:string*/, safe/*:?boolean*/)/*:any*/ {
3475 if(!safe) return getdatabin(getzipfile(zip, file));
3476 if(!file) return null;
3477 try { return getzipbin(zip, file); } catch(e) { return null; }
3478}
3479
3480function zipentries(zip) {
3481 var k = zip.FullPaths || keys(zip.files), o = [];
3482 for(var i = 0; i < k.length; ++i) if(k[i].slice(-1) != '/') o.push(k[i].replace(/^Root Entry[\/]/, ""));
3483 return o.sort();
3484}
3485
3486function zip_add_file(zip, path, content) {
3487 if(zip.FullPaths) {
3488 if(typeof content == "string") {
3489 var res;
3490 if(has_buf) res = Buffer_from(content);
3491 /* TODO: investigate performance in Edge 13 */
3492 //else if(typeof TextEncoder !== "undefined") res = new TextEncoder().encode(content);
3493 else res = utf8decode(content);
3494 return CFB.utils.cfb_add(zip, path, res);
3495 }
3496 CFB.utils.cfb_add(zip, path, content);
3497 }
3498 else zip.file(path, content);
3499}
3500
3501function zip_new() { return CFB.utils.cfb_new(); }
3502
3503function zip_read(d, o) {
3504 switch(o.type) {
3505 case "base64": return CFB.read(d, { type: "base64" });
3506 case "binary": return CFB.read(d, { type: "binary" });
3507 case "buffer": case "array": return CFB.read(d, { type: "buffer" });
3508 }
3509 throw new Error("Unrecognized type " + o.type);
3510}
3511
3512function resolve_path(path/*:string*/, base/*:string*/)/*:string*/ {
3513 if(path.charAt(0) == "/") return path.slice(1);
3514 var result = base.split('/');
3515 if(base.slice(-1) != "/") result.pop(); // folder path
3516 var target = path.split('/');
3517 while (target.length !== 0) {
3518 var step = target.shift();
3519 if (step === '..') result.pop();
3520 else if (step !== '.') result.push(step);
3521 }
3522 return result.join('/');
3523}
3524var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
3525var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
3526var tagregex1=/<[\/\?]?[a-zA-Z0-9:_-]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s*[\/\?]?>/mg, tagregex2 = /<[^>]*>/g;
3527var tagregex = /*#__PURE__*/XML_HEADER.match(tagregex1) ? tagregex1 : tagregex2;
3528var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
3529function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
3530 var z = ({}/*:any*/);
3531 var eq = 0, c = 0;
3532 for(; eq !== tag.length; ++eq) if((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
3533 if(!skip_root) z[0] = tag.slice(0, eq);
3534 if(eq === tag.length) return z;
3535 var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
3536 if(m) for(i = 0; i != m.length; ++i) {
3537 cc = m[i];
3538 for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
3539 q = cc.slice(0,c).trim();
3540 while(cc.charCodeAt(c+1) == 32) ++c;
3541 quot = ((eq=cc.charCodeAt(c+1)) == 34 || eq == 39) ? 1 : 0;
3542 v = cc.slice(c+1+quot, cc.length-quot);
3543 for(j=0;j!=q.length;++j) if(q.charCodeAt(j) === 58) break;
3544 if(j===q.length) {
3545 if(q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
3546 z[q] = v;
3547 if(!skip_LC) z[q.toLowerCase()] = v;
3548 }
3549 else {
3550 var k = (j===5 && q.slice(0,5)==="xmlns"?"xmlns":"")+q.slice(j+1);
3551 if(z[k] && q.slice(j-3,j) == "ext") continue; // from ods
3552 z[k] = v;
3553 if(!skip_LC) z[k.toLowerCase()] = v;
3554 }
3555 }
3556 return z;
3557}
3558function strip_ns(x/*:string*/)/*:string*/ { return x.replace(nsregex2, "<$1"); }
3559
3560var encodings = {
3561 '&quot;': '"',
3562 '&apos;': "'",
3563 '&gt;': '>',
3564 '&lt;': '<',
3565 '&amp;': '&'
3566};
3567var rencoding = /*#__PURE__*/evert(encodings);
3568//var rencstr = "&<>'\"".split("");
3569
3570// TODO: CP remap (need to read file version to determine OS)
3571var unescapexml/*:StringConv*/ = /*#__PURE__*/(function() {
3572 /* 22.4.2.4 bstr (Basic String) */
3573 var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\da-fA-F]+));/ig, coderegex = /_x([\da-fA-F]{4})_/ig;
3574 return function unescapexml(text/*:string*/)/*:string*/ {
3575 var s = text + '', i = s.indexOf("<![CDATA[");
3576 if(i == -1) return s.replace(encregex, function($$, $1) { return encodings[$$]||String.fromCharCode(parseInt($1,$$.indexOf("x")>-1?16:10))||$$; }).replace(coderegex,function(m,c) {return String.fromCharCode(parseInt(c,16));});
3577 var j = s.indexOf("]]>");
3578 return unescapexml(s.slice(0, i)) + s.slice(i+9,j) + unescapexml(s.slice(j+3));
3579 };
3580})();
3581
3582var decregex=/[&<>'"]/g, charegex = /[\u0000-\u0008\u000b-\u001f]/g;
3583function escapexml(text/*:string*/)/*:string*/{
3584 var s = text + '';
3585 return s.replace(decregex, function(y) { return rencoding[y]; }).replace(charegex,function(s) { return "_x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + "_";});
3586}
3587function escapexmltag(text/*:string*/)/*:string*/{ return escapexml(text).replace(/ /g,"_x0020_"); }
3588
3589var htmlcharegex = /[\u0000-\u001f]/g;
3590function escapehtml(text/*:string*/)/*:string*/{
3591 var s = text + '';
3592 return s.replace(decregex, function(y) { return rencoding[y]; }).replace(/\n/g, "<br/>").replace(htmlcharegex,function(s) { return "&#x" + ("000"+s.charCodeAt(0).toString(16)).slice(-4) + ";"; });
3593}
3594
3595function escapexlml(text/*:string*/)/*:string*/{
3596 var s = text + '';
3597 return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
3598}
3599
3600/* TODO: handle codepages */
3601var xlml_fixstr/*:StringConv*/ = /*#__PURE__*/(function() {
3602 var entregex = /&#(\d+);/g;
3603 function entrepl($$/*:string*/,$1/*:string*/)/*:string*/ { return String.fromCharCode(parseInt($1,10)); }
3604 return function xlml_fixstr(str/*:string*/)/*:string*/ { return str.replace(entregex,entrepl); };
3605})();
3606function xlml_unfixstr(str/*:string*/)/*:string*/ { return str.replace(/(\r\n|[\r\n])/g,"\&#10;"); }
3607
3608function parsexmlbool(value/*:any*/)/*:boolean*/ {
3609 switch(value) {
3610 case 1: case true: case '1': case 'true': case 'TRUE': return true;
3611 /* case '0': case 'false': case 'FALSE':*/
3612 default: return false;
3613 }
3614}
3615
3616function utf8reada(orig/*:string*/)/*:string*/ {
3617 var out = "", i = 0, c = 0, d = 0, e = 0, f = 0, w = 0;
3618 while (i < orig.length) {
3619 c = orig.charCodeAt(i++);
3620 if (c < 128) { out += String.fromCharCode(c); continue; }
3621 d = orig.charCodeAt(i++);
3622 if (c>191 && c<224) { f = ((c & 31) << 6); f |= (d & 63); out += String.fromCharCode(f); continue; }
3623 e = orig.charCodeAt(i++);
3624 if (c < 240) { out += String.fromCharCode(((c & 15) << 12) | ((d & 63) << 6) | (e & 63)); continue; }
3625 f = orig.charCodeAt(i++);
3626 w = (((c & 7) << 18) | ((d & 63) << 12) | ((e & 63) << 6) | (f & 63))-65536;
3627 out += String.fromCharCode(0xD800 + ((w>>>10)&1023));
3628 out += String.fromCharCode(0xDC00 + (w&1023));
3629 }
3630 return out;
3631}
3632
3633function utf8readb(data) {
3634 var out = new_raw_buf(2*data.length), w, i, j = 1, k = 0, ww=0, c;
3635 for(i = 0; i < data.length; i+=j) {
3636 j = 1;
3637 if((c=data.charCodeAt(i)) < 128) w = c;
3638 else if(c < 224) { w = (c&31)*64+(data.charCodeAt(i+1)&63); j=2; }
3639 else if(c < 240) { w=(c&15)*4096+(data.charCodeAt(i+1)&63)*64+(data.charCodeAt(i+2)&63); j=3; }
3640 else { j = 4;
3641 w = (c & 7)*262144+(data.charCodeAt(i+1)&63)*4096+(data.charCodeAt(i+2)&63)*64+(data.charCodeAt(i+3)&63);
3642 w -= 65536; ww = 0xD800 + ((w>>>10)&1023); w = 0xDC00 + (w&1023);
3643 }
3644 if(ww !== 0) { out[k++] = ww&255; out[k++] = ww>>>8; ww = 0; }
3645 out[k++] = w%256; out[k++] = w>>>8;
3646 }
3647 return out.slice(0,k).toString('ucs2');
3648}
3649
3650function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); }
3651
3652var utf8corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
3653var utf8read = has_buf && (/*#__PURE__*/utf8readc(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readc || /*#__PURE__*/utf8readb(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readb) || utf8reada;
3654
3655var utf8write/*:StringConv*/ = has_buf ? function(data) { return Buffer_from(data, 'utf8').toString("binary"); } : function(orig/*:string*/)/*:string*/ {
3656 var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0;
3657 while(i < orig.length) {
3658 c = orig.charCodeAt(i++);
3659 switch(true) {
3660 case c < 128: out.push(String.fromCharCode(c)); break;
3661 case c < 2048:
3662 out.push(String.fromCharCode(192 + (c >> 6)));
3663 out.push(String.fromCharCode(128 + (c & 63)));
3664 break;
3665 case c >= 55296 && c < 57344:
3666 c -= 55296; d = orig.charCodeAt(i++) - 56320 + (c<<10);
3667 out.push(String.fromCharCode(240 + ((d >>18) & 7)));
3668 out.push(String.fromCharCode(144 + ((d >>12) & 63)));
3669 out.push(String.fromCharCode(128 + ((d >> 6) & 63)));
3670 out.push(String.fromCharCode(128 + (d & 63)));
3671 break;
3672 default:
3673 out.push(String.fromCharCode(224 + (c >> 12)));
3674 out.push(String.fromCharCode(128 + ((c >> 6) & 63)));
3675 out.push(String.fromCharCode(128 + (c & 63)));
3676 }
3677 }
3678 return out.join("");
3679};
3680
3681// matches <foo>...</foo> extracts content
3682var matchtag = /*#__PURE__*/(function() {
3683 var mtcache/*:{[k:string]:RegExp}*/ = ({}/*:any*/);
3684 return function matchtag(f/*:string*/,g/*:?string*/)/*:RegExp*/ {
3685 var t = f+"|"+(g||"");
3686 if(mtcache[t]) return mtcache[t];
3687 return (mtcache[t] = new RegExp('<(?:\\w+:)?'+f+'(?: xml:space="preserve")?(?:[^>]*)>([\\s\\S]*?)</(?:\\w+:)?'+f+'>',((g||"")/*:any*/)));
3688 };
3689})();
3690
3691var htmldecode/*:{(s:string):string}*/ = /*#__PURE__*/(function() {
3692 var entities/*:Array<[RegExp, string]>*/ = [
3693 ['nbsp', ' '], ['middot', '·'],
3694 ['quot', '"'], ['apos', "'"], ['gt', '>'], ['lt', '<'], ['amp', '&']
3695 ].map(function(x/*:[string, string]*/) { return [new RegExp('&' + x[0] + ';', "ig"), x[1]]; });
3696 return function htmldecode(str/*:string*/)/*:string*/ {
3697 var o = str
3698 // Remove new lines and spaces from start of content
3699 .replace(/^[\t\n\r ]+/, "")
3700 // Remove new lines and spaces from end of content
3701 .replace(/[\t\n\r ]+$/,"")
3702 // Added line which removes any white space characters after and before html tags
3703 .replace(/>\s+/g,">").replace(/\s+</g,"<")
3704 // Replace remaining new lines and spaces with space
3705 .replace(/[\t\n\r ]+/g, " ")
3706 // Replace <br> tags with new lines
3707 .replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
3708 // Strip HTML elements
3709 .replace(/<[^>]*>/g,"");
3710 for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
3711 return o;
3712 };
3713})();
3714
3715var vtregex = /*#__PURE__*/(function(){ var vt_cache = {};
3716 return function vt_regex(bt) {
3717 if(vt_cache[bt] !== undefined) return vt_cache[bt];
3718 return (vt_cache[bt] = new RegExp("<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">", 'g') );
3719};})();
3720var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
3721function parseVector(data/*:string*/, opts)/*:Array<{v:string,t:string}>*/ {
3722 var h = parsexmltag(data);
3723
3724 var matches/*:Array<string>*/ = data.match(vtregex(h.baseType))||[];
3725 var res/*:Array<any>*/ = [];
3726 if(matches.length != h.size) {
3727 if(opts.WTF) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
3728 return res;
3729 }
3730 matches.forEach(function(x/*:string*/) {
3731 var v = x.replace(vtvregex,"").match(vtmregex);
3732 if(v) res.push({v:utf8read(v[2]), t:v[1]});
3733 });
3734 return res;
3735}
3736
3737var wtregex = /(^\s|\s$|\n)/;
3738function writetag(f/*:string*/,g/*:string*/)/*:string*/ { return '<' + f + (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f + '>'; }
3739
3740function wxt_helper(h)/*:string*/ { return keys(h).map(function(k) { return " " + k + '="' + h[k] + '"';}).join(""); }
3741function writextag(f/*:string*/,g/*:?string*/,h) { return '<' + f + ((h != null) ? wxt_helper(h) : "") + ((g != null) ? (g.match(wtregex)?' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';}
3742
3743function write_w3cdtf(d/*:Date*/, t/*:?boolean*/)/*:string*/ { try { return d.toISOString().replace(/\.\d*/,""); } catch(e) { if(t) throw e; } return ""; }
3744
3745function write_vt(s, xlsx/*:?boolean*/)/*:string*/ {
3746 switch(typeof s) {
3747 case 'string':
3748 var o = writextag('vt:lpwstr', escapexml(s));
3749 if(xlsx) o = o.replace(/&quot;/g, "_x0022_");
3750 return o;
3751 case 'number': return writextag((s|0)==s?'vt:i4':'vt:r8', escapexml(String(s)));
3752 case 'boolean': return writextag('vt:bool',s?'true':'false');
3753 }
3754 if(s instanceof Date) return writextag('vt:filetime', write_w3cdtf(s));
3755 throw new Error("Unable to serialize " + s);
3756}
3757
3758function xlml_normalize(d)/*:string*/ {
3759 if(has_buf &&/*::typeof Buffer !== "undefined" && d != null && d instanceof Buffer &&*/ Buffer.isBuffer(d)) return d.toString('utf8');
3760 if(typeof d === 'string') return d;
3761 /* duktape */
3762 if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
3763 throw new Error("Bad input format: expected Buffer or string");
3764}
3765/* UOS uses CJK in tags */
3766var xlmlregex = /<(\/?)([^\s?><!\/:]*:|)([^\s?<>:\/]+)(?:[\s?:\/][^>]*)?>/mg;
3767//var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
3768
3769var XMLNS = ({
3770 CORE_PROPS: 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',
3771 CUST_PROPS: "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties",
3772 EXT_PROPS: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
3773 CT: 'http://schemas.openxmlformats.org/package/2006/content-types',
3774 RELS: 'http://schemas.openxmlformats.org/package/2006/relationships',
3775 TCMNT: 'http://schemas.microsoft.com/office/spreadsheetml/2018/threadedcomments',
3776 'dc': 'http://purl.org/dc/elements/1.1/',
3777 'dcterms': 'http://purl.org/dc/terms/',
3778 'dcmitype': 'http://purl.org/dc/dcmitype/',
3779 'mx': 'http://schemas.microsoft.com/office/mac/excel/2008/main',
3780 'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
3781 'sjs': 'http://schemas.openxmlformats.org/package/2006/sheetjs/core-properties',
3782 'vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',
3783 'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
3784 'xsd': 'http://www.w3.org/2001/XMLSchema'
3785}/*:any*/);
3786
3787var XMLNS_main = [
3788 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
3789 'http://purl.oclc.org/ooxml/spreadsheetml/main',
3790 'http://schemas.microsoft.com/office/excel/2006/main',
3791 'http://schemas.microsoft.com/office/excel/2006/2'
3792];
3793
3794var XLMLNS = ({
3795 'o': 'urn:schemas-microsoft-com:office:office',
3796 'x': 'urn:schemas-microsoft-com:office:excel',
3797 'ss': 'urn:schemas-microsoft-com:office:spreadsheet',
3798 'dt': 'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882',
3799 'mv': 'http://macVmlSchemaUri',
3800 'v': 'urn:schemas-microsoft-com:vml',
3801 'html': 'http://www.w3.org/TR/REC-html40'
3802}/*:any*/);
3803function read_double_le(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ {
3804 var s = 1 - 2 * (b[idx + 7] >>> 7);
3805 var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);
3806 var m = (b[idx+6]&0x0f);
3807 for(var i = 5; i >= 0; --i) m = m * 256 + b[idx + i];
3808 if(e == 0x7ff) return m == 0 ? (s * Infinity) : NaN;
3809 if(e == 0) e = -1022;
3810 else { e -= 1023; m += Math.pow(2,52); }
3811 return s * Math.pow(2, e - 52) * m;
3812}
3813
3814function write_double_le(b/*:RawBytes|CFBlob*/, v/*:number*/, idx/*:number*/) {
3815 var bs = ((((v < 0) || (1/v == -Infinity)) ? 1 : 0) << 7), e = 0, m = 0;
3816 var av = bs ? (-v) : v;
3817 if(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }
3818 else if(av == 0) e = m = 0;
3819 else {
3820 e = Math.floor(Math.log(av) / Math.LN2);
3821 m = av * Math.pow(2, 52 - e);
3822 if((e <= -1023) && (!isFinite(m) || (m < Math.pow(2,52)))) { e = -1022; }
3823 else { m -= Math.pow(2,52); e+=1023; }
3824 }
3825 for(var i = 0; i <= 5; ++i, m/=256) b[idx + i] = m & 0xff;
3826 b[idx + 6] = ((e & 0x0f) << 4) | (m & 0xf);
3827 b[idx + 7] = (e >> 4) | bs;
3828}
3829
3830var ___toBuffer = function(bufs/*:Array<Array<RawBytes> >*/)/*:RawBytes*/ { var x=[],w=10240; for(var i=0;i<bufs[0].length;++i) if(bufs[0][i]) for(var j=0,L=bufs[0][i].length;j<L;j+=w) x.push.apply(x, bufs[0][i].slice(j,j+w)); return x; };
3831var __toBuffer = has_buf ? function(bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0].map(function(x) { return Buffer.isBuffer(x) ? x : Buffer_from(x); })) : ___toBuffer(bufs);} : ___toBuffer;
3832
3833var ___utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<e; i+=2) ss.push(String.fromCharCode(__readUInt16LE(b,i))); return ss.join("").replace(chr0,''); };
3834var __utf16le = has_buf ? function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/)/*:string*/ { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___utf16le(b,s,e); return b.toString('utf16le',s,e).replace(chr0,'')/*.replace(chr1,'!')*/; } : ___utf16le;
3835
3836var ___hexlify = function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { var ss/*:Array<string>*/=[]; for(var i=s; i<s+l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); };
3837var __hexlify = has_buf ? function(b/*:RawBytes|CFBlob*/,s/*:number*/,l/*:number*/)/*:string*/ { return Buffer.isBuffer(b)/*:: && b instanceof Buffer*/ ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); } : ___hexlify;
3838
3839var ___utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { var ss=[]; for(var i=s; i<e; i++) ss.push(String.fromCharCode(__readUInt8(b,i))); return ss.join(""); };
3840var __utf8 = has_buf ? function utf8_b(b/*:RawBytes|CFBlob*/, s/*:number*/, e/*:number*/) { return (Buffer.isBuffer(b)/*:: && (b instanceof Buffer)*/) ? b.toString('utf8',s,e) : ___utf8(b,s,e); } : ___utf8;
3841
3842var ___lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
3843var __lpstr = ___lpstr;
3844
3845var ___cpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
3846var __cpstr = ___cpstr;
3847
3848var ___lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";};
3849var __lpwstr = ___lpwstr;
3850
3851var ___lpp4 = function lpp4_(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";};
3852var __lpp4 = ___lpp4;
3853
3854var ___8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";};
3855var __8lpp4 = ___8lpp4;
3856
3857var ___double = function(b/*:RawBytes|CFBlob*/, idx/*:number*/) { return read_double_le(b, idx);};
3858var __double = ___double;
3859
3860var is_buf = function is_buf_a(a) { return Array.isArray(a) || (typeof Uint8Array !== "undefined" && a instanceof Uint8Array); };
3861
3862if(has_buf/*:: && typeof Buffer !== 'undefined'*/) {
3863 __lpstr = function lpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
3864 __cpstr = function cpstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___cpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";};
3865 __lpwstr = function lpwstr_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i); var len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};
3866 __lpp4 = function lpp4_b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};
3867 __8lpp4 = function lpp4_8b(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(!Buffer.isBuffer(b)/*:: || !(b instanceof Buffer)*/) return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};
3868 __double = function double_(b/*:RawBytes|CFBlob*/, i/*:number*/) { if(Buffer.isBuffer(b)/*::&& b instanceof Buffer*/) return b.readDoubleLE(i); return ___double(b,i); };
3869 is_buf = function is_buf_b(a) { return Buffer.isBuffer(a) || Array.isArray(a) || (typeof Uint8Array !== "undefined" && a instanceof Uint8Array); };
3870}
3871
3872/* from js-xls */
3873function cpdoit() {
3874 __utf16le = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return $cptable.utils.decode(1200, b.slice(s,e)).replace(chr0, ''); };
3875 __utf8 = function(b/*:RawBytes|CFBlob*/,s/*:number*/,e/*:number*/) { return $cptable.utils.decode(65001, b.slice(s,e)); };
3876 __lpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? $cptable.utils.decode(current_ansi, b.slice(i+4, i+4+len-1)) : "";};
3877 __cpstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? $cptable.utils.decode(current_codepage, b.slice(i+4, i+4+len-1)) : "";};
3878 __lpwstr = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = 2*__readUInt32LE(b,i); return len > 0 ? $cptable.utils.decode(1200, b.slice(i+4,i+4+len-1)) : "";};
3879 __lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? $cptable.utils.decode(1200, b.slice(i+4,i+4+len)) : "";};
3880 __8lpp4 = function(b/*:RawBytes|CFBlob*/,i/*:number*/) { var len = __readUInt32LE(b,i); return len > 0 ? $cptable.utils.decode(65001, b.slice(i+4,i+4+len)) : "";};
3881}
3882if(typeof $cptable !== 'undefined') cpdoit();
3883
3884var __readUInt8 = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx]; };
3885var __readUInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+1]*(1<<8))+b[idx]; };
3886var __readInt16LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { var u = (b[idx+1]*(1<<8))+b[idx]; return (u < 0x8000) ? u : ((0xffff - u + 1) * -1); };
3887var __readUInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; };
3888var __readInt32LE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; };
3889var __readInt32BE = function(b/*:RawBytes|CFBlob*/, idx/*:number*/)/*:number*/ { return (b[idx]<<24)|(b[idx+1]<<16)|(b[idx+2]<<8)|b[idx+3]; };
3890
3891function ReadShift(size/*:number*/, t/*:?string*/)/*:number|string*/ {
3892 var o="", oI/*:: :number = 0*/, oR, oo=[], w, vv, i, loc;
3893 switch(t) {
3894 case 'dbcs':
3895 loc = this.l;
3896 if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le");
3897 else for(i = 0; i < size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }
3898 size *= 2;
3899 break;
3900
3901 case 'utf8': o = __utf8(this, this.l, this.l + size); break;
3902 case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;
3903
3904 case 'wstr':
3905 if(typeof $cptable !== 'undefined') o = $cptable.utils.decode(current_codepage, this.slice(this.l, this.l+2*size));
3906 else return ReadShift.call(this, size, 'dbcs');
3907 size = 2 * size; break;
3908
3909 /* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
3910 case 'lpstr-ansi': o = __lpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;
3911 case 'lpstr-cp': o = __cpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;
3912 /* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */
3913 case 'lpwstr': o = __lpwstr(this, this.l); size = 4 + 2 * __readUInt32LE(this, this.l); break;
3914 /* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */
3915 case 'lpp4': size = 4 + __readUInt32LE(this, this.l); o = __lpp4(this, this.l); if(size & 0x02) size += 2; break;
3916 /* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */
3917 case '8lpp4': size = 4 + __readUInt32LE(this, this.l); o = __8lpp4(this, this.l); if(size & 0x03) size += 4 - (size & 0x03); break;
3918
3919 case 'cstr': size = 0; o = "";
3920 while((w=__readUInt8(this, this.l + size++))!==0) oo.push(_getchar(w));
3921 o = oo.join(""); break;
3922 case '_wstr': size = 0; o = "";
3923 while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(_getchar(w));size+=2;}
3924 size+=2; o = oo.join(""); break;
3925
3926 /* sbcs and dbcs support continue records in the SST way TODO codepages */
3927 case 'dbcs-cont': o = ""; loc = this.l;
3928 for(i = 0; i < size; ++i) {
3929 if(this.lens && this.lens.indexOf(loc) !== -1) {
3930 w = __readUInt8(this, loc);
3931 this.l = loc + 1;
3932 vv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont');
3933 return oo.join("") + vv;
3934 }
3935 oo.push(_getchar(__readUInt16LE(this, loc)));
3936 loc+=2;
3937 } o = oo.join(""); size *= 2; break;
3938
3939 case 'cpstr':
3940 if(typeof $cptable !== 'undefined') {
3941 o = $cptable.utils.decode(current_codepage, this.slice(this.l, this.l + size));
3942 break;
3943 }
3944 /* falls through */
3945 case 'sbcs-cont': o = ""; loc = this.l;
3946 for(i = 0; i != size; ++i) {
3947 if(this.lens && this.lens.indexOf(loc) !== -1) {
3948 w = __readUInt8(this, loc);
3949 this.l = loc + 1;
3950 vv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont');
3951 return oo.join("") + vv;
3952 }
3953 oo.push(_getchar(__readUInt8(this, loc)));
3954 loc+=1;
3955 } o = oo.join(""); break;
3956
3957 default:
3958 switch(size) {
3959 case 1: oI = __readUInt8(this, this.l); this.l++; return oI;
3960 case 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI;
3961 case 4: case -4:
3962 if(t === 'i' || ((this[this.l+3] & 0x80)===0)) { oI = ((size > 0) ? __readInt32LE : __readInt32BE)(this, this.l); this.l += 4; return oI; }
3963 else { oR = __readUInt32LE(this, this.l); this.l += 4; } return oR;
3964 case 8: case -8:
3965 if(t === 'f') {
3966 if(size == 8) oR = __double(this, this.l);
3967 else oR = __double([this[this.l+7],this[this.l+6],this[this.l+5],this[this.l+4],this[this.l+3],this[this.l+2],this[this.l+1],this[this.l+0]], 0);
3968 this.l += 8; return oR;
3969 } else size = 8;
3970 /* falls through */
3971 case 16: o = __hexlify(this, this.l, size); break;
3972 }}
3973 this.l+=size; return o;
3974}
3975
3976var __writeUInt32LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };
3977var __writeInt32LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };
3978var __writeUInt16LE = function(b/*:RawBytes|CFBlob*/, val/*:number*/, idx/*:number*/)/*:void*/ { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };
3979
3980function WriteShift(t/*:number*/, val/*:string|number*/, f/*:?string*/)/*:any*/ {
3981 var size = 0, i = 0;
3982 if(f === 'dbcs') {
3983 /*:: if(typeof val !== 'string') throw new Error("unreachable"); */
3984 for(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);
3985 size = 2 * val.length;
3986 } else if(f === 'sbcs') {
3987 if(typeof $cptable !== 'undefined' && current_ansi == 874) {
3988 /* TODO: use tables directly, don't encode */
3989 /*:: if(typeof val !== "string") throw new Error("unreachable"); */
3990 for(i = 0; i != val.length; ++i) {
3991 var cppayload = $cptable.utils.encode(current_ansi, val.charAt(i));
3992 this[this.l + i] = cppayload[0];
3993 }
3994 } else {
3995 /*:: if(typeof val !== 'string') throw new Error("unreachable"); */
3996 val = val.replace(/[^\x00-\x7F]/g, "_");
3997 /*:: if(typeof val !== 'string') throw new Error("unreachable"); */
3998 for(i = 0; i != val.length; ++i) this[this.l + i] = (val.charCodeAt(i) & 0xFF);
3999 }
4000 size = val.length;
4001 } else if(f === 'hex') {
4002 for(; i < t; ++i) {
4003 /*:: if(typeof val !== "string") throw new Error("unreachable"); */
4004 this[this.l++] = (parseInt(val.slice(2*i, 2*i+2), 16)||0);
4005 } return this;
4006 } else if(f === 'utf16le') {
4007 /*:: if(typeof val !== "string") throw new Error("unreachable"); */
4008 var end/*:number*/ = Math.min(this.l + t, this.length);
4009 for(i = 0; i < Math.min(val.length, t); ++i) {
4010 var cc = val.charCodeAt(i);
4011 this[this.l++] = (cc & 0xff);
4012 this[this.l++] = (cc >> 8);
4013 }
4014 while(this.l < end) this[this.l++] = 0;
4015 return this;
4016 } else /*:: if(typeof val === 'number') */ switch(t) {
4017 case 1: size = 1; this[this.l] = val&0xFF; break;
4018 case 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;
4019 case 3: size = 3; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; val >>>= 8; this[this.l+2] = val&0xFF; break;
4020 case 4: size = 4; __writeUInt32LE(this, val, this.l); break;
4021 case 8: size = 8; if(f === 'f') { write_double_le(this, val, this.l); break; }
4022 /* falls through */
4023 case 16: break;
4024 case -4: size = 4; __writeInt32LE(this, val, this.l); break;
4025 }
4026 this.l += size; return this;
4027}
4028
4029function CheckField(hexstr/*:string*/, fld/*:string*/)/*:void*/ {
4030 var m = __hexlify(this,this.l,hexstr.length>>1);
4031 if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
4032 this.l += hexstr.length>>1;
4033}
4034
4035function prep_blob(blob, pos/*:number*/)/*:void*/ {
4036 blob.l = pos;
4037 blob.read_shift = /*::(*/ReadShift/*:: :any)*/;
4038 blob.chk = CheckField;
4039 blob.write_shift = WriteShift;
4040}
4041
4042function parsenoop(blob, length/*:: :number, opts?:any */) { blob.l += length; }
4043
4044function new_buf(sz/*:number*/)/*:Block*/ {
4045 var o = new_raw_buf(sz);
4046 prep_blob(o, 0);
4047 return o;
4048}
4049
4050/* [MS-XLSB] 2.1.4 Record */
4051function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
4052 if(!data) return;
4053 var tmpbyte, cntbyte, length;
4054 prep_blob(data, data.l || 0);
4055 var L = data.length, RT = 0, tgt = 0;
4056 while(data.l < L) {
4057 RT = data.read_shift(1);
4058 if(RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F)<<7);
4059 var R = XLSBRecordEnum[RT] || XLSBRecordEnum[0xFFFF];
4060 tmpbyte = data.read_shift(1);
4061 length = tmpbyte & 0x7F;
4062 for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte);
4063 tgt = data.l + length;
4064 var d = R.f && R.f(data, length, opts);
4065 data.l = tgt;
4066 if(cb(d, R, RT)) return;
4067 }
4068}
4069
4070/* control buffer usage for fixed-length buffers */
4071function buf_array()/*:BufArray*/ {
4072 var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 256 : 2048;
4073 var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ {
4074 var o/*:Block*/ = (new_buf(sz)/*:any*/);
4075 prep_blob(o, 0);
4076 return o;
4077 };
4078
4079 var curbuf/*:Block*/ = newblk(blksz);
4080
4081 var endbuf = function ba_endbuf() {
4082 if(!curbuf) return;
4083 if(curbuf.length > curbuf.l) { curbuf = curbuf.slice(0, curbuf.l); curbuf.l = curbuf.length; }
4084 if(curbuf.length > 0) bufs.push(curbuf);
4085 curbuf = null;
4086 };
4087
4088 var next = function ba_next(sz/*:number*/)/*:Block*/ {
4089 if(curbuf && (sz < (curbuf.length - curbuf.l))) return curbuf;
4090 endbuf();
4091 return (curbuf = newblk(Math.max(sz+1, blksz)));
4092 };
4093
4094 var end = function ba_end() {
4095 endbuf();
4096 return bconcat(bufs);
4097 };
4098
4099 var push = function ba_push(buf) { endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); };
4100
4101 return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
4102}
4103
4104function write_record(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/) {
4105 var t/*:number*/ = +type, l;
4106 if(isNaN(t)) return; // TODO: throw something here?
4107 if(!length) length = XLSBRecordEnum[t].p || (payload||[]).length || 0;
4108 l = 1 + (t >= 0x80 ? 1 : 0) + 1/* + length*/;
4109 if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l;
4110 var o = ba.next(l);
4111 if(t <= 0x7F) o.write_shift(1, t);
4112 else {
4113 o.write_shift(1, (t & 0x7F) + 0x80);
4114 o.write_shift(1, (t >> 7));
4115 }
4116 for(var i = 0; i != 4; ++i) {
4117 if(length >= 0x80) { o.write_shift(1, (length & 0x7F)+0x80); length >>= 7; }
4118 else { o.write_shift(1, length); break; }
4119 }
4120 if(/*:: length != null &&*/length > 0 && is_buf(payload)) ba.push(payload);
4121}
4122/* XLS ranges enforced */
4123function shift_cell_xls(cell/*:CellAddress*/, tgt/*:any*/, opts/*:?any*/)/*:CellAddress*/ {
4124 var out = dup(cell);
4125 if(tgt.s) {
4126 if(out.cRel) out.c += tgt.s.c;
4127 if(out.rRel) out.r += tgt.s.r;
4128 } else {
4129 if(out.cRel) out.c += tgt.c;
4130 if(out.rRel) out.r += tgt.r;
4131 }
4132 if(!opts || opts.biff < 12) {
4133 while(out.c >= 0x100) out.c -= 0x100;
4134 while(out.r >= 0x10000) out.r -= 0x10000;
4135 }
4136 return out;
4137}
4138
4139function shift_range_xls(cell, range, opts) {
4140 var out = dup(cell);
4141 out.s = shift_cell_xls(out.s, range.s, opts);
4142 out.e = shift_cell_xls(out.e, range.s, opts);
4143 return out;
4144}
4145
4146function encode_cell_xls(c/*:CellAddress*/, biff/*:number*/)/*:string*/ {
4147 if(c.cRel && c.c < 0) { c = dup(c); while(c.c < 0) c.c += (biff > 8) ? 0x4000 : 0x100; }
4148 if(c.rRel && c.r < 0) { c = dup(c); while(c.r < 0) c.r += (biff > 8) ? 0x100000 : ((biff > 5) ? 0x10000 : 0x4000); }
4149 var s = encode_cell(c);
4150 if(!c.cRel && c.cRel != null) s = fix_col(s);
4151 if(!c.rRel && c.rRel != null) s = fix_row(s);
4152 return s;
4153}
4154
4155function encode_range_xls(r, opts)/*:string*/ {
4156 if(r.s.r == 0 && !r.s.rRel) {
4157 if(r.e.r == (opts.biff >= 12 ? 0xFFFFF : (opts.biff >= 8 ? 0x10000 : 0x4000)) && !r.e.rRel) {
4158 return (r.s.cRel ? "" : "$") + encode_col(r.s.c) + ":" + (r.e.cRel ? "" : "$") + encode_col(r.e.c);
4159 }
4160 }
4161 if(r.s.c == 0 && !r.s.cRel) {
4162 if(r.e.c == (opts.biff >= 12 ? 0x3FFF : 0xFF) && !r.e.cRel) {
4163 return (r.s.rRel ? "" : "$") + encode_row(r.s.r) + ":" + (r.e.rRel ? "" : "$") + encode_row(r.e.r);
4164 }
4165 }
4166 return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
4167}
4168function decode_row(rowstr/*:string*/)/*:number*/ { return parseInt(unfix_row(rowstr),10) - 1; }
4169function encode_row(row/*:number*/)/*:string*/ { return "" + (row + 1); }
4170function fix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/([A-Z]|^)(\d+)$/,"$1$$$2"); }
4171function unfix_row(cstr/*:string*/)/*:string*/ { return cstr.replace(/\$(\d+)$/,"$1"); }
4172
4173function decode_col(colstr/*:string*/)/*:number*/ { var c = unfix_col(colstr), d = 0, i = 0; for(; i !== c.length; ++i) d = 26*d + c.charCodeAt(i) - 64; return d - 1; }
4174function encode_col(col/*:number*/)/*:string*/ { if(col < 0) throw new Error("invalid column " + col); var s=""; for(++col; col; col=Math.floor((col-1)/26)) s = String.fromCharCode(((col-1)%26) + 65) + s; return s; }
4175function fix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^([A-Z])/,"$$$1"); }
4176function unfix_col(cstr/*:string*/)/*:string*/ { return cstr.replace(/^\$([A-Z])/,"$1"); }
4177
4178function split_cell(cstr/*:string*/)/*:Array<string>*/ { return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/,"$1,$2").split(","); }
4179//function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
4180function decode_cell(cstr/*:string*/)/*:CellAddress*/ {
4181 var R = 0, C = 0;
4182 for(var i = 0; i < cstr.length; ++i) {
4183 var cc = cstr.charCodeAt(i);
4184 if(cc >= 48 && cc <= 57) R = 10 * R + (cc - 48);
4185 else if(cc >= 65 && cc <= 90) C = 26 * C + (cc - 64);
4186 }
4187 return { c: C - 1, r:R - 1 };
4188}
4189//function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); }
4190function encode_cell(cell/*:CellAddress*/)/*:string*/ {
4191 var col = cell.c + 1;
4192 var s="";
4193 for(; col; col=((col-1)/26)|0) s = String.fromCharCode(((col-1)%26) + 65) + s;
4194 return s + (cell.r + 1);
4195}
4196function decode_range(range/*:string*/)/*:Range*/ {
4197 var idx = range.indexOf(":");
4198 if(idx == -1) return { s: decode_cell(range), e: decode_cell(range) };
4199 return { s: decode_cell(range.slice(0, idx)), e: decode_cell(range.slice(idx + 1)) };
4200}
4201/*# if only one arg, it is assumed to be a Range. If 2 args, both are cell addresses */
4202function encode_range(cs/*:CellAddrSpec|Range*/,ce/*:?CellAddrSpec*/)/*:string*/ {
4203 if(typeof ce === 'undefined' || typeof ce === 'number') {
4204/*:: if(!(cs instanceof Range)) throw "unreachable"; */
4205 return encode_range(cs.s, cs.e);
4206 }
4207/*:: if((cs instanceof Range)) throw "unreachable"; */
4208 if(typeof cs !== 'string') cs = encode_cell((cs/*:any*/));
4209 if(typeof ce !== 'string') ce = encode_cell((ce/*:any*/));
4210/*:: if(typeof cs !== 'string') throw "unreachable"; */
4211/*:: if(typeof ce !== 'string') throw "unreachable"; */
4212 return cs == ce ? cs : cs + ":" + ce;
4213}
4214
4215function safe_decode_range(range/*:string*/)/*:Range*/ {
4216 var o = {s:{c:0,r:0},e:{c:0,r:0}};
4217 var idx = 0, i = 0, cc = 0;
4218 var len = range.length;
4219 for(idx = 0; i < len; ++i) {
4220 if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
4221 idx = 26*idx + cc;
4222 }
4223 o.s.c = --idx;
4224
4225 for(idx = 0; i < len; ++i) {
4226 if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
4227 idx = 10*idx + cc;
4228 }
4229 o.s.r = --idx;
4230
4231 if(i === len || cc != 10) { o.e.c=o.s.c; o.e.r=o.s.r; return o; }
4232 ++i;
4233
4234 for(idx = 0; i != len; ++i) {
4235 if((cc=range.charCodeAt(i)-64) < 1 || cc > 26) break;
4236 idx = 26*idx + cc;
4237 }
4238 o.e.c = --idx;
4239
4240 for(idx = 0; i != len; ++i) {
4241 if((cc=range.charCodeAt(i)-48) < 0 || cc > 9) break;
4242 idx = 10*idx + cc;
4243 }
4244 o.e.r = --idx;
4245 return o;
4246}
4247
4248function safe_format_cell(cell/*:Cell*/, v/*:any*/) {
4249 var q = (cell.t == 'd' && v instanceof Date);
4250 if(cell.z != null) try { return (cell.w = SSF_format(cell.z, q ? datenum(v) : v)); } catch(e) { }
4251 try { return (cell.w = SSF_format((cell.XF||{}).numFmtId||(q ? 14 : 0), q ? datenum(v) : v)); } catch(e) { return ''+v; }
4252}
4253
4254function format_cell(cell/*:Cell*/, v/*:any*/, o/*:any*/) {
4255 if(cell == null || cell.t == null || cell.t == 'z') return "";
4256 if(cell.w !== undefined) return cell.w;
4257 if(cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF;
4258 if(cell.t == "e") return BErr[cell.v] || cell.v;
4259 if(v == undefined) return safe_format_cell(cell, cell.v);
4260 return safe_format_cell(cell, v);
4261}
4262
4263function sheet_to_workbook(sheet/*:Worksheet*/, opts)/*:Workbook*/ {
4264 var n = opts && opts.sheet ? opts.sheet : "Sheet1";
4265 var sheets = {}; sheets[n] = sheet;
4266 return { SheetNames: [n], Sheets: sheets };
4267}
4268
4269function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ {
4270 var o = opts || {};
4271 var dense = _ws ? Array.isArray(_ws) : o.dense;
4272 if(DENSE != null && dense == null) dense = DENSE;
4273 var ws/*:Worksheet*/ = _ws || (dense ? ([]/*:any*/) : ({}/*:any*/));
4274 var _R = 0, _C = 0;
4275 if(ws && o.origin != null) {
4276 if(typeof o.origin == 'number') _R = o.origin;
4277 else {
4278 var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
4279 _R = _origin.r; _C = _origin.c;
4280 }
4281 if(!ws["!ref"]) ws["!ref"] = "A1:A1";
4282 }
4283 var range/*:Range*/ = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}}/*:any*/);
4284 if(ws['!ref']) {
4285 var _range = safe_decode_range(ws['!ref']);
4286 range.s.c = _range.s.c;
4287 range.s.r = _range.s.r;
4288 range.e.c = Math.max(range.e.c, _range.e.c);
4289 range.e.r = Math.max(range.e.r, _range.e.r);
4290 if(_R == -1) range.e.r = _R = _range.e.r + 1;
4291 }
4292 for(var R = 0; R != data.length; ++R) {
4293 if(!data[R]) continue;
4294 if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
4295 for(var C = 0; C != data[R].length; ++C) {
4296 if(typeof data[R][C] === 'undefined') continue;
4297 var cell/*:Cell*/ = ({v: data[R][C] }/*:any*/);
4298 var __R = _R + R, __C = _C + C;
4299 if(range.s.r > __R) range.s.r = __R;
4300 if(range.s.c > __C) range.s.c = __C;
4301 if(range.e.r < __R) range.e.r = __R;
4302 if(range.e.c < __C) range.e.c = __C;
4303 if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
4304 else {
4305 if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
4306 if(cell.v === null) {
4307 if(cell.f) cell.t = 'n';
4308 else if(o.nullError) { cell.t = 'e'; cell.v = 0; }
4309 else if(!o.sheetStubs) continue;
4310 else cell.t = 'z';
4311 }
4312 else if(typeof cell.v === 'number') cell.t = 'n';
4313 else if(typeof cell.v === 'boolean') cell.t = 'b';
4314 else if(cell.v instanceof Date) {
4315 cell.z = o.dateNF || table_fmt[14];
4316 if(o.cellDates) { cell.t = 'd'; cell.w = SSF_format(cell.z, datenum(cell.v)); }
4317 else { cell.t = 'n'; cell.v = datenum(cell.v); cell.w = SSF_format(cell.z, cell.v); }
4318 }
4319 else cell.t = 's';
4320 }
4321 if(dense) {
4322 if(!ws[__R]) ws[__R] = [];
4323 if(ws[__R][__C] && ws[__R][__C].z) cell.z = ws[__R][__C].z;
4324 ws[__R][__C] = cell;
4325 } else {
4326 var cell_ref = encode_cell(({c:__C,r:__R}/*:any*/));
4327 if(ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
4328 ws[cell_ref] = cell;
4329 }
4330 }
4331 }
4332 if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
4333 return ws;
4334}
4335function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }
4336
4337function parse_Int32LE(data) {
4338 return data.read_shift(4, 'i');
4339}
4340function write_UInt32LE(x/*:number*/, o) {
4341 if (!o) o = new_buf(4);
4342 o.write_shift(4, x);
4343 return o;
4344}
4345
4346/* [MS-XLSB] 2.5.168 */
4347function parse_XLWideString(data/*::, length*/)/*:string*/ {
4348 var cchCharacters = data.read_shift(4);
4349 return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
4350}
4351function write_XLWideString(data/*:string*/, o) {
4352 var _null = false; if (o == null) { _null = true; o = new_buf(4 + 2 * data.length); }
4353 o.write_shift(4, data.length);
4354 if (data.length > 0) o.write_shift(0, data, 'dbcs');
4355 return _null ? o.slice(0, o.l) : o;
4356}
4357
4358/* [MS-XLSB] 2.5.91 */
4359//function parse_LPWideString(data/*::, length*/)/*:string*/ {
4360// var cchCharacters = data.read_shift(2);
4361// return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, "utf16le");
4362//}
4363
4364/* [MS-XLSB] 2.5.143 */
4365function parse_StrRun(data) {
4366 return { ich: data.read_shift(2), ifnt: data.read_shift(2) };
4367}
4368function write_StrRun(run, o) {
4369 if (!o) o = new_buf(4);
4370 o.write_shift(2, run.ich || 0);
4371 o.write_shift(2, run.ifnt || 0);
4372 return o;
4373}
4374
4375/* [MS-XLSB] 2.5.121 */
4376function parse_RichStr(data, length/*:number*/)/*:XLString*/ {
4377 var start = data.l;
4378 var flags = data.read_shift(1);
4379 var str = parse_XLWideString(data);
4380 var rgsStrRun = [];
4381 var z = ({ t: str, h: str }/*:any*/);
4382 if ((flags & 1) !== 0) { /* fRichStr */
4383 /* TODO: formatted string */
4384 var dwSizeStrRun = data.read_shift(4);
4385 for (var i = 0; i != dwSizeStrRun; ++i) rgsStrRun.push(parse_StrRun(data));
4386 z.r = rgsStrRun;
4387 }
4388 else z.r = [{ ich: 0, ifnt: 0 }];
4389 //if((flags & 2) !== 0) { /* fExtStr */
4390 // /* TODO: phonetic string */
4391 //}
4392 data.l = start + length;
4393 return z;
4394}
4395function write_RichStr(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
4396 /* TODO: formatted string */
4397 var _null = false; if (o == null) { _null = true; o = new_buf(15 + 4 * str.t.length); }
4398 o.write_shift(1, 0);
4399 write_XLWideString(str.t, o);
4400 return _null ? o.slice(0, o.l) : o;
4401}
4402/* [MS-XLSB] 2.4.328 BrtCommentText (RichStr w/1 run) */
4403var parse_BrtCommentText = parse_RichStr;
4404function write_BrtCommentText(str/*:XLString*/, o/*:?Block*/)/*:Block*/ {
4405 /* TODO: formatted string */
4406 var _null = false; if (o == null) { _null = true; o = new_buf(23 + 4 * str.t.length); }
4407 o.write_shift(1, 1);
4408 write_XLWideString(str.t, o);
4409 o.write_shift(4, 1);
4410 write_StrRun({ ich: 0, ifnt: 0 }, o);
4411 return _null ? o.slice(0, o.l) : o;
4412}
4413
4414/* [MS-XLSB] 2.5.9 */
4415function parse_XLSBCell(data)/*:any*/ {
4416 var col = data.read_shift(4);
4417 var iStyleRef = data.read_shift(2);
4418 iStyleRef += data.read_shift(1) << 16;
4419 data.l++; //var fPhShow = data.read_shift(1);
4420 return { c: col, iStyleRef: iStyleRef };
4421}
4422function write_XLSBCell(cell/*:any*/, o/*:?Block*/) {
4423 if (o == null) o = new_buf(8);
4424 o.write_shift(-4, cell.c);
4425 o.write_shift(3, cell.iStyleRef || cell.s);
4426 o.write_shift(1, 0); /* fPhShow */
4427 return o;
4428}
4429
4430/* Short XLSB Cell does not include column */
4431function parse_XLSBShortCell(data)/*:any*/ {
4432 var iStyleRef = data.read_shift(2);
4433 iStyleRef += data.read_shift(1) <<16;
4434 data.l++; //var fPhShow = data.read_shift(1);
4435 return { c:-1, iStyleRef: iStyleRef };
4436}
4437function write_XLSBShortCell(cell/*:any*/, o/*:?Block*/) {
4438 if(o == null) o = new_buf(4);
4439 o.write_shift(3, cell.iStyleRef || cell.s);
4440 o.write_shift(1, 0); /* fPhShow */
4441 return o;
4442}
4443
4444/* [MS-XLSB] 2.5.21 */
4445var parse_XLSBCodeName = parse_XLWideString;
4446var write_XLSBCodeName = write_XLWideString;
4447
4448/* [MS-XLSB] 2.5.166 */
4449function parse_XLNullableWideString(data/*::, length*/)/*:string*/ {
4450 var cchCharacters = data.read_shift(4);
4451 return cchCharacters === 0 || cchCharacters === 0xFFFFFFFF ? "" : data.read_shift(cchCharacters, 'dbcs');
4452}
4453function write_XLNullableWideString(data/*:string*/, o) {
4454 var _null = false; if (o == null) { _null = true; o = new_buf(127); }
4455 o.write_shift(4, data.length > 0 ? data.length : 0xFFFFFFFF);
4456 if (data.length > 0) o.write_shift(0, data, 'dbcs');
4457 return _null ? o.slice(0, o.l) : o;
4458}
4459
4460/* [MS-XLSB] 2.5.165 */
4461var parse_XLNameWideString = parse_XLWideString;
4462//var write_XLNameWideString = write_XLWideString;
4463
4464/* [MS-XLSB] 2.5.114 */
4465var parse_RelID = parse_XLNullableWideString;
4466var write_RelID = write_XLNullableWideString;
4467
4468
4469/* [MS-XLS] 2.5.217 ; [MS-XLSB] 2.5.122 */
4470function parse_RkNumber(data)/*:number*/ {
4471 var b = data.slice(data.l, data.l + 4);
4472 var fX100 = (b[0] & 1), fInt = (b[0] & 2);
4473 data.l += 4;
4474 var RK = fInt === 0 ? __double([0, 0, 0, 0, (b[0] & 0xFC), b[1], b[2], b[3]], 0) : __readInt32LE(b, 0) >> 2;
4475 return fX100 ? (RK / 100) : RK;
4476}
4477function write_RkNumber(data/*:number*/, o) {
4478 if (o == null) o = new_buf(4);
4479 var fX100 = 0, fInt = 0, d100 = data * 100;
4480 if ((data == (data | 0)) && (data >= -(1 << 29)) && (data < (1 << 29))) { fInt = 1; }
4481 else if ((d100 == (d100 | 0)) && (d100 >= -(1 << 29)) && (d100 < (1 << 29))) { fInt = 1; fX100 = 1; }
4482 if (fInt) o.write_shift(-4, ((fX100 ? d100 : data) << 2) + (fX100 + 2));
4483 else throw new Error("unsupported RkNumber " + data); // TODO
4484}
4485
4486
4487/* [MS-XLSB] 2.5.117 RfX */
4488function parse_RfX(data /*::, length*/)/*:Range*/ {
4489 var cell/*:Range*/ = ({ s: {}, e: {} }/*:any*/);
4490 cell.s.r = data.read_shift(4);
4491 cell.e.r = data.read_shift(4);
4492 cell.s.c = data.read_shift(4);
4493 cell.e.c = data.read_shift(4);
4494 return cell;
4495}
4496function write_RfX(r/*:Range*/, o) {
4497 if (!o) o = new_buf(16);
4498 o.write_shift(4, r.s.r);
4499 o.write_shift(4, r.e.r);
4500 o.write_shift(4, r.s.c);
4501 o.write_shift(4, r.e.c);
4502 return o;
4503}
4504
4505/* [MS-XLSB] 2.5.153 UncheckedRfX */
4506var parse_UncheckedRfX = parse_RfX;
4507var write_UncheckedRfX = write_RfX;
4508
4509/* [MS-XLSB] 2.5.155 UncheckedSqRfX */
4510//function parse_UncheckedSqRfX(data) {
4511// var cnt = data.read_shift(4);
4512// var out = [];
4513// for(var i = 0; i < cnt; ++i) {
4514// var rng = parse_UncheckedRfX(data);
4515// out.push(encode_range(rng));
4516// }
4517// return out.join(",");
4518//}
4519//function write_UncheckedSqRfX(sqrfx/*:string*/) {
4520// var parts = sqrfx.split(/\s*,\s*/);
4521// var o = new_buf(4); o.write_shift(4, parts.length);
4522// var out = [o];
4523// parts.forEach(function(rng) {
4524// out.push(write_UncheckedRfX(safe_decode_range(rng)));
4525// });
4526// return bconcat(out);
4527//}
4528
4529/* [MS-XLS] 2.5.342 ; [MS-XLSB] 2.5.171 */
4530/* TODO: error checking, NaN and Infinity values are not valid Xnum */
4531function parse_Xnum(data/*::, length*/) {
4532 if(data.length - data.l < 8) throw "XLS Xnum Buffer underflow";
4533 return data.read_shift(8, 'f');
4534}
4535function write_Xnum(data, o) { return (o || new_buf(8)).write_shift(8, data, 'f'); }
4536
4537/* [MS-XLSB] 2.4.324 BrtColor */
4538function parse_BrtColor(data/*::, length*/) {
4539 var out = {};
4540 var d = data.read_shift(1);
4541
4542 //var fValidRGB = d & 1;
4543 var xColorType = d >>> 1;
4544
4545 var index = data.read_shift(1);
4546 var nTS = data.read_shift(2, 'i');
4547 var bR = data.read_shift(1);
4548 var bG = data.read_shift(1);
4549 var bB = data.read_shift(1);
4550 data.l++; //var bAlpha = data.read_shift(1);
4551
4552 switch (xColorType) {
4553 case 0: out.auto = 1; break;
4554 case 1:
4555 out.index = index;
4556 var icv = XLSIcv[index];
4557 /* automatic pseudo index 81 */
4558 if (icv) out.rgb = rgb2Hex(icv);
4559 break;
4560 case 2:
4561 /* if(!fValidRGB) throw new Error("invalid"); */
4562 out.rgb = rgb2Hex([bR, bG, bB]);
4563 break;
4564 case 3: out.theme = index; break;
4565 }
4566 if (nTS != 0) out.tint = nTS > 0 ? nTS / 32767 : nTS / 32768;
4567
4568 return out;
4569}
4570function write_BrtColor(color, o) {
4571 if (!o) o = new_buf(8);
4572 if (!color || color.auto) { o.write_shift(4, 0); o.write_shift(4, 0); return o; }
4573 if (color.index != null) {
4574 o.write_shift(1, 0x02);
4575 o.write_shift(1, color.index);
4576 } else if (color.theme != null) {
4577 o.write_shift(1, 0x06);
4578 o.write_shift(1, color.theme);
4579 } else {
4580 o.write_shift(1, 0x05);
4581 o.write_shift(1, 0);
4582 }
4583 var nTS = color.tint || 0;
4584 if (nTS > 0) nTS *= 32767;
4585 else if (nTS < 0) nTS *= 32768;
4586 o.write_shift(2, nTS);
4587 if (!color.rgb || color.theme != null) {
4588 o.write_shift(2, 0);
4589 o.write_shift(1, 0);
4590 o.write_shift(1, 0);
4591 } else {
4592 var rgb = (color.rgb || 'FFFFFF');
4593 if (typeof rgb == 'number') rgb = ("000000" + rgb.toString(16)).slice(-6);
4594 o.write_shift(1, parseInt(rgb.slice(0, 2), 16));
4595 o.write_shift(1, parseInt(rgb.slice(2, 4), 16));
4596 o.write_shift(1, parseInt(rgb.slice(4, 6), 16));
4597 o.write_shift(1, 0xFF);
4598 }
4599 return o;
4600}
4601
4602/* [MS-XLSB] 2.5.52 */
4603function parse_FontFlags(data/*::, length, opts*/) {
4604 var d = data.read_shift(1);
4605 data.l++;
4606 var out = {
4607 fBold: d & 0x01,
4608 fItalic: d & 0x02,
4609 fUnderline: d & 0x04,
4610 fStrikeout: d & 0x08,
4611 fOutline: d & 0x10,
4612 fShadow: d & 0x20,
4613 fCondense: d & 0x40,
4614 fExtend: d & 0x80
4615 };
4616 return out;
4617}
4618function write_FontFlags(font, o) {
4619 if (!o) o = new_buf(2);
4620 var grbit =
4621 (font.italic ? 0x02 : 0) |
4622 (font.strike ? 0x08 : 0) |
4623 (font.outline ? 0x10 : 0) |
4624 (font.shadow ? 0x20 : 0) |
4625 (font.condense ? 0x40 : 0) |
4626 (font.extend ? 0x80 : 0);
4627 o.write_shift(1, grbit);
4628 o.write_shift(1, 0);
4629 return o;
4630}
4631
4632/* [MS-OLEDS] 2.3.1 and 2.3.2 */
4633function parse_ClipboardFormatOrString(o, w/*:number*/)/*:string*/ {
4634 // $FlowIgnore
4635 var ClipFmt = { 2: "BITMAP", 3: "METAFILEPICT", 8: "DIB", 14: "ENHMETAFILE" };
4636 var m/*:number*/ = o.read_shift(4);
4637 switch (m) {
4638 case 0x00000000: return "";
4639 case 0xffffffff: case 0xfffffffe: return ClipFmt[o.read_shift(4)] || "";
4640 }
4641 if (m > 0x190) throw new Error("Unsupported Clipboard: " + m.toString(16));
4642 o.l -= 4;
4643 return o.read_shift(0, w == 1 ? "lpstr" : "lpwstr");
4644}
4645function parse_ClipboardFormatOrAnsiString(o) { return parse_ClipboardFormatOrString(o, 1); }
4646function parse_ClipboardFormatOrUnicodeString(o) { return parse_ClipboardFormatOrString(o, 2); }
4647
4648/* [MS-OLEPS] 2.2 PropertyType */
4649// Note: some tree shakers cannot handle VT_VECTOR | $CONST, hence extra vars
4650//var VT_EMPTY = 0x0000;
4651//var VT_NULL = 0x0001;
4652var VT_I2 = 0x0002;
4653var VT_I4 = 0x0003;
4654//var VT_R4 = 0x0004;
4655//var VT_R8 = 0x0005;
4656//var VT_CY = 0x0006;
4657//var VT_DATE = 0x0007;
4658//var VT_BSTR = 0x0008;
4659//var VT_ERROR = 0x000A;
4660var VT_BOOL = 0x000B;
4661var VT_VARIANT = 0x000C;
4662//var VT_DECIMAL = 0x000E;
4663//var VT_I1 = 0x0010;
4664//var VT_UI1 = 0x0011;
4665//var VT_UI2 = 0x0012;
4666var VT_UI4 = 0x0013;
4667//var VT_I8 = 0x0014;
4668//var VT_UI8 = 0x0015;
4669//var VT_INT = 0x0016;
4670//var VT_UINT = 0x0017;
4671var VT_LPSTR = 0x001E;
4672//var VT_LPWSTR = 0x001F;
4673var VT_FILETIME = 0x0040;
4674var VT_BLOB = 0x0041;
4675//var VT_STREAM = 0x0042;
4676//var VT_STORAGE = 0x0043;
4677//var VT_STREAMED_Object = 0x0044;
4678//var VT_STORED_Object = 0x0045;
4679//var VT_BLOB_Object = 0x0046;
4680var VT_CF = 0x0047;
4681//var VT_CLSID = 0x0048;
4682//var VT_VERSIONED_STREAM = 0x0049;
4683var VT_VECTOR = 0x1000;
4684var VT_VECTOR_VARIANT = 0x100C;
4685var VT_VECTOR_LPSTR = 0x101E;
4686//var VT_ARRAY = 0x2000;
4687
4688var VT_STRING = 0x0050; // 2.3.3.1.11 VtString
4689var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString
4690var VT_CUSTOM = [VT_STRING, VT_USTR];
4691
4692/* [MS-OSHARED] 2.3.3.2.2.1 Document Summary Information PIDDSI */
4693var DocSummaryPIDDSI = {
4694 /*::[*/0x01/*::]*/: { n: 'CodePage', t: VT_I2 },
4695 /*::[*/0x02/*::]*/: { n: 'Category', t: VT_STRING },
4696 /*::[*/0x03/*::]*/: { n: 'PresentationFormat', t: VT_STRING },
4697 /*::[*/0x04/*::]*/: { n: 'ByteCount', t: VT_I4 },
4698 /*::[*/0x05/*::]*/: { n: 'LineCount', t: VT_I4 },
4699 /*::[*/0x06/*::]*/: { n: 'ParagraphCount', t: VT_I4 },
4700 /*::[*/0x07/*::]*/: { n: 'SlideCount', t: VT_I4 },
4701 /*::[*/0x08/*::]*/: { n: 'NoteCount', t: VT_I4 },
4702 /*::[*/0x09/*::]*/: { n: 'HiddenCount', t: VT_I4 },
4703 /*::[*/0x0a/*::]*/: { n: 'MultimediaClipCount', t: VT_I4 },
4704 /*::[*/0x0b/*::]*/: { n: 'ScaleCrop', t: VT_BOOL },
4705 /*::[*/0x0c/*::]*/: { n: 'HeadingPairs', t: VT_VECTOR_VARIANT /* VT_VECTOR | VT_VARIANT */ },
4706 /*::[*/0x0d/*::]*/: { n: 'TitlesOfParts', t: VT_VECTOR_LPSTR /* VT_VECTOR | VT_LPSTR */ },
4707 /*::[*/0x0e/*::]*/: { n: 'Manager', t: VT_STRING },
4708 /*::[*/0x0f/*::]*/: { n: 'Company', t: VT_STRING },
4709 /*::[*/0x10/*::]*/: { n: 'LinksUpToDate', t: VT_BOOL },
4710 /*::[*/0x11/*::]*/: { n: 'CharacterCount', t: VT_I4 },
4711 /*::[*/0x13/*::]*/: { n: 'SharedDoc', t: VT_BOOL },
4712 /*::[*/0x16/*::]*/: { n: 'HyperlinksChanged', t: VT_BOOL },
4713 /*::[*/0x17/*::]*/: { n: 'AppVersion', t: VT_I4, p: 'version' },
4714 /*::[*/0x18/*::]*/: { n: 'DigSig', t: VT_BLOB },
4715 /*::[*/0x1A/*::]*/: { n: 'ContentType', t: VT_STRING },
4716 /*::[*/0x1B/*::]*/: { n: 'ContentStatus', t: VT_STRING },
4717 /*::[*/0x1C/*::]*/: { n: 'Language', t: VT_STRING },
4718 /*::[*/0x1D/*::]*/: { n: 'Version', t: VT_STRING },
4719 /*::[*/0xFF/*::]*/: {},
4720 /* [MS-OLEPS] 2.18 */
4721 /*::[*/0x80000000/*::]*/: { n: 'Locale', t: VT_UI4 },
4722 /*::[*/0x80000003/*::]*/: { n: 'Behavior', t: VT_UI4 },
4723 /*::[*/0x72627262/*::]*/: {}
4724};
4725
4726/* [MS-OSHARED] 2.3.3.2.1.1 Summary Information Property Set PIDSI */
4727var SummaryPIDSI = {
4728 /*::[*/0x01/*::]*/: { n: 'CodePage', t: VT_I2 },
4729 /*::[*/0x02/*::]*/: { n: 'Title', t: VT_STRING },
4730 /*::[*/0x03/*::]*/: { n: 'Subject', t: VT_STRING },
4731 /*::[*/0x04/*::]*/: { n: 'Author', t: VT_STRING },
4732 /*::[*/0x05/*::]*/: { n: 'Keywords', t: VT_STRING },
4733 /*::[*/0x06/*::]*/: { n: 'Comments', t: VT_STRING },
4734 /*::[*/0x07/*::]*/: { n: 'Template', t: VT_STRING },
4735 /*::[*/0x08/*::]*/: { n: 'LastAuthor', t: VT_STRING },
4736 /*::[*/0x09/*::]*/: { n: 'RevNumber', t: VT_STRING },
4737 /*::[*/0x0A/*::]*/: { n: 'EditTime', t: VT_FILETIME },
4738 /*::[*/0x0B/*::]*/: { n: 'LastPrinted', t: VT_FILETIME },
4739 /*::[*/0x0C/*::]*/: { n: 'CreatedDate', t: VT_FILETIME },
4740 /*::[*/0x0D/*::]*/: { n: 'ModifiedDate', t: VT_FILETIME },
4741 /*::[*/0x0E/*::]*/: { n: 'PageCount', t: VT_I4 },
4742 /*::[*/0x0F/*::]*/: { n: 'WordCount', t: VT_I4 },
4743 /*::[*/0x10/*::]*/: { n: 'CharCount', t: VT_I4 },
4744 /*::[*/0x11/*::]*/: { n: 'Thumbnail', t: VT_CF },
4745 /*::[*/0x12/*::]*/: { n: 'Application', t: VT_STRING },
4746 /*::[*/0x13/*::]*/: { n: 'DocSecurity', t: VT_I4 },
4747 /*::[*/0xFF/*::]*/: {},
4748 /* [MS-OLEPS] 2.18 */
4749 /*::[*/0x80000000/*::]*/: { n: 'Locale', t: VT_UI4 },
4750 /*::[*/0x80000003/*::]*/: { n: 'Behavior', t: VT_UI4 },
4751 /*::[*/0x72627262/*::]*/: {}
4752};
4753
4754/* [MS-XLS] 2.4.63 Country/Region codes */
4755var CountryEnum = {
4756 /*::[*/0x0001/*::]*/: "US", // United States
4757 /*::[*/0x0002/*::]*/: "CA", // Canada
4758 /*::[*/0x0003/*::]*/: "", // Latin America (except Brazil)
4759 /*::[*/0x0007/*::]*/: "RU", // Russia
4760 /*::[*/0x0014/*::]*/: "EG", // Egypt
4761 /*::[*/0x001E/*::]*/: "GR", // Greece
4762 /*::[*/0x001F/*::]*/: "NL", // Netherlands
4763 /*::[*/0x0020/*::]*/: "BE", // Belgium
4764 /*::[*/0x0021/*::]*/: "FR", // France
4765 /*::[*/0x0022/*::]*/: "ES", // Spain
4766 /*::[*/0x0024/*::]*/: "HU", // Hungary
4767 /*::[*/0x0027/*::]*/: "IT", // Italy
4768 /*::[*/0x0029/*::]*/: "CH", // Switzerland
4769 /*::[*/0x002B/*::]*/: "AT", // Austria
4770 /*::[*/0x002C/*::]*/: "GB", // United Kingdom
4771 /*::[*/0x002D/*::]*/: "DK", // Denmark
4772 /*::[*/0x002E/*::]*/: "SE", // Sweden
4773 /*::[*/0x002F/*::]*/: "NO", // Norway
4774 /*::[*/0x0030/*::]*/: "PL", // Poland
4775 /*::[*/0x0031/*::]*/: "DE", // Germany
4776 /*::[*/0x0034/*::]*/: "MX", // Mexico
4777 /*::[*/0x0037/*::]*/: "BR", // Brazil
4778 /*::[*/0x003d/*::]*/: "AU", // Australia
4779 /*::[*/0x0040/*::]*/: "NZ", // New Zealand
4780 /*::[*/0x0042/*::]*/: "TH", // Thailand
4781 /*::[*/0x0051/*::]*/: "JP", // Japan
4782 /*::[*/0x0052/*::]*/: "KR", // Korea
4783 /*::[*/0x0054/*::]*/: "VN", // Viet Nam
4784 /*::[*/0x0056/*::]*/: "CN", // China
4785 /*::[*/0x005A/*::]*/: "TR", // Turkey
4786 /*::[*/0x0069/*::]*/: "JS", // Ramastan
4787 /*::[*/0x00D5/*::]*/: "DZ", // Algeria
4788 /*::[*/0x00D8/*::]*/: "MA", // Morocco
4789 /*::[*/0x00DA/*::]*/: "LY", // Libya
4790 /*::[*/0x015F/*::]*/: "PT", // Portugal
4791 /*::[*/0x0162/*::]*/: "IS", // Iceland
4792 /*::[*/0x0166/*::]*/: "FI", // Finland
4793 /*::[*/0x01A4/*::]*/: "CZ", // Czech Republic
4794 /*::[*/0x0376/*::]*/: "TW", // Taiwan
4795 /*::[*/0x03C1/*::]*/: "LB", // Lebanon
4796 /*::[*/0x03C2/*::]*/: "JO", // Jordan
4797 /*::[*/0x03C3/*::]*/: "SY", // Syria
4798 /*::[*/0x03C4/*::]*/: "IQ", // Iraq
4799 /*::[*/0x03C5/*::]*/: "KW", // Kuwait
4800 /*::[*/0x03C6/*::]*/: "SA", // Saudi Arabia
4801 /*::[*/0x03CB/*::]*/: "AE", // United Arab Emirates
4802 /*::[*/0x03CC/*::]*/: "IL", // Israel
4803 /*::[*/0x03CE/*::]*/: "QA", // Qatar
4804 /*::[*/0x03D5/*::]*/: "IR", // Iran
4805 /*::[*/0xFFFF/*::]*/: "US" // United States
4806};
4807
4808/* [MS-XLS] 2.5.127 */
4809var XLSFillPattern = [
4810 null,
4811 'solid',
4812 'mediumGray',
4813 'darkGray',
4814 'lightGray',
4815 'darkHorizontal',
4816 'darkVertical',
4817 'darkDown',
4818 'darkUp',
4819 'darkGrid',
4820 'darkTrellis',
4821 'lightHorizontal',
4822 'lightVertical',
4823 'lightDown',
4824 'lightUp',
4825 'lightGrid',
4826 'lightTrellis',
4827 'gray125',
4828 'gray0625'
4829];
4830
4831function rgbify(arr/*:Array<number>*/)/*:Array<[number, number, number]>*/ { return arr.map(function(x) { return [(x>>16)&255,(x>>8)&255,x&255]; }); }
4832
4833/* [MS-XLS] 2.5.161 */
4834/* [MS-XLSB] 2.5.75 Icv */
4835var _XLSIcv = /*#__PURE__*/ rgbify([
4836 /* Color Constants */
4837 0x000000,
4838 0xFFFFFF,
4839 0xFF0000,
4840 0x00FF00,
4841 0x0000FF,
4842 0xFFFF00,
4843 0xFF00FF,
4844 0x00FFFF,
4845
4846 /* Overridable Defaults */
4847 0x000000,
4848 0xFFFFFF,
4849 0xFF0000,
4850 0x00FF00,
4851 0x0000FF,
4852 0xFFFF00,
4853 0xFF00FF,
4854 0x00FFFF,
4855
4856 0x800000,
4857 0x008000,
4858 0x000080,
4859 0x808000,
4860 0x800080,
4861 0x008080,
4862 0xC0C0C0,
4863 0x808080,
4864 0x9999FF,
4865 0x993366,
4866 0xFFFFCC,
4867 0xCCFFFF,
4868 0x660066,
4869 0xFF8080,
4870 0x0066CC,
4871 0xCCCCFF,
4872
4873 0x000080,
4874 0xFF00FF,
4875 0xFFFF00,
4876 0x00FFFF,
4877 0x800080,
4878 0x800000,
4879 0x008080,
4880 0x0000FF,
4881 0x00CCFF,
4882 0xCCFFFF,
4883 0xCCFFCC,
4884 0xFFFF99,
4885 0x99CCFF,
4886 0xFF99CC,
4887 0xCC99FF,
4888 0xFFCC99,
4889
4890 0x3366FF,
4891 0x33CCCC,
4892 0x99CC00,
4893 0xFFCC00,
4894 0xFF9900,
4895 0xFF6600,
4896 0x666699,
4897 0x969696,
4898 0x003366,
4899 0x339966,
4900 0x003300,
4901 0x333300,
4902 0x993300,
4903 0x993366,
4904 0x333399,
4905 0x333333,
4906
4907 /* Other entries to appease BIFF8/12 */
4908 0xFFFFFF, /* 0x40 icvForeground ?? */
4909 0x000000, /* 0x41 icvBackground ?? */
4910 0x000000, /* 0x42 icvFrame ?? */
4911 0x000000, /* 0x43 icv3D ?? */
4912 0x000000, /* 0x44 icv3DText ?? */
4913 0x000000, /* 0x45 icv3DHilite ?? */
4914 0x000000, /* 0x46 icv3DShadow ?? */
4915 0x000000, /* 0x47 icvHilite ?? */
4916 0x000000, /* 0x48 icvCtlText ?? */
4917 0x000000, /* 0x49 icvCtlScrl ?? */
4918 0x000000, /* 0x4A icvCtlInv ?? */
4919 0x000000, /* 0x4B icvCtlBody ?? */
4920 0x000000, /* 0x4C icvCtlFrame ?? */
4921 0x000000, /* 0x4D icvCtlFore ?? */
4922 0x000000, /* 0x4E icvCtlBack ?? */
4923 0x000000, /* 0x4F icvCtlNeutral */
4924 0x000000, /* 0x50 icvInfoBk ?? */
4925 0x000000 /* 0x51 icvInfoText ?? */
4926]);
4927var XLSIcv = /*#__PURE__*/dup(_XLSIcv);
4928
4929/* [MS-XLSB] 2.5.97.2 */
4930var BErr = {
4931 /*::[*/0x00/*::]*/: "#NULL!",
4932 /*::[*/0x07/*::]*/: "#DIV/0!",
4933 /*::[*/0x0F/*::]*/: "#VALUE!",
4934 /*::[*/0x17/*::]*/: "#REF!",
4935 /*::[*/0x1D/*::]*/: "#NAME?",
4936 /*::[*/0x24/*::]*/: "#NUM!",
4937 /*::[*/0x2A/*::]*/: "#N/A",
4938 /*::[*/0x2B/*::]*/: "#GETTING_DATA",
4939 /*::[*/0xFF/*::]*/: "#WTF?"
4940};
4941//var RBErr = evert_num(BErr);
4942var RBErr = {
4943 "#NULL!": 0x00,
4944 "#DIV/0!": 0x07,
4945 "#VALUE!": 0x0F,
4946 "#REF!": 0x17,
4947 "#NAME?": 0x1D,
4948 "#NUM!": 0x24,
4949 "#N/A": 0x2A,
4950 "#GETTING_DATA": 0x2B,
4951 "#WTF?": 0xFF
4952};
4953
4954/* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */
4955/* 12.3 Part Summary <SpreadsheetML> */
4956/* 14.2 Part Summary <DrawingML> */
4957/* [MS-XLSX] 2.1 Part Enumerations ; [MS-XLSB] 2.1.7 Part Enumeration */
4958var ct2type/*{[string]:string}*/ = ({
4959 /* Workbook */
4960 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks",
4961 "application/vnd.ms-excel.sheet.macroEnabled.main+xml": "workbooks",
4962 "application/vnd.ms-excel.sheet.binary.macroEnabled.main": "workbooks",
4963 "application/vnd.ms-excel.addin.macroEnabled.main+xml": "workbooks",
4964 "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": "workbooks",
4965
4966 /* Worksheet */
4967 "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": "sheets",
4968 "application/vnd.ms-excel.worksheet": "sheets",
4969 "application/vnd.ms-excel.binIndexWs": "TODO", /* Binary Index */
4970
4971 /* Chartsheet */
4972 "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": "charts",
4973 "application/vnd.ms-excel.chartsheet": "charts",
4974
4975 /* Macrosheet */
4976 "application/vnd.ms-excel.macrosheet+xml": "macros",
4977 "application/vnd.ms-excel.macrosheet": "macros",
4978 "application/vnd.ms-excel.intlmacrosheet": "TODO",
4979 "application/vnd.ms-excel.binIndexMs": "TODO", /* Binary Index */
4980
4981 /* Dialogsheet */
4982 "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": "dialogs",
4983 "application/vnd.ms-excel.dialogsheet": "dialogs",
4984
4985 /* Shared Strings */
4986 "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml": "strs",
4987 "application/vnd.ms-excel.sharedStrings": "strs",
4988
4989 /* Styles */
4990 "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": "styles",
4991 "application/vnd.ms-excel.styles": "styles",
4992
4993 /* File Properties */
4994 "application/vnd.openxmlformats-package.core-properties+xml": "coreprops",
4995 "application/vnd.openxmlformats-officedocument.custom-properties+xml": "custprops",
4996 "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops",
4997
4998 /* Custom Data Properties */
4999 "application/vnd.openxmlformats-officedocument.customXmlProperties+xml": "TODO",
5000 "application/vnd.openxmlformats-officedocument.spreadsheetml.customProperty": "TODO",
5001
5002 /* Comments */
5003 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": "comments",
5004 "application/vnd.ms-excel.comments": "comments",
5005 "application/vnd.ms-excel.threadedcomments+xml": "threadedcomments",
5006 "application/vnd.ms-excel.person+xml": "people",
5007
5008 /* Metadata (Stock/Geography and Dynamic Array) */
5009 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
5010 "application/vnd.ms-excel.sheetMetadata": "metadata",
5011
5012 /* PivotTable */
5013 "application/vnd.ms-excel.pivotTable": "TODO",
5014 "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
5015
5016 /* Chart Objects */
5017 "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
5018
5019 /* Chart Colors */
5020 "application/vnd.ms-office.chartcolorstyle+xml": "TODO",
5021
5022 /* Chart Style */
5023 "application/vnd.ms-office.chartstyle+xml": "TODO",
5024
5025 /* Chart Advanced */
5026 "application/vnd.ms-office.chartex+xml": "TODO",
5027
5028 /* Calculation Chain */
5029 "application/vnd.ms-excel.calcChain": "calcchains",
5030 "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
5031
5032 /* Printer Settings */
5033 "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings": "TODO",
5034
5035 /* ActiveX */
5036 "application/vnd.ms-office.activeX": "TODO",
5037 "application/vnd.ms-office.activeX+xml": "TODO",
5038
5039 /* Custom Toolbars */
5040 "application/vnd.ms-excel.attachedToolbars": "TODO",
5041
5042 /* External Data Connections */
5043 "application/vnd.ms-excel.connections": "TODO",
5044 "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": "TODO",
5045
5046 /* External Links */
5047 "application/vnd.ms-excel.externalLink": "links",
5048 "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
5049
5050 /* PivotCache */
5051 "application/vnd.ms-excel.pivotCacheDefinition": "TODO",
5052 "application/vnd.ms-excel.pivotCacheRecords": "TODO",
5053 "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml": "TODO",
5054 "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml": "TODO",
5055
5056 /* Query Table */
5057 "application/vnd.ms-excel.queryTable": "TODO",
5058 "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml": "TODO",
5059
5060 /* Shared Workbook */
5061 "application/vnd.ms-excel.userNames": "TODO",
5062 "application/vnd.ms-excel.revisionHeaders": "TODO",
5063 "application/vnd.ms-excel.revisionLog": "TODO",
5064 "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml": "TODO",
5065 "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml": "TODO",
5066 "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml": "TODO",
5067
5068 /* Single Cell Table */
5069 "application/vnd.ms-excel.tableSingleCells": "TODO",
5070 "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml": "TODO",
5071
5072 /* Slicer */
5073 "application/vnd.ms-excel.slicer": "TODO",
5074 "application/vnd.ms-excel.slicerCache": "TODO",
5075 "application/vnd.ms-excel.slicer+xml": "TODO",
5076 "application/vnd.ms-excel.slicerCache+xml": "TODO",
5077
5078 /* Sort Map */
5079 "application/vnd.ms-excel.wsSortMap": "TODO",
5080
5081 /* Table */
5082 "application/vnd.ms-excel.table": "TODO",
5083 "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": "TODO",
5084
5085 /* Themes */
5086 "application/vnd.openxmlformats-officedocument.theme+xml": "themes",
5087
5088 /* Theme Override */
5089 "application/vnd.openxmlformats-officedocument.themeOverride+xml": "TODO",
5090
5091 /* Timeline */
5092 "application/vnd.ms-excel.Timeline+xml": "TODO", /* verify */
5093 "application/vnd.ms-excel.TimelineCache+xml": "TODO", /* verify */
5094
5095 /* VBA */
5096 "application/vnd.ms-office.vbaProject": "vba",
5097 "application/vnd.ms-office.vbaProjectSignature": "TODO",
5098
5099 /* Volatile Dependencies */
5100 "application/vnd.ms-office.volatileDependencies": "TODO",
5101 "application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml": "TODO",
5102
5103 /* Control Properties */
5104 "application/vnd.ms-excel.controlproperties+xml": "TODO",
5105
5106 /* Data Model */
5107 "application/vnd.openxmlformats-officedocument.model+data": "TODO",
5108
5109 /* Survey */
5110 "application/vnd.ms-excel.Survey+xml": "TODO",
5111
5112 /* Drawing */
5113 "application/vnd.openxmlformats-officedocument.drawing+xml": "drawings",
5114 "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
5115 "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
5116 "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
5117 "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml": "TODO",
5118 "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml": "TODO",
5119
5120 /* VML */
5121 "application/vnd.openxmlformats-officedocument.vmlDrawing": "TODO",
5122
5123 "application/vnd.openxmlformats-package.relationships+xml": "rels",
5124 "application/vnd.openxmlformats-officedocument.oleObject": "TODO",
5125
5126 /* Image */
5127 "image/png": "TODO",
5128
5129 "sheet": "js"
5130}/*:any*/);
5131
5132var CT_LIST = {
5133 workbooks: {
5134 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
5135 xlsm: "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
5136 xlsb: "application/vnd.ms-excel.sheet.binary.macroEnabled.main",
5137 xlam: "application/vnd.ms-excel.addin.macroEnabled.main+xml",
5138 xltx: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"
5139 },
5140 strs: { /* Shared Strings */
5141 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
5142 xlsb: "application/vnd.ms-excel.sharedStrings"
5143 },
5144 comments: { /* Comments */
5145 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
5146 xlsb: "application/vnd.ms-excel.comments"
5147 },
5148 sheets: { /* Worksheet */
5149 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
5150 xlsb: "application/vnd.ms-excel.worksheet"
5151 },
5152 charts: { /* Chartsheet */
5153 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
5154 xlsb: "application/vnd.ms-excel.chartsheet"
5155 },
5156 dialogs: { /* Dialogsheet */
5157 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml",
5158 xlsb: "application/vnd.ms-excel.dialogsheet"
5159 },
5160 macros: { /* Macrosheet (Excel 4.0 Macros) */
5161 xlsx: "application/vnd.ms-excel.macrosheet+xml",
5162 xlsb: "application/vnd.ms-excel.macrosheet"
5163 },
5164 metadata: { /* Metadata (Stock/Geography and Dynamic Array) */
5165 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
5166 xlsb: "application/vnd.ms-excel.sheetMetadata"
5167 },
5168 styles: { /* Styles */
5169 xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
5170 xlsb: "application/vnd.ms-excel.styles"
5171 }
5172};
5173
5174function new_ct()/*:any*/ {
5175 return ({
5176 workbooks:[], sheets:[], charts:[], dialogs:[], macros:[],
5177 rels:[], strs:[], comments:[], threadedcomments:[], links:[],
5178 coreprops:[], extprops:[], custprops:[], themes:[], styles:[],
5179 calcchains:[], vba: [], drawings: [], metadata: [], people:[],
5180 TODO:[], xmlns: "" }/*:any*/);
5181}
5182
5183function parse_ct(data/*:?string*/) {
5184 var ct = new_ct();
5185 if(!data || !data.match) return ct;
5186 var ctext = {};
5187 (data.match(tagregex)||[]).forEach(function(x) {
5188 var y = parsexmltag(x);
5189 switch(y[0].replace(nsregex,"<")) {
5190 case '<?xml': break;
5191 case '<Types': ct.xmlns = y['xmlns' + (y[0].match(/<(\w+):/)||["",""])[1] ]; break;
5192 case '<Default': ctext[y.Extension] = y.ContentType; break;
5193 case '<Override':
5194 if(ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
5195 break;
5196 }
5197 });
5198 if(ct.xmlns !== XMLNS.CT) throw new Error("Unknown Namespace: " + ct.xmlns);
5199 ct.calcchain = ct.calcchains.length > 0 ? ct.calcchains[0] : "";
5200 ct.sst = ct.strs.length > 0 ? ct.strs[0] : "";
5201 ct.style = ct.styles.length > 0 ? ct.styles[0] : "";
5202 ct.defaults = ctext;
5203 delete ct.calcchains;
5204 return ct;
5205}
5206
5207function write_ct(ct, opts)/*:string*/ {
5208 var type2ct/*{[string]:Array<string>}*/ = evert_arr(ct2type);
5209
5210 var o/*:Array<string>*/ = [], v;
5211 o[o.length] = (XML_HEADER);
5212 o[o.length] = writextag('Types', null, {
5213 'xmlns': XMLNS.CT,
5214 'xmlns:xsd': XMLNS.xsd,
5215 'xmlns:xsi': XMLNS.xsi
5216 });
5217
5218 o = o.concat([
5219 ['xml', 'application/xml'],
5220 ['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'],
5221 ['vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'],
5222 ['data', 'application/vnd.openxmlformats-officedocument.model+data'],
5223 /* from test files */
5224 ['bmp', 'image/bmp'],
5225 ['png', 'image/png'],
5226 ['gif', 'image/gif'],
5227 ['emf', 'image/x-emf'],
5228 ['wmf', 'image/x-wmf'],
5229 ['jpg', 'image/jpeg'], ['jpeg', 'image/jpeg'],
5230 ['tif', 'image/tiff'], ['tiff', 'image/tiff'],
5231 ['pdf', 'application/pdf'],
5232 ['rels', 'application/vnd.openxmlformats-package.relationships+xml']
5233 ].map(function(x) {
5234 return writextag('Default', null, {'Extension':x[0], 'ContentType': x[1]});
5235 }));
5236
5237 /* only write first instance */
5238 var f1 = function(w) {
5239 if(ct[w] && ct[w].length > 0) {
5240 v = ct[w][0];
5241 o[o.length] = (writextag('Override', null, {
5242 'PartName': (v[0] == '/' ? "":"/") + v,
5243 'ContentType': CT_LIST[w][opts.bookType] || CT_LIST[w]['xlsx']
5244 }));
5245 }
5246 };
5247
5248 /* book type-specific */
5249 var f2 = function(w) {
5250 (ct[w]||[]).forEach(function(v) {
5251 o[o.length] = (writextag('Override', null, {
5252 'PartName': (v[0] == '/' ? "":"/") + v,
5253 'ContentType': CT_LIST[w][opts.bookType] || CT_LIST[w]['xlsx']
5254 }));
5255 });
5256 };
5257
5258 /* standard type */
5259 var f3 = function(t) {
5260 (ct[t]||[]).forEach(function(v) {
5261 o[o.length] = (writextag('Override', null, {
5262 'PartName': (v[0] == '/' ? "":"/") + v,
5263 'ContentType': type2ct[t][0]
5264 }));
5265 });
5266 };
5267
5268 f1('workbooks');
5269 f2('sheets');
5270 f2('charts');
5271 f3('themes');
5272 ['strs', 'styles'].forEach(f1);
5273 ['coreprops', 'extprops', 'custprops'].forEach(f3);
5274 f3('vba');
5275 f3('comments');
5276 f3('threadedcomments');
5277 f3('drawings');
5278 f2('metadata');
5279 f3('people');
5280 if(o.length>2){ o[o.length] = ('</Types>'); o[1]=o[1].replace("/>",">"); }
5281 return o.join("");
5282}
5283/* 9.3 Relationships */
5284var RELS = ({
5285 WB: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
5286 SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
5287 HLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
5288 VML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
5289 XPATH: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",
5290 XMISS: "http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",
5291 XLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
5292 CXML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml",
5293 CXMLP: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps",
5294 CMNT: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
5295 CORE_PROPS: "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
5296 EXT_PROPS: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
5297 CUST_PROPS: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
5298 SST: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
5299 STY: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
5300 THEME: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
5301 CHART: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
5302 CHARTEX: "http://schemas.microsoft.com/office/2014/relationships/chartEx",
5303 CS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet",
5304 WS: [
5305 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
5306 "http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet"
5307 ],
5308 DS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet",
5309 MS: "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet",
5310 IMG: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
5311 DRAW: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
5312 XLMETA: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
5313 TCMNT: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
5314 PEOPLE: "http://schemas.microsoft.com/office/2017/10/relationships/person",
5315 VBA: "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
5316}/*:any*/);
5317
5318
5319/* 9.3.3 Representing Relationships */
5320function get_rels_path(file/*:string*/)/*:string*/ {
5321 var n = file.lastIndexOf("/");
5322 return file.slice(0,n+1) + '_rels/' + file.slice(n+1) + ".rels";
5323}
5324
5325function parse_rels(data/*:?string*/, currentFilePath/*:string*/) {
5326 var rels = {"!id":{}};
5327 if (!data) return rels;
5328 if (currentFilePath.charAt(0) !== '/') {
5329 currentFilePath = '/'+currentFilePath;
5330 }
5331 var hash = {};
5332
5333 (data.match(tagregex)||[]).forEach(function(x) {
5334 var y = parsexmltag(x);
5335 /* 9.3.2.2 OPC_Relationships */
5336 if (y[0] === '<Relationship') {
5337 var rel = {}; rel.Type = y.Type; rel.Target = y.Target; rel.Id = y.Id; if(y.TargetMode) rel.TargetMode = y.TargetMode;
5338 var canonictarget = y.TargetMode === 'External' ? y.Target : resolve_path(y.Target, currentFilePath);
5339 rels[canonictarget] = rel;
5340 hash[y.Id] = rel;
5341 }
5342 });
5343 rels["!id"] = hash;
5344 return rels;
5345}
5346
5347
5348/* TODO */
5349function write_rels(rels)/*:string*/ {
5350 var o = [XML_HEADER, writextag('Relationships', null, {
5351 //'xmlns:ns0': XMLNS.RELS,
5352 'xmlns': XMLNS.RELS
5353 })];
5354 keys(rels['!id']).forEach(function(rid) {
5355 o[o.length] = (writextag('Relationship', null, rels['!id'][rid]));
5356 });
5357 if(o.length>2){ o[o.length] = ('</Relationships>'); o[1]=o[1].replace("/>",">"); }
5358 return o.join("");
5359}
5360
5361function add_rels(rels, rId/*:number*/, f, type, relobj, targetmode/*:?string*/)/*:number*/ {
5362 if(!relobj) relobj = {};
5363 if(!rels['!id']) rels['!id'] = {};
5364 if(!rels['!idx']) rels['!idx'] = 1;
5365 if(rId < 0) for(rId = rels['!idx']; rels['!id']['rId' + rId]; ++rId){/* empty */}
5366 rels['!idx'] = rId + 1;
5367 relobj.Id = 'rId' + rId;
5368 relobj.Type = type;
5369 relobj.Target = f;
5370 if(targetmode) relobj.TargetMode = targetmode;
5371 else if([RELS.HLINK, RELS.XPATH, RELS.XMISS].indexOf(relobj.Type) > -1) relobj.TargetMode = "External";
5372 if(rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
5373 rels['!id'][relobj.Id] = relobj;
5374 rels[('/' + relobj.Target).replace("//","/")] = relobj;
5375 return rId;
5376}
5377/* Open Document Format for Office Applications (OpenDocument) Version 1.2 */
5378/* Part 3 Section 4 Manifest File */
5379var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
5380function parse_manifest(d, opts) {
5381 var str = xlml_normalize(d);
5382 var Rn;
5383 var FEtag;
5384 while((Rn = xlmlregex.exec(str))) switch(Rn[3]) {
5385 case 'manifest': break; // 4.2 <manifest:manifest>
5386 case 'file-entry': // 4.3 <manifest:file-entry>
5387 FEtag = parsexmltag(Rn[0], false);
5388 if(FEtag.path == '/' && FEtag.type !== CT_ODS) throw new Error("This OpenDocument is not a spreadsheet");
5389 break;
5390 case 'encryption-data': // 4.4 <manifest:encryption-data>
5391 case 'algorithm': // 4.5 <manifest:algorithm>
5392 case 'start-key-generation': // 4.6 <manifest:start-key-generation>
5393 case 'key-derivation': // 4.7 <manifest:key-derivation>
5394 throw new Error("Unsupported ODS Encryption");
5395 default: if(opts && opts.WTF) throw Rn;
5396 }
5397}
5398
5399function write_manifest(manifest/*:Array<Array<string> >*/)/*:string*/ {
5400 var o = [XML_HEADER];
5401 o.push('<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">\n');
5402 o.push(' <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>\n');
5403 for(var i = 0; i < manifest.length; ++i) o.push(' <manifest:file-entry manifest:full-path="' + manifest[i][0] + '" manifest:media-type="' + manifest[i][1] + '"/>\n');
5404 o.push('</manifest:manifest>');
5405 return o.join("");
5406}
5407
5408/* Part 3 Section 6 Metadata Manifest File */
5409function write_rdf_type(file/*:string*/, res/*:string*/, tag/*:?string*/) {
5410 return [
5411 ' <rdf:Description rdf:about="' + file + '">\n',
5412 ' <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/' + (tag || "odf") + '#' + res + '"/>\n',
5413 ' </rdf:Description>\n'
5414 ].join("");
5415}
5416function write_rdf_has(base/*:string*/, file/*:string*/) {
5417 return [
5418 ' <rdf:Description rdf:about="' + base + '">\n',
5419 ' <ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="' + file + '"/>\n',
5420 ' </rdf:Description>\n'
5421 ].join("");
5422}
5423function write_rdf(rdf) {
5424 var o = [XML_HEADER];
5425 o.push('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\n');
5426 for(var i = 0; i != rdf.length; ++i) {
5427 o.push(write_rdf_type(rdf[i][0], rdf[i][1]));
5428 o.push(write_rdf_has("",rdf[i][0]));
5429 }
5430 o.push(write_rdf_type("","Document", "pkg"));
5431 o.push('</rdf:RDF>');
5432 return o.join("");
5433}
5434/* TODO: pull properties */
5435function write_meta_ods(/*:: wb: Workbook, opts: any*/)/*:string*/ {
5436 return '<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink" office:version="1.2"><office:meta><meta:generator>Sheet' + 'JS ' + XLSX.version + '</meta:generator></office:meta></office:document-meta>';
5437}
5438
5439/* ECMA-376 Part II 11.1 Core Properties Part */
5440/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
5441var CORE_PROPS/*:Array<Array<string> >*/ = [
5442 ["cp:category", "Category"],
5443 ["cp:contentStatus", "ContentStatus"],
5444 ["cp:keywords", "Keywords"],
5445 ["cp:lastModifiedBy", "LastAuthor"],
5446 ["cp:lastPrinted", "LastPrinted"],
5447 ["cp:revision", "RevNumber"],
5448 ["cp:version", "Version"],
5449 ["dc:creator", "Author"],
5450 ["dc:description", "Comments"],
5451 ["dc:identifier", "Identifier"],
5452 ["dc:language", "Language"],
5453 ["dc:subject", "Subject"],
5454 ["dc:title", "Title"],
5455 ["dcterms:created", "CreatedDate", 'date'],
5456 ["dcterms:modified", "ModifiedDate", 'date']
5457];
5458
5459var CORE_PROPS_REGEX/*:Array<RegExp>*/ = /*#__PURE__*/(function() {
5460 var r = new Array(CORE_PROPS.length);
5461 for(var i = 0; i < CORE_PROPS.length; ++i) {
5462 var f = CORE_PROPS[i];
5463 var g = "(?:"+ f[0].slice(0,f[0].indexOf(":")) +":)"+ f[0].slice(f[0].indexOf(":")+1);
5464 r[i] = new RegExp("<" + g + "[^>]*>([\\s\\S]*?)<\/" + g + ">");
5465 }
5466 return r;
5467})();
5468
5469function parse_core_props(data) {
5470 var p = {};
5471 data = utf8read(data);
5472
5473 for(var i = 0; i < CORE_PROPS.length; ++i) {
5474 var f = CORE_PROPS[i], cur = data.match(CORE_PROPS_REGEX[i]);
5475 if(cur != null && cur.length > 0) p[f[1]] = unescapexml(cur[1]);
5476 if(f[2] === 'date' && p[f[1]]) p[f[1]] = parseDate(p[f[1]]);
5477 }
5478
5479 return p;
5480}
5481
5482function cp_doit(f, g, h, o, p) {
5483 if(p[f] != null || g == null || g === "") return;
5484 p[f] = g;
5485 g = escapexml(g);
5486 o[o.length] = (h ? writextag(f,g,h) : writetag(f,g));
5487}
5488
5489function write_core_props(cp, _opts) {
5490 var opts = _opts || {};
5491 var o = [XML_HEADER, writextag('cp:coreProperties', null, {
5492 //'xmlns': XMLNS.CORE_PROPS,
5493 'xmlns:cp': XMLNS.CORE_PROPS,
5494 'xmlns:dc': XMLNS.dc,
5495 'xmlns:dcterms': XMLNS.dcterms,
5496 'xmlns:dcmitype': XMLNS.dcmitype,
5497 'xmlns:xsi': XMLNS.xsi
5498 })], p = {};
5499 if(!cp && !opts.Props) return o.join("");
5500
5501 if(cp) {
5502 if(cp.CreatedDate != null) cp_doit("dcterms:created", typeof cp.CreatedDate === "string" ? cp.CreatedDate : write_w3cdtf(cp.CreatedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
5503 if(cp.ModifiedDate != null) cp_doit("dcterms:modified", typeof cp.ModifiedDate === "string" ? cp.ModifiedDate : write_w3cdtf(cp.ModifiedDate, opts.WTF), {"xsi:type":"dcterms:W3CDTF"}, o, p);
5504 }
5505
5506 for(var i = 0; i != CORE_PROPS.length; ++i) {
5507 var f = CORE_PROPS[i];
5508 var v = opts.Props && opts.Props[f[1]] != null ? opts.Props[f[1]] : cp ? cp[f[1]] : null;
5509 if(v === true) v = "1";
5510 else if(v === false) v = "0";
5511 else if(typeof v == "number") v = String(v);
5512 if(v != null) cp_doit(f[0], v, null, o, p);
5513 }
5514 if(o.length>2){ o[o.length] = ('</cp:coreProperties>'); o[1]=o[1].replace("/>",">"); }
5515 return o.join("");
5516}
5517/* 15.2.12.3 Extended File Properties Part */
5518/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
5519var EXT_PROPS/*:Array<Array<string> >*/ = [
5520 ["Application", "Application", "string"],
5521 ["AppVersion", "AppVersion", "string"],
5522 ["Company", "Company", "string"],
5523 ["DocSecurity", "DocSecurity", "string"],
5524 ["Manager", "Manager", "string"],
5525 ["HyperlinksChanged", "HyperlinksChanged", "bool"],
5526 ["SharedDoc", "SharedDoc", "bool"],
5527 ["LinksUpToDate", "LinksUpToDate", "bool"],
5528 ["ScaleCrop", "ScaleCrop", "bool"],
5529 ["HeadingPairs", "HeadingPairs", "raw"],
5530 ["TitlesOfParts", "TitlesOfParts", "raw"]
5531];
5532
5533var PseudoPropsPairs = [
5534 "Worksheets", "SheetNames",
5535 "NamedRanges", "DefinedNames",
5536 "Chartsheets", "ChartNames"
5537];
5538function load_props_pairs(HP/*:string|Array<Array<any>>*/, TOP, props, opts) {
5539 var v = [];
5540 if(typeof HP == "string") v = parseVector(HP, opts);
5541 else for(var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function(hp) { return {v:hp}; }));
5542 var parts = (typeof TOP == "string") ? parseVector(TOP, opts).map(function (x) { return x.v; }) : TOP;
5543 var idx = 0, len = 0;
5544 if(parts.length > 0) for(var i = 0; i !== v.length; i += 2) {
5545 len = +(v[i+1].v);
5546 switch(v[i].v) {
5547 case "Worksheets":
5548 case "工作表":
5549 case "Листы":
5550 case "أوراق العمل":
5551 case "ワークシート":
5552 case "גליונות עבודה":
5553 case "Arbeitsblätter":
5554 case "Çalışma Sayfaları":
5555 case "Feuilles de calcul":
5556 case "Fogli di lavoro":
5557 case "Folhas de cálculo":
5558 case "Planilhas":
5559 case "Regneark":
5560 case "Hojas de cálculo":
5561 case "Werkbladen":
5562 props.Worksheets = len;
5563 props.SheetNames = parts.slice(idx, idx + len);
5564 break;
5565
5566 case "Named Ranges":
5567 case "Rangos con nombre":
5568 case "名前付き一覧":
5569 case "Benannte Bereiche":
5570 case "Navngivne områder":
5571 props.NamedRanges = len;
5572 props.DefinedNames = parts.slice(idx, idx + len);
5573 break;
5574
5575 case "Charts":
5576 case "Diagramme":
5577 props.Chartsheets = len;
5578 props.ChartNames = parts.slice(idx, idx + len);
5579 break;
5580 }
5581 idx += len;
5582 }
5583}
5584
5585function parse_ext_props(data, p, opts) {
5586 var q = {}; if(!p) p = {};
5587 data = utf8read(data);
5588
5589 EXT_PROPS.forEach(function(f) {
5590 var xml = (data.match(matchtag(f[0]))||[])[1];
5591 switch(f[2]) {
5592 case "string": if(xml) p[f[1]] = unescapexml(xml); break;
5593 case "bool": p[f[1]] = xml === "true"; break;
5594 case "raw":
5595 var cur = data.match(new RegExp("<" + f[0] + "[^>]*>([\\s\\S]*?)<\/" + f[0] + ">"));
5596 if(cur && cur.length > 0) q[f[1]] = cur[1];
5597 break;
5598 }
5599 });
5600
5601 if(q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
5602
5603 return p;
5604}
5605
5606function write_ext_props(cp/*::, opts*/)/*:string*/ {
5607 var o/*:Array<string>*/ = [], W = writextag;
5608 if(!cp) cp = {};
5609 cp.Application = "SheetJS";
5610 o[o.length] = (XML_HEADER);
5611 o[o.length] = (writextag('Properties', null, {
5612 'xmlns': XMLNS.EXT_PROPS,
5613 'xmlns:vt': XMLNS.vt
5614 }));
5615
5616 EXT_PROPS.forEach(function(f) {
5617 if(cp[f[1]] === undefined) return;
5618 var v;
5619 switch(f[2]) {
5620 case 'string': v = escapexml(String(cp[f[1]])); break;
5621 case 'bool': v = cp[f[1]] ? 'true' : 'false'; break;
5622 }
5623 if(v !== undefined) o[o.length] = (W(f[0], v));
5624 });
5625
5626 /* TODO: HeadingPairs, TitlesOfParts */
5627 o[o.length] = (W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>')+W('vt:variant', W('vt:i4', String(cp.Worksheets))), {size:2, baseType:"variant"})));
5628 o[o.length] = (W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function(s) { return "<vt:lpstr>" + escapexml(s) + "</vt:lpstr>"; }).join(""), {size: cp.Worksheets, baseType:"lpstr"})));
5629 if(o.length>2){ o[o.length] = ('</Properties>'); o[1]=o[1].replace("/>",">"); }
5630 return o.join("");
5631}
5632/* 15.2.12.2 Custom File Properties Part */
5633var custregex = /<[^>]+>[^<]*/g;
5634function parse_cust_props(data/*:string*/, opts) {
5635 var p = {}, name = "";
5636 var m = data.match(custregex);
5637 if(m) for(var i = 0; i != m.length; ++i) {
5638 var x = m[i], y = parsexmltag(x);
5639 switch(y[0]) {
5640 case '<?xml': break;
5641 case '<Properties': break;
5642 case '<property': name = unescapexml(y.name); break;
5643 case '</property>': name = null; break;
5644 default: if (x.indexOf('<vt:') === 0) {
5645 var toks = x.split('>');
5646 var type = toks[0].slice(4), text = toks[1];
5647 /* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */
5648 switch(type) {
5649 case 'lpstr': case 'bstr': case 'lpwstr':
5650 p[name] = unescapexml(text);
5651 break;
5652 case 'bool':
5653 p[name] = parsexmlbool(text);
5654 break;
5655 case 'i1': case 'i2': case 'i4': case 'i8': case 'int': case 'uint':
5656 p[name] = parseInt(text, 10);
5657 break;
5658 case 'r4': case 'r8': case 'decimal':
5659 p[name] = parseFloat(text);
5660 break;
5661 case 'filetime': case 'date':
5662 p[name] = parseDate(text);
5663 break;
5664 case 'cy': case 'error':
5665 p[name] = unescapexml(text);
5666 break;
5667 default:
5668 if(type.slice(-1) == '/') break;
5669 if(opts.WTF && typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
5670 }
5671 } else if(x.slice(0,2) === "</") {/* empty */
5672 } else if(opts.WTF) throw new Error(x);
5673 }
5674 }
5675 return p;
5676}
5677
5678function write_cust_props(cp/*::, opts*/)/*:string*/ {
5679 var o = [XML_HEADER, writextag('Properties', null, {
5680 'xmlns': XMLNS.CUST_PROPS,
5681 'xmlns:vt': XMLNS.vt
5682 })];
5683 if(!cp) return o.join("");
5684 var pid = 1;
5685 keys(cp).forEach(function custprop(k) { ++pid;
5686 o[o.length] = (writextag('property', write_vt(cp[k], true), {
5687 'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
5688 'pid': pid,
5689 'name': escapexml(k)
5690 }));
5691 });
5692 if(o.length>2){ o[o.length] = '</Properties>'; o[1]=o[1].replace("/>",">"); }
5693 return o.join("");
5694}
5695/* Common Name -> XLML Name */
5696var XLMLDocPropsMap = {
5697 Title: 'Title',
5698 Subject: 'Subject',
5699 Author: 'Author',
5700 Keywords: 'Keywords',
5701 Comments: 'Description',
5702 LastAuthor: 'LastAuthor',
5703 RevNumber: 'Revision',
5704 Application: 'AppName',
5705 /* TotalTime: 'TotalTime', */
5706 LastPrinted: 'LastPrinted',
5707 CreatedDate: 'Created',
5708 ModifiedDate: 'LastSaved',
5709 /* Pages */
5710 /* Words */
5711 /* Characters */
5712 Category: 'Category',
5713 /* PresentationFormat */
5714 Manager: 'Manager',
5715 Company: 'Company',
5716 /* Guid */
5717 /* HyperlinkBase */
5718 /* Bytes */
5719 /* Lines */
5720 /* Paragraphs */
5721 /* CharactersWithSpaces */
5722 AppVersion: 'Version',
5723
5724 ContentStatus: 'ContentStatus', /* NOTE: missing from schema */
5725 Identifier: 'Identifier', /* NOTE: missing from schema */
5726 Language: 'Language' /* NOTE: missing from schema */
5727};
5728var evert_XLMLDPM;
5729
5730function xlml_set_prop(Props, tag/*:string*/, val) {
5731 if(!evert_XLMLDPM) evert_XLMLDPM = evert(XLMLDocPropsMap);
5732 tag = evert_XLMLDPM[tag] || tag;
5733 Props[tag] = val;
5734}
5735
5736function xlml_write_docprops(Props, opts) {
5737 var o/*:Array<string>*/ = [];
5738 keys(XLMLDocPropsMap).map(function(m) {
5739 for(var i = 0; i < CORE_PROPS.length; ++i) if(CORE_PROPS[i][1] == m) return CORE_PROPS[i];
5740 for(i = 0; i < EXT_PROPS.length; ++i) if(EXT_PROPS[i][1] == m) return EXT_PROPS[i];
5741 throw m;
5742 }).forEach(function(p) {
5743 if(Props[p[1]] == null) return;
5744 var m = opts && opts.Props && opts.Props[p[1]] != null ? opts.Props[p[1]] : Props[p[1]];
5745 switch(p[2]) {
5746 case 'date': m = new Date(m).toISOString().replace(/\.\d*Z/,"Z"); break;
5747 }
5748 if(typeof m == 'number') m = String(m);
5749 else if(m === true || m === false) { m = m ? "1" : "0"; }
5750 else if(m instanceof Date) m = new Date(m).toISOString().replace(/\.\d*Z/,"");
5751 o.push(writetag(XLMLDocPropsMap[p[1]] || p[1], m));
5752 });
5753 return writextag('DocumentProperties', o.join(""), {xmlns:XLMLNS.o });
5754}
5755function xlml_write_custprops(Props, Custprops/*::, opts*/) {
5756 var BLACKLIST = ["Worksheets","SheetNames"];
5757 var T = 'CustomDocumentProperties';
5758 var o/*:Array<string>*/ = [];
5759 if(Props) keys(Props).forEach(function(k) {
5760 /*:: if(!Props) return; */
5761 if(!Object.prototype.hasOwnProperty.call(Props, k)) return;
5762 for(var i = 0; i < CORE_PROPS.length; ++i) if(k == CORE_PROPS[i][1]) return;
5763 for(i = 0; i < EXT_PROPS.length; ++i) if(k == EXT_PROPS[i][1]) return;
5764 for(i = 0; i < BLACKLIST.length; ++i) if(k == BLACKLIST[i]) return;
5765
5766 var m = Props[k];
5767 var t = "string";
5768 if(typeof m == 'number') { t = "float"; m = String(m); }
5769 else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
5770 else m = String(m);
5771 o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
5772 });
5773 if(Custprops) keys(Custprops).forEach(function(k) {
5774 /*:: if(!Custprops) return; */
5775 if(!Object.prototype.hasOwnProperty.call(Custprops, k)) return;
5776 if(Props && Object.prototype.hasOwnProperty.call(Props, k)) return;
5777 var m = Custprops[k];
5778 var t = "string";
5779 if(typeof m == 'number') { t = "float"; m = String(m); }
5780 else if(m === true || m === false) { t = "boolean"; m = m ? "1" : "0"; }
5781 else if(m instanceof Date) { t = "dateTime.tz"; m = m.toISOString(); }
5782 else m = String(m);
5783 o.push(writextag(escapexmltag(k), m, {"dt:dt":t}));
5784 });
5785 return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
5786}
5787/* [MS-DTYP] 2.3.3 FILETIME */
5788/* [MS-OLEDS] 2.1.3 FILETIME (Packet Version) */
5789/* [MS-OLEPS] 2.8 FILETIME (Packet Version) */
5790function parse_FILETIME(blob) {
5791 var dwLowDateTime = blob.read_shift(4), dwHighDateTime = blob.read_shift(4);
5792 return new Date(((dwHighDateTime/1e7*Math.pow(2,32) + dwLowDateTime/1e7) - 11644473600)*1000).toISOString().replace(/\.000/,"");
5793}
5794function write_FILETIME(time/*:string|Date*/) {
5795 var date = (typeof time == "string") ? new Date(Date.parse(time)) : time;
5796 var t = date.getTime() / 1000 + 11644473600;
5797 var l = t % Math.pow(2,32), h = (t - l) / Math.pow(2,32);
5798 l *= 1e7; h *= 1e7;
5799 var w = (l / Math.pow(2,32)) | 0;
5800 if(w > 0) { l = l % Math.pow(2,32); h += w; }
5801 var o = new_buf(8); o.write_shift(4, l); o.write_shift(4, h); return o;
5802}
5803
5804/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
5805function parse_lpstr(blob, type, pad/*:?number*/) {
5806 var start = blob.l;
5807 var str = blob.read_shift(0, 'lpstr-cp');
5808 if(pad) while((blob.l - start) & 3) ++blob.l;
5809 return str;
5810}
5811
5812/* [MS-OSHARED] 2.3.3.1.6 Lpwstr */
5813function parse_lpwstr(blob, type, pad) {
5814 var str = blob.read_shift(0, 'lpwstr');
5815 if(pad) blob.l += (4 - ((str.length+1) & 3)) & 3;
5816 return str;
5817}
5818
5819
5820/* [MS-OSHARED] 2.3.3.1.11 VtString */
5821/* [MS-OSHARED] 2.3.3.1.12 VtUnalignedString */
5822function parse_VtStringBase(blob, stringType, pad) {
5823 if(stringType === 0x1F /*VT_LPWSTR*/) return parse_lpwstr(blob);
5824 return parse_lpstr(blob, stringType, pad);
5825}
5826
5827function parse_VtString(blob, t/*:number*/, pad/*:?boolean*/) { return parse_VtStringBase(blob, t, pad === false ? 0: 4); }
5828function parse_VtUnalignedString(blob, t/*:number*/) { if(!t) throw new Error("VtUnalignedString must have positive length"); return parse_VtStringBase(blob, t, 0); }
5829
5830/* [MS-OSHARED] 2.3.3.1.7 VtVecLpwstrValue */
5831function parse_VtVecLpwstrValue(blob)/*:Array<string>*/ {
5832 var length = blob.read_shift(4);
5833 var ret/*:Array<string>*/ = [];
5834 for(var i = 0; i != length; ++i) {
5835 var start = blob.l;
5836 ret[i] = blob.read_shift(0, 'lpwstr').replace(chr0,'');
5837 if((blob.l - start) & 0x02) blob.l += 2;
5838 }
5839 return ret;
5840}
5841
5842/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
5843function parse_VtVecUnalignedLpstrValue(blob)/*:Array<string>*/ {
5844 var length = blob.read_shift(4);
5845 var ret/*:Array<string>*/ = [];
5846 for(var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr-cp').replace(chr0,'');
5847 return ret;
5848}
5849
5850
5851/* [MS-OSHARED] 2.3.3.1.13 VtHeadingPair */
5852function parse_VtHeadingPair(blob) {
5853 var start = blob.l;
5854 var headingString = parse_TypedPropertyValue(blob, VT_USTR);
5855 if(blob[blob.l] == 0x00 && blob[blob.l+1] == 0x00 && ((blob.l - start) & 0x02)) blob.l += 2;
5856 var headerParts = parse_TypedPropertyValue(blob, VT_I4);
5857 return [headingString, headerParts];
5858}
5859
5860/* [MS-OSHARED] 2.3.3.1.14 VtVecHeadingPairValue */
5861function parse_VtVecHeadingPairValue(blob) {
5862 var cElements = blob.read_shift(4);
5863 var out = [];
5864 for(var i = 0; i < cElements / 2; ++i) out.push(parse_VtHeadingPair(blob));
5865 return out;
5866}
5867
5868/* [MS-OLEPS] 2.18.1 Dictionary (uses 2.17, 2.16) */
5869function parse_dictionary(blob,CodePage) {
5870 var cnt = blob.read_shift(4);
5871 var dict/*:{[number]:string}*/ = ({}/*:any*/);
5872 for(var j = 0; j != cnt; ++j) {
5873 var pid = blob.read_shift(4);
5874 var len = blob.read_shift(4);
5875 dict[pid] = blob.read_shift(len, (CodePage === 0x4B0 ?'utf16le':'utf8')).replace(chr0,'').replace(chr1,'!');
5876 if(CodePage === 0x4B0 && (len % 2)) blob.l += 2;
5877 }
5878 if(blob.l & 3) blob.l = (blob.l>>2+1)<<2;
5879 return dict;
5880}
5881
5882/* [MS-OLEPS] 2.9 BLOB */
5883function parse_BLOB(blob) {
5884 var size = blob.read_shift(4);
5885 var bytes = blob.slice(blob.l,blob.l+size);
5886 blob.l += size;
5887 if((size & 3) > 0) blob.l += (4 - (size & 3)) & 3;
5888 return bytes;
5889}
5890
5891/* [MS-OLEPS] 2.11 ClipboardData */
5892function parse_ClipboardData(blob) {
5893 // TODO
5894 var o = {};
5895 o.Size = blob.read_shift(4);
5896 //o.Format = blob.read_shift(4);
5897 blob.l += o.Size + 3 - (o.Size - 1) % 4;
5898 return o;
5899}
5900
5901/* [MS-OLEPS] 2.15 TypedPropertyValue */
5902function parse_TypedPropertyValue(blob, type/*:number*/, _opts)/*:any*/ {
5903 var t = blob.read_shift(2), ret, opts = _opts||{};
5904 blob.l += 2;
5905 if(type !== VT_VARIANT)
5906 if(t !== type && VT_CUSTOM.indexOf(type)===-1 && !((type & 0xFFFE) == 0x101E && (t & 0xFFFE) == 0x101E)) throw new Error('Expected type ' + type + ' saw ' + t);
5907 switch(type === VT_VARIANT ? t : type) {
5908 case 0x02 /*VT_I2*/: ret = blob.read_shift(2, 'i'); if(!opts.raw) blob.l += 2; return ret;
5909 case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
5910 case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
5911 case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
5912 case 0x1E /*VT_LPSTR*/: return parse_lpstr(blob, t, 4).replace(chr0,'');
5913 case 0x1F /*VT_LPWSTR*/: return parse_lpwstr(blob);
5914 case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
5915 case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
5916 case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
5917 case 0x50 /*VT_STRING*/: return parse_VtString(blob, t, !opts.raw).replace(chr0,'');
5918 case 0x51 /*VT_USTR*/: return parse_VtUnalignedString(blob, t/*, 4*/).replace(chr0,'');
5919 case 0x100C /*VT_VECTOR|VT_VARIANT*/: return parse_VtVecHeadingPairValue(blob);
5920 case 0x101E /*VT_VECTOR|VT_LPSTR*/:
5921 case 0x101F /*VT_VECTOR|VT_LPWSTR*/:
5922 return t == 0x101F ? parse_VtVecLpwstrValue(blob) : parse_VtVecUnalignedLpstrValue(blob);
5923 default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
5924 }
5925}
5926function write_TypedPropertyValue(type/*:number*/, value) {
5927 var o = new_buf(4), p = new_buf(4);
5928 o.write_shift(4, type == 0x50 ? 0x1F : type);
5929 switch(type) {
5930 case 0x03 /*VT_I4*/: p.write_shift(-4, value); break;
5931 case 0x05 /*VT_I4*/: p = new_buf(8); p.write_shift(8, value, 'f'); break;
5932 case 0x0B /*VT_BOOL*/: p.write_shift(4, value ? 0x01 : 0x00); break;
5933 case 0x40 /*VT_FILETIME*/: /*:: if(typeof value !== "string" && !(value instanceof Date)) throw "unreachable"; */ p = write_FILETIME(value); break;
5934 case 0x1F /*VT_LPWSTR*/:
5935 case 0x50 /*VT_STRING*/:
5936 /*:: if(typeof value !== "string") throw "unreachable"; */
5937 p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
5938 p.write_shift(4, value.length + 1);
5939 p.write_shift(0, value, "dbcs");
5940 while(p.l != p.length) p.write_shift(1, 0);
5941 break;
5942 default: throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
5943 }
5944 return bconcat([o, p]);
5945}
5946
5947/* [MS-OLEPS] 2.20 PropertySet */
5948function parse_PropertySet(blob, PIDSI) {
5949 var start_addr = blob.l;
5950 var size = blob.read_shift(4);
5951 var NumProps = blob.read_shift(4);
5952 var Props = [], i = 0;
5953 var CodePage = 0;
5954 var Dictionary = -1, DictObj/*:{[number]:string}*/ = ({}/*:any*/);
5955 for(i = 0; i != NumProps; ++i) {
5956 var PropID = blob.read_shift(4);
5957 var Offset = blob.read_shift(4);
5958 Props[i] = [PropID, Offset + start_addr];
5959 }
5960 Props.sort(function(x,y) { return x[1] - y[1]; });
5961 var PropH = {};
5962 for(i = 0; i != NumProps; ++i) {
5963 if(blob.l !== Props[i][1]) {
5964 var fail = true;
5965 if(i>0 && PIDSI) switch(PIDSI[Props[i-1][0]].t) {
5966 case 0x02 /*VT_I2*/: if(blob.l+2 === Props[i][1]) { blob.l+=2; fail = false; } break;
5967 case 0x50 /*VT_STRING*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break;
5968 case 0x100C /*VT_VECTOR|VT_VARIANT*/: if(blob.l <= Props[i][1]) { blob.l=Props[i][1]; fail = false; } break;
5969 }
5970 if((!PIDSI||i==0) && blob.l <= Props[i][1]) { fail=false; blob.l = Props[i][1]; }
5971 if(fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i);
5972 }
5973 if(PIDSI) {
5974 var piddsi = PIDSI[Props[i][0]];
5975 PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {raw:true});
5976 if(piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
5977 if(piddsi.n == "CodePage") switch(PropH[piddsi.n]) {
5978 case 0: PropH[piddsi.n] = 1252;
5979 /* falls through */
5980 case 874:
5981 case 932:
5982 case 936:
5983 case 949:
5984 case 950:
5985 case 1250:
5986 case 1251:
5987 case 1253:
5988 case 1254:
5989 case 1255:
5990 case 1256:
5991 case 1257:
5992 case 1258:
5993 case 10000:
5994 case 1200:
5995 case 1201:
5996 case 1252:
5997 case 65000: case -536:
5998 case 65001: case -535:
5999 set_cp(CodePage = (PropH[piddsi.n]>>>0) & 0xFFFF); break;
6000 default: throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
6001 }
6002 } else {
6003 if(Props[i][0] === 0x1) {
6004 CodePage = PropH.CodePage = (parse_TypedPropertyValue(blob, VT_I2)/*:number*/);
6005 set_cp(CodePage);
6006 if(Dictionary !== -1) {
6007 var oldpos = blob.l;
6008 blob.l = Props[Dictionary][1];
6009 DictObj = parse_dictionary(blob,CodePage);
6010 blob.l = oldpos;
6011 }
6012 } else if(Props[i][0] === 0) {
6013 if(CodePage === 0) { Dictionary = i; blob.l = Props[i+1][1]; continue; }
6014 DictObj = parse_dictionary(blob,CodePage);
6015 } else {
6016 var name = DictObj[Props[i][0]];
6017 var val;
6018 /* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
6019 switch(blob[blob.l]) {
6020 case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
6021 case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
6022 case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
6023 case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
6024 case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
6025 case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;
6026 case 0x0B /*VT_BOOL*/: blob.l += 4; val = parsebool(blob, 4); break;
6027 case 0x40 /*VT_FILETIME*/: blob.l += 4; val = parseDate(parse_FILETIME(blob)); break;
6028 default: throw new Error("unparsed value: " + blob[blob.l]);
6029 }
6030 PropH[name] = val;
6031 }
6032 }
6033 }
6034 blob.l = start_addr + size; /* step ahead to skip padding */
6035 return PropH;
6036}
6037var XLSPSSkip = [ "CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID" ]; //.concat(PseudoPropsPairs);
6038function guess_property_type(val/*:any*/)/*:number*/ {
6039 switch(typeof val) {
6040 case "boolean": return 0x0B;
6041 case "number": return ((val|0)==val) ? 0x03 : 0x05;
6042 case "string": return 0x1F;
6043 case "object": if(val instanceof Date) return 0x40; break;
6044 }
6045 return -1;
6046}
6047function write_PropertySet(entries, RE, PIDSI) {
6048 var hdr = new_buf(8), piao = [], prop = [];
6049 var sz = 8, i = 0;
6050
6051 var pr = new_buf(8), pio = new_buf(8);
6052 pr.write_shift(4, 0x0002);
6053 pr.write_shift(4, 0x04B0);
6054 pio.write_shift(4, 0x0001);
6055 prop.push(pr); piao.push(pio);
6056 sz += 8 + pr.length;
6057
6058 if(!RE) {
6059 pio = new_buf(8);
6060 pio.write_shift(4, 0);
6061 piao.unshift(pio);
6062
6063 var bufs = [new_buf(4)];
6064 bufs[0].write_shift(4, entries.length);
6065 for(i = 0; i < entries.length; ++i) {
6066 var value = entries[i][0];
6067 pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
6068 pr.write_shift(4, i+2);
6069 pr.write_shift(4, value.length + 1);
6070 pr.write_shift(0, value, "dbcs");
6071 while(pr.l != pr.length) pr.write_shift(1, 0);
6072 bufs.push(pr);
6073 }
6074 pr = bconcat(bufs);
6075 prop.unshift(pr);
6076 sz += 8 + pr.length;
6077 }
6078
6079 for(i = 0; i < entries.length; ++i) {
6080 if(RE && !RE[entries[i][0]]) continue;
6081 if(XLSPSSkip.indexOf(entries[i][0]) > -1 || PseudoPropsPairs.indexOf(entries[i][0]) > -1) continue;
6082 if(entries[i][1] == null) continue;
6083
6084 var val = entries[i][1], idx = 0;
6085 if(RE) {
6086 idx = +RE[entries[i][0]];
6087 var pinfo = (PIDSI/*:: || {}*/)[idx]/*:: || {} */;
6088 if(pinfo.p == "version" && typeof val == "string") {
6089 /*:: if(typeof val !== "string") throw "unreachable"; */
6090 var arr = val.split(".");
6091 val = ((+arr[0])<<16) + ((+arr[1])||0);
6092 }
6093 pr = write_TypedPropertyValue(pinfo.t, val);
6094 } else {
6095 var T = guess_property_type(val);
6096 if(T == -1) { T = 0x1F; val = String(val); }
6097 pr = write_TypedPropertyValue(T, val);
6098 }
6099 prop.push(pr);
6100
6101 pio = new_buf(8);
6102 pio.write_shift(4, !RE ? 2+i : idx);
6103 piao.push(pio);
6104
6105 sz += 8 + pr.length;
6106 }
6107
6108 var w = 8 * (prop.length + 1);
6109 for(i = 0; i < prop.length; ++i) { piao[i].write_shift(4, w); w += prop[i].length; }
6110 hdr.write_shift(4, sz);
6111 hdr.write_shift(4, prop.length);
6112 return bconcat([hdr].concat(piao).concat(prop));
6113}
6114
6115/* [MS-OLEPS] 2.21 PropertySetStream */
6116function parse_PropertySetStream(file, PIDSI, clsid) {
6117 var blob = file.content;
6118 if(!blob) return ({}/*:any*/);
6119 prep_blob(blob, 0);
6120
6121 var NumSets, FMTID0, FMTID1, Offset0, Offset1 = 0;
6122 blob.chk('feff', 'Byte Order: ');
6123
6124 /*var vers = */blob.read_shift(2); // TODO: check version
6125 var SystemIdentifier = blob.read_shift(4);
6126 var CLSID = blob.read_shift(16);
6127 if(CLSID !== CFB.utils.consts.HEADER_CLSID && CLSID !== clsid) throw new Error("Bad PropertySet CLSID " + CLSID);
6128 NumSets = blob.read_shift(4);
6129 if(NumSets !== 1 && NumSets !== 2) throw new Error("Unrecognized #Sets: " + NumSets);
6130 FMTID0 = blob.read_shift(16); Offset0 = blob.read_shift(4);
6131
6132 if(NumSets === 1 && Offset0 !== blob.l) throw new Error("Length mismatch: " + Offset0 + " !== " + blob.l);
6133 else if(NumSets === 2) { FMTID1 = blob.read_shift(16); Offset1 = blob.read_shift(4); }
6134 var PSet0 = parse_PropertySet(blob, PIDSI);
6135
6136 var rval = ({ SystemIdentifier: SystemIdentifier }/*:any*/);
6137 for(var y in PSet0) rval[y] = PSet0[y];
6138 //rval.blob = blob;
6139 rval.FMTID = FMTID0;
6140 //rval.PSet0 = PSet0;
6141 if(NumSets === 1) return rval;
6142 if(Offset1 - blob.l == 2) blob.l += 2;
6143 if(blob.l !== Offset1) throw new Error("Length mismatch 2: " + blob.l + " !== " + Offset1);
6144 var PSet1;
6145 try { PSet1 = parse_PropertySet(blob, null); } catch(e) {/* empty */}
6146 for(y in PSet1) rval[y] = PSet1[y];
6147 rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
6148 return rval;
6149}
6150function write_PropertySetStream(entries, clsid, RE, PIDSI/*:{[key:string|number]:any}*/, entries2/*:?any*/, clsid2/*:?any*/) {
6151 var hdr = new_buf(entries2 ? 68 : 48);
6152 var bufs = [hdr];
6153 hdr.write_shift(2, 0xFFFE);
6154 hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
6155 hdr.write_shift(4, 0x32363237);
6156 hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
6157 hdr.write_shift(4, (entries2 ? 2 : 1));
6158 hdr.write_shift(16, clsid, "hex");
6159 hdr.write_shift(4, (entries2 ? 68 : 48));
6160 var ps0 = write_PropertySet(entries, RE, PIDSI);
6161 bufs.push(ps0);
6162
6163 if(entries2) {
6164 var ps1 = write_PropertySet(entries2, null, null);
6165 hdr.write_shift(16, clsid2, "hex");
6166 hdr.write_shift(4, 68 + ps0.length);
6167 bufs.push(ps1);
6168 }
6169 return bconcat(bufs);
6170}
6171
6172function parsenoop2(blob, length) { blob.read_shift(length); return null; }
6173function writezeroes(n, o) { if(!o) o=new_buf(n); for(var j=0; j<n; ++j) o.write_shift(1, 0); return o; }
6174
6175function parslurp(blob, length, cb) {
6176 var arr = [], target = blob.l + length;
6177 while(blob.l < target) arr.push(cb(blob, target - blob.l));
6178 if(target !== blob.l) throw new Error("Slurp error");
6179 return arr;
6180}
6181
6182function parsebool(blob, length/*:number*/) { return blob.read_shift(length) === 0x1; }
6183function writebool(v/*:any*/, o) { if(!o) o=new_buf(2); o.write_shift(2, +!!v); return o; }
6184
6185function parseuint16(blob/*::, length:?number, opts:?any*/) { return blob.read_shift(2, 'u'); }
6186function writeuint16(v/*:number*/, o) { if(!o) o=new_buf(2); o.write_shift(2, v); return o; }
6187function parseuint16a(blob, length/*:: :?number, opts:?any*/) { return parslurp(blob,length,parseuint16);}
6188
6189/* --- 2.5 Structures --- */
6190
6191/* [MS-XLS] 2.5.10 Bes (boolean or error) */
6192function parse_Bes(blob/*::, length*/) {
6193 var v = blob.read_shift(1), t = blob.read_shift(1);
6194 return t === 0x01 ? v : v === 0x01;
6195}
6196function write_Bes(v, t/*:string*/, o) {
6197 if(!o) o = new_buf(2);
6198 o.write_shift(1, ((t == 'e') ? +v : +!!v));
6199 o.write_shift(1, ((t == 'e') ? 1 : 0));
6200 return o;
6201}
6202
6203/* [MS-XLS] 2.5.240 ShortXLUnicodeString */
6204function parse_ShortXLUnicodeString(blob, length, opts) {
6205 var cch = blob.read_shift(opts && opts.biff >= 12 ? 2 : 1);
6206 var encoding = 'sbcs-cont';
6207 var cp = current_codepage;
6208 if(opts && opts.biff >= 8) current_codepage = 1200;
6209 if(!opts || opts.biff == 8 ) {
6210 var fHighByte = blob.read_shift(1);
6211 if(fHighByte) { encoding = 'dbcs-cont'; }
6212 } else if(opts.biff == 12) {
6213 encoding = 'wstr';
6214 }
6215 if(opts.biff >= 2 && opts.biff <= 5) encoding = 'cpstr';
6216 var o = cch ? blob.read_shift(cch, encoding) : "";
6217 current_codepage = cp;
6218 return o;
6219}
6220
6221/* 2.5.293 XLUnicodeRichExtendedString */
6222function parse_XLUnicodeRichExtendedString(blob) {
6223 var cp = current_codepage;
6224 current_codepage = 1200;
6225 var cch = blob.read_shift(2), flags = blob.read_shift(1);
6226 var /*fHighByte = flags & 0x1,*/ fExtSt = flags & 0x4, fRichSt = flags & 0x8;
6227 var width = 1 + (flags & 0x1); // 0x0 -> utf8, 0x1 -> dbcs
6228 var cRun = 0, cbExtRst;
6229 var z = {};
6230 if(fRichSt) cRun = blob.read_shift(2);
6231 if(fExtSt) cbExtRst = blob.read_shift(4);
6232 var encoding = width == 2 ? 'dbcs-cont' : 'sbcs-cont';
6233 var msg = cch === 0 ? "" : blob.read_shift(cch, encoding);
6234 if(fRichSt) blob.l += 4 * cRun; //TODO: parse this
6235 if(fExtSt) blob.l += cbExtRst; //TODO: parse this
6236 z.t = msg;
6237 if(!fRichSt) { z.raw = "<t>" + z.t + "</t>"; z.r = z.t; }
6238 current_codepage = cp;
6239 return z;
6240}
6241function write_XLUnicodeRichExtendedString(xlstr/*:: :XLString, opts*/) {
6242 var str = (xlstr.t||""), nfmts = 1;
6243
6244 var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0));
6245 hdr.write_shift(2, str.length);
6246 hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01);
6247 if(nfmts > 1) hdr.write_shift(2, nfmts);
6248
6249 var otext = new_buf(2 * str.length);
6250 otext.write_shift(2 * str.length, str, 'utf16le');
6251
6252 var out = [hdr, otext];
6253
6254 return bconcat(out);
6255}
6256
6257/* 2.5.296 XLUnicodeStringNoCch */
6258function parse_XLUnicodeStringNoCch(blob, cch, opts) {
6259 var retval;
6260 if(opts) {
6261 if(opts.biff >= 2 && opts.biff <= 5) return blob.read_shift(cch, 'cpstr');
6262 if(opts.biff >= 12) return blob.read_shift(cch, 'dbcs-cont');
6263 }
6264 var fHighByte = blob.read_shift(1);
6265 if(fHighByte===0) { retval = blob.read_shift(cch, 'sbcs-cont'); }
6266 else { retval = blob.read_shift(cch, 'dbcs-cont'); }
6267 return retval;
6268}
6269
6270/* 2.5.294 XLUnicodeString */
6271function parse_XLUnicodeString(blob, length, opts) {
6272 var cch = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
6273 if(cch === 0) { blob.l++; return ""; }
6274 return parse_XLUnicodeStringNoCch(blob, cch, opts);
6275}
6276/* BIFF5 override */
6277function parse_XLUnicodeString2(blob, length, opts) {
6278 if(opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
6279 var cch = blob.read_shift(1);
6280 if(cch === 0) { blob.l++; return ""; }
6281 return blob.read_shift(cch, (opts.biff <= 4 || !blob.lens ) ? 'cpstr' : 'sbcs-cont');
6282}
6283/* TODO: BIFF5 and lower, codepage awareness */
6284function write_XLUnicodeString(str, opts, o) {
6285 if(!o) o = new_buf(3 + 2 * str.length);
6286 o.write_shift(2, str.length);
6287 o.write_shift(1, 1);
6288 o.write_shift(31, str, 'utf16le');
6289 return o;
6290}
6291
6292/* [MS-XLS] 2.5.61 ControlInfo */
6293function parse_ControlInfo(blob/*::, length, opts*/) {
6294 var flags = blob.read_shift(1);
6295 blob.l++;
6296 var accel = blob.read_shift(2);
6297 blob.l += 2;
6298 return [flags, accel];
6299}
6300
6301/* [MS-OSHARED] 2.3.7.6 URLMoniker TODO: flags */
6302function parse_URLMoniker(blob/*::, length, opts*/) {
6303 var len = blob.read_shift(4), start = blob.l;
6304 var extra = false;
6305 if(len > 24) {
6306 /* look ahead */
6307 blob.l += len - 24;
6308 if(blob.read_shift(16) === "795881f43b1d7f48af2c825dc4852763") extra = true;
6309 blob.l = start;
6310 }
6311 var url = blob.read_shift((extra?len-24:len)>>1, 'utf16le').replace(chr0,"");
6312 if(extra) blob.l += 24;
6313 return url;
6314}
6315
6316/* [MS-OSHARED] 2.3.7.8 FileMoniker TODO: all fields */
6317function parse_FileMoniker(blob/*::, length*/) {
6318 var cAnti = blob.read_shift(2);
6319 var preamble = ""; while(cAnti-- > 0) preamble += "../";
6320 var ansiPath = blob.read_shift(0, 'lpstr-ansi');
6321 blob.l += 2; //var endServer = blob.read_shift(2);
6322 if(blob.read_shift(2) != 0xDEAD) throw new Error("Bad FileMoniker");
6323 var sz = blob.read_shift(4);
6324 if(sz === 0) return preamble + ansiPath.replace(/\\/g,"/");
6325 var bytes = blob.read_shift(4);
6326 if(blob.read_shift(2) != 3) throw new Error("Bad FileMoniker");
6327 var unicodePath = blob.read_shift(bytes>>1, 'utf16le').replace(chr0,"");
6328 return preamble + unicodePath;
6329}
6330
6331/* [MS-OSHARED] 2.3.7.2 HyperlinkMoniker TODO: all the monikers */
6332function parse_HyperlinkMoniker(blob, length) {
6333 var clsid = blob.read_shift(16); length -= 16;
6334 switch(clsid) {
6335 case "e0c9ea79f9bace118c8200aa004ba90b": return parse_URLMoniker(blob, length);
6336 case "0303000000000000c000000000000046": return parse_FileMoniker(blob, length);
6337 default: throw new Error("Unsupported Moniker " + clsid);
6338 }
6339}
6340
6341/* [MS-OSHARED] 2.3.7.9 HyperlinkString */
6342function parse_HyperlinkString(blob/*::, length*/) {
6343 var len = blob.read_shift(4);
6344 var o = len > 0 ? blob.read_shift(len, 'utf16le').replace(chr0, "") : "";
6345 return o;
6346}
6347function write_HyperlinkString(str/*:string*/, o) {
6348 if(!o) o = new_buf(6 + str.length * 2);
6349 o.write_shift(4, 1 + str.length);
6350 for(var i = 0; i < str.length; ++i) o.write_shift(2, str.charCodeAt(i));
6351 o.write_shift(2, 0);
6352 return o;
6353}
6354
6355/* [MS-OSHARED] 2.3.7.1 Hyperlink Object */
6356function parse_Hyperlink(blob, length)/*:Hyperlink*/ {
6357 var end = blob.l + length;
6358 var sVer = blob.read_shift(4);
6359 if(sVer !== 2) throw new Error("Unrecognized streamVersion: " + sVer);
6360 var flags = blob.read_shift(2);
6361 blob.l += 2;
6362 var displayName, targetFrameName, moniker, oleMoniker, Loc="", guid, fileTime;
6363 if(flags & 0x0010) displayName = parse_HyperlinkString(blob, end - blob.l);
6364 if(flags & 0x0080) targetFrameName = parse_HyperlinkString(blob, end - blob.l);
6365 if((flags & 0x0101) === 0x0101) moniker = parse_HyperlinkString(blob, end - blob.l);
6366 if((flags & 0x0101) === 0x0001) oleMoniker = parse_HyperlinkMoniker(blob, end - blob.l);
6367 if(flags & 0x0008) Loc = parse_HyperlinkString(blob, end - blob.l);
6368 if(flags & 0x0020) guid = blob.read_shift(16);
6369 if(flags & 0x0040) fileTime = parse_FILETIME(blob/*, 8*/);
6370 blob.l = end;
6371 var target = targetFrameName||moniker||oleMoniker||"";
6372 if(target && Loc) target+="#"+Loc;
6373 if(!target) target = "#" + Loc;
6374 if((flags & 0x0002) && target.charAt(0) == "/" && target.charAt(1) != "/") target = "file://" + target;
6375 var out = ({Target:target}/*:any*/);
6376 if(guid) out.guid = guid;
6377 if(fileTime) out.time = fileTime;
6378 if(displayName) out.Tooltip = displayName;
6379 return out;
6380}
6381function write_Hyperlink(hl) {
6382 var out = new_buf(512), i = 0;
6383 var Target = hl.Target;
6384 if(Target.slice(0,7) == "file://") Target = Target.slice(7);
6385 var hashidx = Target.indexOf("#");
6386 var F = hashidx > -1 ? 0x1f : 0x17;
6387 switch(Target.charAt(0)) { case "#": F=0x1c; break; case ".": F&=~2; break; }
6388 out.write_shift(4,2); out.write_shift(4, F);
6389 var data = [8,6815827,6619237,4849780,83]; for(i = 0; i < data.length; ++i) out.write_shift(4, data[i]);
6390 if(F == 0x1C) {
6391 Target = Target.slice(1);
6392 write_HyperlinkString(Target, out);
6393 } else if(F & 0x02) {
6394 data = "e0 c9 ea 79 f9 ba ce 11 8c 82 00 aa 00 4b a9 0b".split(" ");
6395 for(i = 0; i < data.length; ++i) out.write_shift(1, parseInt(data[i], 16));
6396 var Pretarget = hashidx > -1 ? Target.slice(0, hashidx) : Target;
6397 out.write_shift(4, 2*(Pretarget.length + 1));
6398 for(i = 0; i < Pretarget.length; ++i) out.write_shift(2, Pretarget.charCodeAt(i));
6399 out.write_shift(2, 0);
6400 if(F & 0x08) write_HyperlinkString(hashidx > -1 ? Target.slice(hashidx+1): "", out);
6401 } else {
6402 data = "03 03 00 00 00 00 00 00 c0 00 00 00 00 00 00 46".split(" ");
6403 for(i = 0; i < data.length; ++i) out.write_shift(1, parseInt(data[i], 16));
6404 var P = 0;
6405 while(Target.slice(P*3,P*3+3)=="../"||Target.slice(P*3,P*3+3)=="..\\") ++P;
6406 out.write_shift(2, P);
6407 out.write_shift(4, Target.length - 3 * P + 1);
6408 for(i = 0; i < Target.length - 3 * P; ++i) out.write_shift(1, Target.charCodeAt(i + 3 * P) & 0xFF);
6409 out.write_shift(1, 0);
6410 out.write_shift(2, 0xFFFF);
6411 out.write_shift(2, 0xDEAD);
6412 for(i = 0; i < 6; ++i) out.write_shift(4, 0);
6413 }
6414 return out.slice(0, out.l);
6415}
6416
6417/* 2.5.178 LongRGBA */
6418function parse_LongRGBA(blob/*::, length*/) { var r = blob.read_shift(1), g = blob.read_shift(1), b = blob.read_shift(1), a = blob.read_shift(1); return [r,g,b,a]; }
6419
6420/* 2.5.177 LongRGB */
6421function parse_LongRGB(blob, length) { var x = parse_LongRGBA(blob, length); x[3] = 0; return x; }
6422
6423
6424/* [MS-XLS] 2.5.19 */
6425function parse_XLSCell(blob/*::, length*/)/*:Cell*/ {
6426 var rw = blob.read_shift(2); // 0-indexed
6427 var col = blob.read_shift(2);
6428 var ixfe = blob.read_shift(2);
6429 return ({r:rw, c:col, ixfe:ixfe}/*:any*/);
6430}
6431function write_XLSCell(R/*:number*/, C/*:number*/, ixfe/*:?number*/, o) {
6432 if(!o) o = new_buf(6);
6433 o.write_shift(2, R);
6434 o.write_shift(2, C);
6435 o.write_shift(2, ixfe||0);
6436 return o;
6437}
6438
6439/* [MS-XLS] 2.5.134 */
6440function parse_frtHeader(blob) {
6441 var rt = blob.read_shift(2);
6442 var flags = blob.read_shift(2); // TODO: parse these flags
6443 blob.l += 8;
6444 return {type: rt, flags: flags};
6445}
6446
6447
6448
6449function parse_OptXLUnicodeString(blob, length, opts) { return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts); }
6450
6451/* [MS-XLS] 2.5.344 */
6452function parse_XTI(blob, length, opts) {
6453 var w = opts.biff > 8 ? 4 : 2;
6454 var iSupBook = blob.read_shift(w), itabFirst = blob.read_shift(w,'i'), itabLast = blob.read_shift(w,'i');
6455 return [iSupBook, itabFirst, itabLast];
6456}
6457
6458/* [MS-XLS] 2.5.218 */
6459function parse_RkRec(blob) {
6460 var ixfe = blob.read_shift(2);
6461 var RK = parse_RkNumber(blob);
6462 return [ixfe, RK];
6463}
6464
6465/* [MS-XLS] 2.5.1 */
6466function parse_AddinUdf(blob, length, opts) {
6467 blob.l += 4; length -= 4;
6468 var l = blob.l + length;
6469 var udfName = parse_ShortXLUnicodeString(blob, length, opts);
6470 var cb = blob.read_shift(2);
6471 l -= blob.l;
6472 if(cb !== l) throw new Error("Malformed AddinUdf: padding = " + l + " != " + cb);
6473 blob.l += cb;
6474 return udfName;
6475}
6476
6477/* [MS-XLS] 2.5.209 TODO: Check sizes */
6478function parse_Ref8U(blob/*::, length*/) {
6479 var rwFirst = blob.read_shift(2);
6480 var rwLast = blob.read_shift(2);
6481 var colFirst = blob.read_shift(2);
6482 var colLast = blob.read_shift(2);
6483 return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}};
6484}
6485function write_Ref8U(r/*:Range*/, o) {
6486 if(!o) o = new_buf(8);
6487 o.write_shift(2, r.s.r);
6488 o.write_shift(2, r.e.r);
6489 o.write_shift(2, r.s.c);
6490 o.write_shift(2, r.e.c);
6491 return o;
6492}
6493
6494/* [MS-XLS] 2.5.211 */
6495function parse_RefU(blob/*::, length*/) {
6496 var rwFirst = blob.read_shift(2);
6497 var rwLast = blob.read_shift(2);
6498 var colFirst = blob.read_shift(1);
6499 var colLast = blob.read_shift(1);
6500 return {s:{c:colFirst, r:rwFirst}, e:{c:colLast,r:rwLast}};
6501}
6502
6503/* [MS-XLS] 2.5.207 */
6504var parse_Ref = parse_RefU;
6505
6506/* [MS-XLS] 2.5.143 */
6507function parse_FtCmo(blob/*::, length*/) {
6508 blob.l += 4;
6509 var ot = blob.read_shift(2);
6510 var id = blob.read_shift(2);
6511 var flags = blob.read_shift(2);
6512 blob.l+=12;
6513 return [id, ot, flags];
6514}
6515
6516/* [MS-XLS] 2.5.149 */
6517function parse_FtNts(blob) {
6518 var out = {};
6519 blob.l += 4;
6520 blob.l += 16; // GUID TODO
6521 out.fSharedNote = blob.read_shift(2);
6522 blob.l += 4;
6523 return out;
6524}
6525
6526/* [MS-XLS] 2.5.142 */
6527function parse_FtCf(blob) {
6528 var out = {};
6529 blob.l += 4;
6530 blob.cf = blob.read_shift(2);
6531 return out;
6532}
6533
6534/* [MS-XLS] 2.5.140 - 2.5.154 and friends */
6535function parse_FtSkip(blob) { blob.l += 2; blob.l += blob.read_shift(2); }
6536var FtTab = {
6537 /*::[*/0x00/*::]*/: parse_FtSkip, /* FtEnd */
6538 /*::[*/0x04/*::]*/: parse_FtSkip, /* FtMacro */
6539 /*::[*/0x05/*::]*/: parse_FtSkip, /* FtButton */
6540 /*::[*/0x06/*::]*/: parse_FtSkip, /* FtGmo */
6541 /*::[*/0x07/*::]*/: parse_FtCf, /* FtCf */
6542 /*::[*/0x08/*::]*/: parse_FtSkip, /* FtPioGrbit */
6543 /*::[*/0x09/*::]*/: parse_FtSkip, /* FtPictFmla */
6544 /*::[*/0x0A/*::]*/: parse_FtSkip, /* FtCbls */
6545 /*::[*/0x0B/*::]*/: parse_FtSkip, /* FtRbo */
6546 /*::[*/0x0C/*::]*/: parse_FtSkip, /* FtSbs */
6547 /*::[*/0x0D/*::]*/: parse_FtNts, /* FtNts */
6548 /*::[*/0x0E/*::]*/: parse_FtSkip, /* FtSbsFmla */
6549 /*::[*/0x0F/*::]*/: parse_FtSkip, /* FtGboData */
6550 /*::[*/0x10/*::]*/: parse_FtSkip, /* FtEdoData */
6551 /*::[*/0x11/*::]*/: parse_FtSkip, /* FtRboData */
6552 /*::[*/0x12/*::]*/: parse_FtSkip, /* FtCblsData */
6553 /*::[*/0x13/*::]*/: parse_FtSkip, /* FtLbsData */
6554 /*::[*/0x14/*::]*/: parse_FtSkip, /* FtCblsFmla */
6555 /*::[*/0x15/*::]*/: parse_FtCmo
6556};
6557function parse_FtArray(blob, length/*::, ot*/) {
6558 var tgt = blob.l + length;
6559 var fts = [];
6560 while(blob.l < tgt) {
6561 var ft = blob.read_shift(2);
6562 blob.l-=2;
6563 try {
6564 fts.push(FtTab[ft](blob, tgt - blob.l));
6565 } catch(e) { blob.l = tgt; return fts; }
6566 }
6567 if(blob.l != tgt) blob.l = tgt; //throw new Error("bad Object Ft-sequence");
6568 return fts;
6569}
6570
6571/* --- 2.4 Records --- */
6572
6573/* [MS-XLS] 2.4.21 */
6574function parse_BOF(blob, length) {
6575 var o = {BIFFVer:0, dt:0};
6576 o.BIFFVer = blob.read_shift(2); length -= 2;
6577 if(length >= 2) { o.dt = blob.read_shift(2); blob.l -= 2; }
6578 switch(o.BIFFVer) {
6579 case 0x0600: /* BIFF8 */
6580 case 0x0500: /* BIFF5 */
6581 case 0x0400: /* BIFF4 */
6582 case 0x0300: /* BIFF3 */
6583 case 0x0200: /* BIFF2 */
6584 case 0x0002: case 0x0007: /* BIFF2 */
6585 break;
6586 default: if(length > 6) throw new Error("Unexpected BIFF Ver " + o.BIFFVer);
6587 }
6588
6589 blob.read_shift(length);
6590 return o;
6591}
6592function write_BOF(wb/*:Workbook*/, t/*:number*/, o) {
6593 var h = 0x0600, w = 16;
6594 switch(o.bookType) {
6595 case 'biff8': break;
6596 case 'biff5': h = 0x0500; w = 8; break;
6597 case 'biff4': h = 0x0004; w = 6; break;
6598 case 'biff3': h = 0x0003; w = 6; break;
6599 case 'biff2': h = 0x0002; w = 4; break;
6600 case 'xla': break;
6601 default: throw new Error("unsupported BIFF version");
6602 }
6603 var out = new_buf(w);
6604 out.write_shift(2, h);
6605 out.write_shift(2, t);
6606 if(w > 4) out.write_shift(2, 0x7262);
6607 if(w > 6) out.write_shift(2, 0x07CD);
6608 if(w > 8) {
6609 out.write_shift(2, 0xC009);
6610 out.write_shift(2, 0x0001);
6611 out.write_shift(2, 0x0706);
6612 out.write_shift(2, 0x0000);
6613 }
6614 return out;
6615}
6616
6617
6618/* [MS-XLS] 2.4.146 */
6619function parse_InterfaceHdr(blob, length) {
6620 if(length === 0) return 0x04b0;
6621 if((blob.read_shift(2))!==0x04b0){/* empty */}
6622 return 0x04b0;
6623}
6624
6625
6626/* [MS-XLS] 2.4.349 */
6627function parse_WriteAccess(blob, length, opts) {
6628 if(opts.enc) { blob.l += length; return ""; }
6629 var l = blob.l;
6630 // TODO: make sure XLUnicodeString doesnt overrun
6631 var UserName = parse_XLUnicodeString2(blob, 0, opts);
6632 blob.read_shift(length + l - blob.l);
6633 return UserName;
6634}
6635function write_WriteAccess(s/*:string*/, opts) {
6636 var b8 = !opts || opts.biff == 8;
6637 var o = new_buf(b8 ? 112 : 54);
6638 o.write_shift(opts.biff == 8 ? 2 : 1, 7);
6639 if(b8) o.write_shift(1, 0);
6640 o.write_shift(4, 0x33336853);
6641 o.write_shift(4, (0x00534A74 | (b8 ? 0 : 0x20000000)));
6642 while(o.l < o.length) o.write_shift(1, (b8 ? 0 : 32));
6643 return o;
6644}
6645
6646/* [MS-XLS] 2.4.351 */
6647function parse_WsBool(blob, length, opts) {
6648 var flags = opts && opts.biff == 8 || length == 2 ? blob.read_shift(2) : (blob.l += length, 0);
6649 return { fDialog: flags & 0x10, fBelow: flags & 0x40, fRight: flags & 0x80 };
6650}
6651
6652/* [MS-XLS] 2.4.28 */
6653function parse_BoundSheet8(blob, length, opts) {
6654 var pos = blob.read_shift(4);
6655 var hidden = blob.read_shift(1) & 0x03;
6656 var dt = blob.read_shift(1);
6657 switch(dt) {
6658 case 0: dt = 'Worksheet'; break;
6659 case 1: dt = 'Macrosheet'; break;
6660 case 2: dt = 'Chartsheet'; break;
6661 case 6: dt = 'VBAModule'; break;
6662 }
6663 var name = parse_ShortXLUnicodeString(blob, 0, opts);
6664 if(name.length === 0) name = "Sheet1";
6665 return { pos:pos, hs:hidden, dt:dt, name:name };
6666}
6667function write_BoundSheet8(data, opts) {
6668 var w = (!opts || opts.biff >= 8 ? 2 : 1);
6669 var o = new_buf(8 + w * data.name.length);
6670 o.write_shift(4, data.pos);
6671 o.write_shift(1, data.hs || 0);
6672 o.write_shift(1, data.dt);
6673 o.write_shift(1, data.name.length);
6674 if(opts.biff >= 8) o.write_shift(1, 1);
6675 o.write_shift(w * data.name.length, data.name, opts.biff < 8 ? 'sbcs' : 'utf16le');
6676 var out = o.slice(0, o.l);
6677 out.l = o.l; return out;
6678}
6679
6680/* [MS-XLS] 2.4.265 TODO */
6681function parse_SST(blob, length)/*:SST*/ {
6682 var end = blob.l + length;
6683 var cnt = blob.read_shift(4);
6684 var ucnt = blob.read_shift(4);
6685 var strs/*:SST*/ = ([]/*:any*/);
6686 for(var i = 0; i != ucnt && blob.l < end; ++i) {
6687 strs.push(parse_XLUnicodeRichExtendedString(blob));
6688 }
6689 strs.Count = cnt; strs.Unique = ucnt;
6690 return strs;
6691}
6692function write_SST(sst, opts) {
6693 var header = new_buf(8);
6694 header.write_shift(4, sst.Count);
6695 header.write_shift(4, sst.Unique);
6696 var strs = [];
6697 for(var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts);
6698 var o = bconcat([header].concat(strs));
6699 /*::(*/o/*:: :any)*/.parts = [header.length].concat(strs.map(function(str) { return str.length; }));
6700 return o;
6701}
6702
6703/* [MS-XLS] 2.4.107 */
6704function parse_ExtSST(blob, length) {
6705 var extsst = {};
6706 extsst.dsst = blob.read_shift(2);
6707 blob.l += length-2;
6708 return extsst;
6709}
6710
6711
6712/* [MS-XLS] 2.4.221 TODO: check BIFF2-4 */
6713function parse_Row(blob) {
6714 var z = ({}/*:any*/);
6715 z.r = blob.read_shift(2);
6716 z.c = blob.read_shift(2);
6717 z.cnt = blob.read_shift(2) - z.c;
6718 var miyRw = blob.read_shift(2);
6719 blob.l += 4; // reserved(2), unused(2)
6720 var flags = blob.read_shift(1); // various flags
6721 blob.l += 3; // reserved(8), ixfe(12), flags(4)
6722 if(flags & 0x07) z.level = flags & 0x07;
6723 // collapsed: flags & 0x10
6724 if(flags & 0x20) z.hidden = true;
6725 if(flags & 0x40) z.hpt = miyRw / 20;
6726 return z;
6727}
6728
6729
6730/* [MS-XLS] 2.4.125 */
6731function parse_ForceFullCalculation(blob) {
6732 var header = parse_frtHeader(blob);
6733 if(header.type != 0x08A3) throw new Error("Invalid Future Record " + header.type);
6734 var fullcalc = blob.read_shift(4);
6735 return fullcalc !== 0x0;
6736}
6737
6738
6739
6740
6741
6742/* [MS-XLS] 2.4.215 rt */
6743function parse_RecalcId(blob) {
6744 blob.read_shift(2);
6745 return blob.read_shift(4);
6746}
6747
6748/* [MS-XLS] 2.4.87 */
6749function parse_DefaultRowHeight(blob, length, opts) {
6750 var f = 0;
6751 if(!(opts && opts.biff == 2)) {
6752 f = blob.read_shift(2);
6753 }
6754 var miyRw = blob.read_shift(2);
6755 if((opts && opts.biff == 2)) {
6756 f = 1 - (miyRw >> 15); miyRw &= 0x7fff;
6757 }
6758 var fl = {Unsynced:f&1,DyZero:(f&2)>>1,ExAsc:(f&4)>>2,ExDsc:(f&8)>>3};
6759 return [fl, miyRw];
6760}
6761
6762/* [MS-XLS] 2.4.345 TODO */
6763function parse_Window1(blob) {
6764 var xWn = blob.read_shift(2), yWn = blob.read_shift(2), dxWn = blob.read_shift(2), dyWn = blob.read_shift(2);
6765 var flags = blob.read_shift(2), iTabCur = blob.read_shift(2), iTabFirst = blob.read_shift(2);
6766 var ctabSel = blob.read_shift(2), wTabRatio = blob.read_shift(2);
6767 return { Pos: [xWn, yWn], Dim: [dxWn, dyWn], Flags: flags, CurTab: iTabCur,
6768 FirstTab: iTabFirst, Selected: ctabSel, TabRatio: wTabRatio };
6769}
6770function write_Window1(/*::opts*/) {
6771 var o = new_buf(18);
6772 o.write_shift(2, 0);
6773 o.write_shift(2, 0);
6774 o.write_shift(2, 0x7260);
6775 o.write_shift(2, 0x44c0);
6776 o.write_shift(2, 0x38);
6777 o.write_shift(2, 0);
6778 o.write_shift(2, 0);
6779 o.write_shift(2, 1);
6780 o.write_shift(2, 0x01f4);
6781 return o;
6782}
6783/* [MS-XLS] 2.4.346 TODO */
6784function parse_Window2(blob, length, opts) {
6785 if(opts && opts.biff >= 2 && opts.biff < 5) return {};
6786 var f = blob.read_shift(2);
6787 return { RTL: f & 0x40 };
6788}
6789function write_Window2(view) {
6790 var o = new_buf(18), f = 0x6b6;
6791 if(view && view.RTL) f |= 0x40;
6792 o.write_shift(2, f);
6793 o.write_shift(4, 0);
6794 o.write_shift(4, 64);
6795 o.write_shift(4, 0);
6796 o.write_shift(4, 0);
6797 return o;
6798}
6799
6800/* [MS-XLS] 2.4.189 TODO */
6801function parse_Pane(/*blob, length, opts*/) {
6802}
6803
6804/* [MS-XLS] 2.4.122 TODO */
6805function parse_Font(blob, length, opts) {
6806 var o/*:any*/ = {
6807 dyHeight: blob.read_shift(2),
6808 fl: blob.read_shift(2)
6809 };
6810 switch((opts && opts.biff) || 8) {
6811 case 2: break;
6812 case 3: case 4: blob.l += 2; break;
6813 default: blob.l += 10; break;
6814 }
6815 o.name = parse_ShortXLUnicodeString(blob, 0, opts);
6816 return o;
6817}
6818function write_Font(data, opts) {
6819 var name = data.name || "Arial";
6820 var b5 = (opts && (opts.biff == 5)), w = (b5 ? (15 + name.length) : (16 + 2 * name.length));
6821 var o = new_buf(w);
6822 o.write_shift(2, (data.sz || 12) * 20);
6823 o.write_shift(4, 0);
6824 o.write_shift(2, 400);
6825 o.write_shift(4, 0);
6826 o.write_shift(2, 0);
6827 o.write_shift(1, name.length);
6828 if(!b5) o.write_shift(1, 1);
6829 o.write_shift((b5 ? 1 : 2) * name.length, name, (b5 ? "sbcs" : "utf16le"));
6830 return o;
6831}
6832
6833/* [MS-XLS] 2.4.149 */
6834function parse_LabelSst(blob) {
6835 var cell = parse_XLSCell(blob);
6836 cell.isst = blob.read_shift(4);
6837 return cell;
6838}
6839function write_LabelSst(R/*:number*/, C/*:number*/, v/*:number*/, os/*:number*/ /*::, opts*/) {
6840 var o = new_buf(10);
6841 write_XLSCell(R, C, os, o);
6842 o.write_shift(4, v);
6843 return o;
6844}
6845
6846/* [MS-XLS] 2.4.148 */
6847function parse_Label(blob, length, opts) {
6848 if(opts.biffguess && opts.biff == 2) opts.biff = 5;
6849 var target = blob.l + length;
6850 var cell = parse_XLSCell(blob, 6);
6851 if(opts.biff == 2) blob.l++;
6852 var str = parse_XLUnicodeString(blob, target - blob.l, opts);
6853 cell.val = str;
6854 return cell;
6855}
6856function write_Label(R/*:number*/, C/*:number*/, v/*:string*/, os/*:number*/, opts) {
6857 var b8 = !opts || opts.biff == 8;
6858 var o = new_buf(6 + 2 + (+b8) + (1 + b8) * v.length);
6859 write_XLSCell(R, C, os, o);
6860 o.write_shift(2, v.length);
6861 if(b8) o.write_shift(1, 1);
6862 o.write_shift((1 + b8) * v.length, v, b8 ? 'utf16le' : 'sbcs');
6863 return o;
6864}
6865
6866
6867/* [MS-XLS] 2.4.126 Number Formats */
6868function parse_Format(blob, length, opts) {
6869 var numFmtId = blob.read_shift(2);
6870 var fmtstr = parse_XLUnicodeString2(blob, 0, opts);
6871 return [numFmtId, fmtstr];
6872}
6873function write_Format(i/*:number*/, f/*:string*/, opts, o) {
6874 var b5 = (opts && (opts.biff == 5));
6875 if(!o) o = new_buf(b5 ? (3 + f.length) : (5 + 2 * f.length));
6876 o.write_shift(2, i);
6877 o.write_shift((b5 ? 1 : 2), f.length);
6878 if(!b5) o.write_shift(1, 1);
6879 o.write_shift((b5 ? 1 : 2) * f.length, f, (b5 ? 'sbcs' : 'utf16le'));
6880 var out = (o.length > o.l) ? o.slice(0, o.l) : o;
6881 if(out.l == null) out.l = out.length;
6882 return out;
6883}
6884var parse_BIFF2Format = parse_XLUnicodeString2;
6885
6886/* [MS-XLS] 2.4.90 */
6887function parse_Dimensions(blob, length, opts) {
6888 var end = blob.l + length;
6889 var w = opts.biff == 8 || !opts.biff ? 4 : 2;
6890 var r = blob.read_shift(w), R = blob.read_shift(w);
6891 var c = blob.read_shift(2), C = blob.read_shift(2);
6892 blob.l = end;
6893 return {s: {r:r, c:c}, e: {r:R, c:C}};
6894}
6895function write_Dimensions(range, opts) {
6896 var w = opts.biff == 8 || !opts.biff ? 4 : 2;
6897 var o = new_buf(2*w + 6);
6898 o.write_shift(w, range.s.r);
6899 o.write_shift(w, range.e.r + 1);
6900 o.write_shift(2, range.s.c);
6901 o.write_shift(2, range.e.c + 1);
6902 o.write_shift(2, 0);
6903 return o;
6904}
6905
6906/* [MS-XLS] 2.4.220 */
6907function parse_RK(blob) {
6908 var rw = blob.read_shift(2), col = blob.read_shift(2);
6909 var rkrec = parse_RkRec(blob);
6910 return {r:rw, c:col, ixfe:rkrec[0], rknum:rkrec[1]};
6911}
6912
6913/* [MS-XLS] 2.4.175 */
6914function parse_MulRk(blob, length) {
6915 var target = blob.l + length - 2;
6916 var rw = blob.read_shift(2), col = blob.read_shift(2);
6917 var rkrecs = [];
6918 while(blob.l < target) rkrecs.push(parse_RkRec(blob));
6919 if(blob.l !== target) throw new Error("MulRK read error");
6920 var lastcol = blob.read_shift(2);
6921 if(rkrecs.length != lastcol - col + 1) throw new Error("MulRK length mismatch");
6922 return {r:rw, c:col, C:lastcol, rkrec:rkrecs};
6923}
6924/* [MS-XLS] 2.4.174 */
6925function parse_MulBlank(blob, length) {
6926 var target = blob.l + length - 2;
6927 var rw = blob.read_shift(2), col = blob.read_shift(2);
6928 var ixfes = [];
6929 while(blob.l < target) ixfes.push(blob.read_shift(2));
6930 if(blob.l !== target) throw new Error("MulBlank read error");
6931 var lastcol = blob.read_shift(2);
6932 if(ixfes.length != lastcol - col + 1) throw new Error("MulBlank length mismatch");
6933 return {r:rw, c:col, C:lastcol, ixfe:ixfes};
6934}
6935
6936/* [MS-XLS] 2.5.20 2.5.249 TODO: interpret values here */
6937function parse_CellStyleXF(blob, length, style, opts) {
6938 var o = {};
6939 var a = blob.read_shift(4), b = blob.read_shift(4);
6940 var c = blob.read_shift(4), d = blob.read_shift(2);
6941 o.patternType = XLSFillPattern[c >> 26];
6942
6943 if(!opts.cellStyles) return o;
6944 o.alc = a & 0x07;
6945 o.fWrap = (a >> 3) & 0x01;
6946 o.alcV = (a >> 4) & 0x07;
6947 o.fJustLast = (a >> 7) & 0x01;
6948 o.trot = (a >> 8) & 0xFF;
6949 o.cIndent = (a >> 16) & 0x0F;
6950 o.fShrinkToFit = (a >> 20) & 0x01;
6951 o.iReadOrder = (a >> 22) & 0x02;
6952 o.fAtrNum = (a >> 26) & 0x01;
6953 o.fAtrFnt = (a >> 27) & 0x01;
6954 o.fAtrAlc = (a >> 28) & 0x01;
6955 o.fAtrBdr = (a >> 29) & 0x01;
6956 o.fAtrPat = (a >> 30) & 0x01;
6957 o.fAtrProt = (a >> 31) & 0x01;
6958
6959 o.dgLeft = b & 0x0F;
6960 o.dgRight = (b >> 4) & 0x0F;
6961 o.dgTop = (b >> 8) & 0x0F;
6962 o.dgBottom = (b >> 12) & 0x0F;
6963 o.icvLeft = (b >> 16) & 0x7F;
6964 o.icvRight = (b >> 23) & 0x7F;
6965 o.grbitDiag = (b >> 30) & 0x03;
6966
6967 o.icvTop = c & 0x7F;
6968 o.icvBottom = (c >> 7) & 0x7F;
6969 o.icvDiag = (c >> 14) & 0x7F;
6970 o.dgDiag = (c >> 21) & 0x0F;
6971
6972 o.icvFore = d & 0x7F;
6973 o.icvBack = (d >> 7) & 0x7F;
6974 o.fsxButton = (d >> 14) & 0x01;
6975 return o;
6976}
6977//function parse_CellXF(blob, length, opts) {return parse_CellStyleXF(blob,length,0, opts);}
6978//function parse_StyleXF(blob, length, opts) {return parse_CellStyleXF(blob,length,1, opts);}
6979
6980/* [MS-XLS] 2.4.353 TODO: actually do this right */
6981function parse_XF(blob, length, opts) {
6982 var o = {};
6983 o.ifnt = blob.read_shift(2); o.numFmtId = blob.read_shift(2); o.flags = blob.read_shift(2);
6984 o.fStyle = (o.flags >> 2) & 0x01;
6985 length -= 6;
6986 o.data = parse_CellStyleXF(blob, length, o.fStyle, opts);
6987 return o;
6988}
6989function write_XF(data, ixfeP, opts, o) {
6990 var b5 = (opts && (opts.biff == 5));
6991 if(!o) o = new_buf(b5 ? 16 : 20);
6992 o.write_shift(2, 0);
6993 if(data.style) {
6994 o.write_shift(2, (data.numFmtId||0));
6995 o.write_shift(2, 0xFFF4);
6996 } else {
6997 o.write_shift(2, (data.numFmtId||0));
6998 o.write_shift(2, (ixfeP<<4));
6999 }
7000 var f = 0;
7001 if(data.numFmtId > 0 && b5) f |= 0x0400;
7002 o.write_shift(4, f);
7003 o.write_shift(4, 0);
7004 if(!b5) o.write_shift(4, 0);
7005 o.write_shift(2, 0);
7006 return o;
7007}
7008
7009/* [MS-XLS] 2.4.134 */
7010function parse_Guts(blob) {
7011 blob.l += 4;
7012 var out = [blob.read_shift(2), blob.read_shift(2)];
7013 if(out[0] !== 0) out[0]--;
7014 if(out[1] !== 0) out[1]--;
7015 if(out[0] > 7 || out[1] > 7) throw new Error("Bad Gutters: " + out.join("|"));
7016 return out;
7017}
7018function write_Guts(guts/*:Array<number>*/) {
7019 var o = new_buf(8);
7020 o.write_shift(4, 0);
7021 o.write_shift(2, guts[0] ? guts[0] + 1 : 0);
7022 o.write_shift(2, guts[1] ? guts[1] + 1 : 0);
7023 return o;
7024}
7025
7026/* [MS-XLS] 2.4.24 */
7027function parse_BoolErr(blob, length, opts) {
7028 var cell = parse_XLSCell(blob, 6);
7029 if(opts.biff == 2 || length == 9) ++blob.l;
7030 var val = parse_Bes(blob, 2);
7031 cell.val = val;
7032 cell.t = (val === true || val === false) ? 'b' : 'e';
7033 return cell;
7034}
7035function write_BoolErr(R/*:number*/, C/*:number*/, v, os/*:number*/, opts, t/*:string*/) {
7036 var o = new_buf(8);
7037 write_XLSCell(R, C, os, o);
7038 write_Bes(v, t, o);
7039 return o;
7040}
7041
7042/* [MS-XLS] 2.4.180 Number */
7043function parse_Number(blob, length, opts) {
7044 if(opts.biffguess && opts.biff == 2) opts.biff = 5;
7045 var cell = parse_XLSCell(blob, 6);
7046 var xnum = parse_Xnum(blob, 8);
7047 cell.val = xnum;
7048 return cell;
7049}
7050function write_Number(R/*:number*/, C/*:number*/, v, os/*:: :number, opts*/) {
7051 var o = new_buf(14);
7052 write_XLSCell(R, C, os, o);
7053 write_Xnum(v, o);
7054 return o;
7055}
7056
7057var parse_XLHeaderFooter = parse_OptXLUnicodeString; // TODO: parse 2.4.136
7058
7059/* [MS-XLS] 2.4.271 */
7060function parse_SupBook(blob, length, opts) {
7061 var end = blob.l + length;
7062 var ctab = blob.read_shift(2);
7063 var cch = blob.read_shift(2);
7064 opts.sbcch = cch;
7065 if(cch == 0x0401 || cch == 0x3A01) return [cch, ctab];
7066 if(cch < 0x01 || cch >0xff) throw new Error("Unexpected SupBook type: "+cch);
7067 var virtPath = parse_XLUnicodeStringNoCch(blob, cch);
7068 /* TODO: 2.5.277 Virtual Path */
7069 var rgst = [];
7070 while(end > blob.l) rgst.push(parse_XLUnicodeString(blob));
7071 return [cch, ctab, virtPath, rgst];
7072}
7073
7074/* [MS-XLS] 2.4.105 TODO */
7075function parse_ExternName(blob, length, opts) {
7076 var flags = blob.read_shift(2);
7077 var body;
7078 var o = ({
7079 fBuiltIn: flags & 0x01,
7080 fWantAdvise: (flags >>> 1) & 0x01,
7081 fWantPict: (flags >>> 2) & 0x01,
7082 fOle: (flags >>> 3) & 0x01,
7083 fOleLink: (flags >>> 4) & 0x01,
7084 cf: (flags >>> 5) & 0x3FF,
7085 fIcon: flags >>> 15 & 0x01
7086 }/*:any*/);
7087 if(opts.sbcch === 0x3A01) body = parse_AddinUdf(blob, length-2, opts);
7088 //else throw new Error("unsupported SupBook cch: " + opts.sbcch);
7089 o.body = body || blob.read_shift(length-2);
7090 if(typeof body === "string") o.Name = body;
7091 return o;
7092}
7093
7094/* [MS-XLS] 2.4.150 TODO */
7095var XLSLblBuiltIn = [
7096 "_xlnm.Consolidate_Area",
7097 "_xlnm.Auto_Open",
7098 "_xlnm.Auto_Close",
7099 "_xlnm.Extract",
7100 "_xlnm.Database",
7101 "_xlnm.Criteria",
7102 "_xlnm.Print_Area",
7103 "_xlnm.Print_Titles",
7104 "_xlnm.Recorder",
7105 "_xlnm.Data_Form",
7106 "_xlnm.Auto_Activate",
7107 "_xlnm.Auto_Deactivate",
7108 "_xlnm.Sheet_Title",
7109 "_xlnm._FilterDatabase"
7110];
7111function parse_Lbl(blob, length, opts) {
7112 var target = blob.l + length;
7113 var flags = blob.read_shift(2);
7114 var chKey = blob.read_shift(1);
7115 var cch = blob.read_shift(1);
7116 var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
7117 var itab = 0;
7118 if(!opts || opts.biff >= 5) {
7119 if(opts.biff != 5) blob.l += 2;
7120 itab = blob.read_shift(2);
7121 if(opts.biff == 5) blob.l += 2;
7122 blob.l += 4;
7123 }
7124 var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
7125 if(flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
7126 var npflen = target - blob.l; if(opts && opts.biff == 2) --npflen;
7127 /*jshint -W018 */
7128 var rgce = (target == blob.l || cce === 0 || !(npflen > 0)) ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
7129 /*jshint +W018 */
7130 return {
7131 chKey: chKey,
7132 Name: name,
7133 itab: itab,
7134 rgce: rgce
7135 };
7136}
7137
7138/* [MS-XLS] 2.4.106 TODO: verify filename encoding */
7139function parse_ExternSheet(blob, length, opts) {
7140 if(opts.biff < 8) return parse_BIFF5ExternSheet(blob, length, opts);
7141 var o = [], target = blob.l + length, len = blob.read_shift(opts.biff > 8 ? 4 : 2);
7142 while(len-- !== 0) o.push(parse_XTI(blob, opts.biff > 8 ? 12 : 6, opts));
7143 // [iSupBook, itabFirst, itabLast];
7144 if(blob.l != target) throw new Error("Bad ExternSheet: " + blob.l + " != " + target);
7145 return o;
7146}
7147function parse_BIFF5ExternSheet(blob, length, opts) {
7148 if(blob[blob.l + 1] == 0x03) blob[blob.l]++;
7149 var o = parse_ShortXLUnicodeString(blob, length, opts);
7150 return o.charCodeAt(0) == 0x03 ? o.slice(1) : o;
7151}
7152
7153/* [MS-XLS] 2.4.176 TODO: check older biff */
7154function parse_NameCmt(blob, length, opts) {
7155 if(opts.biff < 8) { blob.l += length; return; }
7156 var cchName = blob.read_shift(2);
7157 var cchComment = blob.read_shift(2);
7158 var name = parse_XLUnicodeStringNoCch(blob, cchName, opts);
7159 var comment = parse_XLUnicodeStringNoCch(blob, cchComment, opts);
7160 return [name, comment];
7161}
7162
7163/* [MS-XLS] 2.4.260 */
7164function parse_ShrFmla(blob, length, opts) {
7165 var ref = parse_RefU(blob, 6);
7166 blob.l++;
7167 var cUse = blob.read_shift(1);
7168 length -= 8;
7169 return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
7170}
7171
7172/* [MS-XLS] 2.4.4 TODO */
7173function parse_Array(blob, length, opts) {
7174 var ref = parse_Ref(blob, 6);
7175 /* TODO: fAlwaysCalc */
7176 switch(opts.biff) {
7177 case 2: blob.l ++; length -= 7; break;
7178 case 3: case 4: blob.l += 2; length -= 8; break;
7179 default: blob.l += 6; length -= 12;
7180 }
7181 return [ref, parse_ArrayParsedFormula(blob, length, opts, ref)];
7182}
7183
7184/* [MS-XLS] 2.4.173 */
7185function parse_MTRSettings(blob) {
7186 var fMTREnabled = blob.read_shift(4) !== 0x00;
7187 var fUserSetThreadCount = blob.read_shift(4) !== 0x00;
7188 var cUserThreadCount = blob.read_shift(4);
7189 return [fMTREnabled, fUserSetThreadCount, cUserThreadCount];
7190}
7191
7192/* [MS-XLS] 2.5.186 TODO: BIFF5 */
7193function parse_NoteSh(blob, length, opts) {
7194 if(opts.biff < 8) return;
7195 var row = blob.read_shift(2), col = blob.read_shift(2);
7196 var flags = blob.read_shift(2), idObj = blob.read_shift(2);
7197 var stAuthor = parse_XLUnicodeString2(blob, 0, opts);
7198 if(opts.biff < 8) blob.read_shift(1);
7199 return [{r:row,c:col}, stAuthor, idObj, flags];
7200}
7201
7202/* [MS-XLS] 2.4.179 */
7203function parse_Note(blob, length, opts) {
7204 /* TODO: Support revisions */
7205 return parse_NoteSh(blob, length, opts);
7206}
7207
7208/* [MS-XLS] 2.4.168 */
7209function parse_MergeCells(blob, length)/*:Array<Range>*/ {
7210 var merges/*:Array<Range>*/ = [];
7211 var cmcs = blob.read_shift(2);
7212 while (cmcs--) merges.push(parse_Ref8U(blob,length));
7213 return merges;
7214}
7215function write_MergeCells(merges/*:Array<Range>*/) {
7216 var o = new_buf(2 + merges.length * 8);
7217 o.write_shift(2, merges.length);
7218 for(var i = 0; i < merges.length; ++i) write_Ref8U(merges[i], o);
7219 return o;
7220}
7221
7222/* [MS-XLS] 2.4.181 TODO: parse all the things! */
7223function parse_Obj(blob, length, opts) {
7224 if(opts && opts.biff < 8) return parse_BIFF5Obj(blob, length, opts);
7225 var cmo = parse_FtCmo(blob, 22); // id, ot, flags
7226 var fts = parse_FtArray(blob, length-22, cmo[1]);
7227 return { cmo: cmo, ft:fts };
7228}
7229/* from older spec */
7230var parse_BIFF5OT = {
72310x08: function(blob, length) {
7232 var tgt = blob.l + length;
7233 blob.l += 10; // todo
7234 var cf = blob.read_shift(2);
7235 blob.l += 4;
7236 blob.l += 2; //var cbPictFmla = blob.read_shift(2);
7237 blob.l += 2;
7238 blob.l += 2; //var grbit = blob.read_shift(2);
7239 blob.l += 4;
7240 var cchName = blob.read_shift(1);
7241 blob.l += cchName; // TODO: stName
7242 blob.l = tgt; // TODO: fmla
7243 return { fmt:cf };
7244}
7245};
7246
7247function parse_BIFF5Obj(blob, length, opts) {
7248 blob.l += 4; //var cnt = blob.read_shift(4);
7249 var ot = blob.read_shift(2);
7250 var id = blob.read_shift(2);
7251 var grbit = blob.read_shift(2);
7252 blob.l += 2; //var colL = blob.read_shift(2);
7253 blob.l += 2; //var dxL = blob.read_shift(2);
7254 blob.l += 2; //var rwT = blob.read_shift(2);
7255 blob.l += 2; //var dyT = blob.read_shift(2);
7256 blob.l += 2; //var colR = blob.read_shift(2);
7257 blob.l += 2; //var dxR = blob.read_shift(2);
7258 blob.l += 2; //var rwB = blob.read_shift(2);
7259 blob.l += 2; //var dyB = blob.read_shift(2);
7260 blob.l += 2; //var cbMacro = blob.read_shift(2);
7261 blob.l += 6;
7262 length -= 36;
7263 var fts = [];
7264 fts.push((parse_BIFF5OT[ot]||parsenoop)(blob, length, opts));
7265 return { cmo: [id, ot, grbit], ft:fts };
7266}
7267
7268/* [MS-XLS] 2.4.329 TODO: parse properly */
7269function parse_TxO(blob, length, opts) {
7270 var s = blob.l;
7271 var texts = "";
7272try {
7273 blob.l += 4;
7274 var ot = (opts.lastobj||{cmo:[0,0]}).cmo[1];
7275 var controlInfo; // eslint-disable-line no-unused-vars
7276 if([0,5,7,11,12,14].indexOf(ot) == -1) blob.l += 6;
7277 else controlInfo = parse_ControlInfo(blob, 6, opts); // eslint-disable-line no-unused-vars
7278 var cchText = blob.read_shift(2);
7279 /*var cbRuns = */blob.read_shift(2);
7280 /*var ifntEmpty = */parseuint16(blob, 2);
7281 var len = blob.read_shift(2);
7282 blob.l += len;
7283 //var fmla = parse_ObjFmla(blob, s + length - blob.l);
7284
7285 for(var i = 1; i < blob.lens.length-1; ++i) {
7286 if(blob.l-s != blob.lens[i]) throw new Error("TxO: bad continue record");
7287 var hdr = blob[blob.l];
7288 var t = parse_XLUnicodeStringNoCch(blob, blob.lens[i+1]-blob.lens[i]-1);
7289 texts += t;
7290 if(texts.length >= (hdr ? cchText : 2*cchText)) break;
7291 }
7292 if(texts.length !== cchText && texts.length !== cchText*2) {
7293 throw new Error("cchText: " + cchText + " != " + texts.length);
7294 }
7295
7296 blob.l = s + length;
7297 /* [MS-XLS] 2.5.272 TxORuns */
7298// var rgTxoRuns = [];
7299// for(var j = 0; j != cbRuns/8-1; ++j) blob.l += 8;
7300// var cchText2 = blob.read_shift(2);
7301// if(cchText2 !== cchText) throw new Error("TxOLastRun mismatch: " + cchText2 + " " + cchText);
7302// blob.l += 6;
7303// if(s + length != blob.l) throw new Error("TxO " + (s + length) + ", at " + blob.l);
7304 return { t: texts };
7305} catch(e) { blob.l = s + length; return { t: texts }; }
7306}
7307
7308/* [MS-XLS] 2.4.140 */
7309function parse_HLink(blob, length) {
7310 var ref = parse_Ref8U(blob, 8);
7311 blob.l += 16; /* CLSID */
7312 var hlink = parse_Hyperlink(blob, length-24);
7313 return [ref, hlink];
7314}
7315function write_HLink(hl) {
7316 var O = new_buf(24);
7317 var ref = decode_cell(hl[0]);
7318 O.write_shift(2, ref.r); O.write_shift(2, ref.r);
7319 O.write_shift(2, ref.c); O.write_shift(2, ref.c);
7320 var clsid = "d0 c9 ea 79 f9 ba ce 11 8c 82 00 aa 00 4b a9 0b".split(" ");
7321 for(var i = 0; i < 16; ++i) O.write_shift(1, parseInt(clsid[i], 16));
7322 return bconcat([O, write_Hyperlink(hl[1])]);
7323}
7324
7325
7326/* [MS-XLS] 2.4.141 */
7327function parse_HLinkTooltip(blob, length) {
7328 blob.read_shift(2);
7329 var ref = parse_Ref8U(blob, 8);
7330 var wzTooltip = blob.read_shift((length-10)/2, 'dbcs-cont');
7331 wzTooltip = wzTooltip.replace(chr0,"");
7332 return [ref, wzTooltip];
7333}
7334function write_HLinkTooltip(hl) {
7335 var TT = hl[1].Tooltip;
7336 var O = new_buf(10 + 2 * (TT.length + 1));
7337 O.write_shift(2, 0x0800);
7338 var ref = decode_cell(hl[0]);
7339 O.write_shift(2, ref.r); O.write_shift(2, ref.r);
7340 O.write_shift(2, ref.c); O.write_shift(2, ref.c);
7341 for(var i = 0; i < TT.length; ++i) O.write_shift(2, TT.charCodeAt(i));
7342 O.write_shift(2, 0);
7343 return O;
7344}
7345
7346/* [MS-XLS] 2.4.63 */
7347function parse_Country(blob)/*:[string|number, string|number]*/ {
7348 var o = [0,0], d;
7349 d = blob.read_shift(2); o[0] = CountryEnum[d] || d;
7350 d = blob.read_shift(2); o[1] = CountryEnum[d] || d;
7351 return o;
7352}
7353function write_Country(o) {
7354 if(!o) o = new_buf(4);
7355 o.write_shift(2, 0x01);
7356 o.write_shift(2, 0x01);
7357 return o;
7358}
7359
7360/* [MS-XLS] 2.4.50 ClrtClient */
7361function parse_ClrtClient(blob) {
7362 var ccv = blob.read_shift(2);
7363 var o = [];
7364 while(ccv-->0) o.push(parse_LongRGB(blob, 8));
7365 return o;
7366}
7367
7368/* [MS-XLS] 2.4.188 */
7369function parse_Palette(blob) {
7370 var ccv = blob.read_shift(2);
7371 var o = [];
7372 while(ccv-->0) o.push(parse_LongRGB(blob, 8));
7373 return o;
7374}
7375
7376/* [MS-XLS] 2.4.354 */
7377function parse_XFCRC(blob) {
7378 blob.l += 2;
7379 var o = {cxfs:0, crc:0};
7380 o.cxfs = blob.read_shift(2);
7381 o.crc = blob.read_shift(4);
7382 return o;
7383}
7384
7385/* [MS-XLS] 2.4.53 TODO: parse flags */
7386/* [MS-XLSB] 2.4.323 TODO: parse flags */
7387function parse_ColInfo(blob, length, opts) {
7388 if(!opts.cellStyles) return parsenoop(blob, length);
7389 var w = opts && opts.biff >= 12 ? 4 : 2;
7390 var colFirst = blob.read_shift(w);
7391 var colLast = blob.read_shift(w);
7392 var coldx = blob.read_shift(w);
7393 var ixfe = blob.read_shift(w);
7394 var flags = blob.read_shift(2);
7395 if(w == 2) blob.l += 2;
7396 var o = ({s:colFirst, e:colLast, w:coldx, ixfe:ixfe, flags:flags}/*:any*/);
7397 if(opts.biff >= 5 || !opts.biff) o.level = (flags >> 8) & 0x7;
7398 return o;
7399}
7400function write_ColInfo(col, idx) {
7401 var o = new_buf(12);
7402 o.write_shift(2, idx);
7403 o.write_shift(2, idx);
7404 o.write_shift(2, col.width * 256);
7405 o.write_shift(2, 0);
7406 var f = 0;
7407 if(col.hidden) f |= 1;
7408 o.write_shift(1, f);
7409 f = col.level || 0;
7410 o.write_shift(1, f);
7411 o.write_shift(2, 0);
7412 return o;
7413}
7414
7415/* [MS-XLS] 2.4.257 */
7416function parse_Setup(blob, length) {
7417 var o = {};
7418 if(length < 32) return o;
7419 blob.l += 16;
7420 o.header = parse_Xnum(blob, 8);
7421 o.footer = parse_Xnum(blob, 8);
7422 blob.l += 2;
7423 return o;
7424}
7425
7426/* [MS-XLS] 2.4.261 */
7427function parse_ShtProps(blob, length, opts) {
7428 var def = {area:false};
7429 if(opts.biff != 5) { blob.l += length; return def; }
7430 var d = blob.read_shift(1); blob.l += 3;
7431 if((d & 0x10)) def.area = true;
7432 return def;
7433}
7434
7435/* [MS-XLS] 2.4.241 */
7436function write_RRTabId(n/*:number*/) {
7437 var out = new_buf(2 * n);
7438 for(var i = 0; i < n; ++i) out.write_shift(2, i+1);
7439 return out;
7440}
7441
7442var parse_Blank = parse_XLSCell; /* [MS-XLS] 2.4.20 Just the cell */
7443var parse_Scl = parseuint16a; /* [MS-XLS] 2.4.247 num, den */
7444var parse_String = parse_XLUnicodeString; /* [MS-XLS] 2.4.268 */
7445
7446/* --- Specific to versions before BIFF8 --- */
7447function parse_ImData(blob) {
7448 var cf = blob.read_shift(2);
7449 var env = blob.read_shift(2);
7450 var lcb = blob.read_shift(4);
7451 var o = {fmt:cf, env:env, len:lcb, data:blob.slice(blob.l,blob.l+lcb)};
7452 blob.l += lcb;
7453 return o;
7454}
7455
7456/* BIFF2_??? where ??? is the name from [XLS] */
7457function parse_BIFF2STR(blob, length, opts) {
7458 if(opts.biffguess && opts.biff == 5) opts.biff = 2;
7459 var cell = parse_XLSCell(blob, 6);
7460 ++blob.l;
7461 var str = parse_XLUnicodeString2(blob, length-7, opts);
7462 cell.t = 'str';
7463 cell.val = str;
7464 return cell;
7465}
7466
7467function parse_BIFF2NUM(blob/*::, length*/) {
7468 var cell = parse_XLSCell(blob, 6);
7469 ++blob.l;
7470 var num = parse_Xnum(blob, 8);
7471 cell.t = 'n';
7472 cell.val = num;
7473 return cell;
7474}
7475function write_BIFF2NUM(r/*:number*/, c/*:number*/, val/*:number*/) {
7476 var out = new_buf(15);
7477 write_BIFF2Cell(out, r, c);
7478 out.write_shift(8, val, 'f');
7479 return out;
7480}
7481
7482function parse_BIFF2INT(blob) {
7483 var cell = parse_XLSCell(blob, 6);
7484 ++blob.l;
7485 var num = blob.read_shift(2);
7486 cell.t = 'n';
7487 cell.val = num;
7488 return cell;
7489}
7490function write_BIFF2INT(r/*:number*/, c/*:number*/, val/*:number*/) {
7491 var out = new_buf(9);
7492 write_BIFF2Cell(out, r, c);
7493 out.write_shift(2, val);
7494 return out;
7495}
7496
7497function parse_BIFF2STRING(blob) {
7498 var cch = blob.read_shift(1);
7499 if(cch === 0) { blob.l++; return ""; }
7500 return blob.read_shift(cch, 'sbcs-cont');
7501}
7502
7503/* TODO: convert to BIFF8 font struct */
7504function parse_BIFF2FONTXTRA(blob, length) {
7505 blob.l += 6; // unknown
7506 blob.l += 2; // font weight "bls"
7507 blob.l += 1; // charset
7508 blob.l += 3; // unknown
7509 blob.l += 1; // font family
7510 blob.l += length - 13;
7511}
7512
7513/* TODO: parse rich text runs */
7514function parse_RString(blob, length, opts) {
7515 var end = blob.l + length;
7516 var cell = parse_XLSCell(blob, 6);
7517 var cch = blob.read_shift(2);
7518 var str = parse_XLUnicodeStringNoCch(blob, cch, opts);
7519 blob.l = end;
7520 cell.t = 'str';
7521 cell.val = str;
7522 return cell;
7523}
7524/* from js-harb (C) 2014-present SheetJS */
7525var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5];
7526var DBF = /*#__PURE__*/(function() {
7527var dbf_codepage_map = {
7528 /* Code Pages Supported by Visual FoxPro */
7529 /*::[*/0x01/*::]*/: 437, /*::[*/0x02/*::]*/: 850,
7530 /*::[*/0x03/*::]*/: 1252, /*::[*/0x04/*::]*/: 10000,
7531 /*::[*/0x64/*::]*/: 852, /*::[*/0x65/*::]*/: 866,
7532 /*::[*/0x66/*::]*/: 865, /*::[*/0x67/*::]*/: 861,
7533 /*::[*/0x68/*::]*/: 895, /*::[*/0x69/*::]*/: 620,
7534 /*::[*/0x6A/*::]*/: 737, /*::[*/0x6B/*::]*/: 857,
7535 /*::[*/0x78/*::]*/: 950, /*::[*/0x79/*::]*/: 949,
7536 /*::[*/0x7A/*::]*/: 936, /*::[*/0x7B/*::]*/: 932,
7537 /*::[*/0x7C/*::]*/: 874, /*::[*/0x7D/*::]*/: 1255,
7538 /*::[*/0x7E/*::]*/: 1256, /*::[*/0x96/*::]*/: 10007,
7539 /*::[*/0x97/*::]*/: 10029, /*::[*/0x98/*::]*/: 10006,
7540 /*::[*/0xC8/*::]*/: 1250, /*::[*/0xC9/*::]*/: 1251,
7541 /*::[*/0xCA/*::]*/: 1254, /*::[*/0xCB/*::]*/: 1253,
7542
7543 /* shapefile DBF extension */
7544 /*::[*/0x00/*::]*/: 20127, /*::[*/0x08/*::]*/: 865,
7545 /*::[*/0x09/*::]*/: 437, /*::[*/0x0A/*::]*/: 850,
7546 /*::[*/0x0B/*::]*/: 437, /*::[*/0x0D/*::]*/: 437,
7547 /*::[*/0x0E/*::]*/: 850, /*::[*/0x0F/*::]*/: 437,
7548 /*::[*/0x10/*::]*/: 850, /*::[*/0x11/*::]*/: 437,
7549 /*::[*/0x12/*::]*/: 850, /*::[*/0x13/*::]*/: 932,
7550 /*::[*/0x14/*::]*/: 850, /*::[*/0x15/*::]*/: 437,
7551 /*::[*/0x16/*::]*/: 850, /*::[*/0x17/*::]*/: 865,
7552 /*::[*/0x18/*::]*/: 437, /*::[*/0x19/*::]*/: 437,
7553 /*::[*/0x1A/*::]*/: 850, /*::[*/0x1B/*::]*/: 437,
7554 /*::[*/0x1C/*::]*/: 863, /*::[*/0x1D/*::]*/: 850,
7555 /*::[*/0x1F/*::]*/: 852, /*::[*/0x22/*::]*/: 852,
7556 /*::[*/0x23/*::]*/: 852, /*::[*/0x24/*::]*/: 860,
7557 /*::[*/0x25/*::]*/: 850, /*::[*/0x26/*::]*/: 866,
7558 /*::[*/0x37/*::]*/: 850, /*::[*/0x40/*::]*/: 852,
7559 /*::[*/0x4D/*::]*/: 936, /*::[*/0x4E/*::]*/: 949,
7560 /*::[*/0x4F/*::]*/: 950, /*::[*/0x50/*::]*/: 874,
7561 /*::[*/0x57/*::]*/: 1252, /*::[*/0x58/*::]*/: 1252,
7562 /*::[*/0x59/*::]*/: 1252, /*::[*/0x6C/*::]*/: 863,
7563 /*::[*/0x86/*::]*/: 737, /*::[*/0x87/*::]*/: 852,
7564 /*::[*/0x88/*::]*/: 857, /*::[*/0xCC/*::]*/: 1257,
7565
7566 /*::[*/0xFF/*::]*/: 16969
7567};
7568var dbf_reverse_map = evert({
7569 /*::[*/0x01/*::]*/: 437, /*::[*/0x02/*::]*/: 850,
7570 /*::[*/0x03/*::]*/: 1252, /*::[*/0x04/*::]*/: 10000,
7571 /*::[*/0x64/*::]*/: 852, /*::[*/0x65/*::]*/: 866,
7572 /*::[*/0x66/*::]*/: 865, /*::[*/0x67/*::]*/: 861,
7573 /*::[*/0x68/*::]*/: 895, /*::[*/0x69/*::]*/: 620,
7574 /*::[*/0x6A/*::]*/: 737, /*::[*/0x6B/*::]*/: 857,
7575 /*::[*/0x78/*::]*/: 950, /*::[*/0x79/*::]*/: 949,
7576 /*::[*/0x7A/*::]*/: 936, /*::[*/0x7B/*::]*/: 932,
7577 /*::[*/0x7C/*::]*/: 874, /*::[*/0x7D/*::]*/: 1255,
7578 /*::[*/0x7E/*::]*/: 1256, /*::[*/0x96/*::]*/: 10007,
7579 /*::[*/0x97/*::]*/: 10029, /*::[*/0x98/*::]*/: 10006,
7580 /*::[*/0xC8/*::]*/: 1250, /*::[*/0xC9/*::]*/: 1251,
7581 /*::[*/0xCA/*::]*/: 1254, /*::[*/0xCB/*::]*/: 1253,
7582 /*::[*/0x00/*::]*/: 20127
7583});
7584/* TODO: find an actual specification */
7585function dbf_to_aoa(buf, opts)/*:AOA*/ {
7586 var out/*:AOA*/ = [];
7587 var d/*:Block*/ = (new_raw_buf(1)/*:any*/);
7588 switch(opts.type) {
7589 case 'base64': d = s2a(Base64_decode(buf)); break;
7590 case 'binary': d = s2a(buf); break;
7591 case 'buffer':
7592 case 'array': d = buf; break;
7593 }
7594 prep_blob(d, 0);
7595
7596 /* header */
7597 var ft = d.read_shift(1);
7598 var memo = !!(ft & 0x88);
7599 var vfp = false, l7 = false;
7600 switch(ft) {
7601 case 0x02: break; // dBASE II
7602 case 0x03: break; // dBASE III
7603 case 0x30: vfp = true; memo = true; break; // VFP
7604 case 0x31: vfp = true; memo = true; break; // VFP with autoincrement
7605 // 0x43 dBASE IV SQL table files
7606 // 0x63 dBASE IV SQL system files
7607 case 0x83: break; // dBASE III with memo
7608 case 0x8B: break; // dBASE IV with memo
7609 case 0x8C: l7 = true; break; // dBASE Level 7 with memo
7610 // case 0xCB dBASE IV SQL table files with memo
7611 case 0xF5: break; // FoxPro 2.x with memo
7612 // case 0xFB FoxBASE
7613 default: throw new Error("DBF Unsupported Version: " + ft.toString(16));
7614 }
7615
7616 var nrow = 0, fpos = 0x0209;
7617 if(ft == 0x02) nrow = d.read_shift(2);
7618 d.l += 3; // dBASE II stores DDMMYY date, others use YYMMDD
7619 if(ft != 0x02) nrow = d.read_shift(4);
7620 if(nrow > 1048576) nrow = 1e6;
7621
7622 if(ft != 0x02) fpos = d.read_shift(2); // header length
7623 var rlen = d.read_shift(2); // record length
7624
7625 var /*flags = 0,*/ current_cp = opts.codepage || 1252;
7626 if(ft != 0x02) { // 20 reserved bytes
7627 d.l+=16;
7628 /*flags = */d.read_shift(1);
7629 //if(memo && ((flags & 0x02) === 0)) throw new Error("DBF Flags " + flags.toString(16) + " ft " + ft.toString(16));
7630
7631 /* codepage present in FoxPro and dBASE Level 7 */
7632 if(d[d.l] !== 0) current_cp = dbf_codepage_map[d[d.l]];
7633 d.l+=1;
7634
7635 d.l+=2;
7636 }
7637 if(l7) d.l += 36; // Level 7: 32 byte "Language driver name", 4 byte reserved
7638
7639/*:: type DBFField = { name:string; len:number; type:string; } */
7640 var fields/*:Array<DBFField>*/ = [], field/*:DBFField*/ = ({}/*:any*/);
7641 var hend = Math.min(d.length, (ft == 0x02 ? 0x209 : (fpos - 10 - (vfp ? 264 : 0))));
7642 var ww = l7 ? 32 : 11;
7643 while(d.l < hend && d[d.l] != 0x0d) {
7644 field = ({}/*:any*/);
7645 field.name = $cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)).replace(/[\u0000\r\n].*$/g,"");
7646 d.l += ww;
7647 field.type = String.fromCharCode(d.read_shift(1));
7648 if(ft != 0x02 && !l7) field.offset = d.read_shift(4);
7649 field.len = d.read_shift(1);
7650 if(ft == 0x02) field.offset = d.read_shift(2);
7651 field.dec = d.read_shift(1);
7652 if(field.name.length) fields.push(field);
7653 if(ft != 0x02) d.l += l7 ? 13 : 14;
7654 switch(field.type) {
7655 case 'B': // Double (VFP) / Binary (dBASE L7)
7656 if((!vfp || field.len != 8) && opts.WTF) console.log('Skipping ' + field.name + ':' + field.type);
7657 break;
7658 case 'G': // General (FoxPro and dBASE L7)
7659 case 'P': // Picture (FoxPro and dBASE L7)
7660 if(opts.WTF) console.log('Skipping ' + field.name + ':' + field.type);
7661 break;
7662 case '+': // Autoincrement (dBASE L7 only)
7663 case '0': // _NullFlags (VFP only)
7664 case '@': // Timestamp (dBASE L7 only)
7665 case 'C': // Character (dBASE II)
7666 case 'D': // Date (dBASE III)
7667 case 'F': // Float (dBASE IV)
7668 case 'I': // Long (VFP and dBASE L7)
7669 case 'L': // Logical (dBASE II)
7670 case 'M': // Memo (dBASE III)
7671 case 'N': // Number (dBASE II)
7672 case 'O': // Double (dBASE L7 only)
7673 case 'T': // Datetime (VFP only)
7674 case 'Y': // Currency (VFP only)
7675 break;
7676 default: throw new Error('Unknown Field Type: ' + field.type);
7677 }
7678 }
7679
7680 if(d[d.l] !== 0x0D) d.l = fpos-1;
7681 if(d.read_shift(1) !== 0x0D) throw new Error("DBF Terminator not found " + d.l + " " + d[d.l]);
7682 d.l = fpos;
7683
7684 /* data */
7685 var R = 0, C = 0;
7686 out[0] = [];
7687 for(C = 0; C != fields.length; ++C) out[0][C] = fields[C].name;
7688 while(nrow-- > 0) {
7689 if(d[d.l] === 0x2A) {
7690 // TODO: record marked as deleted -- create a hidden row?
7691 d.l+=rlen;
7692 continue;
7693 }
7694 ++d.l;
7695 out[++R] = []; C = 0;
7696 for(C = 0; C != fields.length; ++C) {
7697 var dd = d.slice(d.l, d.l+fields[C].len); d.l+=fields[C].len;
7698 prep_blob(dd, 0);
7699 var s = $cptable.utils.decode(current_cp, dd);
7700 switch(fields[C].type) {
7701 case 'C':
7702 // NOTE: it is conventional to write ' / / ' for empty dates
7703 if(s.trim().length) out[R][C] = s.replace(/\s+$/,"");
7704 break;
7705 case 'D':
7706 if(s.length === 8) out[R][C] = new Date(+s.slice(0,4), +s.slice(4,6)-1, +s.slice(6,8));
7707 else out[R][C] = s;
7708 break;
7709 case 'F': out[R][C] = parseFloat(s.trim()); break;
7710 case '+': case 'I': out[R][C] = l7 ? dd.read_shift(-4, 'i') ^ 0x80000000 : dd.read_shift(4, 'i'); break;
7711 case 'L': switch(s.trim().toUpperCase()) {
7712 case 'Y': case 'T': out[R][C] = true; break;
7713 case 'N': case 'F': out[R][C] = false; break;
7714 case '': case '?': break;
7715 default: throw new Error("DBF Unrecognized L:|" + s + "|");
7716 } break;
7717 case 'M': /* TODO: handle memo files */
7718 if(!memo) throw new Error("DBF Unexpected MEMO for type " + ft.toString(16));
7719 out[R][C] = "##MEMO##" + (l7 ? parseInt(s.trim(), 10): dd.read_shift(4));
7720 break;
7721 case 'N':
7722 s = s.replace(/\u0000/g,"").trim();
7723 // NOTE: dBASE II interprets " . " as 0
7724 if(s && s != ".") out[R][C] = +s || 0; break;
7725 case '@':
7726 // NOTE: dBASE specs appear to be incorrect
7727 out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400);
7728 break;
7729 case 'T': out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4)); break;
7730 case 'Y': out[R][C] = dd.read_shift(4,'i')/1e4 + (dd.read_shift(4, 'i')/1e4)*Math.pow(2,32); break;
7731 case 'O': out[R][C] = -dd.read_shift(-8, 'f'); break;
7732 case 'B': if(vfp && fields[C].len == 8) { out[R][C] = dd.read_shift(8,'f'); break; }
7733 /* falls through */
7734 case 'G': case 'P': dd.l += fields[C].len; break;
7735 case '0':
7736 if(fields[C].name === '_NullFlags') break;
7737 /* falls through */
7738 default: throw new Error("DBF Unsupported data type " + fields[C].type);
7739 }
7740 }
7741 }
7742 if(ft != 0x02) if(d.l < d.length && d[d.l++] != 0x1A) throw new Error("DBF EOF Marker missing " + (d.l-1) + " of " + d.length + " " + d[d.l-1].toString(16));
7743 if(opts && opts.sheetRows) out = out.slice(0, opts.sheetRows);
7744 opts.DBF = fields;
7745 return out;
7746}
7747
7748function dbf_to_sheet(buf, opts)/*:Worksheet*/ {
7749 var o = opts || {};
7750 if(!o.dateNF) o.dateNF = "yyyymmdd";
7751 var ws = aoa_to_sheet(dbf_to_aoa(buf, o), o);
7752 ws["!cols"] = o.DBF.map(function(field) { return {
7753 wch: field.len,
7754 DBF: field
7755 };});
7756 delete o.DBF;
7757 return ws;
7758}
7759
7760function dbf_to_workbook(buf, opts)/*:Workbook*/ {
7761 try { return sheet_to_workbook(dbf_to_sheet(buf, opts), opts); }
7762 catch(e) { if(opts && opts.WTF) throw e; }
7763 return ({SheetNames:[],Sheets:{}});
7764}
7765
7766var _RLEN = { 'B': 8, 'C': 250, 'L': 1, 'D': 8, '?': 0, '': 0 };
7767function sheet_to_dbf(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
7768 var o = opts || {};
7769 if(+o.codepage >= 0) set_cp(+o.codepage);
7770 if(o.type == "string") throw new Error("Cannot write DBF to JS string");
7771 var ba = buf_array();
7772 var aoa/*:AOA*/ = sheet_to_json(ws, {header:1, raw:true, cellDates:true});
7773 var headers = aoa[0], data = aoa.slice(1), cols = ws["!cols"] || [];
7774 var i = 0, j = 0, hcnt = 0, rlen = 1;
7775 for(i = 0; i < headers.length; ++i) {
7776 if(((cols[i]||{}).DBF||{}).name) { headers[i] = cols[i].DBF.name; ++hcnt; continue; }
7777 if(headers[i] == null) continue;
7778 ++hcnt;
7779 if(typeof headers[i] === 'number') headers[i] = headers[i].toString(10);
7780 if(typeof headers[i] !== 'string') throw new Error("DBF Invalid column name " + headers[i] + " |" + (typeof headers[i]) + "|");
7781 if(headers.indexOf(headers[i]) !== i) for(j=0; j<1024;++j)
7782 if(headers.indexOf(headers[i] + "_" + j) == -1) { headers[i] += "_" + j; break; }
7783 }
7784 var range = safe_decode_range(ws['!ref']);
7785 var coltypes/*:Array<string>*/ = [];
7786 var colwidths/*:Array<number>*/ = [];
7787 var coldecimals/*:Array<number>*/ = [];
7788 for(i = 0; i <= range.e.c - range.s.c; ++i) {
7789 var guess = '', _guess = '', maxlen = 0;
7790 var col/*:Array<any>*/ = [];
7791 for(j=0; j < data.length; ++j) {
7792 if(data[j][i] != null) col.push(data[j][i]);
7793 }
7794 if(col.length == 0 || headers[i] == null) { coltypes[i] = '?'; continue; }
7795 for(j = 0; j < col.length; ++j) {
7796 switch(typeof col[j]) {
7797 /* TODO: check if L2 compat is desired */
7798 case 'number': _guess = 'B'; break;
7799 case 'string': _guess = 'C'; break;
7800 case 'boolean': _guess = 'L'; break;
7801 case 'object': _guess = col[j] instanceof Date ? 'D' : 'C'; break;
7802 default: _guess = 'C';
7803 }
7804 maxlen = Math.max(maxlen, String(col[j]).length);
7805 guess = guess && guess != _guess ? 'C' : _guess;
7806 //if(guess == 'C') break;
7807 }
7808 if(maxlen > 250) maxlen = 250;
7809 _guess = ((cols[i]||{}).DBF||{}).type;
7810 /* TODO: more fine grained control over DBF type resolution */
7811 if(_guess == 'C') {
7812 if(cols[i].DBF.len > maxlen) maxlen = cols[i].DBF.len;
7813 }
7814 if(guess == 'B' && _guess == 'N') {
7815 guess = 'N';
7816 coldecimals[i] = cols[i].DBF.dec;
7817 maxlen = cols[i].DBF.len;
7818 }
7819 colwidths[i] = guess == 'C' || _guess == 'N' ? maxlen : (_RLEN[guess] || 0);
7820 rlen += colwidths[i];
7821 coltypes[i] = guess;
7822 }
7823
7824 var h = ba.next(32);
7825 h.write_shift(4, 0x13021130);
7826 h.write_shift(4, data.length);
7827 h.write_shift(2, 296 + 32 * hcnt);
7828 h.write_shift(2, rlen);
7829 for(i=0; i < 4; ++i) h.write_shift(4, 0);
7830 h.write_shift(4, 0x00000000 | ((+dbf_reverse_map[/*::String(*/current_ansi/*::)*/] || 0x03)<<8));
7831
7832 for(i = 0, j = 0; i < headers.length; ++i) {
7833 if(headers[i] == null) continue;
7834 var hf = ba.next(32);
7835 var _f = (headers[i].slice(-10) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00").slice(0, 11);
7836 hf.write_shift(1, _f, "sbcs");
7837 hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs");
7838 hf.write_shift(4, j);
7839 hf.write_shift(1, colwidths[i] || _RLEN[coltypes[i]] || 0);
7840 hf.write_shift(1, coldecimals[i] || 0);
7841 hf.write_shift(1, 0x02);
7842 hf.write_shift(4, 0);
7843 hf.write_shift(1, 0);
7844 hf.write_shift(4, 0);
7845 hf.write_shift(4, 0);
7846 j += (colwidths[i] || _RLEN[coltypes[i]] || 0);
7847 }
7848
7849 var hb = ba.next(264);
7850 hb.write_shift(4, 0x0000000D);
7851 for(i=0; i < 65;++i) hb.write_shift(4, 0x00000000);
7852 for(i=0; i < data.length; ++i) {
7853 var rout = ba.next(rlen);
7854 rout.write_shift(1, 0);
7855 for(j=0; j<headers.length; ++j) {
7856 if(headers[j] == null) continue;
7857 switch(coltypes[j]) {
7858 case 'L': rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46); break;
7859 case 'B': rout.write_shift(8, data[i][j]||0, 'f'); break;
7860 case 'N':
7861 var _n = "0";
7862 if(typeof data[i][j] == "number") _n = data[i][j].toFixed(coldecimals[j]||0);
7863 for(hcnt=0; hcnt < colwidths[j]-_n.length; ++hcnt) rout.write_shift(1, 0x20);
7864 rout.write_shift(1, _n, "sbcs");
7865 break;
7866 case 'D':
7867 if(!data[i][j]) rout.write_shift(8, "00000000", "sbcs");
7868 else {
7869 rout.write_shift(4, ("0000"+data[i][j].getFullYear()).slice(-4), "sbcs");
7870 rout.write_shift(2, ("00"+(data[i][j].getMonth()+1)).slice(-2), "sbcs");
7871 rout.write_shift(2, ("00"+data[i][j].getDate()).slice(-2), "sbcs");
7872 } break;
7873 case 'C':
7874 var _s = String(data[i][j] != null ? data[i][j] : "").slice(0, colwidths[j]);
7875 rout.write_shift(1, _s, "sbcs");
7876 for(hcnt=0; hcnt < colwidths[j]-_s.length; ++hcnt) rout.write_shift(1, 0x20); break;
7877 }
7878 }
7879 // data
7880 }
7881 ba.next(1).write_shift(1, 0x1A);
7882 return ba.end();
7883}
7884 return {
7885 to_workbook: dbf_to_workbook,
7886 to_sheet: dbf_to_sheet,
7887 from_sheet: sheet_to_dbf
7888 };
7889})();
7890
7891var SYLK = /*#__PURE__*/(function() {
7892 /* TODO: stress test sequences */
7893 var sylk_escapes = ({
7894 AA:'À', BA:'Á', CA:'Â', DA:195, HA:'Ä', JA:197,
7895 AE:'È', BE:'É', CE:'Ê', HE:'Ë',
7896 AI:'Ì', BI:'Í', CI:'Î', HI:'Ï',
7897 AO:'Ò', BO:'Ó', CO:'Ô', DO:213, HO:'Ö',
7898 AU:'Ù', BU:'Ú', CU:'Û', HU:'Ü',
7899 Aa:'à', Ba:'á', Ca:'â', Da:227, Ha:'ä', Ja:229,
7900 Ae:'è', Be:'é', Ce:'ê', He:'ë',
7901 Ai:'ì', Bi:'í', Ci:'î', Hi:'ï',
7902 Ao:'ò', Bo:'ó', Co:'ô', Do:245, Ho:'ö',
7903 Au:'ù', Bu:'ú', Cu:'û', Hu:'ü',
7904 KC:'Ç', Kc:'ç', q:'æ', z:'œ', a:'Æ', j:'Œ',
7905 DN:209, Dn:241, Hy:255,
7906 S:169, c:170, R:174, "B ":180,
7907 /*::[*/0/*::]*/:176, /*::[*/1/*::]*/:177, /*::[*/2/*::]*/:178,
7908 /*::[*/3/*::]*/:179, /*::[*/5/*::]*/:181, /*::[*/6/*::]*/:182,
7909 /*::[*/7/*::]*/:183, Q:185, k:186, b:208, i:216, l:222, s:240, y:248,
7910 "!":161, '"':162, "#":163, "(":164, "%":165, "'":167, "H ":168,
7911 "+":171, ";":187, "<":188, "=":189, ">":190, "?":191, "{":223
7912 }/*:any*/);
7913 var sylk_char_regex = new RegExp("\u001BN(" + keys(sylk_escapes).join("|").replace(/\|\|\|/, "|\\||").replace(/([?()+])/g,"\\$1") + "|\\|)", "gm");
7914 var sylk_char_fn = function(_, $1){ var o = sylk_escapes[$1]; return typeof o == "number" ? _getansi(o) : o; };
7915 var decode_sylk_char = function($$, $1, $2) { var newcc = (($1.charCodeAt(0) - 0x20)<<4) | ($2.charCodeAt(0) - 0x30); return newcc == 59 ? $$ : _getansi(newcc); };
7916 sylk_escapes["|"] = 254;
7917 /* TODO: find an actual specification */
7918 function sylk_to_aoa(d/*:RawData*/, opts)/*:[AOA, Worksheet]*/ {
7919 switch(opts.type) {
7920 case 'base64': return sylk_to_aoa_str(Base64_decode(d), opts);
7921 case 'binary': return sylk_to_aoa_str(d, opts);
7922 case 'buffer': return sylk_to_aoa_str(has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d), opts);
7923 case 'array': return sylk_to_aoa_str(cc2str(d), opts);
7924 }
7925 throw new Error("Unrecognized type " + opts.type);
7926 }
7927 function sylk_to_aoa_str(str/*:string*/, opts)/*:[AOA, Worksheet]*/ {
7928 var records = str.split(/[\n\r]+/), R = -1, C = -1, ri = 0, rj = 0, arr/*:AOA*/ = [];
7929 var formats/*:Array<string>*/ = [];
7930 var next_cell_format/*:string|null*/ = null;
7931 var sht = {}, rowinfo/*:Array<RowInfo>*/ = [], colinfo/*:Array<ColInfo>*/ = [], cw/*:Array<string>*/ = [];
7932 var Mval = 0, j;
7933 if(+opts.codepage >= 0) set_cp(+opts.codepage);
7934 for (; ri !== records.length; ++ri) {
7935 Mval = 0;
7936 var rstr=records[ri].trim().replace(/\x1B([\x20-\x2F])([\x30-\x3F])/g, decode_sylk_char).replace(sylk_char_regex, sylk_char_fn);
7937 var record=rstr.replace(/;;/g, "\u0000").split(";").map(function(x) { return x.replace(/\u0000/g, ";"); });
7938 var RT=record[0], val;
7939 if(rstr.length > 0) switch(RT) {
7940 case 'ID': break; /* header */
7941 case 'E': break; /* EOF */
7942 case 'B': break; /* dimensions */
7943 case 'O': break; /* options? */
7944 case 'W': break; /* window? */
7945 case 'P':
7946 if(record[1].charAt(0) == 'P')
7947 formats.push(rstr.slice(3).replace(/;;/g, ";"));
7948 break;
7949 case 'C':
7950 var C_seen_K = false, C_seen_X = false, C_seen_S = false, C_seen_E = false, _R = -1, _C = -1;
7951 for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
7952 case 'A': break; // TODO: comment
7953 case 'X': C = parseInt(record[rj].slice(1))-1; C_seen_X = true; break;
7954 case 'Y':
7955 R = parseInt(record[rj].slice(1))-1; if(!C_seen_X) C = 0;
7956 for(j = arr.length; j <= R; ++j) arr[j] = [];
7957 break;
7958 case 'K':
7959 val = record[rj].slice(1);
7960 if(val.charAt(0) === '"') val = val.slice(1,val.length - 1);
7961 else if(val === 'TRUE') val = true;
7962 else if(val === 'FALSE') val = false;
7963 else if(!isNaN(fuzzynum(val))) {
7964 val = fuzzynum(val);
7965 if(next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(val);
7966 } else if(!isNaN(fuzzydate(val).getDate())) {
7967 val = parseDate(val);
7968 }
7969 if(typeof $cptable !== 'undefined' && typeof val == "string" && ((opts||{}).type != "string") && (opts||{}).codepage) val = $cptable.utils.decode(opts.codepage, val);
7970 C_seen_K = true;
7971 break;
7972 case 'E':
7973 C_seen_E = true;
7974 var formula = rc_to_a1(record[rj].slice(1), {r:R,c:C});
7975 arr[R][C] = [arr[R][C], formula];
7976 break;
7977 case 'S':
7978 C_seen_S = true;
7979 arr[R][C] = [arr[R][C], "S5S"];
7980 break;
7981 case 'G': break; // unknown
7982 case 'R': _R = parseInt(record[rj].slice(1))-1; break;
7983 case 'C': _C = parseInt(record[rj].slice(1))-1; break;
7984 default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
7985 }
7986 if(C_seen_K) {
7987 if(arr[R][C] && arr[R][C].length == 2) arr[R][C][0] = val;
7988 else arr[R][C] = val;
7989 next_cell_format = null;
7990 }
7991 if(C_seen_S) {
7992 if(C_seen_E) throw new Error("SYLK shared formula cannot have own formula");
7993 var shrbase = _R > -1 && arr[_R][_C];
7994 if(!shrbase || !shrbase[1]) throw new Error("SYLK shared formula cannot find base");
7995 arr[R][C][1] = shift_formula_str(shrbase[1], {r: R - _R, c: C - _C});
7996 }
7997 break;
7998 case 'F':
7999 var F_seen = 0;
8000 for(rj=1; rj<record.length; ++rj) switch(record[rj].charAt(0)) {
8001 case 'X': C = parseInt(record[rj].slice(1))-1; ++F_seen; break;
8002 case 'Y':
8003 R = parseInt(record[rj].slice(1))-1; /*C = 0;*/
8004 for(j = arr.length; j <= R; ++j) arr[j] = [];
8005 break;
8006 case 'M': Mval = parseInt(record[rj].slice(1)) / 20; break;
8007 case 'F': break; /* ??? */
8008 case 'G': break; /* hide grid */
8009 case 'P':
8010 next_cell_format = formats[parseInt(record[rj].slice(1))];
8011 break;
8012 case 'S': break; /* cell style */
8013 case 'D': break; /* column */
8014 case 'N': break; /* font */
8015 case 'W':
8016 cw = record[rj].slice(1).split(" ");
8017 for(j = parseInt(cw[0], 10); j <= parseInt(cw[1], 10); ++j) {
8018 Mval = parseInt(cw[2], 10);
8019 colinfo[j-1] = Mval === 0 ? {hidden:true}: {wch:Mval}; process_col(colinfo[j-1]);
8020 } break;
8021 case 'C': /* default column format */
8022 C = parseInt(record[rj].slice(1))-1;
8023 if(!colinfo[C]) colinfo[C] = {};
8024 break;
8025 case 'R': /* row properties */
8026 R = parseInt(record[rj].slice(1))-1;
8027 if(!rowinfo[R]) rowinfo[R] = {};
8028 if(Mval > 0) { rowinfo[R].hpt = Mval; rowinfo[R].hpx = pt2px(Mval); }
8029 else if(Mval === 0) rowinfo[R].hidden = true;
8030 break;
8031 default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
8032 }
8033 if(F_seen < 1) next_cell_format = null; break;
8034 default: if(opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
8035 }
8036 }
8037 if(rowinfo.length > 0) sht['!rows'] = rowinfo;
8038 if(colinfo.length > 0) sht['!cols'] = colinfo;
8039 if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
8040 return [arr, sht];
8041 }
8042
8043 function sylk_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
8044 var aoasht = sylk_to_aoa(d, opts);
8045 var aoa = aoasht[0], ws = aoasht[1];
8046 var o = aoa_to_sheet(aoa, opts);
8047 keys(ws).forEach(function(k) { o[k] = ws[k]; });
8048 return o;
8049 }
8050
8051 function sylk_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(sylk_to_sheet(d, opts), opts); }
8052
8053 function write_ws_cell_sylk(cell/*:Cell*/, ws/*:Worksheet*/, R/*:number*/, C/*:number*//*::, opts*/)/*:string*/ {
8054 var o = "C;Y" + (R+1) + ";X" + (C+1) + ";K";
8055 switch(cell.t) {
8056 case 'n':
8057 o += (cell.v||0);
8058 if(cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {r:R, c:C}); break;
8059 case 'b': o += cell.v ? "TRUE" : "FALSE"; break;
8060 case 'e': o += cell.w || cell.v; break;
8061 case 'd': o += '"' + (cell.w || cell.v) + '"'; break;
8062 case 's': o += '"' + cell.v.replace(/"/g,"").replace(/;/g, ";;") + '"'; break;
8063 }
8064 return o;
8065 }
8066
8067 function write_ws_cols_sylk(out, cols) {
8068 cols.forEach(function(col, i) {
8069 var rec = "F;W" + (i+1) + " " + (i+1) + " ";
8070 if(col.hidden) rec += "0";
8071 else {
8072 if(typeof col.width == 'number' && !col.wpx) col.wpx = width2px(col.width);
8073 if(typeof col.wpx == 'number' && !col.wch) col.wch = px2char(col.wpx);
8074 if(typeof col.wch == 'number') rec += Math.round(col.wch);
8075 }
8076 if(rec.charAt(rec.length - 1) != " ") out.push(rec);
8077 });
8078 }
8079
8080 function write_ws_rows_sylk(out/*:Array<string>*/, rows/*:Array<RowInfo>*/) {
8081 rows.forEach(function(row, i) {
8082 var rec = "F;";
8083 if(row.hidden) rec += "M0;";
8084 else if(row.hpt) rec += "M" + 20 * row.hpt + ";";
8085 else if(row.hpx) rec += "M" + 20 * px2pt(row.hpx) + ";";
8086 if(rec.length > 2) out.push(rec + "R" + (i+1));
8087 });
8088 }
8089
8090 function sheet_to_sylk(ws/*:Worksheet*/, opts/*:?any*/)/*:string*/ {
8091 var preamble/*:Array<string>*/ = ["ID;PWXL;N;E"], o/*:Array<string>*/ = [];
8092 var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
8093 var dense = Array.isArray(ws);
8094 var RS = "\r\n";
8095
8096 preamble.push("P;PGeneral");
8097 preamble.push("F;P0;DG0G8;M255");
8098 if(ws['!cols']) write_ws_cols_sylk(preamble, ws['!cols']);
8099 if(ws['!rows']) write_ws_rows_sylk(preamble, ws['!rows']);
8100
8101 preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c,r.s.r,r.e.c,r.e.r].join(" "));
8102 for(var R = r.s.r; R <= r.e.r; ++R) {
8103 for(var C = r.s.c; C <= r.e.c; ++C) {
8104 var coord = encode_cell({r:R,c:C});
8105 cell = dense ? (ws[R]||[])[C]: ws[coord];
8106 if(!cell || (cell.v == null && (!cell.f || cell.F))) continue;
8107 o.push(write_ws_cell_sylk(cell, ws, R, C, opts));
8108 }
8109 }
8110 return preamble.join(RS) + RS + o.join(RS) + RS + "E" + RS;
8111 }
8112
8113 return {
8114 to_workbook: sylk_to_workbook,
8115 to_sheet: sylk_to_sheet,
8116 from_sheet: sheet_to_sylk
8117 };
8118})();
8119
8120var DIF = /*#__PURE__*/(function() {
8121 function dif_to_aoa(d/*:RawData*/, opts)/*:AOA*/ {
8122 switch(opts.type) {
8123 case 'base64': return dif_to_aoa_str(Base64_decode(d), opts);
8124 case 'binary': return dif_to_aoa_str(d, opts);
8125 case 'buffer': return dif_to_aoa_str(has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d), opts);
8126 case 'array': return dif_to_aoa_str(cc2str(d), opts);
8127 }
8128 throw new Error("Unrecognized type " + opts.type);
8129 }
8130 function dif_to_aoa_str(str/*:string*/, opts)/*:AOA*/ {
8131 var records = str.split('\n'), R = -1, C = -1, ri = 0, arr/*:AOA*/ = [];
8132 for (; ri !== records.length; ++ri) {
8133 if (records[ri].trim() === 'BOT') { arr[++R] = []; C = 0; continue; }
8134 if (R < 0) continue;
8135 var metadata = records[ri].trim().split(",");
8136 var type = metadata[0], value = metadata[1];
8137 ++ri;
8138 var data = records[ri] || "";
8139 while(((data.match(/["]/g)||[]).length & 1) && ri < records.length - 1) data += "\n" + records[++ri];
8140 data = data.trim();
8141 switch (+type) {
8142 case -1:
8143 if (data === 'BOT') { arr[++R] = []; C = 0; continue; }
8144 else if (data !== 'EOD') throw new Error("Unrecognized DIF special command " + data);
8145 break;
8146 case 0:
8147 if(data === 'TRUE') arr[R][C] = true;
8148 else if(data === 'FALSE') arr[R][C] = false;
8149 else if(!isNaN(fuzzynum(value))) arr[R][C] = fuzzynum(value);
8150 else if(!isNaN(fuzzydate(value).getDate())) arr[R][C] = parseDate(value);
8151 else arr[R][C] = value;
8152 ++C; break;
8153 case 1:
8154 data = data.slice(1,data.length-1);
8155 data = data.replace(/""/g, '"');
8156 if(DIF_XL && data && data.match(/^=".*"$/)) data = data.slice(2, -1);
8157 arr[R][C++] = data !== '' ? data : null;
8158 break;
8159 }
8160 if (data === 'EOD') break;
8161 }
8162 if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
8163 return arr;
8164 }
8165
8166 function dif_to_sheet(str/*:string*/, opts)/*:Worksheet*/ { return aoa_to_sheet(dif_to_aoa(str, opts), opts); }
8167 function dif_to_workbook(str/*:string*/, opts)/*:Workbook*/ { return sheet_to_workbook(dif_to_sheet(str, opts), opts); }
8168
8169 var sheet_to_dif = /*#__PURE__*/(function() {
8170 var push_field = function pf(o/*:Array<string>*/, topic/*:string*/, v/*:number*/, n/*:number*/, s/*:string*/) {
8171 o.push(topic);
8172 o.push(v + "," + n);
8173 o.push('"' + s.replace(/"/g,'""') + '"');
8174 };
8175 var push_value = function po(o/*:Array<string>*/, type/*:number*/, v/*:any*/, s/*:string*/) {
8176 o.push(type + "," + v);
8177 o.push(type == 1 ? '"' + s.replace(/"/g,'""') + '"' : s);
8178 };
8179 return function sheet_to_dif(ws/*:Worksheet*//*::, opts:?any*/)/*:string*/ {
8180 var o/*:Array<string>*/ = [];
8181 var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
8182 var dense = Array.isArray(ws);
8183 push_field(o, "TABLE", 0, 1, "sheetjs");
8184 push_field(o, "VECTORS", 0, r.e.r - r.s.r + 1,"");
8185 push_field(o, "TUPLES", 0, r.e.c - r.s.c + 1,"");
8186 push_field(o, "DATA", 0, 0,"");
8187 for(var R = r.s.r; R <= r.e.r; ++R) {
8188 push_value(o, -1, 0, "BOT");
8189 for(var C = r.s.c; C <= r.e.c; ++C) {
8190 var coord = encode_cell({r:R,c:C});
8191 cell = dense ? (ws[R]||[])[C] : ws[coord];
8192 if(!cell) { push_value(o, 1, 0, ""); continue;}
8193 switch(cell.t) {
8194 case 'n':
8195 var val = DIF_XL ? cell.w : cell.v;
8196 if(!val && cell.v != null) val = cell.v;
8197 if(val == null) {
8198 if(DIF_XL && cell.f && !cell.F) push_value(o, 1, 0, "=" + cell.f);
8199 else push_value(o, 1, 0, "");
8200 }
8201 else push_value(o, 0, val, "V");
8202 break;
8203 case 'b':
8204 push_value(o, 0, cell.v ? 1 : 0, cell.v ? "TRUE" : "FALSE");
8205 break;
8206 case 's':
8207 push_value(o, 1, 0, (!DIF_XL || isNaN(cell.v)) ? cell.v : '="' + cell.v + '"');
8208 break;
8209 case 'd':
8210 if(!cell.w) cell.w = SSF_format(cell.z || table_fmt[14], datenum(parseDate(cell.v)));
8211 if(DIF_XL) push_value(o, 0, cell.w, "V");
8212 else push_value(o, 1, 0, cell.w);
8213 break;
8214 default: push_value(o, 1, 0, "");
8215 }
8216 }
8217 }
8218 push_value(o, -1, 0, "EOD");
8219 var RS = "\r\n";
8220 var oo = o.join(RS);
8221 //while((oo.length & 0x7F) != 0) oo += "\0";
8222 return oo;
8223 };
8224 })();
8225 return {
8226 to_workbook: dif_to_workbook,
8227 to_sheet: dif_to_sheet,
8228 from_sheet: sheet_to_dif
8229 };
8230})();
8231
8232var ETH = /*#__PURE__*/(function() {
8233 function decode(s/*:string*/)/*:string*/ { return s.replace(/\\b/g,"\\").replace(/\\c/g,":").replace(/\\n/g,"\n"); }
8234 function encode(s/*:string*/)/*:string*/ { return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g,"\\n"); }
8235
8236 function eth_to_aoa(str/*:string*/, opts)/*:AOA*/ {
8237 var records = str.split('\n'), R = -1, C = -1, ri = 0, arr/*:AOA*/ = [];
8238 for (; ri !== records.length; ++ri) {
8239 var record = records[ri].trim().split(":");
8240 if(record[0] !== 'cell') continue;
8241 var addr = decode_cell(record[1]);
8242 if(arr.length <= addr.r) for(R = arr.length; R <= addr.r; ++R) if(!arr[R]) arr[R] = [];
8243 R = addr.r; C = addr.c;
8244 switch(record[2]) {
8245 case 't': arr[R][C] = decode(record[3]); break;
8246 case 'v': arr[R][C] = +record[3]; break;
8247 case 'vtf': var _f = record[record.length - 1];
8248 /* falls through */
8249 case 'vtc':
8250 switch(record[3]) {
8251 case 'nl': arr[R][C] = +record[4] ? true : false; break;
8252 default: arr[R][C] = +record[4]; break;
8253 }
8254 if(record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
8255 }
8256 }
8257 if(opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
8258 return arr;
8259 }
8260
8261 function eth_to_sheet(d/*:string*/, opts)/*:Worksheet*/ { return aoa_to_sheet(eth_to_aoa(d, opts), opts); }
8262 function eth_to_workbook(d/*:string*/, opts)/*:Workbook*/ { return sheet_to_workbook(eth_to_sheet(d, opts), opts); }
8263
8264 var header = [
8265 "socialcalc:version:1.5",
8266 "MIME-Version: 1.0",
8267 "Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave"
8268 ].join("\n");
8269
8270 var sep = [
8271 "--SocialCalcSpreadsheetControlSave",
8272 "Content-type: text/plain; charset=UTF-8"
8273 ].join("\n") + "\n";
8274
8275 /* TODO: the other parts */
8276 var meta = [
8277 "# SocialCalc Spreadsheet Control Save",
8278 "part:sheet"
8279 ].join("\n");
8280
8281 var end = "--SocialCalcSpreadsheetControlSave--";
8282
8283 function sheet_to_eth_data(ws/*:Worksheet*/)/*:string*/ {
8284 if(!ws || !ws['!ref']) return "";
8285 var o/*:Array<string>*/ = [], oo/*:Array<string>*/ = [], cell, coord = "";
8286 var r = decode_range(ws['!ref']);
8287 var dense = Array.isArray(ws);
8288 for(var R = r.s.r; R <= r.e.r; ++R) {
8289 for(var C = r.s.c; C <= r.e.c; ++C) {
8290 coord = encode_cell({r:R,c:C});
8291 cell = dense ? (ws[R]||[])[C] : ws[coord];
8292 if(!cell || cell.v == null || cell.t === 'z') continue;
8293 oo = ["cell", coord, 't'];
8294 switch(cell.t) {
8295 case 's': case 'str': oo.push(encode(cell.v)); break;
8296 case 'n':
8297 if(!cell.f) { oo[2]='v'; oo[3]=cell.v; }
8298 else { oo[2]='vtf'; oo[3]='n'; oo[4]=cell.v; oo[5]=encode(cell.f); }
8299 break;
8300 case 'b':
8301 oo[2] = 'vt'+(cell.f?'f':'c'); oo[3]='nl'; oo[4]=cell.v?"1":"0";
8302 oo[5] = encode(cell.f||(cell.v?'TRUE':'FALSE'));
8303 break;
8304 case 'd':
8305 var t = datenum(parseDate(cell.v));
8306 oo[2] = 'vtc'; oo[3] = 'nd'; oo[4] = ""+t;
8307 oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
8308 break;
8309 case 'e': continue;
8310 }
8311 o.push(oo.join(":"));
8312 }
8313 }
8314 o.push("sheet:c:" + (r.e.c-r.s.c+1) + ":r:" + (r.e.r-r.s.r+1) + ":tvf:1");
8315 o.push("valueformat:1:text-wiki");
8316 //o.push("copiedfrom:" + ws['!ref']); // clipboard only
8317 return o.join("\n");
8318 }
8319
8320 function sheet_to_eth(ws/*:Worksheet*//*::, opts:?any*/)/*:string*/ {
8321 return [header, sep, meta, sep, sheet_to_eth_data(ws), end].join("\n");
8322 // return ["version:1.5", sheet_to_eth_data(ws)].join("\n"); // clipboard form
8323 }
8324
8325 return {
8326 to_workbook: eth_to_workbook,
8327 to_sheet: eth_to_sheet,
8328 from_sheet: sheet_to_eth
8329 };
8330})();
8331
8332var PRN = /*#__PURE__*/(function() {
8333 function set_text_arr(data/*:string*/, arr/*:AOA*/, R/*:number*/, C/*:number*/, o/*:any*/) {
8334 if(o.raw) arr[R][C] = data;
8335 else if(data === ""){/* empty */}
8336 else if(data === 'TRUE') arr[R][C] = true;
8337 else if(data === 'FALSE') arr[R][C] = false;
8338 else if(!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);
8339 else if(!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);
8340 else arr[R][C] = data;
8341 }
8342
8343 function prn_to_aoa_str(f/*:string*/, opts)/*:AOA*/ {
8344 var o = opts || {};
8345 var arr/*:AOA*/ = ([]/*:any*/);
8346 if(!f || f.length === 0) return arr;
8347 var lines = f.split(/[\r\n]/);
8348 var L = lines.length - 1;
8349 while(L >= 0 && lines[L].length === 0) --L;
8350 var start = 10, idx = 0;
8351 var R = 0;
8352 for(; R <= L; ++R) {
8353 idx = lines[R].indexOf(" ");
8354 if(idx == -1) idx = lines[R].length; else idx++;
8355 start = Math.max(start, idx);
8356 }
8357 for(R = 0; R <= L; ++R) {
8358 arr[R] = [];
8359 /* TODO: confirm that widths are always 10 */
8360 var C = 0;
8361 set_text_arr(lines[R].slice(0, start).trim(), arr, R, C, o);
8362 for(C = 1; C <= (lines[R].length - start)/10 + 1; ++C)
8363 set_text_arr(lines[R].slice(start+(C-1)*10,start+C*10).trim(),arr,R,C,o);
8364 }
8365 if(o.sheetRows) arr = arr.slice(0, o.sheetRows);
8366 return arr;
8367 }
8368
8369 // List of accepted CSV separators
8370 var guess_seps = {
8371 /*::[*/0x2C/*::]*/: ',',
8372 /*::[*/0x09/*::]*/: "\t",
8373 /*::[*/0x3B/*::]*/: ';',
8374 /*::[*/0x7C/*::]*/: '|'
8375 };
8376
8377 // CSV separator weights to be used in case of equal numbers
8378 var guess_sep_weights = {
8379 /*::[*/0x2C/*::]*/: 3,
8380 /*::[*/0x09/*::]*/: 2,
8381 /*::[*/0x3B/*::]*/: 1,
8382 /*::[*/0x7C/*::]*/: 0
8383 };
8384
8385 function guess_sep(str) {
8386 var cnt = {}, instr = false, end = 0, cc = 0;
8387 for(;end < str.length;++end) {
8388 if((cc=str.charCodeAt(end)) == 0x22) instr = !instr;
8389 else if(!instr && cc in guess_seps) cnt[cc] = (cnt[cc]||0)+1;
8390 }
8391
8392 cc = [];
8393 for(end in cnt) if ( Object.prototype.hasOwnProperty.call(cnt, end) ) {
8394 cc.push([ cnt[end], end ]);
8395 }
8396
8397 if ( !cc.length ) {
8398 cnt = guess_sep_weights;
8399 for(end in cnt) if ( Object.prototype.hasOwnProperty.call(cnt, end) ) {
8400 cc.push([ cnt[end], end ]);
8401 }
8402 }
8403
8404 cc.sort(function(a, b) { return a[0] - b[0] || guess_sep_weights[a[1]] - guess_sep_weights[b[1]]; });
8405
8406 return guess_seps[cc.pop()[1]] || 0x2C;
8407 }
8408
8409 function dsv_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
8410 var o = opts || {};
8411 var sep = "";
8412 if(DENSE != null && o.dense == null) o.dense = DENSE;
8413 var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/);
8414 var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:0}}/*:any*/);
8415
8416 if(str.slice(0,4) == "sep=") {
8417 // If the line ends in \r\n
8418 if(str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10 ) {
8419 sep = str.charAt(4); str = str.slice(7);
8420 }
8421 // If line ends in \r OR \n
8422 else if(str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10 ) {
8423 sep = str.charAt(4); str = str.slice(6);
8424 }
8425 else sep = guess_sep(str.slice(0,1024));
8426 }
8427 else if(o && o.FS) sep = o.FS;
8428 else sep = guess_sep(str.slice(0,1024));
8429 var R = 0, C = 0, v = 0;
8430 var start = 0, end = 0, sepcc = sep.charCodeAt(0), instr = false, cc=0, startcc=str.charCodeAt(0);
8431 str = str.replace(/\r\n/mg, "\n");
8432 var _re/*:?RegExp*/ = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
8433 function finish_cell() {
8434 var s = str.slice(start, end);
8435 var cell = ({}/*:any*/);
8436 if(s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1,-1).replace(/""/g,'"');
8437 if(s.length === 0) cell.t = 'z';
8438 else if(o.raw) { cell.t = 's'; cell.v = s; }
8439 else if(s.trim().length === 0) { cell.t = 's'; cell.v = s; }
8440 else if(s.charCodeAt(0) == 0x3D) {
8441 if(s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) { cell.t = 's'; cell.v = s.slice(2,-1).replace(/""/g,'"'); }
8442 else if(fuzzyfmla(s)) { cell.t = 'n'; cell.f = s.slice(1); }
8443 else { cell.t = 's'; cell.v = s; } }
8444 else if(s == "TRUE") { cell.t = 'b'; cell.v = true; }
8445 else if(s == "FALSE") { cell.t = 'b'; cell.v = false; }
8446 else if(!isNaN(v = fuzzynum(s))) { cell.t = 'n'; if(o.cellText !== false) cell.w = s; cell.v = v; }
8447 else if(!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
8448 cell.z = o.dateNF || table_fmt[14];
8449 var k = 0;
8450 if(_re && s.match(_re)){ s=dateNF_fix(s, o.dateNF, (s.match(_re)||[])); k=1; }
8451 if(o.cellDates) { cell.t = 'd'; cell.v = parseDate(s, k); }
8452 else { cell.t = 'n'; cell.v = datenum(parseDate(s, k)); }
8453 if(o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v):cell.v);
8454 if(!o.cellNF) delete cell.z;
8455 } else {
8456 cell.t = 's';
8457 cell.v = s;
8458 }
8459 if(cell.t == 'z'){}
8460 else if(o.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = cell; }
8461 else ws[encode_cell({c:C,r:R})] = cell;
8462 start = end+1; startcc = str.charCodeAt(start);
8463 if(range.e.c < C) range.e.c = C;
8464 if(range.e.r < R) range.e.r = R;
8465 if(cc == sepcc) ++C; else { C = 0; ++R; if(o.sheetRows && o.sheetRows <= R) return true; }
8466 }
8467 outer: for(;end < str.length;++end) switch((cc=str.charCodeAt(end))) {
8468 case 0x22: if(startcc === 0x22) instr = !instr; break;
8469 case sepcc: case 0x0a: case 0x0d: if(!instr && finish_cell()) break outer; break;
8470 default: break;
8471 }
8472 if(end - start > 0) finish_cell();
8473
8474 ws['!ref'] = encode_range(range);
8475 return ws;
8476 }
8477
8478 function prn_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
8479 if(!(opts && opts.PRN)) return dsv_to_sheet_str(str, opts);
8480 if(opts.FS) return dsv_to_sheet_str(str, opts);
8481 if(str.slice(0,4) == "sep=") return dsv_to_sheet_str(str, opts);
8482 if(str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
8483 return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
8484 }
8485
8486 function prn_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
8487 var str = "", bytes = opts.type == 'string' ? [0,0,0,0] : firstbyte(d, opts);
8488 switch(opts.type) {
8489 case 'base64': str = Base64_decode(d); break;
8490 case 'binary': str = d; break;
8491 case 'buffer':
8492 if(opts.codepage == 65001) str = d.toString('utf8'); // TODO: test if buf
8493 else if(opts.codepage && typeof $cptable !== 'undefined') str = $cptable.utils.decode(opts.codepage, d);
8494 else str = has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d);
8495 break;
8496 case 'array': str = cc2str(d); break;
8497 case 'string': str = d; break;
8498 default: throw new Error("Unrecognized type " + opts.type);
8499 }
8500 if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));
8501 else if(opts.type != 'string' && opts.type != 'buffer' && opts.codepage == 65001) str = utf8read(str);
8502 else if((opts.type == 'binary') && typeof $cptable !== 'undefined' && opts.codepage) str = $cptable.utils.decode(opts.codepage, $cptable.utils.encode(28591,str));
8503 if(str.slice(0,19) == "socialcalc:version:") return ETH.to_sheet(opts.type == 'string' ? str : utf8read(str), opts);
8504 return prn_to_sheet_str(str, opts);
8505 }
8506
8507 function prn_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(prn_to_sheet(d, opts), opts); }
8508
8509 function sheet_to_prn(ws/*:Worksheet*//*::, opts:?any*/)/*:string*/ {
8510 var o/*:Array<string>*/ = [];
8511 var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
8512 var dense = Array.isArray(ws);
8513 for(var R = r.s.r; R <= r.e.r; ++R) {
8514 var oo/*:Array<string>*/ = [];
8515 for(var C = r.s.c; C <= r.e.c; ++C) {
8516 var coord = encode_cell({r:R,c:C});
8517 cell = dense ? (ws[R]||[])[C] : ws[coord];
8518 if(!cell || cell.v == null) { oo.push(" "); continue; }
8519 var w = (cell.w || (format_cell(cell), cell.w) || "").slice(0,10);
8520 while(w.length < 10) w += " ";
8521 oo.push(w + (C === 0 ? " " : ""));
8522 }
8523 o.push(oo.join(""));
8524 }
8525 return o.join("\n");
8526 }
8527
8528 return {
8529 to_workbook: prn_to_workbook,
8530 to_sheet: prn_to_sheet,
8531 from_sheet: sheet_to_prn
8532 };
8533})();
8534
8535/* Excel defaults to SYLK but warns if data is not valid */
8536function read_wb_ID(d, opts) {
8537 var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true;
8538 try {
8539 var out = SYLK.to_workbook(d, o);
8540 o.WTF = OLD_WTF;
8541 return out;
8542 } catch(e) {
8543 o.WTF = OLD_WTF;
8544 if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e;
8545 return PRN.to_workbook(d, opts);
8546 }
8547}
8548
8549var WK_ = /*#__PURE__*/(function() {
8550 function lotushopper(data, cb/*:RecordHopperCB*/, opts/*:any*/) {
8551 if(!data) return;
8552 prep_blob(data, data.l || 0);
8553 var Enum = opts.Enum || WK1Enum;
8554 while(data.l < data.length) {
8555 var RT = data.read_shift(2);
8556 var R = Enum[RT] || Enum[0xFFFF];
8557 var length = data.read_shift(2);
8558 var tgt = data.l + length;
8559 var d = R.f && R.f(data, length, opts);
8560 data.l = tgt;
8561 if(cb(d, R, RT)) return;
8562 }
8563 }
8564
8565 function lotus_to_workbook(d/*:RawData*/, opts) {
8566 switch(opts.type) {
8567 case 'base64': return lotus_to_workbook_buf(s2a(Base64_decode(d)), opts);
8568 case 'binary': return lotus_to_workbook_buf(s2a(d), opts);
8569 case 'buffer':
8570 case 'array': return lotus_to_workbook_buf(d, opts);
8571 }
8572 throw "Unsupported type " + opts.type;
8573 }
8574
8575 function lotus_to_workbook_buf(d, opts)/*:Workbook*/ {
8576 if(!d) return d;
8577 var o = opts || {};
8578 if(DENSE != null && o.dense == null) o.dense = DENSE;
8579 var s/*:Worksheet*/ = ((o.dense ? [] : {})/*:any*/), n = "Sheet1", next_n = "", sidx = 0;
8580 var sheets = {}, snames = [], realnames = [];
8581
8582 var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
8583 var sheetRows = o.sheetRows || 0;
8584
8585 if(d[2] == 0x00) {
8586 if(d[3] == 0x08 || d[3] == 0x09) {
8587 if(d.length >= 16 && d[14] == 0x05 && d[15] === 0x6c) throw new Error("Unsupported Works 3 for Mac file");
8588 }
8589 }
8590
8591 if(d[2] == 0x02) {
8592 o.Enum = WK1Enum;
8593 lotushopper(d, function(val, R, RT) { switch(RT) {
8594 case 0x00: /* BOF */
8595 o.vers = val;
8596 if(val >= 0x1000) o.qpro = true;
8597 break;
8598 case 0x06: refguess = val; break; /* RANGE */
8599 case 0xCC: if(val) next_n = val; break; /* SHEETNAMECS */
8600 case 0xDE: next_n = val; break; /* SHEETNAMELP */
8601 case 0x0F: /* LABEL */
8602 case 0x33: /* STRING */
8603 if(!o.qpro) val[1].v = val[1].v.slice(1);
8604 /* falls through */
8605 case 0x0D: /* INTEGER */
8606 case 0x0E: /* NUMBER */
8607 case 0x10: /* FORMULA */
8608 /* TODO: actual translation of the format code */
8609 if(RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
8610 val[1].z = o.dateNF || table_fmt[14];
8611 if(o.cellDates) { val[1].t = 'd'; val[1].v = numdate(val[1].v); }
8612 }
8613
8614 if(o.qpro) {
8615 if(val[3] > sidx) {
8616 s["!ref"] = encode_range(refguess);
8617 sheets[n] = s;
8618 snames.push(n);
8619 s = (o.dense ? [] : {});
8620 refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
8621 sidx = val[3]; n = next_n || "Sheet" + (sidx + 1); next_n = "";
8622 }
8623 }
8624
8625 var tmpcell = o.dense ? (s[val[0].r]||[])[val[0].c] : s[encode_cell(val[0])];
8626 if(tmpcell) {
8627 tmpcell.t = val[1].t; tmpcell.v = val[1].v;
8628 if(val[1].z != null) tmpcell.z = val[1].z;
8629 if(val[1].f != null) tmpcell.f = val[1].f;
8630 break;
8631 }
8632 if(o.dense) {
8633 if(!s[val[0].r]) s[val[0].r] = [];
8634 s[val[0].r][val[0].c] = val[1];
8635 } else s[encode_cell(val[0])] = val[1];
8636 break;
8637 default:
8638 }}, o);
8639 } else if(d[2] == 0x1A || d[2] == 0x0E) {
8640 o.Enum = WK3Enum;
8641 if(d[2] == 0x0E) { o.qpro = true; d.l = 0; }
8642 lotushopper(d, function(val, R, RT) { switch(RT) {
8643 case 0xCC: n = val; break; /* SHEETNAMECS */
8644 case 0x16: /* LABEL16 */
8645 val[1].v = val[1].v.slice(1);
8646 /* falls through */
8647 case 0x17: /* NUMBER17 */
8648 case 0x18: /* NUMBER18 */
8649 case 0x19: /* FORMULA19 */
8650 case 0x25: /* NUMBER25 */
8651 case 0x27: /* NUMBER27 */
8652 case 0x28: /* FORMULA28 */
8653 if(val[3] > sidx) {
8654 s["!ref"] = encode_range(refguess);
8655 sheets[n] = s;
8656 snames.push(n);
8657 s = (o.dense ? [] : {});
8658 refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
8659 sidx = val[3]; n = "Sheet" + (sidx + 1);
8660 }
8661 if(sheetRows > 0 && val[0].r >= sheetRows) break;
8662 if(o.dense) {
8663 if(!s[val[0].r]) s[val[0].r] = [];
8664 s[val[0].r][val[0].c] = val[1];
8665 } else s[encode_cell(val[0])] = val[1];
8666 if(refguess.e.c < val[0].c) refguess.e.c = val[0].c;
8667 if(refguess.e.r < val[0].r) refguess.e.r = val[0].r;
8668 break;
8669 case 0x1B: /* XFORMAT */
8670 if(val[0x36b0]) realnames[val[0x36b0][0]] = val[0x36b0][1];
8671 break;
8672 case 0x0601: /* SHEETINFOQP */
8673 realnames[val[0]] = val[1]; if(val[0] == sidx) n = val[1]; break;
8674 default: break;
8675 }}, o);
8676 } else throw new Error("Unrecognized LOTUS BOF " + d[2]);
8677 s["!ref"] = encode_range(refguess);
8678 sheets[next_n || n] = s;
8679 snames.push(next_n || n);
8680 if(!realnames.length) return { SheetNames: snames, Sheets: sheets };
8681 var osheets = {}, rnames = [];
8682 /* TODO: verify no collisions */
8683 for(var i = 0; i < realnames.length; ++i) if(sheets[snames[i]]) {
8684 rnames.push(realnames[i] || snames[i]);
8685 osheets[realnames[i]] = sheets[realnames[i]] || sheets[snames[i]];
8686 } else {
8687 rnames.push(realnames[i]);
8688 osheets[realnames[i]] = ({ "!ref": "A1" });
8689 }
8690 return { SheetNames: rnames, Sheets: osheets };
8691 }
8692
8693 function sheet_to_wk1(ws/*:Worksheet*/, opts/*:WriteOpts*/) {
8694 var o = opts || {};
8695 if(+o.codepage >= 0) set_cp(+o.codepage);
8696 if(o.type == "string") throw new Error("Cannot write WK1 to JS string");
8697 var ba = buf_array();
8698 var range = safe_decode_range(ws["!ref"]);
8699 var dense = Array.isArray(ws);
8700 var cols = [];
8701
8702 write_biff_rec(ba, 0x00, write_BOF_WK1(0x0406));
8703 write_biff_rec(ba, 0x06, write_RANGE(range));
8704 var max_R = Math.min(range.e.r, 8191);
8705 for(var R = range.s.r; R <= max_R; ++R) {
8706 var rr = encode_row(R);
8707 for(var C = range.s.c; C <= range.e.c; ++C) {
8708 if(R === range.s.r) cols[C] = encode_col(C);
8709 var ref = cols[C] + rr;
8710 var cell = dense ? (ws[R]||[])[C] : ws[ref];
8711 if(!cell || cell.t == "z") continue;
8712 /* TODO: formula records */
8713 if(cell.t == "n") {
8714 if((cell.v|0)==cell.v && cell.v >= -32768 && cell.v <= 32767) write_biff_rec(ba, 0x0d, write_INTEGER(R, C, cell.v));
8715 else write_biff_rec(ba, 0x0e, write_NUMBER(R, C, cell.v));
8716 } else {
8717 var str = format_cell(cell);
8718 write_biff_rec(ba, 0x0F, write_LABEL(R, C, str.slice(0, 239)));
8719 }
8720 }
8721 }
8722
8723 write_biff_rec(ba, 0x01);
8724 return ba.end();
8725 }
8726
8727 function book_to_wk3(wb/*:Workbook*/, opts/*:WriteOpts*/) {
8728 var o = opts || {};
8729 if(+o.codepage >= 0) set_cp(+o.codepage);
8730 if(o.type == "string") throw new Error("Cannot write WK3 to JS string");
8731 var ba = buf_array();
8732
8733 write_biff_rec(ba, 0x00, write_BOF_WK3(wb));
8734
8735 for(var i = 0, cnt = 0; i < wb.SheetNames.length; ++i) if((wb.Sheets[wb.SheetNames[i]] || {})["!ref"]) write_biff_rec(ba, 0x1b, write_XFORMAT_SHEETNAME(wb.SheetNames[i], cnt++));
8736
8737 var wsidx = 0;
8738 for(i = 0; i < wb.SheetNames.length; ++i) {
8739 var ws = wb.Sheets[wb.SheetNames[i]];
8740 if(!ws || !ws["!ref"]) continue;
8741 var range = safe_decode_range(ws["!ref"]);
8742 var dense = Array.isArray(ws);
8743 var cols = [];
8744 var max_R = Math.min(range.e.r, 8191);
8745 for(var R = range.s.r; R <= max_R; ++R) {
8746 var rr = encode_row(R);
8747 for(var C = range.s.c; C <= range.e.c; ++C) {
8748 if(R === range.s.r) cols[C] = encode_col(C);
8749 var ref = cols[C] + rr;
8750 var cell = dense ? (ws[R]||[])[C] : ws[ref];
8751 if(!cell || cell.t == "z") continue;
8752 /* TODO: FORMULA19 NUMBER18 records */
8753 if(cell.t == "n") {
8754 write_biff_rec(ba, 0x17, write_NUMBER_17(R, C, wsidx, cell.v));
8755 } else {
8756 var str = format_cell(cell);
8757 /* TODO: max len? */
8758 write_biff_rec(ba, 0x16, write_LABEL_16(R, C, wsidx, str.slice(0, 239)));
8759 }
8760 }
8761 }
8762 ++wsidx;
8763 }
8764
8765 write_biff_rec(ba, 0x01);
8766 return ba.end();
8767 }
8768
8769
8770 function write_BOF_WK1(v/*:number*/) {
8771 var out = new_buf(2);
8772 out.write_shift(2, v);
8773 return out;
8774 }
8775
8776 function write_BOF_WK3(wb/*:Workbook*/) {
8777 var out = new_buf(26);
8778 out.write_shift(2, 0x1000);
8779 out.write_shift(2, 0x0004);
8780 out.write_shift(4, 0x0000);
8781 var rows = 0, cols = 0, wscnt = 0;
8782 for(var i = 0; i < wb.SheetNames.length; ++i) {
8783 var name = wb.SheetNames[i];
8784 var ws = wb.Sheets[name];
8785 if(!ws || !ws["!ref"]) continue;
8786 ++wscnt;
8787 var range = decode_range(ws["!ref"]);
8788 if(rows < range.e.r) rows = range.e.r;
8789 if(cols < range.e.c) cols = range.e.c;
8790 }
8791 if(rows > 8191) rows = 8191;
8792 out.write_shift(2, rows);
8793 out.write_shift(1, wscnt);
8794 out.write_shift(1, cols);
8795 out.write_shift(2, 0x00);
8796 out.write_shift(2, 0x00);
8797 out.write_shift(1, 0x01);
8798 out.write_shift(1, 0x02);
8799 out.write_shift(4, 0);
8800 out.write_shift(4, 0);
8801 return out;
8802 }
8803
8804 function parse_RANGE(blob, length, opts) {
8805 var o = {s:{c:0,r:0},e:{c:0,r:0}};
8806 if(length == 8 && opts.qpro) {
8807 o.s.c = blob.read_shift(1);
8808 blob.l++;
8809 o.s.r = blob.read_shift(2);
8810 o.e.c = blob.read_shift(1);
8811 blob.l++;
8812 o.e.r = blob.read_shift(2);
8813 return o;
8814 }
8815 o.s.c = blob.read_shift(2);
8816 o.s.r = blob.read_shift(2);
8817 if(length == 12 && opts.qpro) blob.l += 2;
8818 o.e.c = blob.read_shift(2);
8819 o.e.r = blob.read_shift(2);
8820 if(length == 12 && opts.qpro) blob.l += 2;
8821 if(o.s.c == 0xFFFF) o.s.c = o.e.c = o.s.r = o.e.r = 0;
8822 return o;
8823 }
8824 function write_RANGE(range) {
8825 var out = new_buf(8);
8826 out.write_shift(2, range.s.c);
8827 out.write_shift(2, range.s.r);
8828 out.write_shift(2, range.e.c);
8829 out.write_shift(2, range.e.r);
8830 return out;
8831 }
8832
8833 function parse_cell(blob, length, opts) {
8834 var o = [{c:0,r:0}, {t:'n',v:0}, 0, 0];
8835 if(opts.qpro && opts.vers != 0x5120) {
8836 o[0].c = blob.read_shift(1);
8837 o[3] = blob.read_shift(1);
8838 o[0].r = blob.read_shift(2);
8839 blob.l+=2;
8840 } else {
8841 o[2] = blob.read_shift(1);
8842 o[0].c = blob.read_shift(2); o[0].r = blob.read_shift(2);
8843 }
8844 return o;
8845 }
8846
8847 function parse_LABEL(blob, length, opts) {
8848 var tgt = blob.l + length;
8849 var o = parse_cell(blob, length, opts);
8850 o[1].t = 's';
8851 if(opts.vers == 0x5120) {
8852 blob.l++;
8853 var len = blob.read_shift(1);
8854 o[1].v = blob.read_shift(len, 'utf8');
8855 return o;
8856 }
8857 if(opts.qpro) blob.l++;
8858 o[1].v = blob.read_shift(tgt - blob.l, 'cstr');
8859 return o;
8860 }
8861 function write_LABEL(R, C, s) {
8862 /* TODO: encoding */
8863 var o = new_buf(7 + s.length);
8864 o.write_shift(1, 0xFF);
8865 o.write_shift(2, C);
8866 o.write_shift(2, R);
8867 o.write_shift(1, 0x27); // ??
8868 for(var i = 0; i < o.length; ++i) {
8869 var cc = s.charCodeAt(i);
8870 o.write_shift(1, cc >= 0x80 ? 0x5F : cc);
8871 }
8872 o.write_shift(1, 0);
8873 return o;
8874 }
8875
8876 function parse_INTEGER(blob, length, opts) {
8877 var o = parse_cell(blob, length, opts);
8878 o[1].v = blob.read_shift(2, 'i');
8879 return o;
8880 }
8881 function write_INTEGER(R, C, v) {
8882 var o = new_buf(7);
8883 o.write_shift(1, 0xFF);
8884 o.write_shift(2, C);
8885 o.write_shift(2, R);
8886 o.write_shift(2, v, 'i');
8887 return o;
8888 }
8889
8890 function parse_NUMBER(blob, length, opts) {
8891 var o = parse_cell(blob, length, opts);
8892 o[1].v = blob.read_shift(8, 'f');
8893 return o;
8894 }
8895 function write_NUMBER(R, C, v) {
8896 var o = new_buf(13);
8897 o.write_shift(1, 0xFF);
8898 o.write_shift(2, C);
8899 o.write_shift(2, R);
8900 o.write_shift(8, v, 'f');
8901 return o;
8902 }
8903
8904 function parse_FORMULA(blob, length, opts) {
8905 var tgt = blob.l + length;
8906 var o = parse_cell(blob, length, opts);
8907 /* TODO: formula */
8908 o[1].v = blob.read_shift(8, 'f');
8909 if(opts.qpro) blob.l = tgt;
8910 else {
8911 var flen = blob.read_shift(2);
8912 wk1_fmla_to_csf(blob.slice(blob.l, blob.l + flen), o);
8913 blob.l += flen;
8914 }
8915 return o;
8916 }
8917
8918 function wk1_parse_rc(B, V, col) {
8919 var rel = V & 0x8000;
8920 V &= ~0x8000;
8921 V = (rel ? B : 0) + ((V >= 0x2000) ? V - 0x4000 : V);
8922 return (rel ? "" : "$") + (col ? encode_col(V) : encode_row(V));
8923 }
8924 /* var oprec = [
8925 8, 8, 8, 8, 8, 8, 8, 8, 6, 4, 4, 5, 5, 7, 3, 3,
8926 3, 3, 3, 3, 1, 1, 2, 6, 8, 8, 8, 8, 8, 8, 8, 8
8927 ]; */
8928 /* TODO: flesh out */
8929 var FuncTab = {
8930 0x33: ["FALSE", 0],
8931 0x34: ["TRUE", 0],
8932 0x46: ["LEN", 1],
8933 0x50: ["SUM", 69],
8934 0x51: ["AVERAGEA", 69],
8935 0x52: ["COUNTA", 69],
8936 0x53: ["MINA", 69],
8937 0x54: ["MAXA", 69],
8938 0x6F: ["T", 1]
8939 };
8940 var BinOpTab = [
8941 "", "", "", "", "", "", "", "", // eslint-disable-line no-mixed-spaces-and-tabs
8942 "", "+", "-", "*", "/", "^", "=", "<>", // eslint-disable-line no-mixed-spaces-and-tabs
8943 "<=", ">=", "<", ">", "", "", "", "", // eslint-disable-line no-mixed-spaces-and-tabs
8944 "&", "", "", "", "", "", "", "" // eslint-disable-line no-mixed-spaces-and-tabs
8945 ];
8946
8947 function wk1_fmla_to_csf(blob, o) {
8948 prep_blob(blob, 0);
8949 var out = [], argc = 0, R = "", C = "", argL = "", argR = "";
8950 while(blob.l < blob.length) {
8951 var cc = blob[blob.l++];
8952 switch(cc) {
8953 case 0x00: out.push(blob.read_shift(8, 'f')); break;
8954 case 0x01: {
8955 C = wk1_parse_rc(o[0].c, blob.read_shift(2), true);
8956 R = wk1_parse_rc(o[0].r, blob.read_shift(2), false);
8957 out.push(C + R);
8958 } break;
8959 case 0x02: {
8960 var c = wk1_parse_rc(o[0].c, blob.read_shift(2), true);
8961 var r = wk1_parse_rc(o[0].r, blob.read_shift(2), false);
8962 C = wk1_parse_rc(o[0].c, blob.read_shift(2), true);
8963 R = wk1_parse_rc(o[0].r, blob.read_shift(2), false);
8964 out.push(c + r + ":" + C + R);
8965 } break;
8966 case 0x03:
8967 if(blob.l < blob.length) { console.error("WK1 premature formula end"); return; }
8968 break;
8969 case 0x04: out.push("(" + out.pop() + ")"); break;
8970 case 0x05: out.push(blob.read_shift(2)); break;
8971 case 0x06: {
8972 /* TODO: text encoding */
8973 var Z = ""; while((cc = blob[blob.l++])) Z += String.fromCharCode(cc);
8974 out.push('"' + Z.replace(/"/g, '""') + '"');
8975 } break;
8976
8977 case 0x08: out.push("-" + out.pop()); break;
8978 case 0x17: out.push("+" + out.pop()); break;
8979 case 0x16: out.push("NOT(" + out.pop() + ")"); break;
8980
8981 case 0x14: case 0x15: {
8982 argR = out.pop(); argL = out.pop();
8983 out.push(["AND", "OR"][cc - 0x14] + "(" + argL + "," + argR + ")");
8984 } break;
8985
8986 default:
8987 if(cc < 0x20 && BinOpTab[cc]) {
8988 argR = out.pop(); argL = out.pop();
8989 out.push(argL + BinOpTab[cc] + argR);
8990 } else if(FuncTab[cc]) {
8991 argc = FuncTab[cc][1];
8992 if(argc == 69) argc = blob[blob.l++];
8993 if(argc > out.length) { console.error("WK1 bad formula parse 0x" + cc.toString(16) + ":|" + out.join("|") + "|"); return; }
8994 var args = out.slice(-argc);
8995 out.length -= argc;
8996 out.push(FuncTab[cc][0] + "(" + args.join(",") + ")");
8997 }
8998 else if(cc <= 0x07) return console.error("WK1 invalid opcode " + cc.toString(16));
8999 else if(cc <= 0x18) return console.error("WK1 unsupported op " + cc.toString(16));
9000 else if(cc <= 0x1E) return console.error("WK1 invalid opcode " + cc.toString(16));
9001 else if(cc <= 0x73) return console.error("WK1 unsupported function opcode " + cc.toString(16));
9002 // possible future functions ??
9003 else return console.error("WK1 unrecognized opcode " + cc.toString(16));
9004 }
9005 }
9006 if(out.length == 1) o[1].f = "" + out[0];
9007 else console.error("WK1 bad formula parse |" + out.join("|") + "|");
9008 }
9009
9010
9011 function parse_cell_3(blob/*::, length*/) {
9012 var o = [{c:0,r:0}, {t:'n',v:0}, 0];
9013 o[0].r = blob.read_shift(2); o[3] = blob[blob.l++]; o[0].c = blob[blob.l++];
9014 return o;
9015 }
9016
9017 function parse_LABEL_16(blob, length) {
9018 var o = parse_cell_3(blob, length);
9019 o[1].t = 's';
9020 o[1].v = blob.read_shift(length - 4, 'cstr');
9021 return o;
9022 }
9023 function write_LABEL_16(R, C, wsidx, s) {
9024 /* TODO: encoding */
9025 var o = new_buf(6 + s.length);
9026 o.write_shift(2, R);
9027 o.write_shift(1, wsidx);
9028 o.write_shift(1, C);
9029 o.write_shift(1, 0x27);
9030 for(var i = 0; i < s.length; ++i) {
9031 var cc = s.charCodeAt(i);
9032 o.write_shift(1, cc >= 0x80 ? 0x5F : cc);
9033 }
9034 o.write_shift(1, 0);
9035 return o;
9036 }
9037
9038 function parse_NUMBER_18(blob, length) {
9039 var o = parse_cell_3(blob, length);
9040 o[1].v = blob.read_shift(2);
9041 var v = o[1].v >> 1;
9042 if(o[1].v & 0x1) {
9043 switch(v & 0x07) {
9044 case 0: v = (v >> 3) * 5000; break;
9045 case 1: v = (v >> 3) * 500; break;
9046 case 2: v = (v >> 3) / 20; break;
9047 case 3: v = (v >> 3) / 200; break;
9048 case 4: v = (v >> 3) / 2000; break;
9049 case 5: v = (v >> 3) / 20000; break;
9050 case 6: v = (v >> 3) / 16; break;
9051 case 7: v = (v >> 3) / 64; break;
9052 }
9053 }
9054 o[1].v = v;
9055 return o;
9056 }
9057
9058 function parse_NUMBER_17(blob, length) {
9059 var o = parse_cell_3(blob, length);
9060 var v1 = blob.read_shift(4);
9061 var v2 = blob.read_shift(4);
9062 var e = blob.read_shift(2);
9063 if(e == 0xFFFF) {
9064 if(v1 === 0 && v2 === 0xC0000000) { o[1].t = "e"; o[1].v = 0x0F; } // ERR -> #VALUE!
9065 else if(v1 === 0 && v2 === 0xD0000000) { o[1].t = "e"; o[1].v = 0x2A; } // NA -> #N/A
9066 else o[1].v = 0;
9067 return o;
9068 }
9069 var s = e & 0x8000; e = (e&0x7FFF) - 16446;
9070 o[1].v = (1 - s*2) * (v2 * Math.pow(2, e+32) + v1 * Math.pow(2, e));
9071 return o;
9072 }
9073 function write_NUMBER_17(R, C, wsidx, v) {
9074 var o = new_buf(14);
9075 o.write_shift(2, R);
9076 o.write_shift(1, wsidx);
9077 o.write_shift(1, C);
9078 if(v == 0) {
9079 o.write_shift(4, 0);
9080 o.write_shift(4, 0);
9081 o.write_shift(2, 0xFFFF);
9082 return o;
9083 }
9084 var s = 0, e = 0, v1 = 0, v2 = 0;
9085 if(v < 0) { s = 1; v = -v; }
9086 e = Math.log2(v) | 0;
9087 v /= Math.pow(2, e-31);
9088 v2 = (v)>>>0;
9089 if((v2&0x80000000) == 0) { v/=2; ++e; v2 = v >>> 0; }
9090 v -= v2;
9091 v2 |= 0x80000000;
9092 v2 >>>= 0;
9093 v *= Math.pow(2, 32);
9094 v1 = v>>>0;
9095 o.write_shift(4, v1);
9096 o.write_shift(4, v2);
9097 e += 0x3FFF + (s ? 0x8000 : 0);
9098 o.write_shift(2, e);
9099 return o;
9100 }
9101
9102 function parse_FORMULA_19(blob, length) {
9103 var o = parse_NUMBER_17(blob, 14);
9104 blob.l += length - 14; /* TODO: WK3 formula */
9105 return o;
9106 }
9107
9108 function parse_NUMBER_25(blob, length) {
9109 var o = parse_cell_3(blob, length);
9110 var v1 = blob.read_shift(4);
9111 o[1].v = v1 >> 6;
9112 return o;
9113 }
9114
9115 function parse_NUMBER_27(blob, length) {
9116 var o = parse_cell_3(blob, length);
9117 var v1 = blob.read_shift(8,'f');
9118 o[1].v = v1;
9119 return o;
9120 }
9121
9122 function parse_FORMULA_28(blob, length) {
9123 var o = parse_NUMBER_27(blob, 14);
9124 blob.l += length - 10; /* TODO: formula */
9125 return o;
9126 }
9127
9128 function parse_SHEETNAMECS(blob, length) {
9129 return blob[blob.l + length - 1] == 0 ? blob.read_shift(length, 'cstr') : "";
9130 }
9131
9132 function parse_SHEETNAMELP(blob, length) {
9133 var len = blob[blob.l++];
9134 if(len > length - 1) len = length - 1;
9135 var o = ""; while(o.length < len) o += String.fromCharCode(blob[blob.l++]);
9136 return o;
9137 }
9138
9139 function parse_SHEETINFOQP(blob, length, opts) {
9140 if(!opts.qpro || length < 21) return;
9141 var id = blob.read_shift(1);
9142 blob.l += 17;
9143 blob.l += 1; //var len = blob.read_shift(1);
9144 blob.l += 2;
9145 var nm = blob.read_shift(length - 21, 'cstr');
9146 return [id, nm];
9147 }
9148
9149 function parse_XFORMAT(blob, length) {
9150 var o = {}, tgt = blob.l + length;
9151 while(blob.l < tgt) {
9152 var dt = blob.read_shift(2);
9153 if(dt == 0x36b0) {
9154 o[dt] = [0, ""];
9155 o[dt][0] = blob.read_shift(2);
9156 while(blob[blob.l]) { o[dt][1] += String.fromCharCode(blob[blob.l]); blob.l++; } blob.l++;
9157 }
9158 // TODO: 0x3a99 ??
9159 }
9160 return o;
9161 }
9162 function write_XFORMAT_SHEETNAME(name, wsidx) {
9163 var out = new_buf(5 + name.length);
9164 out.write_shift(2, 0x36b0);
9165 out.write_shift(2, wsidx);
9166 for(var i = 0; i < name.length; ++i) {
9167 var cc = name.charCodeAt(i);
9168 out[out.l++] = cc > 0x7F ? 0x5F : cc;
9169 }
9170 out[out.l++] = 0;
9171 return out;
9172 }
9173
9174 var WK1Enum = {
9175 /*::[*/0x0000/*::]*/: { n:"BOF", f:parseuint16 },
9176 /*::[*/0x0001/*::]*/: { n:"EOF" },
9177 /*::[*/0x0002/*::]*/: { n:"CALCMODE" },
9178 /*::[*/0x0003/*::]*/: { n:"CALCORDER" },
9179 /*::[*/0x0004/*::]*/: { n:"SPLIT" },
9180 /*::[*/0x0005/*::]*/: { n:"SYNC" },
9181 /*::[*/0x0006/*::]*/: { n:"RANGE", f:parse_RANGE },
9182 /*::[*/0x0007/*::]*/: { n:"WINDOW1" },
9183 /*::[*/0x0008/*::]*/: { n:"COLW1" },
9184 /*::[*/0x0009/*::]*/: { n:"WINTWO" },
9185 /*::[*/0x000A/*::]*/: { n:"COLW2" },
9186 /*::[*/0x000B/*::]*/: { n:"NAME" },
9187 /*::[*/0x000C/*::]*/: { n:"BLANK" },
9188 /*::[*/0x000D/*::]*/: { n:"INTEGER", f:parse_INTEGER },
9189 /*::[*/0x000E/*::]*/: { n:"NUMBER", f:parse_NUMBER },
9190 /*::[*/0x000F/*::]*/: { n:"LABEL", f:parse_LABEL },
9191 /*::[*/0x0010/*::]*/: { n:"FORMULA", f:parse_FORMULA },
9192 /*::[*/0x0018/*::]*/: { n:"TABLE" },
9193 /*::[*/0x0019/*::]*/: { n:"ORANGE" },
9194 /*::[*/0x001A/*::]*/: { n:"PRANGE" },
9195 /*::[*/0x001B/*::]*/: { n:"SRANGE" },
9196 /*::[*/0x001C/*::]*/: { n:"FRANGE" },
9197 /*::[*/0x001D/*::]*/: { n:"KRANGE1" },
9198 /*::[*/0x0020/*::]*/: { n:"HRANGE" },
9199 /*::[*/0x0023/*::]*/: { n:"KRANGE2" },
9200 /*::[*/0x0024/*::]*/: { n:"PROTEC" },
9201 /*::[*/0x0025/*::]*/: { n:"FOOTER" },
9202 /*::[*/0x0026/*::]*/: { n:"HEADER" },
9203 /*::[*/0x0027/*::]*/: { n:"SETUP" },
9204 /*::[*/0x0028/*::]*/: { n:"MARGINS" },
9205 /*::[*/0x0029/*::]*/: { n:"LABELFMT" },
9206 /*::[*/0x002A/*::]*/: { n:"TITLES" },
9207 /*::[*/0x002B/*::]*/: { n:"SHEETJS" },
9208 /*::[*/0x002D/*::]*/: { n:"GRAPH" },
9209 /*::[*/0x002E/*::]*/: { n:"NGRAPH" },
9210 /*::[*/0x002F/*::]*/: { n:"CALCCOUNT" },
9211 /*::[*/0x0030/*::]*/: { n:"UNFORMATTED" },
9212 /*::[*/0x0031/*::]*/: { n:"CURSORW12" },
9213 /*::[*/0x0032/*::]*/: { n:"WINDOW" },
9214 /*::[*/0x0033/*::]*/: { n:"STRING", f:parse_LABEL },
9215 /*::[*/0x0037/*::]*/: { n:"PASSWORD" },
9216 /*::[*/0x0038/*::]*/: { n:"LOCKED" },
9217 /*::[*/0x003C/*::]*/: { n:"QUERY" },
9218 /*::[*/0x003D/*::]*/: { n:"QUERYNAME" },
9219 /*::[*/0x003E/*::]*/: { n:"PRINT" },
9220 /*::[*/0x003F/*::]*/: { n:"PRINTNAME" },
9221 /*::[*/0x0040/*::]*/: { n:"GRAPH2" },
9222 /*::[*/0x0041/*::]*/: { n:"GRAPHNAME" },
9223 /*::[*/0x0042/*::]*/: { n:"ZOOM" },
9224 /*::[*/0x0043/*::]*/: { n:"SYMSPLIT" },
9225 /*::[*/0x0044/*::]*/: { n:"NSROWS" },
9226 /*::[*/0x0045/*::]*/: { n:"NSCOLS" },
9227 /*::[*/0x0046/*::]*/: { n:"RULER" },
9228 /*::[*/0x0047/*::]*/: { n:"NNAME" },
9229 /*::[*/0x0048/*::]*/: { n:"ACOMM" },
9230 /*::[*/0x0049/*::]*/: { n:"AMACRO" },
9231 /*::[*/0x004A/*::]*/: { n:"PARSE" },
9232 /*::[*/0x0066/*::]*/: { n:"PRANGES??" },
9233 /*::[*/0x0067/*::]*/: { n:"RRANGES??" },
9234 /*::[*/0x0068/*::]*/: { n:"FNAME??" },
9235 /*::[*/0x0069/*::]*/: { n:"MRANGES??" },
9236 /*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
9237 /*::[*/0x00DE/*::]*/: { n:"SHEETNAMELP", f:parse_SHEETNAMELP },
9238 /*::[*/0xFFFF/*::]*/: { n:"" }
9239 };
9240
9241 var WK3Enum = {
9242 /*::[*/0x0000/*::]*/: { n:"BOF" },
9243 /*::[*/0x0001/*::]*/: { n:"EOF" },
9244 /*::[*/0x0002/*::]*/: { n:"PASSWORD" },
9245 /*::[*/0x0003/*::]*/: { n:"CALCSET" },
9246 /*::[*/0x0004/*::]*/: { n:"WINDOWSET" },
9247 /*::[*/0x0005/*::]*/: { n:"SHEETCELLPTR" },
9248 /*::[*/0x0006/*::]*/: { n:"SHEETLAYOUT" },
9249 /*::[*/0x0007/*::]*/: { n:"COLUMNWIDTH" },
9250 /*::[*/0x0008/*::]*/: { n:"HIDDENCOLUMN" },
9251 /*::[*/0x0009/*::]*/: { n:"USERRANGE" },
9252 /*::[*/0x000A/*::]*/: { n:"SYSTEMRANGE" },
9253 /*::[*/0x000B/*::]*/: { n:"ZEROFORCE" },
9254 /*::[*/0x000C/*::]*/: { n:"SORTKEYDIR" },
9255 /*::[*/0x000D/*::]*/: { n:"FILESEAL" },
9256 /*::[*/0x000E/*::]*/: { n:"DATAFILLNUMS" },
9257 /*::[*/0x000F/*::]*/: { n:"PRINTMAIN" },
9258 /*::[*/0x0010/*::]*/: { n:"PRINTSTRING" },
9259 /*::[*/0x0011/*::]*/: { n:"GRAPHMAIN" },
9260 /*::[*/0x0012/*::]*/: { n:"GRAPHSTRING" },
9261 /*::[*/0x0013/*::]*/: { n:"??" },
9262 /*::[*/0x0014/*::]*/: { n:"ERRCELL" },
9263 /*::[*/0x0015/*::]*/: { n:"NACELL" },
9264 /*::[*/0x0016/*::]*/: { n:"LABEL16", f:parse_LABEL_16},
9265 /*::[*/0x0017/*::]*/: { n:"NUMBER17", f:parse_NUMBER_17 },
9266 /*::[*/0x0018/*::]*/: { n:"NUMBER18", f:parse_NUMBER_18 },
9267 /*::[*/0x0019/*::]*/: { n:"FORMULA19", f:parse_FORMULA_19},
9268 /*::[*/0x001A/*::]*/: { n:"FORMULA1A" },
9269 /*::[*/0x001B/*::]*/: { n:"XFORMAT", f:parse_XFORMAT },
9270 /*::[*/0x001C/*::]*/: { n:"DTLABELMISC" },
9271 /*::[*/0x001D/*::]*/: { n:"DTLABELCELL" },
9272 /*::[*/0x001E/*::]*/: { n:"GRAPHWINDOW" },
9273 /*::[*/0x001F/*::]*/: { n:"CPA" },
9274 /*::[*/0x0020/*::]*/: { n:"LPLAUTO" },
9275 /*::[*/0x0021/*::]*/: { n:"QUERY" },
9276 /*::[*/0x0022/*::]*/: { n:"HIDDENSHEET" },
9277 /*::[*/0x0023/*::]*/: { n:"??" },
9278 /*::[*/0x0025/*::]*/: { n:"NUMBER25", f:parse_NUMBER_25 },
9279 /*::[*/0x0026/*::]*/: { n:"??" },
9280 /*::[*/0x0027/*::]*/: { n:"NUMBER27", f:parse_NUMBER_27 },
9281 /*::[*/0x0028/*::]*/: { n:"FORMULA28", f:parse_FORMULA_28 },
9282 /*::[*/0x008E/*::]*/: { n:"??" },
9283 /*::[*/0x0093/*::]*/: { n:"??" },
9284 /*::[*/0x0096/*::]*/: { n:"??" },
9285 /*::[*/0x0097/*::]*/: { n:"??" },
9286 /*::[*/0x0098/*::]*/: { n:"??" },
9287 /*::[*/0x0099/*::]*/: { n:"??" },
9288 /*::[*/0x009A/*::]*/: { n:"??" },
9289 /*::[*/0x009B/*::]*/: { n:"??" },
9290 /*::[*/0x009C/*::]*/: { n:"??" },
9291 /*::[*/0x00A3/*::]*/: { n:"??" },
9292 /*::[*/0x00AE/*::]*/: { n:"??" },
9293 /*::[*/0x00AF/*::]*/: { n:"??" },
9294 /*::[*/0x00B0/*::]*/: { n:"??" },
9295 /*::[*/0x00B1/*::]*/: { n:"??" },
9296 /*::[*/0x00B8/*::]*/: { n:"??" },
9297 /*::[*/0x00B9/*::]*/: { n:"??" },
9298 /*::[*/0x00BA/*::]*/: { n:"??" },
9299 /*::[*/0x00BB/*::]*/: { n:"??" },
9300 /*::[*/0x00BC/*::]*/: { n:"??" },
9301 /*::[*/0x00C3/*::]*/: { n:"??" },
9302 /*::[*/0x00C9/*::]*/: { n:"??" },
9303 /*::[*/0x00CC/*::]*/: { n:"SHEETNAMECS", f:parse_SHEETNAMECS },
9304 /*::[*/0x00CD/*::]*/: { n:"??" },
9305 /*::[*/0x00CE/*::]*/: { n:"??" },
9306 /*::[*/0x00CF/*::]*/: { n:"??" },
9307 /*::[*/0x00D0/*::]*/: { n:"??" },
9308 /*::[*/0x0100/*::]*/: { n:"??" },
9309 /*::[*/0x0103/*::]*/: { n:"??" },
9310 /*::[*/0x0104/*::]*/: { n:"??" },
9311 /*::[*/0x0105/*::]*/: { n:"??" },
9312 /*::[*/0x0106/*::]*/: { n:"??" },
9313 /*::[*/0x0107/*::]*/: { n:"??" },
9314 /*::[*/0x0109/*::]*/: { n:"??" },
9315 /*::[*/0x010A/*::]*/: { n:"??" },
9316 /*::[*/0x010B/*::]*/: { n:"??" },
9317 /*::[*/0x010C/*::]*/: { n:"??" },
9318 /*::[*/0x010E/*::]*/: { n:"??" },
9319 /*::[*/0x010F/*::]*/: { n:"??" },
9320 /*::[*/0x0180/*::]*/: { n:"??" },
9321 /*::[*/0x0185/*::]*/: { n:"??" },
9322 /*::[*/0x0186/*::]*/: { n:"??" },
9323 /*::[*/0x0189/*::]*/: { n:"??" },
9324 /*::[*/0x018C/*::]*/: { n:"??" },
9325 /*::[*/0x0200/*::]*/: { n:"??" },
9326 /*::[*/0x0202/*::]*/: { n:"??" },
9327 /*::[*/0x0201/*::]*/: { n:"??" },
9328 /*::[*/0x0204/*::]*/: { n:"??" },
9329 /*::[*/0x0205/*::]*/: { n:"??" },
9330 /*::[*/0x0280/*::]*/: { n:"??" },
9331 /*::[*/0x0281/*::]*/: { n:"??" },
9332 /*::[*/0x0282/*::]*/: { n:"??" },
9333 /*::[*/0x0283/*::]*/: { n:"??" },
9334 /*::[*/0x0284/*::]*/: { n:"??" },
9335 /*::[*/0x0285/*::]*/: { n:"??" },
9336 /*::[*/0x0286/*::]*/: { n:"??" },
9337 /*::[*/0x0287/*::]*/: { n:"??" },
9338 /*::[*/0x0288/*::]*/: { n:"??" },
9339 /*::[*/0x0292/*::]*/: { n:"??" },
9340 /*::[*/0x0293/*::]*/: { n:"??" },
9341 /*::[*/0x0294/*::]*/: { n:"??" },
9342 /*::[*/0x0295/*::]*/: { n:"??" },
9343 /*::[*/0x0296/*::]*/: { n:"??" },
9344 /*::[*/0x0299/*::]*/: { n:"??" },
9345 /*::[*/0x029A/*::]*/: { n:"??" },
9346 /*::[*/0x0300/*::]*/: { n:"??" },
9347 /*::[*/0x0304/*::]*/: { n:"??" },
9348 /*::[*/0x0601/*::]*/: { n:"SHEETINFOQP", f:parse_SHEETINFOQP },
9349 /*::[*/0x0640/*::]*/: { n:"??" },
9350 /*::[*/0x0642/*::]*/: { n:"??" },
9351 /*::[*/0x0701/*::]*/: { n:"??" },
9352 /*::[*/0x0702/*::]*/: { n:"??" },
9353 /*::[*/0x0703/*::]*/: { n:"??" },
9354 /*::[*/0x0704/*::]*/: { n:"??" },
9355 /*::[*/0x0780/*::]*/: { n:"??" },
9356 /*::[*/0x0800/*::]*/: { n:"??" },
9357 /*::[*/0x0801/*::]*/: { n:"??" },
9358 /*::[*/0x0804/*::]*/: { n:"??" },
9359 /*::[*/0x0A80/*::]*/: { n:"??" },
9360 /*::[*/0x2AF6/*::]*/: { n:"??" },
9361 /*::[*/0x3231/*::]*/: { n:"??" },
9362 /*::[*/0x6E49/*::]*/: { n:"??" },
9363 /*::[*/0x6F44/*::]*/: { n:"??" },
9364 /*::[*/0xFFFF/*::]*/: { n:"" }
9365 };
9366 return {
9367 sheet_to_wk1: sheet_to_wk1,
9368 book_to_wk3: book_to_wk3,
9369 to_workbook: lotus_to_workbook
9370 };
9371})();
9372/* 18.4.7 rPr CT_RPrElt */
9373function parse_rpr(rpr) {
9374 var font = {}, m = rpr.match(tagregex), i = 0;
9375 var pass = false;
9376 if(m) for(;i!=m.length; ++i) {
9377 var y = parsexmltag(m[i]);
9378 switch(y[0].replace(/\w*:/g,"")) {
9379 /* 18.8.12 condense CT_BooleanProperty */
9380 /* ** not required . */
9381 case '<condense': break;
9382 /* 18.8.17 extend CT_BooleanProperty */
9383 /* ** not required . */
9384 case '<extend': break;
9385 /* 18.8.36 shadow CT_BooleanProperty */
9386 /* ** not required . */
9387 case '<shadow':
9388 if(!y.val) break;
9389 /* falls through */
9390 case '<shadow>':
9391 case '<shadow/>': font.shadow = 1; break;
9392 case '</shadow>': break;
9393
9394 /* 18.4.1 charset CT_IntProperty TODO */
9395 case '<charset':
9396 if(y.val == '1') break;
9397 font.cp = CS2CP[parseInt(y.val, 10)];
9398 break;
9399
9400 /* 18.4.2 outline CT_BooleanProperty TODO */
9401 case '<outline':
9402 if(!y.val) break;
9403 /* falls through */
9404 case '<outline>':
9405 case '<outline/>': font.outline = 1; break;
9406 case '</outline>': break;
9407
9408 /* 18.4.5 rFont CT_FontName */
9409 case '<rFont': font.name = y.val; break;
9410
9411 /* 18.4.11 sz CT_FontSize */
9412 case '<sz': font.sz = y.val; break;
9413
9414 /* 18.4.10 strike CT_BooleanProperty */
9415 case '<strike':
9416 if(!y.val) break;
9417 /* falls through */
9418 case '<strike>':
9419 case '<strike/>': font.strike = 1; break;
9420 case '</strike>': break;
9421
9422 /* 18.4.13 u CT_UnderlineProperty */
9423 case '<u':
9424 if(!y.val) break;
9425 switch(y.val) {
9426 case 'double': font.uval = "double"; break;
9427 case 'singleAccounting': font.uval = "single-accounting"; break;
9428 case 'doubleAccounting': font.uval = "double-accounting"; break;
9429 }
9430 /* falls through */
9431 case '<u>':
9432 case '<u/>': font.u = 1; break;
9433 case '</u>': break;
9434
9435 /* 18.8.2 b */
9436 case '<b':
9437 if(y.val == '0') break;
9438 /* falls through */
9439 case '<b>':
9440 case '<b/>': font.b = 1; break;
9441 case '</b>': break;
9442
9443 /* 18.8.26 i */
9444 case '<i':
9445 if(y.val == '0') break;
9446 /* falls through */
9447 case '<i>':
9448 case '<i/>': font.i = 1; break;
9449 case '</i>': break;
9450
9451 /* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */
9452 case '<color':
9453 if(y.rgb) font.color = y.rgb.slice(2,8);
9454 break;
9455 case '<color>': case '<color/>': case '</color>': break;
9456
9457 /* 18.8.18 family ST_FontFamily */
9458 case '<family': font.family = y.val; break;
9459 case '<family>': case '<family/>': case '</family>': break;
9460
9461 /* 18.4.14 vertAlign CT_VerticalAlignFontProperty TODO */
9462 case '<vertAlign': font.valign = y.val; break;
9463 case '<vertAlign>': case '<vertAlign/>': case '</vertAlign>': break;
9464
9465 /* 18.8.35 scheme CT_FontScheme TODO */
9466 case '<scheme': break;
9467 case '<scheme>': case '<scheme/>': case '</scheme>': break;
9468
9469 /* 18.2.10 extLst CT_ExtensionList ? */
9470 case '<extLst': case '<extLst>': case '</extLst>': break;
9471 case '<ext': pass = true; break;
9472 case '</ext>': pass = false; break;
9473 default:
9474 if(y[0].charCodeAt(1) !== 47 && !pass) throw new Error('Unrecognized rich format ' + y[0]);
9475 }
9476 }
9477 return font;
9478}
9479
9480var parse_rs = /*#__PURE__*/(function() {
9481 var tregex = matchtag("t"), rpregex = matchtag("rPr");
9482 /* 18.4.4 r CT_RElt */
9483 function parse_r(r) {
9484 /* 18.4.12 t ST_Xstring */
9485 var t = r.match(tregex)/*, cp = 65001*/;
9486 if(!t) return {t:"s", v:""};
9487
9488 var o/*:Cell*/ = ({t:'s', v:unescapexml(t[1])}/*:any*/);
9489 var rpr = r.match(rpregex);
9490 if(rpr) o.s = parse_rpr(rpr[1]);
9491 return o;
9492 }
9493 var rregex = /<(?:\w+:)?r>/g, rend = /<\/(?:\w+:)?r>/;
9494 return function parse_rs(rs) {
9495 return rs.replace(rregex,"").split(rend).map(parse_r).filter(function(r) { return r.v; });
9496 };
9497})();
9498
9499
9500/* Parse a list of <r> tags */
9501var rs_to_html = /*#__PURE__*/(function parse_rs_factory() {
9502 var nlregex = /(\r\n|\n)/g;
9503 function parse_rpr2(font, intro, outro) {
9504 var style/*:Array<string>*/ = [];
9505
9506 if(font.u) style.push("text-decoration: underline;");
9507 if(font.uval) style.push("text-underline-style:" + font.uval + ";");
9508 if(font.sz) style.push("font-size:" + font.sz + "pt;");
9509 if(font.outline) style.push("text-effect: outline;");
9510 if(font.shadow) style.push("text-shadow: auto;");
9511 intro.push('<span style="' + style.join("") + '">');
9512
9513 if(font.b) { intro.push("<b>"); outro.push("</b>"); }
9514 if(font.i) { intro.push("<i>"); outro.push("</i>"); }
9515 if(font.strike) { intro.push("<s>"); outro.push("</s>"); }
9516
9517 var align = font.valign || "";
9518 if(align == "superscript" || align == "super") align = "sup";
9519 else if(align == "subscript") align = "sub";
9520 if(align != "") { intro.push("<" + align + ">"); outro.push("</" + align + ">"); }
9521
9522 outro.push("</span>");
9523 return font;
9524 }
9525
9526 /* 18.4.4 r CT_RElt */
9527 function r_to_html(r) {
9528 var terms/*:[Array<string>, string, Array<string>]*/ = [[],r.v,[]];
9529 if(!r.v) return "";
9530
9531 if(r.s) parse_rpr2(r.s, terms[0], terms[2]);
9532
9533 return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
9534 }
9535
9536 return function parse_rs(rs) {
9537 return rs.map(r_to_html).join("");
9538 };
9539})();
9540
9541/* 18.4.8 si CT_Rst */
9542var sitregex = /<(?:\w+:)?t[^>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r>/;
9543var sirphregex = /<(?:\w+:)?rPh.*?>([\s\S]*?)<\/(?:\w+:)?rPh>/g;
9544function parse_si(x, opts) {
9545 var html = opts ? opts.cellHTML : true;
9546 var z = {};
9547 if(!x) return { t: "" };
9548 //var y;
9549 /* 18.4.12 t ST_Xstring (Plaintext String) */
9550 // TODO: is whitespace actually valid here?
9551 if(x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
9552 z.t = unescapexml(utf8read(x.slice(x.indexOf(">")+1).split(/<\/(?:\w+:)?t>/)[0]||""));
9553 z.r = utf8read(x);
9554 if(html) z.h = escapehtml(z.t);
9555 }
9556 /* 18.4.4 r CT_RElt (Rich Text Run) */
9557 else if((/*y = */x.match(sirregex))) {
9558 z.r = utf8read(x);
9559 z.t = unescapexml(utf8read((x.replace(sirphregex, '').match(sitregex)||[]).join("").replace(tagregex,"")));
9560 if(html) z.h = rs_to_html(parse_rs(z.r));
9561 }
9562 /* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
9563 /* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */
9564 return z;
9565}
9566
9567/* 18.4 Shared String Table */
9568var sstr0 = /<(?:\w+:)?sst([^>]*)>([\s\S]*)<\/(?:\w+:)?sst>/;
9569var sstr1 = /<(?:\w+:)?(?:si|sstItem)>/g;
9570var sstr2 = /<\/(?:\w+:)?(?:si|sstItem)>/;
9571function parse_sst_xml(data/*:string*/, opts)/*:SST*/ {
9572 var s/*:SST*/ = ([]/*:any*/), ss = "";
9573 if(!data) return s;
9574 /* 18.4.9 sst CT_Sst */
9575 var sst = data.match(sstr0);
9576 if(sst) {
9577 ss = sst[2].replace(sstr1,"").split(sstr2);
9578 for(var i = 0; i != ss.length; ++i) {
9579 var o = parse_si(ss[i].trim(), opts);
9580 if(o != null) s[s.length] = o;
9581 }
9582 sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
9583 }
9584 return s;
9585}
9586
9587var straywsregex = /^\s|\s$|[\t\n\r]/;
9588function write_sst_xml(sst/*:SST*/, opts)/*:string*/ {
9589 if(!opts.bookSST) return "";
9590 var o = [XML_HEADER];
9591 o[o.length] = (writextag('sst', null, {
9592 xmlns: XMLNS_main[0],
9593 count: sst.Count,
9594 uniqueCount: sst.Unique
9595 }));
9596 for(var i = 0; i != sst.length; ++i) { if(sst[i] == null) continue;
9597 var s/*:XLString*/ = sst[i];
9598 var sitag = "<si>";
9599 if(s.r) sitag += s.r;
9600 else {
9601 sitag += "<t";
9602 if(!s.t) s.t = "";
9603 if(s.t.match(straywsregex)) sitag += ' xml:space="preserve"';
9604 sitag += ">" + escapexml(s.t) + "</t>";
9605 }
9606 sitag += "</si>";
9607 o[o.length] = (sitag);
9608 }
9609 if(o.length>2){ o[o.length] = ('</sst>'); o[1]=o[1].replace("/>",">"); }
9610 return o.join("");
9611}
9612/* [MS-XLSB] 2.4.221 BrtBeginSst */
9613function parse_BrtBeginSst(data) {
9614 return [data.read_shift(4), data.read_shift(4)];
9615}
9616
9617/* [MS-XLSB] 2.1.7.45 Shared Strings */
9618function parse_sst_bin(data, opts)/*:SST*/ {
9619 var s/*:SST*/ = ([]/*:any*/);
9620 var pass = false;
9621 recordhopper(data, function hopper_sst(val, R, RT) {
9622 switch(RT) {
9623 case 0x009F: /* BrtBeginSst */
9624 s.Count = val[0]; s.Unique = val[1]; break;
9625 case 0x0013: /* BrtSSTItem */
9626 s.push(val); break;
9627 case 0x00A0: /* BrtEndSst */
9628 return true;
9629
9630 case 0x0023: /* BrtFRTBegin */
9631 pass = true; break;
9632 case 0x0024: /* BrtFRTEnd */
9633 pass = false; break;
9634
9635 default:
9636 if(R.T){}
9637 if(!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
9638 }
9639 });
9640 return s;
9641}
9642
9643function write_BrtBeginSst(sst, o) {
9644 if(!o) o = new_buf(8);
9645 o.write_shift(4, sst.Count);
9646 o.write_shift(4, sst.Unique);
9647 return o;
9648}
9649
9650var write_BrtSSTItem = write_RichStr;
9651
9652function write_sst_bin(sst/*::, opts*/) {
9653 var ba = buf_array();
9654 write_record(ba, 0x009F /* BrtBeginSst */, write_BrtBeginSst(sst));
9655 for(var i = 0; i < sst.length; ++i) write_record(ba, 0x0013 /* BrtSSTItem */, write_BrtSSTItem(sst[i]));
9656 /* FRTSST */
9657 write_record(ba, 0x00A0 /* BrtEndSst */);
9658 return ba.end();
9659}
9660function _JS2ANSI(str/*:string*/)/*:Array<number>*/ {
9661 if(typeof $cptable !== 'undefined') return $cptable.utils.encode(current_ansi, str);
9662 var o/*:Array<number>*/ = [], oo = str.split("");
9663 for(var i = 0; i < oo.length; ++i) o[i] = oo[i].charCodeAt(0);
9664 return o;
9665}
9666
9667/* [MS-OFFCRYPTO] 2.1.4 Version */
9668function parse_CRYPTOVersion(blob, length/*:?number*/) {
9669 var o/*:any*/ = {};
9670 o.Major = blob.read_shift(2);
9671 o.Minor = blob.read_shift(2);
9672 /*:: if(length == null) return o; */
9673 if(length >= 4) blob.l += length - 4;
9674 return o;
9675}
9676
9677/* [MS-OFFCRYPTO] 2.1.5 DataSpaceVersionInfo */
9678function parse_DataSpaceVersionInfo(blob) {
9679 var o = {};
9680 o.id = blob.read_shift(0, 'lpp4');
9681 o.R = parse_CRYPTOVersion(blob, 4);
9682 o.U = parse_CRYPTOVersion(blob, 4);
9683 o.W = parse_CRYPTOVersion(blob, 4);
9684 return o;
9685}
9686
9687/* [MS-OFFCRYPTO] 2.1.6.1 DataSpaceMapEntry Structure */
9688function parse_DataSpaceMapEntry(blob) {
9689 var len = blob.read_shift(4);
9690 var end = blob.l + len - 4;
9691 var o = {};
9692 var cnt = blob.read_shift(4);
9693 var comps/*:Array<{t:number, v:string}>*/ = [];
9694 /* [MS-OFFCRYPTO] 2.1.6.2 DataSpaceReferenceComponent Structure */
9695 while(cnt-- > 0) comps.push({ t: blob.read_shift(4), v: blob.read_shift(0, 'lpp4') });
9696 o.name = blob.read_shift(0, 'lpp4');
9697 o.comps = comps;
9698 if(blob.l != end) throw new Error("Bad DataSpaceMapEntry: " + blob.l + " != " + end);
9699 return o;
9700}
9701
9702/* [MS-OFFCRYPTO] 2.1.6 DataSpaceMap */
9703function parse_DataSpaceMap(blob) {
9704 var o = [];
9705 blob.l += 4; // must be 0x8
9706 var cnt = blob.read_shift(4);
9707 while(cnt-- > 0) o.push(parse_DataSpaceMapEntry(blob));
9708 return o;
9709}
9710
9711/* [MS-OFFCRYPTO] 2.1.7 DataSpaceDefinition */
9712function parse_DataSpaceDefinition(blob)/*:Array<string>*/ {
9713 var o/*:Array<string>*/ = [];
9714 blob.l += 4; // must be 0x8
9715 var cnt = blob.read_shift(4);
9716 while(cnt-- > 0) o.push(blob.read_shift(0, 'lpp4'));
9717 return o;
9718}
9719
9720/* [MS-OFFCRYPTO] 2.1.8 DataSpaceDefinition */
9721function parse_TransformInfoHeader(blob) {
9722 var o = {};
9723 /*var len = */blob.read_shift(4);
9724 blob.l += 4; // must be 0x1
9725 o.id = blob.read_shift(0, 'lpp4');
9726 o.name = blob.read_shift(0, 'lpp4');
9727 o.R = parse_CRYPTOVersion(blob, 4);
9728 o.U = parse_CRYPTOVersion(blob, 4);
9729 o.W = parse_CRYPTOVersion(blob, 4);
9730 return o;
9731}
9732
9733function parse_Primary(blob) {
9734 /* [MS-OFFCRYPTO] 2.2.6 IRMDSTransformInfo */
9735 var hdr = parse_TransformInfoHeader(blob);
9736 /* [MS-OFFCRYPTO] 2.1.9 EncryptionTransformInfo */
9737 hdr.ename = blob.read_shift(0, '8lpp4');
9738 hdr.blksz = blob.read_shift(4);
9739 hdr.cmode = blob.read_shift(4);
9740 if(blob.read_shift(4) != 0x04) throw new Error("Bad !Primary record");
9741 return hdr;
9742}
9743
9744/* [MS-OFFCRYPTO] 2.3.2 Encryption Header */
9745function parse_EncryptionHeader(blob, length/*:number*/) {
9746 var tgt = blob.l + length;
9747 var o = {};
9748 o.Flags = (blob.read_shift(4) & 0x3F);
9749 blob.l += 4;
9750 o.AlgID = blob.read_shift(4);
9751 var valid = false;
9752 switch(o.AlgID) {
9753 case 0x660E: case 0x660F: case 0x6610: valid = (o.Flags == 0x24); break;
9754 case 0x6801: valid = (o.Flags == 0x04); break;
9755 case 0: valid = (o.Flags == 0x10 || o.Flags == 0x04 || o.Flags == 0x24); break;
9756 default: throw 'Unrecognized encryption algorithm: ' + o.AlgID;
9757 }
9758 if(!valid) throw new Error("Encryption Flags/AlgID mismatch");
9759 o.AlgIDHash = blob.read_shift(4);
9760 o.KeySize = blob.read_shift(4);
9761 o.ProviderType = blob.read_shift(4);
9762 blob.l += 8;
9763 o.CSPName = blob.read_shift((tgt-blob.l)>>1, 'utf16le');
9764 blob.l = tgt;
9765 return o;
9766}
9767
9768/* [MS-OFFCRYPTO] 2.3.3 Encryption Verifier */
9769function parse_EncryptionVerifier(blob, length/*:number*/) {
9770 var o = {}, tgt = blob.l + length;
9771 blob.l += 4; // SaltSize must be 0x10
9772 o.Salt = blob.slice(blob.l, blob.l+16); blob.l += 16;
9773 o.Verifier = blob.slice(blob.l, blob.l+16); blob.l += 16;
9774 /*var sz = */blob.read_shift(4);
9775 o.VerifierHash = blob.slice(blob.l, tgt); blob.l = tgt;
9776 return o;
9777}
9778
9779/* [MS-OFFCRYPTO] 2.3.4.* EncryptionInfo Stream */
9780function parse_EncryptionInfo(blob) {
9781 var vers = parse_CRYPTOVersion(blob);
9782 switch(vers.Minor) {
9783 case 0x02: return [vers.Minor, parse_EncInfoStd(blob, vers)];
9784 case 0x03: return [vers.Minor, parse_EncInfoExt(blob, vers)];
9785 case 0x04: return [vers.Minor, parse_EncInfoAgl(blob, vers)];
9786 }
9787 throw new Error("ECMA-376 Encrypted file unrecognized Version: " + vers.Minor);
9788}
9789
9790/* [MS-OFFCRYPTO] 2.3.4.5 EncryptionInfo Stream (Standard Encryption) */
9791function parse_EncInfoStd(blob/*::, vers*/) {
9792 var flags = blob.read_shift(4);
9793 if((flags & 0x3F) != 0x24) throw new Error("EncryptionInfo mismatch");
9794 var sz = blob.read_shift(4);
9795 //var tgt = blob.l + sz;
9796 var hdr = parse_EncryptionHeader(blob, sz);
9797 var verifier = parse_EncryptionVerifier(blob, blob.length - blob.l);
9798 return { t:"Std", h:hdr, v:verifier };
9799}
9800/* [MS-OFFCRYPTO] 2.3.4.6 EncryptionInfo Stream (Extensible Encryption) */
9801function parse_EncInfoExt(/*::blob, vers*/) { throw new Error("File is password-protected: ECMA-376 Extensible"); }
9802/* [MS-OFFCRYPTO] 2.3.4.10 EncryptionInfo Stream (Agile Encryption) */
9803function parse_EncInfoAgl(blob/*::, vers*/) {
9804 var KeyData = ["saltSize","blockSize","keyBits","hashSize","cipherAlgorithm","cipherChaining","hashAlgorithm","saltValue"];
9805 blob.l+=4;
9806 var xml = blob.read_shift(blob.length - blob.l, 'utf8');
9807 var o = {};
9808 xml.replace(tagregex, function xml_agile(x) {
9809 var y/*:any*/ = parsexmltag(x);
9810 switch(strip_ns(y[0])) {
9811 case '<?xml': break;
9812 case '<encryption': case '</encryption>': break;
9813 case '<keyData': KeyData.forEach(function(k) { o[k] = y[k]; }); break;
9814 case '<dataIntegrity': o.encryptedHmacKey = y.encryptedHmacKey; o.encryptedHmacValue = y.encryptedHmacValue; break;
9815 case '<keyEncryptors>': case '<keyEncryptors': o.encs = []; break;
9816 case '</keyEncryptors>': break;
9817
9818 case '<keyEncryptor': o.uri = y.uri; break;
9819 case '</keyEncryptor>': break;
9820 case '<encryptedKey': o.encs.push(y); break;
9821 default: throw y[0];
9822 }
9823 });
9824 return o;
9825}
9826
9827/* [MS-OFFCRYPTO] 2.3.5.1 RC4 CryptoAPI Encryption Header */
9828function parse_RC4CryptoHeader(blob, length/*:number*/) {
9829 var o = {};
9830 var vers = o.EncryptionVersionInfo = parse_CRYPTOVersion(blob, 4); length -= 4;
9831 if(vers.Minor != 2) throw new Error('unrecognized minor version code: ' + vers.Minor);
9832 if(vers.Major > 4 || vers.Major < 2) throw new Error('unrecognized major version code: ' + vers.Major);
9833 o.Flags = blob.read_shift(4); length -= 4;
9834 var sz = blob.read_shift(4); length -= 4;
9835 o.EncryptionHeader = parse_EncryptionHeader(blob, sz); length -= sz;
9836 o.EncryptionVerifier = parse_EncryptionVerifier(blob, length);
9837 return o;
9838}
9839/* [MS-OFFCRYPTO] 2.3.6.1 RC4 Encryption Header */
9840function parse_RC4Header(blob/*::, length*/) {
9841 var o = {};
9842 var vers = o.EncryptionVersionInfo = parse_CRYPTOVersion(blob, 4);
9843 if(vers.Major != 1 || vers.Minor != 1) throw 'unrecognized version code ' + vers.Major + ' : ' + vers.Minor;
9844 o.Salt = blob.read_shift(16);
9845 o.EncryptedVerifier = blob.read_shift(16);
9846 o.EncryptedVerifierHash = blob.read_shift(16);
9847 return o;
9848}
9849
9850/* [MS-OFFCRYPTO] 2.3.7.1 Binary Document Password Verifier Derivation */
9851function crypto_CreatePasswordVerifier_Method1(Password/*:string*/) {
9852 var Verifier = 0x0000, PasswordArray;
9853 var PasswordDecoded = _JS2ANSI(Password);
9854 var len = PasswordDecoded.length + 1, i, PasswordByte;
9855 var Intermediate1, Intermediate2, Intermediate3;
9856 PasswordArray = new_raw_buf(len);
9857 PasswordArray[0] = PasswordDecoded.length;
9858 for(i = 1; i != len; ++i) PasswordArray[i] = PasswordDecoded[i-1];
9859 for(i = len-1; i >= 0; --i) {
9860 PasswordByte = PasswordArray[i];
9861 Intermediate1 = ((Verifier & 0x4000) === 0x0000) ? 0 : 1;
9862 Intermediate2 = (Verifier << 1) & 0x7FFF;
9863 Intermediate3 = Intermediate1 | Intermediate2;
9864 Verifier = Intermediate3 ^ PasswordByte;
9865 }
9866 return Verifier ^ 0xCE4B;
9867}
9868
9869/* [MS-OFFCRYPTO] 2.3.7.2 Binary Document XOR Array Initialization */
9870var crypto_CreateXorArray_Method1 = /*#__PURE__*/(function() {
9871 var PadArray = [0xBB, 0xFF, 0xFF, 0xBA, 0xFF, 0xFF, 0xB9, 0x80, 0x00, 0xBE, 0x0F, 0x00, 0xBF, 0x0F, 0x00];
9872 var InitialCode = [0xE1F0, 0x1D0F, 0xCC9C, 0x84C0, 0x110C, 0x0E10, 0xF1CE, 0x313E, 0x1872, 0xE139, 0xD40F, 0x84F9, 0x280C, 0xA96A, 0x4EC3];
9873 var XorMatrix = [0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09, 0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF, 0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0, 0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40, 0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5, 0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A, 0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9, 0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0, 0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC, 0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10, 0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168, 0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C, 0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD, 0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC, 0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4];
9874 var Ror = function(Byte) { return ((Byte/2) | (Byte*128)) & 0xFF; };
9875 var XorRor = function(byte1, byte2) { return Ror(byte1 ^ byte2); };
9876 var CreateXorKey_Method1 = function(Password) {
9877 var XorKey = InitialCode[Password.length - 1];
9878 var CurrentElement = 0x68;
9879 for(var i = Password.length-1; i >= 0; --i) {
9880 var Char = Password[i];
9881 for(var j = 0; j != 7; ++j) {
9882 if(Char & 0x40) XorKey ^= XorMatrix[CurrentElement];
9883 Char *= 2; --CurrentElement;
9884 }
9885 }
9886 return XorKey;
9887 };
9888 return function(password/*:string*/) {
9889 var Password = _JS2ANSI(password);
9890 var XorKey = CreateXorKey_Method1(Password);
9891 var Index = Password.length;
9892 var ObfuscationArray = new_raw_buf(16);
9893 for(var i = 0; i != 16; ++i) ObfuscationArray[i] = 0x00;
9894 var Temp, PasswordLastChar, PadIndex;
9895 if((Index & 1) === 1) {
9896 Temp = XorKey >> 8;
9897 ObfuscationArray[Index] = XorRor(PadArray[0], Temp);
9898 --Index;
9899 Temp = XorKey & 0xFF;
9900 PasswordLastChar = Password[Password.length - 1];
9901 ObfuscationArray[Index] = XorRor(PasswordLastChar, Temp);
9902 }
9903 while(Index > 0) {
9904 --Index;
9905 Temp = XorKey >> 8;
9906 ObfuscationArray[Index] = XorRor(Password[Index], Temp);
9907 --Index;
9908 Temp = XorKey & 0xFF;
9909 ObfuscationArray[Index] = XorRor(Password[Index], Temp);
9910 }
9911 Index = 15;
9912 PadIndex = 15 - Password.length;
9913 while(PadIndex > 0) {
9914 Temp = XorKey >> 8;
9915 ObfuscationArray[Index] = XorRor(PadArray[PadIndex], Temp);
9916 --Index;
9917 --PadIndex;
9918 Temp = XorKey & 0xFF;
9919 ObfuscationArray[Index] = XorRor(Password[Index], Temp);
9920 --Index;
9921 --PadIndex;
9922 }
9923 return ObfuscationArray;
9924 };
9925})();
9926
9927/* [MS-OFFCRYPTO] 2.3.7.3 Binary Document XOR Data Transformation Method 1 */
9928var crypto_DecryptData_Method1 = function(password/*:string*/, Data, XorArrayIndex, XorArray, O) {
9929 /* If XorArray is set, use it; if O is not set, make changes in-place */
9930 if(!O) O = Data;
9931 if(!XorArray) XorArray = crypto_CreateXorArray_Method1(password);
9932 var Index, Value;
9933 for(Index = 0; Index != Data.length; ++Index) {
9934 Value = Data[Index];
9935 Value ^= XorArray[XorArrayIndex];
9936 Value = ((Value>>5) | (Value<<3)) & 0xFF;
9937 O[Index] = Value;
9938 ++XorArrayIndex;
9939 }
9940 return [O, XorArrayIndex, XorArray];
9941};
9942
9943var crypto_MakeXorDecryptor = function(password/*:string*/) {
9944 var XorArrayIndex = 0, XorArray = crypto_CreateXorArray_Method1(password);
9945 return function(Data) {
9946 var O = crypto_DecryptData_Method1("", Data, XorArrayIndex, XorArray);
9947 XorArrayIndex = O[1];
9948 return O[0];
9949 };
9950};
9951
9952/* 2.5.343 */
9953function parse_XORObfuscation(blob, length, opts, out) {
9954 var o = ({ key: parseuint16(blob), verificationBytes: parseuint16(blob) }/*:any*/);
9955 if(opts.password) o.verifier = crypto_CreatePasswordVerifier_Method1(opts.password);
9956 out.valid = o.verificationBytes === o.verifier;
9957 if(out.valid) out.insitu = crypto_MakeXorDecryptor(opts.password);
9958 return o;
9959}
9960
9961/* 2.4.117 */
9962function parse_FilePassHeader(blob, length/*:number*/, oo) {
9963 var o = oo || {}; o.Info = blob.read_shift(2); blob.l -= 2;
9964 if(o.Info === 1) o.Data = parse_RC4Header(blob, length);
9965 else o.Data = parse_RC4CryptoHeader(blob, length);
9966 return o;
9967}
9968function parse_FilePass(blob, length/*:number*/, opts) {
9969 var o = ({ Type: opts.biff >= 8 ? blob.read_shift(2) : 0 }/*:any*/); /* wEncryptionType */
9970 if(o.Type) parse_FilePassHeader(blob, length-2, o);
9971 else parse_XORObfuscation(blob, opts.biff >= 8 ? length : length - 2, opts, o);
9972 return o;
9973}
9974
9975
9976var RTF = /*#__PURE__*/(function() {
9977 function rtf_to_sheet(d/*:RawData*/, opts)/*:Worksheet*/ {
9978 switch(opts.type) {
9979 case 'base64': return rtf_to_sheet_str(Base64_decode(d), opts);
9980 case 'binary': return rtf_to_sheet_str(d, opts);
9981 case 'buffer': return rtf_to_sheet_str(has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d), opts);
9982 case 'array': return rtf_to_sheet_str(cc2str(d), opts);
9983 }
9984 throw new Error("Unrecognized type " + opts.type);
9985 }
9986
9987 /* TODO: this is a stub */
9988 function rtf_to_sheet_str(str/*:string*/, opts)/*:Worksheet*/ {
9989 var o = opts || {};
9990 var ws/*:Worksheet*/ = o.dense ? ([]/*:any*/) : ({}/*:any*/);
9991
9992 var rows = str.match(/\\trowd.*?\\row\b/g);
9993 if(!rows.length) throw new Error("RTF missing table");
9994 var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:0, r:rows.length - 1}}/*:any*/);
9995 rows.forEach(function(rowtf, R) {
9996 if(Array.isArray(ws)) ws[R] = [];
9997 var rtfre = /\\\w+\b/g;
9998 var last_index = 0;
9999 var res;
10000 var C = -1;
10001 while((res = rtfre.exec(rowtf))) {
10002 switch(res[0]) {
10003 case "\\cell":
10004 var data = rowtf.slice(last_index, rtfre.lastIndex - res[0].length);
10005 if(data[0] == " ") data = data.slice(1);
10006 ++C;
10007 if(data.length) {
10008 // TODO: value parsing, including codepage adjustments
10009 var cell = {v: data, t:"s"};
10010 if(Array.isArray(ws)) ws[R][C] = cell;
10011 else ws[encode_cell({r:R, c:C})] = cell;
10012 }
10013 break;
10014 }
10015 last_index = rtfre.lastIndex;
10016 }
10017 if(C > range.e.c) range.e.c = C;
10018 });
10019 ws['!ref'] = encode_range(range);
10020 return ws;
10021 }
10022
10023 function rtf_to_workbook(d/*:RawData*/, opts)/*:Workbook*/ { return sheet_to_workbook(rtf_to_sheet(d, opts), opts); }
10024
10025 /* TODO: this is a stub */
10026 function sheet_to_rtf(ws/*:Worksheet*//*::, opts*/)/*:string*/ {
10027 var o = ["{\\rtf1\\ansi"];
10028 var r = safe_decode_range(ws['!ref']), cell/*:Cell*/;
10029 var dense = Array.isArray(ws);
10030 for(var R = r.s.r; R <= r.e.r; ++R) {
10031 o.push("\\trowd\\trautofit1");
10032 for(var C = r.s.c; C <= r.e.c; ++C) o.push("\\cellx" + (C+1));
10033 o.push("\\pard\\intbl");
10034 for(C = r.s.c; C <= r.e.c; ++C) {
10035 var coord = encode_cell({r:R,c:C});
10036 cell = dense ? (ws[R]||[])[C]: ws[coord];
10037 if(!cell || cell.v == null && (!cell.f || cell.F)) continue;
10038 o.push(" " + (cell.w || (format_cell(cell), cell.w)));
10039 o.push("\\cell");
10040 }
10041 o.push("\\pard\\intbl\\row");
10042 }
10043 return o.join("") + "}";
10044 }
10045
10046 return {
10047 to_workbook: rtf_to_workbook,
10048 to_sheet: rtf_to_sheet,
10049 from_sheet: sheet_to_rtf
10050 };
10051})();
10052function hex2RGB(h) {
10053 var o = h.slice(h[0]==="#"?1:0).slice(0,6);
10054 return [parseInt(o.slice(0,2),16),parseInt(o.slice(2,4),16),parseInt(o.slice(4,6),16)];
10055}
10056function rgb2Hex(rgb) {
10057 for(var i=0,o=1; i!=3; ++i) o = o*256 + (rgb[i]>255?255:rgb[i]<0?0:rgb[i]);
10058 return o.toString(16).toUpperCase().slice(1);
10059}
10060
10061function rgb2HSL(rgb) {
10062 var R = rgb[0]/255, G = rgb[1]/255, B=rgb[2]/255;
10063 var M = Math.max(R, G, B), m = Math.min(R, G, B), C = M - m;
10064 if(C === 0) return [0, 0, R];
10065
10066 var H6 = 0, S = 0, L2 = (M + m);
10067 S = C / (L2 > 1 ? 2 - L2 : L2);
10068 switch(M){
10069 case R: H6 = ((G - B) / C + 6)%6; break;
10070 case G: H6 = ((B - R) / C + 2); break;
10071 case B: H6 = ((R - G) / C + 4); break;
10072 }
10073 return [H6 / 6, S, L2 / 2];
10074}
10075
10076function hsl2RGB(hsl){
10077 var H = hsl[0], S = hsl[1], L = hsl[2];
10078 var C = S * 2 * (L < 0.5 ? L : 1 - L), m = L - C/2;
10079 var rgb = [m,m,m], h6 = 6*H;
10080
10081 var X;
10082 if(S !== 0) switch(h6|0) {
10083 case 0: case 6: X = C * h6; rgb[0] += C; rgb[1] += X; break;
10084 case 1: X = C * (2 - h6); rgb[0] += X; rgb[1] += C; break;
10085 case 2: X = C * (h6 - 2); rgb[1] += C; rgb[2] += X; break;
10086 case 3: X = C * (4 - h6); rgb[1] += X; rgb[2] += C; break;
10087 case 4: X = C * (h6 - 4); rgb[2] += C; rgb[0] += X; break;
10088 case 5: X = C * (6 - h6); rgb[2] += X; rgb[0] += C; break;
10089 }
10090 for(var i = 0; i != 3; ++i) rgb[i] = Math.round(rgb[i]*255);
10091 return rgb;
10092}
10093
10094/* 18.8.3 bgColor tint algorithm */
10095function rgb_tint(hex, tint) {
10096 if(tint === 0) return hex;
10097 var hsl = rgb2HSL(hex2RGB(hex));
10098 if (tint < 0) hsl[2] = hsl[2] * (1 + tint);
10099 else hsl[2] = 1 - (1 - hsl[2]) * (1 - tint);
10100 return rgb2Hex(hsl2RGB(hsl));
10101}
10102
10103/* 18.3.1.13 width calculations */
10104/* [MS-OI29500] 2.1.595 Column Width & Formatting */
10105var DEF_MDW = 6, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
10106function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
10107function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
10108function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; }
10109//function px2char_(px) { return (((px - 5)/MDW * 100 + 0.5))/100; }
10110//function char2width_(chr) { return (((chr * MDW + 5)/MDW*256))/256; }
10111function cycle_width(collw) { return char2width(px2char(width2px(collw))); }
10112/* XLSX/XLSB/XLS specify width in units of MDW */
10113function find_mdw_colw(collw) {
10114 var delta = Math.abs(collw - cycle_width(collw)), _MDW = MDW;
10115 if(delta > 0.005) for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) if(Math.abs(collw - cycle_width(collw)) <= delta) { delta = Math.abs(collw - cycle_width(collw)); _MDW = MDW; }
10116 MDW = _MDW;
10117}
10118/* XLML specifies width in terms of pixels */
10119/*function find_mdw_wpx(wpx) {
10120 var delta = Infinity, guess = 0, _MDW = MIN_MDW;
10121 for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) {
10122 guess = char2width_(px2char_(wpx))*256;
10123 guess = (guess) % 1;
10124 if(guess > 0.5) guess--;
10125 if(Math.abs(guess) < delta) { delta = Math.abs(guess); _MDW = MDW; }
10126 }
10127 MDW = _MDW;
10128}*/
10129
10130function process_col(coll/*:ColInfo*/) {
10131 if(coll.width) {
10132 coll.wpx = width2px(coll.width);
10133 coll.wch = px2char(coll.wpx);
10134 coll.MDW = MDW;
10135 } else if(coll.wpx) {
10136 coll.wch = px2char(coll.wpx);
10137 coll.width = char2width(coll.wch);
10138 coll.MDW = MDW;
10139 } else if(typeof coll.wch == 'number') {
10140 coll.width = char2width(coll.wch);
10141 coll.wpx = width2px(coll.width);
10142 coll.MDW = MDW;
10143 }
10144 if(coll.customWidth) delete coll.customWidth;
10145}
10146
10147var DEF_PPI = 96, PPI = DEF_PPI;
10148function px2pt(px) { return px * 96 / PPI; }
10149function pt2px(pt) { return pt * PPI / 96; }
10150
10151/* [MS-EXSPXML3] 2.4.54 ST_enmPattern */
10152var XLMLPatternTypeMap = {
10153 "None": "none",
10154 "Solid": "solid",
10155 "Gray50": "mediumGray",
10156 "Gray75": "darkGray",
10157 "Gray25": "lightGray",
10158 "HorzStripe": "darkHorizontal",
10159 "VertStripe": "darkVertical",
10160 "ReverseDiagStripe": "darkDown",
10161 "DiagStripe": "darkUp",
10162 "DiagCross": "darkGrid",
10163 "ThickDiagCross": "darkTrellis",
10164 "ThinHorzStripe": "lightHorizontal",
10165 "ThinVertStripe": "lightVertical",
10166 "ThinReverseDiagStripe": "lightDown",
10167 "ThinHorzCross": "lightGrid"
10168};
10169
10170/* 18.8.5 borders CT_Borders */
10171function parse_borders(t, styles, themes, opts) {
10172 styles.Borders = [];
10173 var border = {};
10174 var pass = false;
10175 (t[0].match(tagregex)||[]).forEach(function(x) {
10176 var y = parsexmltag(x);
10177 switch(strip_ns(y[0])) {
10178 case '<borders': case '<borders>': case '</borders>': break;
10179
10180 /* 18.8.4 border CT_Border */
10181 case '<border': case '<border>': case '<border/>':
10182 border = /*::(*/{}/*:: :any)*/;
10183 if(y.diagonalUp) border.diagonalUp = parsexmlbool(y.diagonalUp);
10184 if(y.diagonalDown) border.diagonalDown = parsexmlbool(y.diagonalDown);
10185 styles.Borders.push(border);
10186 break;
10187 case '</border>': break;
10188
10189 /* note: not in spec, appears to be CT_BorderPr */
10190 case '<left/>': break;
10191 case '<left': case '<left>': break;
10192 case '</left>': break;
10193
10194 /* note: not in spec, appears to be CT_BorderPr */
10195 case '<right/>': break;
10196 case '<right': case '<right>': break;
10197 case '</right>': break;
10198
10199 /* 18.8.43 top CT_BorderPr */
10200 case '<top/>': break;
10201 case '<top': case '<top>': break;
10202 case '</top>': break;
10203
10204 /* 18.8.6 bottom CT_BorderPr */
10205 case '<bottom/>': break;
10206 case '<bottom': case '<bottom>': break;
10207 case '</bottom>': break;
10208
10209 /* 18.8.13 diagonal CT_BorderPr */
10210 case '<diagonal': case '<diagonal>': case '<diagonal/>': break;
10211 case '</diagonal>': break;
10212
10213 /* 18.8.25 horizontal CT_BorderPr */
10214 case '<horizontal': case '<horizontal>': case '<horizontal/>': break;
10215 case '</horizontal>': break;
10216
10217 /* 18.8.44 vertical CT_BorderPr */
10218 case '<vertical': case '<vertical>': case '<vertical/>': break;
10219 case '</vertical>': break;
10220
10221 /* 18.8.37 start CT_BorderPr */
10222 case '<start': case '<start>': case '<start/>': break;
10223 case '</start>': break;
10224
10225 /* 18.8.16 end CT_BorderPr */
10226 case '<end': case '<end>': case '<end/>': break;
10227 case '</end>': break;
10228
10229 /* 18.8.? color CT_Color */
10230 case '<color': case '<color>':
10231 break;
10232 case '<color/>': case '</color>': break;
10233
10234 /* 18.2.10 extLst CT_ExtensionList ? */
10235 case '<extLst': case '<extLst>': case '</extLst>': break;
10236 case '<ext': pass = true; break;
10237 case '</ext>': pass = false; break;
10238 default: if(opts && opts.WTF) {
10239 if(!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
10240 }
10241 }
10242 });
10243}
10244
10245/* 18.8.21 fills CT_Fills */
10246function parse_fills(t, styles, themes, opts) {
10247 styles.Fills = [];
10248 var fill = {};
10249 var pass = false;
10250 (t[0].match(tagregex)||[]).forEach(function(x) {
10251 var y = parsexmltag(x);
10252 switch(strip_ns(y[0])) {
10253 case '<fills': case '<fills>': case '</fills>': break;
10254
10255 /* 18.8.20 fill CT_Fill */
10256 case '<fill>': case '<fill': case '<fill/>':
10257 fill = {}; styles.Fills.push(fill); break;
10258 case '</fill>': break;
10259
10260 /* 18.8.24 gradientFill CT_GradientFill */
10261 case '<gradientFill>': break;
10262 case '<gradientFill':
10263 case '</gradientFill>': styles.Fills.push(fill); fill = {}; break;
10264
10265 /* 18.8.32 patternFill CT_PatternFill */
10266 case '<patternFill': case '<patternFill>':
10267 if(y.patternType) fill.patternType = y.patternType;
10268 break;
10269 case '<patternFill/>': case '</patternFill>': break;
10270
10271 /* 18.8.3 bgColor CT_Color */
10272 case '<bgColor':
10273 if(!fill.bgColor) fill.bgColor = {};
10274 if(y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
10275 if(y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
10276 if(y.tint) fill.bgColor.tint = parseFloat(y.tint);
10277 /* Excel uses ARGB strings */
10278 if(y.rgb) fill.bgColor.rgb = y.rgb.slice(-6);
10279 break;
10280 case '<bgColor/>': case '</bgColor>': break;
10281
10282 /* 18.8.19 fgColor CT_Color */
10283 case '<fgColor':
10284 if(!fill.fgColor) fill.fgColor = {};
10285 if(y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
10286 if(y.tint) fill.fgColor.tint = parseFloat(y.tint);
10287 /* Excel uses ARGB strings */
10288 if(y.rgb != null) fill.fgColor.rgb = y.rgb.slice(-6);
10289 break;
10290 case '<fgColor/>': case '</fgColor>': break;
10291
10292 /* 18.8.38 stop CT_GradientStop */
10293 case '<stop': case '<stop/>': break;
10294 case '</stop>': break;
10295
10296 /* 18.8.? color CT_Color */
10297 case '<color': case '<color/>': break;
10298 case '</color>': break;
10299
10300 /* 18.2.10 extLst CT_ExtensionList ? */
10301 case '<extLst': case '<extLst>': case '</extLst>': break;
10302 case '<ext': pass = true; break;
10303 case '</ext>': pass = false; break;
10304 default: if(opts && opts.WTF) {
10305 if(!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
10306 }
10307 }
10308 });
10309}
10310
10311/* 18.8.23 fonts CT_Fonts */
10312function parse_fonts(t, styles, themes, opts) {
10313 styles.Fonts = [];
10314 var font = {};
10315 var pass = false;
10316 (t[0].match(tagregex)||[]).forEach(function(x) {
10317 var y = parsexmltag(x);
10318 switch(strip_ns(y[0])) {
10319 case '<fonts': case '<fonts>': case '</fonts>': break;
10320
10321 /* 18.8.22 font CT_Font */
10322 case '<font': case '<font>': break;
10323 case '</font>': case '<font/>':
10324 styles.Fonts.push(font);
10325 font = {};
10326 break;
10327
10328 /* 18.8.29 name CT_FontName */
10329 case '<name': if(y.val) font.name = utf8read(y.val); break;
10330 case '<name/>': case '</name>': break;
10331
10332 /* 18.8.2 b CT_BooleanProperty */
10333 case '<b': font.bold = y.val ? parsexmlbool(y.val) : 1; break;
10334 case '<b/>': font.bold = 1; break;
10335
10336 /* 18.8.26 i CT_BooleanProperty */
10337 case '<i': font.italic = y.val ? parsexmlbool(y.val) : 1; break;
10338 case '<i/>': font.italic = 1; break;
10339
10340 /* 18.4.13 u CT_UnderlineProperty */
10341 case '<u':
10342 switch(y.val) {
10343 case "none": font.underline = 0x00; break;
10344 case "single": font.underline = 0x01; break;
10345 case "double": font.underline = 0x02; break;
10346 case "singleAccounting": font.underline = 0x21; break;
10347 case "doubleAccounting": font.underline = 0x22; break;
10348 } break;
10349 case '<u/>': font.underline = 1; break;
10350
10351 /* 18.4.10 strike CT_BooleanProperty */
10352 case '<strike': font.strike = y.val ? parsexmlbool(y.val) : 1; break;
10353 case '<strike/>': font.strike = 1; break;
10354
10355 /* 18.4.2 outline CT_BooleanProperty */
10356 case '<outline': font.outline = y.val ? parsexmlbool(y.val) : 1; break;
10357 case '<outline/>': font.outline = 1; break;
10358
10359 /* 18.8.36 shadow CT_BooleanProperty */
10360 case '<shadow': font.shadow = y.val ? parsexmlbool(y.val) : 1; break;
10361 case '<shadow/>': font.shadow = 1; break;
10362
10363 /* 18.8.12 condense CT_BooleanProperty */
10364 case '<condense': font.condense = y.val ? parsexmlbool(y.val) : 1; break;
10365 case '<condense/>': font.condense = 1; break;
10366
10367 /* 18.8.17 extend CT_BooleanProperty */
10368 case '<extend': font.extend = y.val ? parsexmlbool(y.val) : 1; break;
10369 case '<extend/>': font.extend = 1; break;
10370
10371 /* 18.4.11 sz CT_FontSize */
10372 case '<sz': if(y.val) font.sz = +y.val; break;
10373 case '<sz/>': case '</sz>': break;
10374
10375 /* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
10376 case '<vertAlign': if(y.val) font.vertAlign = y.val; break;
10377 case '<vertAlign/>': case '</vertAlign>': break;
10378
10379 /* 18.8.18 family CT_FontFamily */
10380 case '<family': if(y.val) font.family = parseInt(y.val,10); break;
10381 case '<family/>': case '</family>': break;
10382
10383 /* 18.8.35 scheme CT_FontScheme */
10384 case '<scheme': if(y.val) font.scheme = y.val; break;
10385 case '<scheme/>': case '</scheme>': break;
10386
10387 /* 18.4.1 charset CT_IntProperty */
10388 case '<charset':
10389 if(y.val == '1') break;
10390 y.codepage = CS2CP[parseInt(y.val, 10)];
10391 break;
10392
10393 /* 18.?.? color CT_Color */
10394 case '<color':
10395 if(!font.color) font.color = {};
10396 if(y.auto) font.color.auto = parsexmlbool(y.auto);
10397
10398 if(y.rgb) font.color.rgb = y.rgb.slice(-6);
10399 else if(y.indexed) {
10400 font.color.index = parseInt(y.indexed, 10);
10401 var icv = XLSIcv[font.color.index];
10402 if(font.color.index == 81) icv = XLSIcv[1];
10403 if(!icv) icv = XLSIcv[1]; //throw new Error(x); // note: 206 is valid
10404 font.color.rgb = icv[0].toString(16) + icv[1].toString(16) + icv[2].toString(16);
10405 } else if(y.theme) {
10406 font.color.theme = parseInt(y.theme, 10);
10407 if(y.tint) font.color.tint = parseFloat(y.tint);
10408 if(y.theme && themes.themeElements && themes.themeElements.clrScheme) {
10409 font.color.rgb = rgb_tint(themes.themeElements.clrScheme[font.color.theme].rgb, font.color.tint || 0);
10410 }
10411 }
10412
10413 break;
10414 case '<color/>': case '</color>': break;
10415
10416 /* note: sometimes mc:AlternateContent appears bare */
10417 case '<AlternateContent': pass = true; break;
10418 case '</AlternateContent>': pass = false; break;
10419
10420 /* 18.2.10 extLst CT_ExtensionList ? */
10421 case '<extLst': case '<extLst>': case '</extLst>': break;
10422 case '<ext': pass = true; break;
10423 case '</ext>': pass = false; break;
10424 default: if(opts && opts.WTF) {
10425 if(!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
10426 }
10427 }
10428 });
10429}
10430
10431/* 18.8.31 numFmts CT_NumFmts */
10432function parse_numFmts(t, styles, opts) {
10433 styles.NumberFmt = [];
10434 var k/*Array<number>*/ = (keys(table_fmt)/*:any*/);
10435 for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = table_fmt[k[i]];
10436 var m = t[0].match(tagregex);
10437 if(!m) return;
10438 for(i=0; i < m.length; ++i) {
10439 var y = parsexmltag(m[i]);
10440 switch(strip_ns(y[0])) {
10441 case '<numFmts': case '</numFmts>': case '<numFmts/>': case '<numFmts>': break;
10442 case '<numFmt': {
10443 var f=unescapexml(utf8read(y.formatCode)), j=parseInt(y.numFmtId,10);
10444 styles.NumberFmt[j] = f;
10445 if(j>0) {
10446 if(j > 0x188) {
10447 for(j = 0x188; j > 0x3c; --j) if(styles.NumberFmt[j] == null) break;
10448 styles.NumberFmt[j] = f;
10449 }
10450 SSF_load(f,j);
10451 }
10452 } break;
10453 case '</numFmt>': break;
10454 default: if(opts.WTF) throw new Error('unrecognized ' + y[0] + ' in numFmts');
10455 }
10456 }
10457}
10458
10459function write_numFmts(NF/*:{[n:number|string]:string}*//*::, opts*/) {
10460 var o = ["<numFmts>"];
10461 [[5,8],[23,26],[41,44],[/*63*/50,/*66],[164,*/392]].forEach(function(r) {
10462 for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) o[o.length] = (writextag('numFmt',null,{numFmtId:i,formatCode:escapexml(NF[i])}));
10463 });
10464 if(o.length === 1) return "";
10465 o[o.length] = ("</numFmts>");
10466 o[0] = writextag('numFmts', null, { count:o.length-2 }).replace("/>", ">");
10467 return o.join("");
10468}
10469
10470/* 18.8.10 cellXfs CT_CellXfs */
10471var cellXF_uint = [ "numFmtId", "fillId", "fontId", "borderId", "xfId" ];
10472var cellXF_bool = [ "applyAlignment", "applyBorder", "applyFill", "applyFont", "applyNumberFormat", "applyProtection", "pivotButton", "quotePrefix" ];
10473function parse_cellXfs(t, styles, opts) {
10474 styles.CellXf = [];
10475 var xf;
10476 var pass = false;
10477 (t[0].match(tagregex)||[]).forEach(function(x) {
10478 var y = parsexmltag(x), i = 0;
10479 switch(strip_ns(y[0])) {
10480 case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
10481
10482 /* 18.8.45 xf CT_Xf */
10483 case '<xf': case '<xf/>':
10484 xf = y;
10485 delete xf[0];
10486 for(i = 0; i < cellXF_uint.length; ++i) if(xf[cellXF_uint[i]])
10487 xf[cellXF_uint[i]] = parseInt(xf[cellXF_uint[i]], 10);
10488 for(i = 0; i < cellXF_bool.length; ++i) if(xf[cellXF_bool[i]])
10489 xf[cellXF_bool[i]] = parsexmlbool(xf[cellXF_bool[i]]);
10490 if(styles.NumberFmt && xf.numFmtId > 0x188) {
10491 for(i = 0x188; i > 0x3c; --i) if(styles.NumberFmt[xf.numFmtId] == styles.NumberFmt[i]) { xf.numFmtId = i; break; }
10492 }
10493 styles.CellXf.push(xf); break;
10494 case '</xf>': break;
10495
10496 /* 18.8.1 alignment CT_CellAlignment */
10497 case '<alignment': case '<alignment/>':
10498 var alignment = {};
10499 if(y.vertical) alignment.vertical = y.vertical;
10500 if(y.horizontal) alignment.horizontal = y.horizontal;
10501 if(y.textRotation != null) alignment.textRotation = y.textRotation;
10502 if(y.indent) alignment.indent = y.indent;
10503 if(y.wrapText) alignment.wrapText = parsexmlbool(y.wrapText);
10504 xf.alignment = alignment;
10505 break;
10506 case '</alignment>': break;
10507
10508 /* 18.8.33 protection CT_CellProtection */
10509 case '<protection':
10510 break;
10511 case '</protection>': case '<protection/>': break;
10512
10513 /* note: sometimes mc:AlternateContent appears bare */
10514 case '<AlternateContent': pass = true; break;
10515 case '</AlternateContent>': pass = false; break;
10516
10517 /* 18.2.10 extLst CT_ExtensionList ? */
10518 case '<extLst': case '<extLst>': case '</extLst>': break;
10519 case '<ext': pass = true; break;
10520 case '</ext>': pass = false; break;
10521 default: if(opts && opts.WTF) {
10522 if(!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
10523 }
10524 }
10525 });
10526}
10527
10528function write_cellXfs(cellXfs)/*:string*/ {
10529 var o/*:Array<string>*/ = [];
10530 o[o.length] = (writextag('cellXfs',null));
10531 cellXfs.forEach(function(c) {
10532 o[o.length] = (writextag('xf', null, c));
10533 });
10534 o[o.length] = ("</cellXfs>");
10535 if(o.length === 2) return "";
10536 o[0] = writextag('cellXfs',null, {count:o.length-2}).replace("/>",">");
10537 return o.join("");
10538}
10539
10540/* 18.8 Styles CT_Stylesheet*/
10541var parse_sty_xml= /*#__PURE__*/(function make_pstyx() {
10542var numFmtRegex = /<(?:\w+:)?numFmts([^>]*)>[\S\s]*?<\/(?:\w+:)?numFmts>/;
10543var cellXfRegex = /<(?:\w+:)?cellXfs([^>]*)>[\S\s]*?<\/(?:\w+:)?cellXfs>/;
10544var fillsRegex = /<(?:\w+:)?fills([^>]*)>[\S\s]*?<\/(?:\w+:)?fills>/;
10545var fontsRegex = /<(?:\w+:)?fonts([^>]*)>[\S\s]*?<\/(?:\w+:)?fonts>/;
10546var bordersRegex = /<(?:\w+:)?borders([^>]*)>[\S\s]*?<\/(?:\w+:)?borders>/;
10547
10548return function parse_sty_xml(data, themes, opts) {
10549 var styles = {};
10550 if(!data) return styles;
10551 data = data.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
10552 /* 18.8.39 styleSheet CT_Stylesheet */
10553 var t;
10554
10555 /* 18.8.31 numFmts CT_NumFmts ? */
10556 if((t=data.match(numFmtRegex))) parse_numFmts(t, styles, opts);
10557
10558 /* 18.8.23 fonts CT_Fonts ? */
10559 if((t=data.match(fontsRegex))) parse_fonts(t, styles, themes, opts);
10560
10561 /* 18.8.21 fills CT_Fills ? */
10562 if((t=data.match(fillsRegex))) parse_fills(t, styles, themes, opts);
10563
10564 /* 18.8.5 borders CT_Borders ? */
10565 if((t=data.match(bordersRegex))) parse_borders(t, styles, themes, opts);
10566
10567 /* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
10568 /* 18.8.8 cellStyles CT_CellStyles ? */
10569
10570 /* 18.8.10 cellXfs CT_CellXfs ? */
10571 if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
10572
10573 /* 18.8.15 dxfs CT_Dxfs ? */
10574 /* 18.8.42 tableStyles CT_TableStyles ? */
10575 /* 18.8.11 colors CT_Colors ? */
10576 /* 18.2.10 extLst CT_ExtensionList ? */
10577
10578 return styles;
10579};
10580})();
10581
10582function write_sty_xml(wb/*:Workbook*/, opts)/*:string*/ {
10583 var o = [XML_HEADER, writextag('styleSheet', null, {
10584 'xmlns': XMLNS_main[0],
10585 'xmlns:vt': XMLNS.vt
10586 })], w;
10587 if(wb.SSF && (w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
10588 o[o.length] = ('<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>');
10589 o[o.length] = ('<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>');
10590 o[o.length] = ('<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>');
10591 o[o.length] = ('<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>');
10592 if((w = write_cellXfs(opts.cellXfs))) o[o.length] = (w);
10593 o[o.length] = ('<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>');
10594 o[o.length] = ('<dxfs count="0"/>');
10595 o[o.length] = ('<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>');
10596
10597 if(o.length>2){ o[o.length] = ('</styleSheet>'); o[1]=o[1].replace("/>",">"); }
10598 return o.join("");
10599}
10600/* [MS-XLSB] 2.4.657 BrtFmt */
10601function parse_BrtFmt(data, length/*:number*/) {
10602 var numFmtId = data.read_shift(2);
10603 var stFmtCode = parse_XLWideString(data,length-2);
10604 return [numFmtId, stFmtCode];
10605}
10606function write_BrtFmt(i/*:number*/, f/*:string*/, o) {
10607 if(!o) o = new_buf(6 + 4 * f.length);
10608 o.write_shift(2, i);
10609 write_XLWideString(f, o);
10610 var out = (o.length > o.l) ? o.slice(0, o.l) : o;
10611 if(o.l == null) o.l = o.length;
10612 return out;
10613}
10614
10615/* [MS-XLSB] 2.4.659 BrtFont TODO */
10616function parse_BrtFont(data, length/*:number*/, opts) {
10617 var out = ({}/*:any*/);
10618
10619 out.sz = data.read_shift(2) / 20;
10620
10621 var grbit = parse_FontFlags(data, 2, opts);
10622 if(grbit.fItalic) out.italic = 1;
10623 if(grbit.fCondense) out.condense = 1;
10624 if(grbit.fExtend) out.extend = 1;
10625 if(grbit.fShadow) out.shadow = 1;
10626 if(grbit.fOutline) out.outline = 1;
10627 if(grbit.fStrikeout) out.strike = 1;
10628
10629 var bls = data.read_shift(2);
10630 if(bls === 0x02BC) out.bold = 1;
10631
10632 switch(data.read_shift(2)) {
10633 /* case 0: out.vertAlign = "baseline"; break; */
10634 case 1: out.vertAlign = "superscript"; break;
10635 case 2: out.vertAlign = "subscript"; break;
10636 }
10637
10638 var underline = data.read_shift(1);
10639 if(underline != 0) out.underline = underline;
10640
10641 var family = data.read_shift(1);
10642 if(family > 0) out.family = family;
10643
10644 var bCharSet = data.read_shift(1);
10645 if(bCharSet > 0) out.charset = bCharSet;
10646
10647 data.l++;
10648 out.color = parse_BrtColor(data, 8);
10649
10650 switch(data.read_shift(1)) {
10651 /* case 0: out.scheme = "none": break; */
10652 case 1: out.scheme = "major"; break;
10653 case 2: out.scheme = "minor"; break;
10654 }
10655
10656 out.name = parse_XLWideString(data, length - 21);
10657
10658 return out;
10659}
10660function write_BrtFont(font/*:any*/, o) {
10661 if(!o) o = new_buf(25+4*32);
10662 o.write_shift(2, font.sz * 20);
10663 write_FontFlags(font, o);
10664 o.write_shift(2, font.bold ? 0x02BC : 0x0190);
10665 var sss = 0;
10666 if(font.vertAlign == "superscript") sss = 1;
10667 else if(font.vertAlign == "subscript") sss = 2;
10668 o.write_shift(2, sss);
10669 o.write_shift(1, font.underline || 0);
10670 o.write_shift(1, font.family || 0);
10671 o.write_shift(1, font.charset || 0);
10672 o.write_shift(1, 0);
10673 write_BrtColor(font.color, o);
10674 var scheme = 0;
10675 if(font.scheme == "major") scheme = 1;
10676 if(font.scheme == "minor") scheme = 2;
10677 o.write_shift(1, scheme);
10678 write_XLWideString(font.name, o);
10679 return o.length > o.l ? o.slice(0, o.l) : o;
10680}
10681
10682/* [MS-XLSB] 2.4.650 BrtFill */
10683var XLSBFillPTNames = [
10684 "none",
10685 "solid",
10686 "mediumGray",
10687 "darkGray",
10688 "lightGray",
10689 "darkHorizontal",
10690 "darkVertical",
10691 "darkDown",
10692 "darkUp",
10693 "darkGrid",
10694 "darkTrellis",
10695 "lightHorizontal",
10696 "lightVertical",
10697 "lightDown",
10698 "lightUp",
10699 "lightGrid",
10700 "lightTrellis",
10701 "gray125",
10702 "gray0625"
10703];
10704var rev_XLSBFillPTNames/*:EvertNumType*/;
10705/* TODO: gradient fill representation */
10706var parse_BrtFill = parsenoop;
10707function write_BrtFill(fill, o) {
10708 if(!o) o = new_buf(4*3 + 8*7 + 16*1);
10709 if(!rev_XLSBFillPTNames) rev_XLSBFillPTNames = (evert(XLSBFillPTNames)/*:any*/);
10710 var fls/*:number*/ = rev_XLSBFillPTNames[fill.patternType];
10711 if(fls == null) fls = 0x28;
10712 o.write_shift(4, fls);
10713 var j = 0;
10714 if(fls != 0x28) {
10715 /* TODO: custom FG Color */
10716 write_BrtColor({auto:1}, o);
10717 /* TODO: custom BG Color */
10718 write_BrtColor({auto:1}, o);
10719
10720 for(; j < 12; ++j) o.write_shift(4, 0);
10721 } else {
10722 for(; j < 4; ++j) o.write_shift(4, 0);
10723
10724 for(; j < 12; ++j) o.write_shift(4, 0); /* TODO */
10725 /* iGradientType */
10726 /* xnumDegree */
10727 /* xnumFillToLeft */
10728 /* xnumFillToRight */
10729 /* xnumFillToTop */
10730 /* xnumFillToBottom */
10731 /* cNumStop */
10732 /* xfillGradientStop */
10733 }
10734 return o.length > o.l ? o.slice(0, o.l) : o;
10735}
10736
10737/* [MS-XLSB] 2.4.824 BrtXF */
10738function parse_BrtXF(data, length/*:number*/) {
10739 var tgt = data.l + length;
10740 var ixfeParent = data.read_shift(2);
10741 var ifmt = data.read_shift(2);
10742 data.l = tgt;
10743 return {ixfe:ixfeParent, numFmtId:ifmt };
10744}
10745function write_BrtXF(data, ixfeP, o) {
10746 if(!o) o = new_buf(16);
10747 o.write_shift(2, ixfeP||0);
10748 o.write_shift(2, data.numFmtId||0);
10749 o.write_shift(2, 0); /* iFont */
10750 o.write_shift(2, 0); /* iFill */
10751 o.write_shift(2, 0); /* ixBorder */
10752 o.write_shift(1, 0); /* trot */
10753 o.write_shift(1, 0); /* indent */
10754 var flow = 0;
10755 o.write_shift(1, flow); /* flags */
10756 o.write_shift(1, 0); /* flags */
10757 o.write_shift(1, 0); /* xfGrbitAtr */
10758 o.write_shift(1, 0);
10759 return o;
10760}
10761
10762/* [MS-XLSB] 2.5.4 Blxf TODO */
10763function write_Blxf(data, o) {
10764 if(!o) o = new_buf(10);
10765 o.write_shift(1, 0); /* dg */
10766 o.write_shift(1, 0);
10767 o.write_shift(4, 0); /* color */
10768 o.write_shift(4, 0); /* color */
10769 return o;
10770}
10771/* [MS-XLSB] 2.4.302 BrtBorder TODO */
10772var parse_BrtBorder = parsenoop;
10773function write_BrtBorder(border, o) {
10774 if(!o) o = new_buf(51);
10775 o.write_shift(1, 0); /* diagonal */
10776 write_Blxf(null, o); /* top */
10777 write_Blxf(null, o); /* bottom */
10778 write_Blxf(null, o); /* left */
10779 write_Blxf(null, o); /* right */
10780 write_Blxf(null, o); /* diag */
10781 return o.length > o.l ? o.slice(0, o.l) : o;
10782}
10783
10784/* [MS-XLSB] 2.4.763 BrtStyle TODO */
10785function write_BrtStyle(style, o) {
10786 if(!o) o = new_buf(12+4*10);
10787 o.write_shift(4, style.xfId);
10788 o.write_shift(2, 1);
10789 o.write_shift(1, +style.builtinId);
10790 o.write_shift(1, 0); /* iLevel */
10791 write_XLNullableWideString(style.name || "", o);
10792 return o.length > o.l ? o.slice(0, o.l) : o;
10793}
10794
10795/* [MS-XLSB] 2.4.272 BrtBeginTableStyles */
10796function write_BrtBeginTableStyles(cnt, defTableStyle, defPivotStyle) {
10797 var o = new_buf(4+256*2*4);
10798 o.write_shift(4, cnt);
10799 write_XLNullableWideString(defTableStyle, o);
10800 write_XLNullableWideString(defPivotStyle, o);
10801 return o.length > o.l ? o.slice(0, o.l) : o;
10802}
10803
10804/* [MS-XLSB] 2.1.7.50 Styles */
10805function parse_sty_bin(data, themes, opts) {
10806 var styles = {};
10807 styles.NumberFmt = ([]/*:any*/);
10808 for(var y in table_fmt) styles.NumberFmt[y] = table_fmt[y];
10809
10810 styles.CellXf = [];
10811 styles.Fonts = [];
10812 var state/*:Array<string>*/ = [];
10813 var pass = false;
10814 recordhopper(data, function hopper_sty(val, R, RT) {
10815 switch(RT) {
10816 case 0x002C: /* BrtFmt */
10817 styles.NumberFmt[val[0]] = val[1]; SSF_load(val[1], val[0]);
10818 break;
10819 case 0x002B: /* BrtFont */
10820 styles.Fonts.push(val);
10821 if(val.color.theme != null && themes && themes.themeElements && themes.themeElements.clrScheme) {
10822 val.color.rgb = rgb_tint(themes.themeElements.clrScheme[val.color.theme].rgb, val.color.tint || 0);
10823 }
10824 break;
10825 case 0x0401: /* BrtKnownFonts */ break;
10826 case 0x002D: /* BrtFill */
10827 break;
10828 case 0x002E: /* BrtBorder */
10829 break;
10830 case 0x002F: /* BrtXF */
10831 if(state[state.length - 1] == 0x0269 /* BrtBeginCellXFs */) {
10832 styles.CellXf.push(val);
10833 }
10834 break;
10835 case 0x0030: /* BrtStyle */
10836 case 0x01FB: /* BrtDXF */
10837 case 0x023C: /* BrtMRUColor */
10838 case 0x01DB: /* BrtIndexedColor */
10839 break;
10840
10841 case 0x0493: /* BrtDXF14 */
10842 case 0x0836: /* BrtDXF15 */
10843 case 0x046A: /* BrtSlicerStyleElement */
10844 case 0x0200: /* BrtTableStyleElement */
10845 case 0x082F: /* BrtTimelineStyleElement */
10846 case 0x0C00: /* BrtUid */
10847 break;
10848
10849 case 0x0023: /* BrtFRTBegin */
10850 pass = true; break;
10851 case 0x0024: /* BrtFRTEnd */
10852 pass = false; break;
10853 case 0x0025: /* BrtACBegin */
10854 state.push(RT); pass = true; break;
10855 case 0x0026: /* BrtACEnd */
10856 state.pop(); pass = false; break;
10857
10858 default:
10859 if(R.T > 0) state.push(RT);
10860 else if(R.T < 0) state.pop();
10861 else if(!pass || (opts.WTF && state[state.length-1] != 0x0025 /* BrtACBegin */)) throw new Error("Unexpected record 0x" + RT.toString(16));
10862 }
10863 });
10864 return styles;
10865}
10866
10867function write_FMTS_bin(ba, NF/*:?SSFTable*/) {
10868 if(!NF) return;
10869 var cnt = 0;
10870 [[5,8],[23,26],[41,44],[/*63*/50,/*66],[164,*/392]].forEach(function(r) {
10871 /*:: if(!NF) return; */
10872 for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) ++cnt;
10873 });
10874
10875 if(cnt == 0) return;
10876 write_record(ba, 0x0267 /* BrtBeginFmts */, write_UInt32LE(cnt));
10877 [[5,8],[23,26],[41,44],[/*63*/50,/*66],[164,*/392]].forEach(function(r) {
10878 /*:: if(!NF) return; */
10879 for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_record(ba, 0x002C /* BrtFmt */, write_BrtFmt(i, NF[i]));
10880 });
10881 write_record(ba, 0x0268 /* BrtEndFmts */);
10882}
10883
10884function write_FONTS_bin(ba/*::, data*/) {
10885 var cnt = 1;
10886
10887 if(cnt == 0) return;
10888 write_record(ba, 0x0263 /* BrtBeginFonts */, write_UInt32LE(cnt));
10889 write_record(ba, 0x002B /* BrtFont */, write_BrtFont({
10890 sz:12,
10891 color: {theme:1},
10892 name: "Calibri",
10893 family: 2,
10894 scheme: "minor"
10895 }));
10896 /* 1*65491BrtFont [ACFONTS] */
10897 write_record(ba, 0x0264 /* BrtEndFonts */);
10898}
10899
10900function write_FILLS_bin(ba/*::, data*/) {
10901 var cnt = 2;
10902
10903 if(cnt == 0) return;
10904 write_record(ba, 0x025B /* BrtBeginFills */, write_UInt32LE(cnt));
10905 write_record(ba, 0x002D /* BrtFill */, write_BrtFill({patternType:"none"}));
10906 write_record(ba, 0x002D /* BrtFill */, write_BrtFill({patternType:"gray125"}));
10907 /* 1*65431BrtFill */
10908 write_record(ba, 0x025C /* BrtEndFills */);
10909}
10910
10911function write_BORDERS_bin(ba/*::, data*/) {
10912 var cnt = 1;
10913
10914 if(cnt == 0) return;
10915 write_record(ba, 0x0265 /* BrtBeginBorders */, write_UInt32LE(cnt));
10916 write_record(ba, 0x002E /* BrtBorder */, write_BrtBorder({}));
10917 /* 1*65430BrtBorder */
10918 write_record(ba, 0x0266 /* BrtEndBorders */);
10919}
10920
10921function write_CELLSTYLEXFS_bin(ba/*::, data*/) {
10922 var cnt = 1;
10923 write_record(ba, 0x0272 /* BrtBeginCellStyleXFs */, write_UInt32LE(cnt));
10924 write_record(ba, 0x002F /* BrtXF */, write_BrtXF({
10925 numFmtId: 0,
10926 fontId: 0,
10927 fillId: 0,
10928 borderId: 0
10929 }, 0xFFFF));
10930 /* 1*65430(BrtXF *FRT) */
10931 write_record(ba, 0x0273 /* BrtEndCellStyleXFs */);
10932}
10933
10934function write_CELLXFS_bin(ba, data) {
10935 write_record(ba, 0x0269 /* BrtBeginCellXFs */, write_UInt32LE(data.length));
10936 data.forEach(function(c) { write_record(ba, 0x002F /* BrtXF */, write_BrtXF(c,0)); });
10937 /* 1*65430(BrtXF *FRT) */
10938 write_record(ba, 0x026A /* BrtEndCellXFs */);
10939}
10940
10941function write_STYLES_bin(ba/*::, data*/) {
10942 var cnt = 1;
10943
10944 write_record(ba, 0x026B /* BrtBeginStyles */, write_UInt32LE(cnt));
10945 write_record(ba, 0x0030 /* BrtStyle */, write_BrtStyle({
10946 xfId:0,
10947 builtinId:0,
10948 name:"Normal"
10949 }));
10950 /* 1*65430(BrtStyle *FRT) */
10951 write_record(ba, 0x026C /* BrtEndStyles */);
10952}
10953
10954function write_DXFS_bin(ba/*::, data*/) {
10955 var cnt = 0;
10956
10957 write_record(ba, 0x01F9 /* BrtBeginDXFs */, write_UInt32LE(cnt));
10958 /* *2147483647(BrtDXF *FRT) */
10959 write_record(ba, 0x01FA /* BrtEndDXFs */);
10960}
10961
10962function write_TABLESTYLES_bin(ba/*::, data*/) {
10963 var cnt = 0;
10964
10965 write_record(ba, 0x01FC /* BrtBeginTableStyles */, write_BrtBeginTableStyles(cnt, "TableStyleMedium9", "PivotStyleMedium4"));
10966 /* *TABLESTYLE */
10967 write_record(ba, 0x01FD /* BrtEndTableStyles */);
10968}
10969
10970function write_COLORPALETTE_bin(/*::ba, data*/) {
10971 return;
10972 /* BrtBeginColorPalette [INDEXEDCOLORS] [MRUCOLORS] BrtEndColorPalette */
10973}
10974
10975/* [MS-XLSB] 2.1.7.50 Styles */
10976function write_sty_bin(wb, opts) {
10977 var ba = buf_array();
10978 write_record(ba, 0x0116 /* BrtBeginStyleSheet */);
10979 write_FMTS_bin(ba, wb.SSF);
10980 write_FONTS_bin(ba, wb);
10981 write_FILLS_bin(ba, wb);
10982 write_BORDERS_bin(ba, wb);
10983 write_CELLSTYLEXFS_bin(ba, wb);
10984 write_CELLXFS_bin(ba, opts.cellXfs);
10985 write_STYLES_bin(ba, wb);
10986 write_DXFS_bin(ba, wb);
10987 write_TABLESTYLES_bin(ba, wb);
10988 write_COLORPALETTE_bin(ba, wb);
10989 /* FRTSTYLESHEET*/
10990 write_record(ba, 0x0117 /* BrtEndStyleSheet */);
10991 return ba.end();
10992}
10993/* Even though theme layout is dk1 lt1 dk2 lt2, true order is lt1 dk1 lt2 dk2 */
10994var XLSXThemeClrScheme = [
10995 '</a:lt1>', '</a:dk1>', '</a:lt2>', '</a:dk2>',
10996 '</a:accent1>', '</a:accent2>', '</a:accent3>',
10997 '</a:accent4>', '</a:accent5>', '</a:accent6>',
10998 '</a:hlink>', '</a:folHlink>'
10999];
11000/* 20.1.6.2 clrScheme CT_ColorScheme */
11001function parse_clrScheme(t, themes, opts) {
11002 themes.themeElements.clrScheme = [];
11003 var color = {};
11004 (t[0].match(tagregex)||[]).forEach(function(x) {
11005 var y = parsexmltag(x);
11006 switch(y[0]) {
11007 /* 20.1.6.2 clrScheme (Color Scheme) CT_ColorScheme */
11008 case '<a:clrScheme': case '</a:clrScheme>': break;
11009
11010 /* 20.1.2.3.32 srgbClr CT_SRgbColor */
11011 case '<a:srgbClr':
11012 color.rgb = y.val; break;
11013
11014 /* 20.1.2.3.33 sysClr CT_SystemColor */
11015 case '<a:sysClr':
11016 color.rgb = y.lastClr; break;
11017
11018 /* 20.1.4.1.1 accent1 (Accent 1) */
11019 /* 20.1.4.1.2 accent2 (Accent 2) */
11020 /* 20.1.4.1.3 accent3 (Accent 3) */
11021 /* 20.1.4.1.4 accent4 (Accent 4) */
11022 /* 20.1.4.1.5 accent5 (Accent 5) */
11023 /* 20.1.4.1.6 accent6 (Accent 6) */
11024 /* 20.1.4.1.9 dk1 (Dark 1) */
11025 /* 20.1.4.1.10 dk2 (Dark 2) */
11026 /* 20.1.4.1.15 folHlink (Followed Hyperlink) */
11027 /* 20.1.4.1.19 hlink (Hyperlink) */
11028 /* 20.1.4.1.22 lt1 (Light 1) */
11029 /* 20.1.4.1.23 lt2 (Light 2) */
11030 case '<a:dk1>': case '</a:dk1>':
11031 case '<a:lt1>': case '</a:lt1>':
11032 case '<a:dk2>': case '</a:dk2>':
11033 case '<a:lt2>': case '</a:lt2>':
11034 case '<a:accent1>': case '</a:accent1>':
11035 case '<a:accent2>': case '</a:accent2>':
11036 case '<a:accent3>': case '</a:accent3>':
11037 case '<a:accent4>': case '</a:accent4>':
11038 case '<a:accent5>': case '</a:accent5>':
11039 case '<a:accent6>': case '</a:accent6>':
11040 case '<a:hlink>': case '</a:hlink>':
11041 case '<a:folHlink>': case '</a:folHlink>':
11042 if (y[0].charAt(1) === '/') {
11043 themes.themeElements.clrScheme[XLSXThemeClrScheme.indexOf(y[0])] = color;
11044 color = {};
11045 } else {
11046 color.name = y[0].slice(3, y[0].length - 1);
11047 }
11048 break;
11049
11050 default: if(opts && opts.WTF) throw new Error('Unrecognized ' + y[0] + ' in clrScheme');
11051 }
11052 });
11053}
11054
11055/* 20.1.4.1.18 fontScheme CT_FontScheme */
11056function parse_fontScheme(/*::t, themes, opts*/) { }
11057
11058/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
11059function parse_fmtScheme(/*::t, themes, opts*/) { }
11060
11061var clrsregex = /<a:clrScheme([^>]*)>[\s\S]*<\/a:clrScheme>/;
11062var fntsregex = /<a:fontScheme([^>]*)>[\s\S]*<\/a:fontScheme>/;
11063var fmtsregex = /<a:fmtScheme([^>]*)>[\s\S]*<\/a:fmtScheme>/;
11064
11065/* 20.1.6.10 themeElements CT_BaseStyles */
11066function parse_themeElements(data, themes, opts) {
11067 themes.themeElements = {};
11068
11069 var t;
11070
11071 [
11072 /* clrScheme CT_ColorScheme */
11073 ['clrScheme', clrsregex, parse_clrScheme],
11074 /* fontScheme CT_FontScheme */
11075 ['fontScheme', fntsregex, parse_fontScheme],
11076 /* fmtScheme CT_StyleMatrix */
11077 ['fmtScheme', fmtsregex, parse_fmtScheme]
11078 ].forEach(function(m) {
11079 if(!(t=data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
11080 m[2](t, themes, opts);
11081 });
11082}
11083
11084var themeltregex = /<a:themeElements([^>]*)>[\s\S]*<\/a:themeElements>/;
11085
11086/* 14.2.7 Theme Part */
11087function parse_theme_xml(data/*:string*/, opts) {
11088 /* 20.1.6.9 theme CT_OfficeStyleSheet */
11089 if(!data || data.length === 0) data = write_theme();
11090
11091 var t;
11092 var themes = {};
11093
11094 /* themeElements CT_BaseStyles */
11095 if(!(t=data.match(themeltregex))) throw new Error('themeElements not found in theme');
11096 parse_themeElements(t[0], themes, opts);
11097 themes.raw = data;
11098 return themes;
11099}
11100
11101function write_theme(Themes, opts)/*:string*/ {
11102 if(opts && opts.themeXLSX) return opts.themeXLSX;
11103 if(Themes && typeof Themes.raw == "string") return Themes.raw;
11104 var o = [XML_HEADER];
11105 o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
11106 o[o.length] = '<a:themeElements>';
11107
11108 o[o.length] = '<a:clrScheme name="Office">';
11109 o[o.length] = '<a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1>';
11110 o[o.length] = '<a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1>';
11111 o[o.length] = '<a:dk2><a:srgbClr val="1F497D"/></a:dk2>';
11112 o[o.length] = '<a:lt2><a:srgbClr val="EEECE1"/></a:lt2>';
11113 o[o.length] = '<a:accent1><a:srgbClr val="4F81BD"/></a:accent1>';
11114 o[o.length] = '<a:accent2><a:srgbClr val="C0504D"/></a:accent2>';
11115 o[o.length] = '<a:accent3><a:srgbClr val="9BBB59"/></a:accent3>';
11116 o[o.length] = '<a:accent4><a:srgbClr val="8064A2"/></a:accent4>';
11117 o[o.length] = '<a:accent5><a:srgbClr val="4BACC6"/></a:accent5>';
11118 o[o.length] = '<a:accent6><a:srgbClr val="F79646"/></a:accent6>';
11119 o[o.length] = '<a:hlink><a:srgbClr val="0000FF"/></a:hlink>';
11120 o[o.length] = '<a:folHlink><a:srgbClr val="800080"/></a:folHlink>';
11121 o[o.length] = '</a:clrScheme>';
11122
11123 o[o.length] = '<a:fontScheme name="Office">';
11124 o[o.length] = '<a:majorFont>';
11125 o[o.length] = '<a:latin typeface="Cambria"/>';
11126 o[o.length] = '<a:ea typeface=""/>';
11127 o[o.length] = '<a:cs typeface=""/>';
11128 o[o.length] = '<a:font script="Jpan" typeface="MS Pゴシック"/>';
11129 o[o.length] = '<a:font script="Hang" typeface="맑은 고딕"/>';
11130 o[o.length] = '<a:font script="Hans" typeface="宋体"/>';
11131 o[o.length] = '<a:font script="Hant" typeface="新細明體"/>';
11132 o[o.length] = '<a:font script="Arab" typeface="Times New Roman"/>';
11133 o[o.length] = '<a:font script="Hebr" typeface="Times New Roman"/>';
11134 o[o.length] = '<a:font script="Thai" typeface="Tahoma"/>';
11135 o[o.length] = '<a:font script="Ethi" typeface="Nyala"/>';
11136 o[o.length] = '<a:font script="Beng" typeface="Vrinda"/>';
11137 o[o.length] = '<a:font script="Gujr" typeface="Shruti"/>';
11138 o[o.length] = '<a:font script="Khmr" typeface="MoolBoran"/>';
11139 o[o.length] = '<a:font script="Knda" typeface="Tunga"/>';
11140 o[o.length] = '<a:font script="Guru" typeface="Raavi"/>';
11141 o[o.length] = '<a:font script="Cans" typeface="Euphemia"/>';
11142 o[o.length] = '<a:font script="Cher" typeface="Plantagenet Cherokee"/>';
11143 o[o.length] = '<a:font script="Yiii" typeface="Microsoft Yi Baiti"/>';
11144 o[o.length] = '<a:font script="Tibt" typeface="Microsoft Himalaya"/>';
11145 o[o.length] = '<a:font script="Thaa" typeface="MV Boli"/>';
11146 o[o.length] = '<a:font script="Deva" typeface="Mangal"/>';
11147 o[o.length] = '<a:font script="Telu" typeface="Gautami"/>';
11148 o[o.length] = '<a:font script="Taml" typeface="Latha"/>';
11149 o[o.length] = '<a:font script="Syrc" typeface="Estrangelo Edessa"/>';
11150 o[o.length] = '<a:font script="Orya" typeface="Kalinga"/>';
11151 o[o.length] = '<a:font script="Mlym" typeface="Kartika"/>';
11152 o[o.length] = '<a:font script="Laoo" typeface="DokChampa"/>';
11153 o[o.length] = '<a:font script="Sinh" typeface="Iskoola Pota"/>';
11154 o[o.length] = '<a:font script="Mong" typeface="Mongolian Baiti"/>';
11155 o[o.length] = '<a:font script="Viet" typeface="Times New Roman"/>';
11156 o[o.length] = '<a:font script="Uigh" typeface="Microsoft Uighur"/>';
11157 o[o.length] = '<a:font script="Geor" typeface="Sylfaen"/>';
11158 o[o.length] = '</a:majorFont>';
11159 o[o.length] = '<a:minorFont>';
11160 o[o.length] = '<a:latin typeface="Calibri"/>';
11161 o[o.length] = '<a:ea typeface=""/>';
11162 o[o.length] = '<a:cs typeface=""/>';
11163 o[o.length] = '<a:font script="Jpan" typeface="MS Pゴシック"/>';
11164 o[o.length] = '<a:font script="Hang" typeface="맑은 고딕"/>';
11165 o[o.length] = '<a:font script="Hans" typeface="宋体"/>';
11166 o[o.length] = '<a:font script="Hant" typeface="新細明體"/>';
11167 o[o.length] = '<a:font script="Arab" typeface="Arial"/>';
11168 o[o.length] = '<a:font script="Hebr" typeface="Arial"/>';
11169 o[o.length] = '<a:font script="Thai" typeface="Tahoma"/>';
11170 o[o.length] = '<a:font script="Ethi" typeface="Nyala"/>';
11171 o[o.length] = '<a:font script="Beng" typeface="Vrinda"/>';
11172 o[o.length] = '<a:font script="Gujr" typeface="Shruti"/>';
11173 o[o.length] = '<a:font script="Khmr" typeface="DaunPenh"/>';
11174 o[o.length] = '<a:font script="Knda" typeface="Tunga"/>';
11175 o[o.length] = '<a:font script="Guru" typeface="Raavi"/>';
11176 o[o.length] = '<a:font script="Cans" typeface="Euphemia"/>';
11177 o[o.length] = '<a:font script="Cher" typeface="Plantagenet Cherokee"/>';
11178 o[o.length] = '<a:font script="Yiii" typeface="Microsoft Yi Baiti"/>';
11179 o[o.length] = '<a:font script="Tibt" typeface="Microsoft Himalaya"/>';
11180 o[o.length] = '<a:font script="Thaa" typeface="MV Boli"/>';
11181 o[o.length] = '<a:font script="Deva" typeface="Mangal"/>';
11182 o[o.length] = '<a:font script="Telu" typeface="Gautami"/>';
11183 o[o.length] = '<a:font script="Taml" typeface="Latha"/>';
11184 o[o.length] = '<a:font script="Syrc" typeface="Estrangelo Edessa"/>';
11185 o[o.length] = '<a:font script="Orya" typeface="Kalinga"/>';
11186 o[o.length] = '<a:font script="Mlym" typeface="Kartika"/>';
11187 o[o.length] = '<a:font script="Laoo" typeface="DokChampa"/>';
11188 o[o.length] = '<a:font script="Sinh" typeface="Iskoola Pota"/>';
11189 o[o.length] = '<a:font script="Mong" typeface="Mongolian Baiti"/>';
11190 o[o.length] = '<a:font script="Viet" typeface="Arial"/>';
11191 o[o.length] = '<a:font script="Uigh" typeface="Microsoft Uighur"/>';
11192 o[o.length] = '<a:font script="Geor" typeface="Sylfaen"/>';
11193 o[o.length] = '</a:minorFont>';
11194 o[o.length] = '</a:fontScheme>';
11195
11196 o[o.length] = '<a:fmtScheme name="Office">';
11197 o[o.length] = '<a:fillStyleLst>';
11198 o[o.length] = '<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>';
11199 o[o.length] = '<a:gradFill rotWithShape="1">';
11200 o[o.length] = '<a:gsLst>';
11201 o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs>';
11202 o[o.length] = '<a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs>';
11203 o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
11204 o[o.length] = '</a:gsLst>';
11205 o[o.length] = '<a:lin ang="16200000" scaled="1"/>';
11206 o[o.length] = '</a:gradFill>';
11207 o[o.length] = '<a:gradFill rotWithShape="1">';
11208 o[o.length] = '<a:gsLst>';
11209 o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="100000"/><a:shade val="100000"/><a:satMod val="130000"/></a:schemeClr></a:gs>';
11210 o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="50000"/><a:shade val="100000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
11211 o[o.length] = '</a:gsLst>';
11212 o[o.length] = '<a:lin ang="16200000" scaled="0"/>';
11213 o[o.length] = '</a:gradFill>';
11214 o[o.length] = '</a:fillStyleLst>';
11215 o[o.length] = '<a:lnStyleLst>';
11216 o[o.length] = '<a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln>';
11217 o[o.length] = '<a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln>';
11218 o[o.length] = '<a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln>';
11219 o[o.length] = '</a:lnStyleLst>';
11220 o[o.length] = '<a:effectStyleLst>';
11221 o[o.length] = '<a:effectStyle>';
11222 o[o.length] = '<a:effectLst>';
11223 o[o.length] = '<a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw>';
11224 o[o.length] = '</a:effectLst>';
11225 o[o.length] = '</a:effectStyle>';
11226 o[o.length] = '<a:effectStyle>';
11227 o[o.length] = '<a:effectLst>';
11228 o[o.length] = '<a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw>';
11229 o[o.length] = '</a:effectLst>';
11230 o[o.length] = '</a:effectStyle>';
11231 o[o.length] = '<a:effectStyle>';
11232 o[o.length] = '<a:effectLst>';
11233 o[o.length] = '<a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw>';
11234 o[o.length] = '</a:effectLst>';
11235 o[o.length] = '<a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d>';
11236 o[o.length] = '<a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d>';
11237 o[o.length] = '</a:effectStyle>';
11238 o[o.length] = '</a:effectStyleLst>';
11239 o[o.length] = '<a:bgFillStyleLst>';
11240 o[o.length] = '<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>';
11241 o[o.length] = '<a:gradFill rotWithShape="1">';
11242 o[o.length] = '<a:gsLst>';
11243 o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
11244 o[o.length] = '<a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
11245 o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs>';
11246 o[o.length] = '</a:gsLst>';
11247 o[o.length] = '<a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path>';
11248 o[o.length] = '</a:gradFill>';
11249 o[o.length] = '<a:gradFill rotWithShape="1">';
11250 o[o.length] = '<a:gsLst>';
11251 o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs>';
11252 o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs>';
11253 o[o.length] = '</a:gsLst>';
11254 o[o.length] = '<a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path>';
11255 o[o.length] = '</a:gradFill>';
11256 o[o.length] = '</a:bgFillStyleLst>';
11257 o[o.length] = '</a:fmtScheme>';
11258 o[o.length] = '</a:themeElements>';
11259
11260 o[o.length] = '<a:objectDefaults>';
11261 o[o.length] = '<a:spDef>';
11262 o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style>';
11263 o[o.length] = '</a:spDef>';
11264 o[o.length] = '<a:lnDef>';
11265 o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style>';
11266 o[o.length] = '</a:lnDef>';
11267 o[o.length] = '</a:objectDefaults>';
11268 o[o.length] = '<a:extraClrSchemeLst/>';
11269 o[o.length] = '</a:theme>';
11270 return o.join("");
11271}
11272/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
11273function parse_Theme(blob, length, opts) {
11274 var end = blob.l + length;
11275 var dwThemeVersion = blob.read_shift(4);
11276 if(dwThemeVersion === 124226) return;
11277 if(!opts.cellStyles) { blob.l = end; return; }
11278 var data = blob.slice(blob.l);
11279 blob.l = end;
11280 var zip; try { zip = zip_read(data, {type: "array"}); } catch(e) { return; }
11281 var themeXML = getzipstr(zip, "theme/theme/theme1.xml", true);
11282 if(!themeXML) return;
11283 return parse_theme_xml(themeXML, opts);
11284}
11285
11286/* 2.5.49 */
11287function parse_ColorTheme(blob/*::, length*/) { return blob.read_shift(4); }
11288
11289/* 2.5.155 */
11290function parse_FullColorExt(blob/*::, length*/) {
11291 var o = {};
11292 o.xclrType = blob.read_shift(2);
11293 o.nTintShade = blob.read_shift(2);
11294 switch(o.xclrType) {
11295 case 0: blob.l += 4; break;
11296 case 1: o.xclrValue = parse_IcvXF(blob, 4); break;
11297 case 2: o.xclrValue = parse_LongRGBA(blob, 4); break;
11298 case 3: o.xclrValue = parse_ColorTheme(blob, 4); break;
11299 case 4: blob.l += 4; break;
11300 }
11301 blob.l += 8;
11302 return o;
11303}
11304
11305/* 2.5.164 TODO: read 7 bits*/
11306function parse_IcvXF(blob, length) {
11307 return parsenoop(blob, length);
11308}
11309
11310/* 2.5.280 */
11311function parse_XFExtGradient(blob, length) {
11312 return parsenoop(blob, length);
11313}
11314
11315/* [MS-XLS] 2.5.108 */
11316function parse_ExtProp(blob/*::, length*/)/*:Array<any>*/ {
11317 var extType = blob.read_shift(2);
11318 var cb = blob.read_shift(2) - 4;
11319 var o = [extType];
11320 switch(extType) {
11321 case 0x04: case 0x05: case 0x07: case 0x08:
11322 case 0x09: case 0x0A: case 0x0B: case 0x0D:
11323 o[1] = parse_FullColorExt(blob, cb); break;
11324 case 0x06: o[1] = parse_XFExtGradient(blob, cb); break;
11325 case 0x0E: case 0x0F: o[1] = blob.read_shift(cb === 1 ? 1 : 2); break;
11326 default: throw new Error("Unrecognized ExtProp type: " + extType + " " + cb);
11327 }
11328 return o;
11329}
11330
11331/* 2.4.355 */
11332function parse_XFExt(blob, length) {
11333 var end = blob.l + length;
11334 blob.l += 2;
11335 var ixfe = blob.read_shift(2);
11336 blob.l += 2;
11337 var cexts = blob.read_shift(2);
11338 var ext/*:AOA*/ = [];
11339 while(cexts-- > 0) ext.push(parse_ExtProp(blob, end-blob.l));
11340 return {ixfe:ixfe, ext:ext};
11341}
11342
11343/* xf is an XF, see parse_XFExt for xfext */
11344function update_xfext(xf, xfext) {
11345 xfext.forEach(function(xfe) {
11346 switch(xfe[0]) { /* 2.5.108 extPropData */
11347 case 0x04: break; /* foreground color */
11348 case 0x05: break; /* background color */
11349 case 0x06: break; /* gradient fill */
11350 case 0x07: break; /* top cell border color */
11351 case 0x08: break; /* bottom cell border color */
11352 case 0x09: break; /* left cell border color */
11353 case 0x0a: break; /* right cell border color */
11354 case 0x0b: break; /* diagonal cell border color */
11355 case 0x0d: /* text color */
11356 break;
11357 case 0x0e: break; /* font scheme */
11358 case 0x0f: break; /* indentation level */
11359 }
11360 });
11361}
11362
11363function parse_BrtMdtinfo(data, length) {
11364 return {
11365 flags: data.read_shift(4),
11366 version: data.read_shift(4),
11367 name: parse_XLWideString(data, length - 8)
11368 };
11369}
11370function write_BrtMdtinfo(data) {
11371 var o = new_buf(12 + 2 * data.name.length);
11372 o.write_shift(4, data.flags);
11373 o.write_shift(4, data.version);
11374 write_XLWideString(data.name, o);
11375 return o.slice(0, o.l);
11376}
11377function parse_BrtMdb(data) {
11378 var out = [];
11379 var cnt = data.read_shift(4);
11380 while (cnt-- > 0)
11381 out.push([data.read_shift(4), data.read_shift(4)]);
11382 return out;
11383}
11384function write_BrtMdb(mdb) {
11385 var o = new_buf(4 + 8 * mdb.length);
11386 o.write_shift(4, mdb.length);
11387 for (var i = 0; i < mdb.length; ++i) {
11388 o.write_shift(4, mdb[i][0]);
11389 o.write_shift(4, mdb[i][1]);
11390 }
11391 return o;
11392}
11393function write_BrtBeginEsfmd(cnt, name) {
11394 var o = new_buf(8 + 2 * name.length);
11395 o.write_shift(4, cnt);
11396 write_XLWideString(name, o);
11397 return o.slice(0, o.l);
11398}
11399function parse_BrtBeginEsmdb(data) {
11400 data.l += 4;
11401 return data.read_shift(4) != 0;
11402}
11403function write_BrtBeginEsmdb(cnt, cm) {
11404 var o = new_buf(8);
11405 o.write_shift(4, cnt);
11406 o.write_shift(4, cm ? 1 : 0);
11407 return o;
11408}
11409function parse_xlmeta_bin(data, name, _opts) {
11410 var out = { Types: [], Cell: [], Value: [] };
11411 var opts = _opts || {};
11412 var state = [];
11413 var pass = false;
11414 var metatype = 2;
11415 recordhopper(data, function(val, R, RT) {
11416 switch (RT) {
11417 case 335:
11418 out.Types.push({ name: val.name });
11419 break;
11420 case 51:
11421 val.forEach(function(r) {
11422 if (metatype == 1)
11423 out.Cell.push({ type: out.Types[r[0] - 1].name, index: r[1] });
11424 else if (metatype == 0)
11425 out.Value.push({ type: out.Types[r[0] - 1].name, index: r[1] });
11426 });
11427 break;
11428 case 337:
11429 metatype = val ? 1 : 0;
11430 break;
11431 case 338:
11432 metatype = 2;
11433 break;
11434 case 35:
11435 state.push(RT);
11436 pass = true;
11437 break;
11438 case 36:
11439 state.pop();
11440 pass = false;
11441 break;
11442 default:
11443 if (R.T) {
11444 } else if (!pass || opts.WTF && state[state.length - 1] != 35)
11445 throw new Error("Unexpected record 0x" + RT.toString(16));
11446 }
11447 });
11448 return out;
11449}
11450function write_xlmeta_bin() {
11451 var ba = buf_array();
11452 write_record(ba, 332);
11453 write_record(ba, 334, write_UInt32LE(1));
11454 write_record(ba, 335, write_BrtMdtinfo({
11455 name: "XLDAPR",
11456 version: 12e4,
11457 flags: 3496657072
11458 }));
11459 write_record(ba, 336);
11460 write_record(ba, 339, write_BrtBeginEsfmd(1, "XLDAPR"));
11461 write_record(ba, 52);
11462 write_record(ba, 35, write_UInt32LE(514));
11463 write_record(ba, 4096, write_UInt32LE(0));
11464 write_record(ba, 4097, writeuint16(1));
11465 write_record(ba, 36);
11466 write_record(ba, 53);
11467 write_record(ba, 340);
11468 write_record(ba, 337, write_BrtBeginEsmdb(1, true));
11469 write_record(ba, 51, write_BrtMdb([[1, 0]]));
11470 write_record(ba, 338);
11471 write_record(ba, 333);
11472 return ba.end();
11473}
11474function parse_xlmeta_xml(data, name, opts) {
11475 var out = { Types: [], Cell: [], Value: [] };
11476 if (!data)
11477 return out;
11478 var pass = false;
11479 var metatype = 2;
11480 var lastmeta;
11481 data.replace(tagregex, function(x) {
11482 var y = parsexmltag(x);
11483 switch (strip_ns(y[0])) {
11484 case "<?xml":
11485 break;
11486 case "<metadata":
11487 case "</metadata>":
11488 break;
11489 case "<metadataTypes":
11490 case "</metadataTypes>":
11491 break;
11492 case "<metadataType":
11493 out.Types.push({ name: y.name });
11494 break;
11495 case "</metadataType>":
11496 break;
11497 case "<futureMetadata":
11498 for (var j = 0; j < out.Types.length; ++j)
11499 if (out.Types[j].name == y.name)
11500 lastmeta = out.Types[j];
11501 break;
11502 case "</futureMetadata>":
11503 break;
11504 case "<bk>":
11505 break;
11506 case "</bk>":
11507 break;
11508 case "<rc":
11509 if (metatype == 1)
11510 out.Cell.push({ type: out.Types[y.t - 1].name, index: +y.v });
11511 else if (metatype == 0)
11512 out.Value.push({ type: out.Types[y.t - 1].name, index: +y.v });
11513 break;
11514 case "</rc>":
11515 break;
11516 case "<cellMetadata":
11517 metatype = 1;
11518 break;
11519 case "</cellMetadata>":
11520 metatype = 2;
11521 break;
11522 case "<valueMetadata":
11523 metatype = 0;
11524 break;
11525 case "</valueMetadata>":
11526 metatype = 2;
11527 break;
11528 case "<extLst":
11529 case "<extLst>":
11530 case "</extLst>":
11531 case "<extLst/>":
11532 break;
11533 case "<ext":
11534 pass = true;
11535 break;
11536 case "</ext>":
11537 pass = false;
11538 break;
11539 case "<rvb":
11540 if (!lastmeta)
11541 break;
11542 if (!lastmeta.offsets)
11543 lastmeta.offsets = [];
11544 lastmeta.offsets.push(+y.i);
11545 break;
11546 default:
11547 if (!pass && opts.WTF)
11548 throw new Error("unrecognized " + y[0] + " in metadata");
11549 }
11550 return x;
11551 });
11552 return out;
11553}
11554function write_xlmeta_xml() {
11555 var o = [XML_HEADER];
11556 o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n <metadataTypes count="1">\n <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n </metadataTypes>\n <futureMetadata name="XLDAPR" count="1">\n <bk>\n <extLst>\n <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n </ext>\n </extLst>\n </bk>\n </futureMetadata>\n <cellMetadata count="1">\n <bk>\n <rc t="1" v="0"/>\n </bk>\n </cellMetadata>\n</metadata>');
11557 return o.join("");
11558}
11559/* 18.6 Calculation Chain */
11560function parse_cc_xml(data/*::, name, opts*/)/*:Array<any>*/ {
11561 var d = [];
11562 if(!data) return d;
11563 var i = 1;
11564 (data.match(tagregex)||[]).forEach(function(x) {
11565 var y = parsexmltag(x);
11566 switch(y[0]) {
11567 case '<?xml': break;
11568 /* 18.6.2 calcChain CT_CalcChain 1 */
11569 case '<calcChain': case '<calcChain>': case '</calcChain>': break;
11570 /* 18.6.1 c CT_CalcCell 1 */
11571 case '<c': delete y[0]; if(y.i) i = y.i; else y.i = i; d.push(y); break;
11572 }
11573 });
11574 return d;
11575}
11576
11577//function write_cc_xml(data, opts) { }
11578
11579/* [MS-XLSB] 2.6.4.1 */
11580function parse_BrtCalcChainItem$(data) {
11581 var out = {};
11582 out.i = data.read_shift(4);
11583 var cell = {};
11584 cell.r = data.read_shift(4);
11585 cell.c = data.read_shift(4);
11586 out.r = encode_cell(cell);
11587 var flags = data.read_shift(1);
11588 if(flags & 0x2) out.l = '1';
11589 if(flags & 0x8) out.a = '1';
11590 return out;
11591}
11592
11593/* 18.6 Calculation Chain */
11594function parse_cc_bin(data, name, opts) {
11595 var out = [];
11596 var pass = false;
11597 recordhopper(data, function hopper_cc(val, R, RT) {
11598 switch(RT) {
11599 case 0x003F: /* 'BrtCalcChainItem$' */
11600 out.push(val); break;
11601
11602 default:
11603 if(R.T){/* empty */}
11604 else if(!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
11605 }
11606 });
11607 return out;
11608}
11609
11610//function write_cc_bin(data, opts) { }
11611/* 18.14 Supplementary Workbook Data */
11612function parse_xlink_xml(/*::data, rel, name:string, _opts*/) {
11613 //var opts = _opts || {};
11614 //if(opts.WTF) throw "XLSX External Link";
11615}
11616
11617/* [MS-XLSB] 2.1.7.25 External Link */
11618function parse_xlink_bin(data, rel, name/*:string*/, _opts) {
11619 if(!data) return data;
11620 var opts = _opts || {};
11621
11622 var pass = false, end = false;
11623
11624 recordhopper(data, function xlink_parse(val, R, RT) {
11625 if(end) return;
11626 switch(RT) {
11627 case 0x0167: /* 'BrtSupTabs' */
11628 case 0x016B: /* 'BrtExternTableStart' */
11629 case 0x016C: /* 'BrtExternTableEnd' */
11630 case 0x016E: /* 'BrtExternRowHdr' */
11631 case 0x016F: /* 'BrtExternCellBlank' */
11632 case 0x0170: /* 'BrtExternCellReal' */
11633 case 0x0171: /* 'BrtExternCellBool' */
11634 case 0x0172: /* 'BrtExternCellError' */
11635 case 0x0173: /* 'BrtExternCellString' */
11636 case 0x01D8: /* 'BrtExternValueMeta' */
11637 case 0x0241: /* 'BrtSupNameStart' */
11638 case 0x0242: /* 'BrtSupNameValueStart' */
11639 case 0x0243: /* 'BrtSupNameValueEnd' */
11640 case 0x0244: /* 'BrtSupNameNum' */
11641 case 0x0245: /* 'BrtSupNameErr' */
11642 case 0x0246: /* 'BrtSupNameSt' */
11643 case 0x0247: /* 'BrtSupNameNil' */
11644 case 0x0248: /* 'BrtSupNameBool' */
11645 case 0x0249: /* 'BrtSupNameFmla' */
11646 case 0x024A: /* 'BrtSupNameBits' */
11647 case 0x024B: /* 'BrtSupNameEnd' */
11648 break;
11649
11650 case 0x0023: /* 'BrtFRTBegin' */
11651 pass = true; break;
11652 case 0x0024: /* 'BrtFRTEnd' */
11653 pass = false; break;
11654
11655 default:
11656 if(R.T){/* empty */}
11657 else if(!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
11658 }
11659 }, opts);
11660}
11661/* 20.5 DrawingML - SpreadsheetML Drawing */
11662/* 20.5.2.35 wsDr CT_Drawing */
11663function parse_drawing(data, rels/*:any*/) {
11664 if(!data) return "??";
11665 /*
11666 Chartsheet Drawing:
11667 - 20.5.2.35 wsDr CT_Drawing
11668 - 20.5.2.1 absoluteAnchor CT_AbsoluteAnchor
11669 - 20.5.2.16 graphicFrame CT_GraphicalObjectFrame
11670 - 20.1.2.2.16 graphic CT_GraphicalObject
11671 - 20.1.2.2.17 graphicData CT_GraphicalObjectData
11672 - chart reference
11673 the actual type is based on the URI of the graphicData
11674 TODO: handle embedded charts and other types of graphics
11675 */
11676 var id = (data.match(/<c:chart [^>]*r:id="([^"]*)"/)||["",""])[1];
11677
11678 return rels['!id'][id].Target;
11679}
11680
11681/* L.5.5.2 SpreadsheetML Comments + VML Schema */
11682var _shapeid = 1024;
11683function write_comments_vml(rId/*:number*/, comments) {
11684 var csize = [21600, 21600];
11685 /* L.5.2.1.2 Path Attribute */
11686 var bbox = ["m0,0l0",csize[1],csize[0],csize[1],csize[0],"0xe"].join(",");
11687 var o = [
11688 writextag("xml", null, { 'xmlns:v': XLMLNS.v, 'xmlns:o': XLMLNS.o, 'xmlns:x': XLMLNS.x, 'xmlns:mv': XLMLNS.mv }).replace(/\/>/,">"),
11689 writextag("o:shapelayout", writextag("o:idmap", null, {'v:ext':"edit", 'data':rId}), {'v:ext':"edit"}),
11690 writextag("v:shapetype", [
11691 writextag("v:stroke", null, {joinstyle:"miter"}),
11692 writextag("v:path", null, {gradientshapeok:"t", 'o:connecttype':"rect"})
11693 ].join(""), {id:"_x0000_t202", 'o:spt':202, coordsize:csize.join(","),path:bbox})
11694 ];
11695 while(_shapeid < rId * 1000) _shapeid += 1000;
11696
11697 comments.forEach(function(x) {
11698 var c = decode_cell(x[0]);
11699 var fillopts = /*::(*/{'color2':"#BEFF82", 'type':"gradient"}/*:: :any)*/;
11700 if(fillopts.type == "gradient") fillopts.angle = "-180";
11701 var fillparm = fillopts.type == "gradient" ? writextag("o:fill", null, {type:"gradientUnscaled", 'v:ext':"view"}) : null;
11702 var fillxml = writextag('v:fill', fillparm, fillopts);
11703
11704 var shadata = ({on:"t", 'obscured':"t"}/*:any*/);
11705 ++_shapeid;
11706
11707 o = o.concat([
11708 '<v:shape' + wxt_helper({
11709 id:'_x0000_s' + _shapeid,
11710 type:"#_x0000_t202",
11711 style:"position:absolute; margin-left:80pt;margin-top:5pt;width:104pt;height:64pt;z-index:10" + (x[1].hidden ? ";visibility:hidden" : "") ,
11712 fillcolor:"#ECFAD4",
11713 strokecolor:"#edeaa1"
11714 }) + '>',
11715 fillxml,
11716 writextag("v:shadow", null, shadata),
11717 writextag("v:path", null, {'o:connecttype':"none"}),
11718 '<v:textbox><div style="text-align:left"></div></v:textbox>',
11719 '<x:ClientData ObjectType="Note">',
11720 '<x:MoveWithCells/>',
11721 '<x:SizeWithCells/>',
11722 /* Part 4 19.4.2.3 Anchor (Anchor) */
11723 writetag('x:Anchor', [c.c+1, 0, c.r+1, 0, c.c+3, 20, c.r+5, 20].join(",")),
11724 writetag('x:AutoFill', "False"),
11725 writetag('x:Row', String(c.r)),
11726 writetag('x:Column', String(c.c)),
11727 x[1].hidden ? '' : '<x:Visible/>',
11728 '</x:ClientData>',
11729 '</v:shape>'
11730 ]); });
11731 o.push('</xml>');
11732 return o.join("");
11733}
11734function sheet_insert_comments(sheet, comments/*:Array<RawComment>*/, threaded/*:boolean*/, people/*:?Array<any>*/) {
11735 var dense = Array.isArray(sheet);
11736 var cell/*:Cell*/;
11737 comments.forEach(function(comment) {
11738 var r = decode_cell(comment.ref);
11739 if(dense) {
11740 if(!sheet[r.r]) sheet[r.r] = [];
11741 cell = sheet[r.r][r.c];
11742 } else cell = sheet[comment.ref];
11743 if (!cell) {
11744 cell = ({t:"z"}/*:any*/);
11745 if(dense) sheet[r.r][r.c] = cell;
11746 else sheet[comment.ref] = cell;
11747 var range = safe_decode_range(sheet["!ref"]||"BDWGO1000001:A1");
11748 if(range.s.r > r.r) range.s.r = r.r;
11749 if(range.e.r < r.r) range.e.r = r.r;
11750 if(range.s.c > r.c) range.s.c = r.c;
11751 if(range.e.c < r.c) range.e.c = r.c;
11752 var encoded = encode_range(range);
11753 if (encoded !== sheet["!ref"]) sheet["!ref"] = encoded;
11754 }
11755
11756 if (!cell.c) cell.c = [];
11757 var o/*:Comment*/ = ({a: comment.author, t: comment.t, r: comment.r, T: threaded});
11758 if(comment.h) o.h = comment.h;
11759
11760 /* threaded comments always override */
11761 for(var i = cell.c.length - 1; i >= 0; --i) {
11762 if(!threaded && cell.c[i].T) return;
11763 if(threaded && !cell.c[i].T) cell.c.splice(i, 1);
11764 }
11765 if(threaded && people) for(i = 0; i < people.length; ++i) {
11766 if(o.a == people[i].id) { o.a = people[i].name || o.a; break; }
11767 }
11768 cell.c.push(o);
11769 });
11770}
11771
11772/* 18.7 Comments */
11773function parse_comments_xml(data/*:string*/, opts)/*:Array<RawComment>*/ {
11774 /* 18.7.6 CT_Comments */
11775 if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
11776 var authors/*:Array<string>*/ = [];
11777 var commentList/*:Array<RawComment>*/ = [];
11778 var authtag = data.match(/<(?:\w+:)?authors>([\s\S]*)<\/(?:\w+:)?authors>/);
11779 if(authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function(x) {
11780 if(x === "" || x.trim() === "") return;
11781 var a = x.match(/<(?:\w+:)?author[^>]*>(.*)/);
11782 if(a) authors.push(a[1]);
11783 });
11784 var cmnttag = data.match(/<(?:\w+:)?commentList>([\s\S]*)<\/(?:\w+:)?commentList>/);
11785 if(cmnttag && cmnttag[1]) cmnttag[1].split(/<\/\w*:?comment>/).forEach(function(x) {
11786 if(x === "" || x.trim() === "") return;
11787 var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
11788 if(!cm) return;
11789 var y = parsexmltag(cm[0]);
11790 var comment/*:RawComment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
11791 var cell = decode_cell(y.ref);
11792 if(opts.sheetRows && opts.sheetRows <= cell.r) return;
11793 var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
11794 var rt = !!textMatch && !!textMatch[1] && parse_si(textMatch[1]) || {r:"",t:"",h:""};
11795 comment.r = rt.r;
11796 if(rt.r == "<t></t>") rt.t = rt.h = "";
11797 comment.t = (rt.t||"").replace(/\r\n/g,"\n").replace(/\r/g,"\n");
11798 if(opts.cellHTML) comment.h = rt.h;
11799 commentList.push(comment);
11800 });
11801 return commentList;
11802}
11803
11804function write_comments_xml(data/*::, opts*/) {
11805 var o = [XML_HEADER, writextag('comments', null, { 'xmlns': XMLNS_main[0] })];
11806
11807 var iauthor/*:Array<string>*/ = [];
11808 o.push("<authors>");
11809 data.forEach(function(x) { x[1].forEach(function(w) { var a = escapexml(w.a);
11810 if(iauthor.indexOf(a) == -1) {
11811 iauthor.push(a);
11812 o.push("<author>" + a + "</author>");
11813 }
11814 if(w.T && w.ID && iauthor.indexOf("tc=" + w.ID) == -1) {
11815 iauthor.push("tc=" + w.ID);
11816 o.push("<author>" + "tc=" + w.ID + "</author>");
11817 }
11818 }); });
11819 if(iauthor.length == 0) { iauthor.push("SheetJ5"); o.push("<author>SheetJ5</author>"); }
11820 o.push("</authors>");
11821 o.push("<commentList>");
11822 data.forEach(function(d) {
11823 /* 18.7.3 CT_Comment */
11824 var lastauthor = 0, ts = [];
11825 if(d[1][0] && d[1][0].T && d[1][0].ID) lastauthor = iauthor.indexOf("tc=" + d[1][0].ID);
11826 else d[1].forEach(function(c) {
11827 if(c.a) lastauthor = iauthor.indexOf(escapexml(c.a));
11828 ts.push(c.t||"");
11829 });
11830 o.push('<comment ref="' + d[0] + '" authorId="' + lastauthor + '"><text>');
11831 if(ts.length <= 1) o.push(writetag("t", escapexml(ts[0]||"")));
11832 else {
11833 /* based on Threaded Comments -> Comments projection */
11834 var t = "Comment:\n " + (ts[0]) + "\n";
11835 for(var i = 1; i < ts.length; ++i) t += "Reply:\n " + ts[i] + "\n";
11836 o.push(writetag("t", escapexml(t)));
11837 }
11838 o.push('</text></comment>');
11839 });
11840 o.push("</commentList>");
11841 if(o.length>2) { o[o.length] = ('</comments>'); o[1]=o[1].replace("/>",">"); }
11842 return o.join("");
11843}
11844
11845/* [MS-XLSX] 2.1.17 */
11846function parse_tcmnt_xml(data/*:string*/, opts)/*:Array<RawComment>*/ {
11847 var out = [];
11848 var pass = false, comment = {}, tidx = 0;
11849 data.replace(tagregex, function xml_tcmnt(x, idx) {
11850 var y/*:any*/ = parsexmltag(x);
11851 switch(strip_ns(y[0])) {
11852 case '<?xml': break;
11853
11854 /* 2.6.207 ThreadedComments CT_ThreadedComments */
11855 case '<ThreadedComments': break;
11856 case '</ThreadedComments>': break;
11857
11858 /* 2.6.205 threadedComment CT_ThreadedComment */
11859 case '<threadedComment': comment = {author: y.personId, guid: y.id, ref: y.ref, T: 1}; break;
11860 case '</threadedComment>': if(comment.t != null) out.push(comment); break;
11861
11862 case '<text>': case '<text': tidx = idx + x.length; break;
11863 case '</text>': comment.t = data.slice(tidx, idx).replace(/\r\n/g, "\n").replace(/\r/g, "\n"); break;
11864
11865 /* 2.6.206 mentions CT_ThreadedCommentMentions TODO */
11866 case '<mentions': case '<mentions>': pass = true; break;
11867 case '</mentions>': pass = false; break;
11868
11869 /* 2.6.202 mention CT_Mention TODO */
11870
11871 /* 18.2.10 extLst CT_ExtensionList ? */
11872 case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
11873 /* 18.2.7 ext CT_Extension + */
11874 case '<ext': pass=true; break;
11875 case '</ext>': pass=false; break;
11876
11877 default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in threaded comments');
11878 }
11879 return x;
11880 });
11881 return out;
11882}
11883
11884function write_tcmnt_xml(comments, people, opts) {
11885 var o = [XML_HEADER, writextag('ThreadedComments', null, { 'xmlns': XMLNS.TCMNT }).replace(/[\/]>/, ">")];
11886 comments.forEach(function(carr) {
11887 var rootid = "";
11888 (carr[1] || []).forEach(function(c, idx) {
11889 if(!c.T) { delete c.ID; return; }
11890 if(c.a && people.indexOf(c.a) == -1) people.push(c.a);
11891 var tcopts = {
11892 ref: carr[0],
11893 id: "{54EE7951-7262-4200-6969-" + ("000000000000" + opts.tcid++).slice(-12) + "}"
11894 };
11895 if(idx == 0) rootid = tcopts.id;
11896 else tcopts.parentId = rootid;
11897 c.ID = tcopts.id;
11898 if(c.a) tcopts.personId = "{54EE7950-7262-4200-6969-" + ("000000000000" + people.indexOf(c.a)).slice(-12) + "}";
11899 o.push(writextag('threadedComment', writetag('text', c.t||""), tcopts));
11900 });
11901 });
11902 o.push('</ThreadedComments>');
11903 return o.join("");
11904}
11905
11906/* [MS-XLSX] 2.1.18 */
11907function parse_people_xml(data/*:string*/, opts) {
11908 var out = [];
11909 var pass = false;
11910 data.replace(tagregex, function xml_tcmnt(x) {
11911 var y/*:any*/ = parsexmltag(x);
11912 switch(strip_ns(y[0])) {
11913 case '<?xml': break;
11914
11915 /* 2.4.85 personList CT_PersonList */
11916 case '<personList': break;
11917 case '</personList>': break;
11918
11919 /* 2.6.203 person CT_Person TODO: providers */
11920 case '<person': out.push({name: y.displayname, id: y.id }); break;
11921 case '</person>': break;
11922
11923 /* 18.2.10 extLst CT_ExtensionList ? */
11924 case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
11925 /* 18.2.7 ext CT_Extension + */
11926 case '<ext': pass=true; break;
11927 case '</ext>': pass=false; break;
11928
11929 default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in threaded comments');
11930 }
11931 return x;
11932 });
11933 return out;
11934}
11935function write_people_xml(people/*, opts*/) {
11936 var o = [XML_HEADER, writextag('personList', null, {
11937 'xmlns': XMLNS.TCMNT,
11938 'xmlns:x': XMLNS_main[0]
11939 }).replace(/[\/]>/, ">")];
11940 people.forEach(function(person, idx) {
11941 o.push(writextag('person', null, {
11942 displayName: person,
11943 id: "{54EE7950-7262-4200-6969-" + ("000000000000" + idx).slice(-12) + "}",
11944 userId: person,
11945 providerId: "None"
11946 }));
11947 });
11948 o.push("</personList>");
11949 return o.join("");
11950}
11951/* [MS-XLSB] 2.4.28 BrtBeginComment */
11952function parse_BrtBeginComment(data) {
11953 var out = {};
11954 out.iauthor = data.read_shift(4);
11955 var rfx = parse_UncheckedRfX(data, 16);
11956 out.rfx = rfx.s;
11957 out.ref = encode_cell(rfx.s);
11958 data.l += 16; /*var guid = parse_GUID(data); */
11959 return out;
11960}
11961function write_BrtBeginComment(data, o) {
11962 if(o == null) o = new_buf(36);
11963 o.write_shift(4, data[1].iauthor);
11964 write_UncheckedRfX((data[0]/*:any*/), o);
11965 o.write_shift(4, 0);
11966 o.write_shift(4, 0);
11967 o.write_shift(4, 0);
11968 o.write_shift(4, 0);
11969 return o;
11970}
11971
11972/* [MS-XLSB] 2.4.327 BrtCommentAuthor */
11973var parse_BrtCommentAuthor = parse_XLWideString;
11974function write_BrtCommentAuthor(data) { return write_XLWideString(data.slice(0, 54)); }
11975
11976/* [MS-XLSB] 2.1.7.8 Comments */
11977function parse_comments_bin(data, opts)/*:Array<RawComment>*/ {
11978 var out/*:Array<RawComment>*/ = [];
11979 var authors/*:Array<string>*/ = [];
11980 var c = {};
11981 var pass = false;
11982 recordhopper(data, function hopper_cmnt(val, R, RT) {
11983 switch(RT) {
11984 case 0x0278: /* 'BrtCommentAuthor' */
11985 authors.push(val); break;
11986 case 0x027B: /* 'BrtBeginComment' */
11987 c = val; break;
11988 case 0x027D: /* 'BrtCommentText' */
11989 c.t = val.t; c.h = val.h; c.r = val.r; break;
11990 case 0x027C: /* 'BrtEndComment' */
11991 c.author = authors[c.iauthor];
11992 delete (c/*:any*/).iauthor;
11993 if(opts.sheetRows && c.rfx && opts.sheetRows <= c.rfx.r) break;
11994 if(!c.t) c.t = "";
11995 delete c.rfx; out.push(c); break;
11996
11997 case 0x0C00: /* 'BrtUid' */
11998 break;
11999
12000 case 0x0023: /* 'BrtFRTBegin' */
12001 pass = true; break;
12002 case 0x0024: /* 'BrtFRTEnd' */
12003 pass = false; break;
12004 case 0x0025: /* 'BrtACBegin' */ break;
12005 case 0x0026: /* 'BrtACEnd' */ break;
12006
12007
12008 default:
12009 if(R.T){/* empty */}
12010 else if(!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
12011 }
12012 });
12013 return out;
12014}
12015
12016function write_comments_bin(data/*::, opts*/) {
12017 var ba = buf_array();
12018 var iauthor/*:Array<string>*/ = [];
12019 write_record(ba, 0x0274 /* BrtBeginComments */);
12020
12021 write_record(ba, 0x0276 /* BrtBeginCommentAuthors */);
12022 data.forEach(function(comment) {
12023 comment[1].forEach(function(c) {
12024 if(iauthor.indexOf(c.a) > -1) return;
12025 iauthor.push(c.a.slice(0,54));
12026 write_record(ba, 0x0278 /* BrtCommentAuthor */, write_BrtCommentAuthor(c.a));
12027 });
12028 });
12029 write_record(ba, 0x0277 /* BrtEndCommentAuthors */);
12030
12031 write_record(ba, 0x0279 /* BrtBeginCommentList */);
12032 data.forEach(function(comment) {
12033 comment[1].forEach(function(c) {
12034 c.iauthor = iauthor.indexOf(c.a);
12035 var range = {s:decode_cell(comment[0]),e:decode_cell(comment[0])};
12036 write_record(ba, 0x027B /* BrtBeginComment */, write_BrtBeginComment([range, c]));
12037 if(c.t && c.t.length > 0) write_record(ba, 0x027D /* BrtCommentText */, write_BrtCommentText(c));
12038 write_record(ba, 0x027C /* BrtEndComment */);
12039 delete c.iauthor;
12040 });
12041 });
12042 write_record(ba, 0x027A /* BrtEndCommentList */);
12043
12044 write_record(ba, 0x0275 /* BrtEndComments */);
12045 return ba.end();
12046}
12047var CT_VBA = "application/vnd.ms-office.vbaProject";
12048function make_vba_xls(cfb) {
12049 var newcfb = CFB.utils.cfb_new({ root: "R" });
12050 cfb.FullPaths.forEach(function(p, i) {
12051 if (p.slice(-1) === "/" || !p.match(/_VBA_PROJECT_CUR/))
12052 return;
12053 var newpath = p.replace(/^[^\/]*/, "R").replace(/\/_VBA_PROJECT_CUR\u0000*/, "");
12054 CFB.utils.cfb_add(newcfb, newpath, cfb.FileIndex[i].content);
12055 });
12056 return CFB.write(newcfb);
12057}
12058function fill_vba_xls(cfb, vba) {
12059 vba.FullPaths.forEach(function(p, i) {
12060 if (i == 0)
12061 return;
12062 var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
12063 if (newpath.slice(-1) !== "/")
12064 CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
12065 });
12066}
12067var VBAFMTS = ["xlsb", "xlsm", "xlam", "biff8", "xla"];
12068/* macro and dialog sheet stubs */
12069function parse_ds_bin(/*::data:any, opts, idx:number, rels, wb, themes, styles*/)/*:Worksheet*/ { return {'!type':'dialog'}; }
12070function parse_ds_xml(/*::data:any, opts, idx:number, rels, wb, themes, styles*/)/*:Worksheet*/ { return {'!type':'dialog'}; }
12071function parse_ms_bin(/*::data:any, opts, idx:number, rels, wb, themes, styles*/)/*:Worksheet*/ { return {'!type':'macro'}; }
12072function parse_ms_xml(/*::data:any, opts, idx:number, rels, wb, themes, styles*/)/*:Worksheet*/ { return {'!type':'macro'}; }
12073/* TODO: it will be useful to parse the function str */
12074var rc_to_a1 = /*#__PURE__*/(function(){
12075 var rcregex = /(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g;
12076 var rcbase/*:Cell*/ = ({r:0,c:0}/*:any*/);
12077 function rcfunc($$,$1,$2,$3) {
12078 var cRel = false, rRel = false;
12079
12080 if($2.length == 0) rRel = true;
12081 else if($2.charAt(0) == "[") { rRel = true; $2 = $2.slice(1, -1); }
12082
12083 if($3.length == 0) cRel = true;
12084 else if($3.charAt(0) == "[") { cRel = true; $3 = $3.slice(1, -1); }
12085
12086 var R = $2.length>0?parseInt($2,10)|0:0, C = $3.length>0?parseInt($3,10)|0:0;
12087
12088 if(cRel) C += rcbase.c; else --C;
12089 if(rRel) R += rcbase.r; else --R;
12090 return $1 + (cRel ? "" : "$") + encode_col(C) + (rRel ? "" : "$") + encode_row(R);
12091 }
12092 return function rc_to_a1(fstr/*:string*/, base/*:Cell*/)/*:string*/ {
12093 rcbase = base;
12094 return fstr.replace(rcregex, rcfunc);
12095 };
12096})();
12097
12098var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g;
12099var a1_to_rc = /*#__PURE__*/(function(){
12100 return function a1_to_rc(fstr/*:string*/, base/*:CellAddress*/) {
12101 return fstr.replace(crefregex, function($0, $1, $2, $3, $4, $5) {
12102 var c = decode_col($3) - ($2 ? 0 : base.c);
12103 var r = decode_row($5) - ($4 ? 0 : base.r);
12104 var R = (r == 0 ? "" : !$4 ? "[" + r + "]" : (r+1));
12105 var C = (c == 0 ? "" : !$2 ? "[" + c + "]" : (c+1));
12106 return $1 + "R" + R + "C" + C;
12107 });
12108 };
12109})();
12110
12111/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
12112function shift_formula_str(f/*:string*/, delta/*:Cell*/)/*:string*/ {
12113 return f.replace(crefregex, function($0, $1, $2, $3, $4, $5) {
12114 return $1+($2=="$" ? $2+$3 : encode_col(decode_col($3)+delta.c))+($4=="$" ? $4+$5 : encode_row(decode_row($5) + delta.r));
12115 });
12116}
12117
12118function shift_formula_xlsx(f/*:string*/, range/*:string*/, cell/*:string*/)/*:string*/ {
12119 var r = decode_range(range), s = r.s, c = decode_cell(cell);
12120 var delta = {r:c.r - s.r, c:c.c - s.c};
12121 return shift_formula_str(f, delta);
12122}
12123
12124/* TODO: parse formula */
12125function fuzzyfmla(f/*:string*/)/*:boolean*/ {
12126 if(f.length == 1) return false;
12127 return true;
12128}
12129
12130function _xlfn(f/*:string*/)/*:string*/ {
12131 return f.replace(/_xlfn\./g,"");
12132}
12133function parseread1(blob) { blob.l+=1; return; }
12134
12135/* [MS-XLS] 2.5.51 */
12136function parse_ColRelU(blob, length) {
12137 var c = blob.read_shift(length == 1 ? 1 : 2);
12138 return [c & 0x3FFF, (c >> 14) & 1, (c >> 15) & 1];
12139}
12140
12141/* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.89 */
12142function parse_RgceArea(blob, length, opts) {
12143 var w = 2;
12144 if(opts) {
12145 if(opts.biff >= 2 && opts.biff <= 5) return parse_RgceArea_BIFF2(blob, length, opts);
12146 else if(opts.biff == 12) w = 4;
12147 }
12148 var r=blob.read_shift(w), R=blob.read_shift(w);
12149 var c=parse_ColRelU(blob, 2);
12150 var C=parse_ColRelU(blob, 2);
12151 return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} };
12152}
12153/* BIFF 2-5 encodes flags in the row field */
12154function parse_RgceArea_BIFF2(blob/*::, length, opts*/) {
12155 var r=parse_ColRelU(blob, 2), R=parse_ColRelU(blob, 2);
12156 var c=blob.read_shift(1);
12157 var C=blob.read_shift(1);
12158 return { s:{r:r[0], c:c, cRel:r[1], rRel:r[2]}, e:{r:R[0], c:C, cRel:R[1], rRel:R[2]} };
12159}
12160
12161/* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.90 */
12162function parse_RgceAreaRel(blob, length, opts) {
12163 if(opts.biff < 8) return parse_RgceArea_BIFF2(blob, length, opts);
12164 var r=blob.read_shift(opts.biff == 12 ? 4 : 2), R=blob.read_shift(opts.biff == 12 ? 4 : 2);
12165 var c=parse_ColRelU(blob, 2);
12166 var C=parse_ColRelU(blob, 2);
12167 return { s:{r:r, c:c[0], cRel:c[1], rRel:c[2]}, e:{r:R, c:C[0], cRel:C[1], rRel:C[2]} };
12168}
12169
12170/* [MS-XLS] 2.5.198.109 ; [MS-XLSB] 2.5.97.91 */
12171function parse_RgceLoc(blob, length, opts) {
12172 if(opts && opts.biff >= 2 && opts.biff <= 5) return parse_RgceLoc_BIFF2(blob, length, opts);
12173 var r = blob.read_shift(opts && opts.biff == 12 ? 4 : 2);
12174 var c = parse_ColRelU(blob, 2);
12175 return {r:r, c:c[0], cRel:c[1], rRel:c[2]};
12176}
12177function parse_RgceLoc_BIFF2(blob/*::, length, opts*/) {
12178 var r = parse_ColRelU(blob, 2);
12179 var c = blob.read_shift(1);
12180 return {r:r[0], c:c, cRel:r[1], rRel:r[2]};
12181}
12182
12183/* [MS-XLS] 2.5.198.107, 2.5.47 */
12184function parse_RgceElfLoc(blob/*::, length, opts*/) {
12185 var r = blob.read_shift(2);
12186 var c = blob.read_shift(2);
12187 return {r:r, c:c & 0xFF, fQuoted:!!(c & 0x4000), cRel:c>>15, rRel:c>>15 };
12188}
12189
12190/* [MS-XLS] 2.5.198.111 ; [MS-XLSB] 2.5.97.92 TODO */
12191function parse_RgceLocRel(blob, length, opts) {
12192 var biff = opts && opts.biff ? opts.biff : 8;
12193 if(biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
12194 var r = blob.read_shift(biff >= 12 ? 4 : 2);
12195 var cl = blob.read_shift(2);
12196 var cRel = (cl & 0x4000) >> 14, rRel = (cl & 0x8000) >> 15;
12197 cl &= 0x3FFF;
12198 if(rRel == 1) while(r > 0x7FFFF) r -= 0x100000;
12199 if(cRel == 1) while(cl > 0x1FFF) cl = cl - 0x4000;
12200 return {r:r,c:cl,cRel:cRel,rRel:rRel};
12201}
12202function parse_RgceLocRel_BIFF2(blob/*::, length:number, opts*/) {
12203 var rl = blob.read_shift(2);
12204 var c = blob.read_shift(1);
12205 var rRel = (rl & 0x8000) >> 15, cRel = (rl & 0x4000) >> 14;
12206 rl &= 0x3FFF;
12207 if(rRel == 1 && rl >= 0x2000) rl = rl - 0x4000;
12208 if(cRel == 1 && c >= 0x80) c = c - 0x100;
12209 return {r:rl,c:c,cRel:cRel,rRel:rRel};
12210}
12211
12212/* [MS-XLS] 2.5.198.27 ; [MS-XLSB] 2.5.97.18 */
12213function parse_PtgArea(blob, length, opts) {
12214 var type = (blob[blob.l++] & 0x60) >> 5;
12215 var area = parse_RgceArea(blob, opts.biff >= 2 && opts.biff <= 5 ? 6 : 8, opts);
12216 return [type, area];
12217}
12218
12219/* [MS-XLS] 2.5.198.28 ; [MS-XLSB] 2.5.97.19 */
12220function parse_PtgArea3d(blob, length, opts) {
12221 var type = (blob[blob.l++] & 0x60) >> 5;
12222 var ixti = blob.read_shift(2, 'i');
12223 var w = 8;
12224 if(opts) switch(opts.biff) {
12225 case 5: blob.l += 12; w = 6; break;
12226 case 12: w = 12; break;
12227 }
12228 var area = parse_RgceArea(blob, w, opts);
12229 return [type, ixti, area];
12230}
12231
12232/* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */
12233function parse_PtgAreaErr(blob, length, opts) {
12234 var type = (blob[blob.l++] & 0x60) >> 5;
12235 blob.l += opts && (opts.biff > 8) ? 12 : (opts.biff < 8 ? 6 : 8);
12236 return [type];
12237}
12238/* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */
12239function parse_PtgAreaErr3d(blob, length, opts) {
12240 var type = (blob[blob.l++] & 0x60) >> 5;
12241 var ixti = blob.read_shift(2);
12242 var w = 8;
12243 if(opts) switch(opts.biff) {
12244 case 5: blob.l += 12; w = 6; break;
12245 case 12: w = 12; break;
12246 }
12247 blob.l += w;
12248 return [type, ixti];
12249}
12250
12251/* [MS-XLS] 2.5.198.31 ; [MS-XLSB] 2.5.97.22 */
12252function parse_PtgAreaN(blob, length, opts) {
12253 var type = (blob[blob.l++] & 0x60) >> 5;
12254 var area = parse_RgceAreaRel(blob, length - 1, opts);
12255 return [type, area];
12256}
12257
12258/* [MS-XLS] 2.5.198.32 ; [MS-XLSB] 2.5.97.23 */
12259function parse_PtgArray(blob, length, opts) {
12260 var type = (blob[blob.l++] & 0x60) >> 5;
12261 blob.l += opts.biff == 2 ? 6 : opts.biff == 12 ? 14 : 7;
12262 return [type];
12263}
12264
12265/* [MS-XLS] 2.5.198.33 ; [MS-XLSB] 2.5.97.24 */
12266function parse_PtgAttrBaxcel(blob) {
12267 var bitSemi = blob[blob.l+1] & 0x01; /* 1 = volatile */
12268 var bitBaxcel = 1;
12269 blob.l += 4;
12270 return [bitSemi, bitBaxcel];
12271}
12272
12273/* [MS-XLS] 2.5.198.34 ; [MS-XLSB] 2.5.97.25 */
12274function parse_PtgAttrChoose(blob, length, opts)/*:Array<number>*/ {
12275 blob.l +=2;
12276 var offset = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
12277 var o/*:Array<number>*/ = [];
12278 /* offset is 1 less than the number of elements */
12279 for(var i = 0; i <= offset; ++i) o.push(blob.read_shift(opts && opts.biff == 2 ? 1 : 2));
12280 return o;
12281}
12282
12283/* [MS-XLS] 2.5.198.35 ; [MS-XLSB] 2.5.97.26 */
12284function parse_PtgAttrGoto(blob, length, opts) {
12285 var bitGoto = (blob[blob.l+1] & 0xFF) ? 1 : 0;
12286 blob.l += 2;
12287 return [bitGoto, blob.read_shift(opts && opts.biff == 2 ? 1 : 2)];
12288}
12289
12290/* [MS-XLS] 2.5.198.36 ; [MS-XLSB] 2.5.97.27 */
12291function parse_PtgAttrIf(blob, length, opts) {
12292 var bitIf = (blob[blob.l+1] & 0xFF) ? 1 : 0;
12293 blob.l += 2;
12294 return [bitIf, blob.read_shift(opts && opts.biff == 2 ? 1 : 2)];
12295}
12296
12297/* [MS-XLSB] 2.5.97.28 */
12298function parse_PtgAttrIfError(blob) {
12299 var bitIf = (blob[blob.l+1] & 0xFF) ? 1 : 0;
12300 blob.l += 2;
12301 return [bitIf, blob.read_shift(2)];
12302}
12303
12304/* [MS-XLS] 2.5.198.37 ; [MS-XLSB] 2.5.97.29 */
12305function parse_PtgAttrSemi(blob, length, opts) {
12306 var bitSemi = (blob[blob.l+1] & 0xFF) ? 1 : 0;
12307 blob.l += opts && opts.biff == 2 ? 3 : 4;
12308 return [bitSemi];
12309}
12310
12311/* [MS-XLS] 2.5.198.40 ; [MS-XLSB] 2.5.97.32 */
12312function parse_PtgAttrSpaceType(blob/*::, length*/) {
12313 var type = blob.read_shift(1), cch = blob.read_shift(1);
12314 return [type, cch];
12315}
12316
12317/* [MS-XLS] 2.5.198.38 ; [MS-XLSB] 2.5.97.30 */
12318function parse_PtgAttrSpace(blob) {
12319 blob.read_shift(2);
12320 return parse_PtgAttrSpaceType(blob, 2);
12321}
12322
12323/* [MS-XLS] 2.5.198.39 ; [MS-XLSB] 2.5.97.31 */
12324function parse_PtgAttrSpaceSemi(blob) {
12325 blob.read_shift(2);
12326 return parse_PtgAttrSpaceType(blob, 2);
12327}
12328
12329/* [MS-XLS] 2.5.198.84 ; [MS-XLSB] 2.5.97.68 TODO */
12330function parse_PtgRef(blob, length, opts) {
12331 //var ptg = blob[blob.l] & 0x1F;
12332 var type = (blob[blob.l] & 0x60)>>5;
12333 blob.l += 1;
12334 var loc = parse_RgceLoc(blob, 0, opts);
12335 return [type, loc];
12336}
12337
12338/* [MS-XLS] 2.5.198.88 ; [MS-XLSB] 2.5.97.72 TODO */
12339function parse_PtgRefN(blob, length, opts) {
12340 var type = (blob[blob.l] & 0x60)>>5;
12341 blob.l += 1;
12342 var loc = parse_RgceLocRel(blob, 0, opts);
12343 return [type, loc];
12344}
12345
12346/* [MS-XLS] 2.5.198.85 ; [MS-XLSB] 2.5.97.69 TODO */
12347function parse_PtgRef3d(blob, length, opts) {
12348 var type = (blob[blob.l] & 0x60)>>5;
12349 blob.l += 1;
12350 var ixti = blob.read_shift(2); // XtiIndex
12351 if(opts && opts.biff == 5) blob.l += 12;
12352 var loc = parse_RgceLoc(blob, 0, opts); // TODO: or RgceLocRel
12353 return [type, ixti, loc];
12354}
12355
12356
12357/* [MS-XLS] 2.5.198.62 ; [MS-XLSB] 2.5.97.45 TODO */
12358function parse_PtgFunc(blob, length, opts) {
12359 //var ptg = blob[blob.l] & 0x1F;
12360 var type = (blob[blob.l] & 0x60)>>5;
12361 blob.l += 1;
12362 var iftab = blob.read_shift(opts && opts.biff <= 3 ? 1 : 2);
12363 return [FtabArgc[iftab], Ftab[iftab], type];
12364}
12365/* [MS-XLS] 2.5.198.63 ; [MS-XLSB] 2.5.97.46 TODO */
12366function parse_PtgFuncVar(blob, length, opts) {
12367 var type = blob[blob.l++];
12368 var cparams = blob.read_shift(1), tab = opts && opts.biff <= 3 ? [(type == 0x58 ? -1 : 0), blob.read_shift(1)]: parsetab(blob);
12369 return [cparams, (tab[0] === 0 ? Ftab : Cetab)[tab[1]]];
12370}
12371
12372function parsetab(blob) {
12373 return [blob[blob.l+1]>>7, blob.read_shift(2) & 0x7FFF];
12374}
12375
12376/* [MS-XLS] 2.5.198.41 ; [MS-XLSB] 2.5.97.33 */
12377function parse_PtgAttrSum(blob, length, opts) {
12378 blob.l += opts && opts.biff == 2 ? 3 : 4; return;
12379}
12380
12381/* [MS-XLS] 2.5.198.58 ; [MS-XLSB] 2.5.97.40 */
12382function parse_PtgExp(blob, length, opts) {
12383 blob.l++;
12384 if(opts && opts.biff == 12) return [blob.read_shift(4, 'i'), 0];
12385 var row = blob.read_shift(2);
12386 var col = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
12387 return [row, col];
12388}
12389
12390/* [MS-XLS] 2.5.198.57 ; [MS-XLSB] 2.5.97.39 */
12391function parse_PtgErr(blob) { blob.l++; return BErr[blob.read_shift(1)]; }
12392
12393/* [MS-XLS] 2.5.198.66 ; [MS-XLSB] 2.5.97.49 */
12394function parse_PtgInt(blob) { blob.l++; return blob.read_shift(2); }
12395
12396/* [MS-XLS] 2.5.198.42 ; [MS-XLSB] 2.5.97.34 */
12397function parse_PtgBool(blob) { blob.l++; return blob.read_shift(1)!==0;}
12398
12399/* [MS-XLS] 2.5.198.79 ; [MS-XLSB] 2.5.97.63 */
12400function parse_PtgNum(blob) { blob.l++; return parse_Xnum(blob, 8); }
12401
12402/* [MS-XLS] 2.5.198.89 ; [MS-XLSB] 2.5.97.74 */
12403function parse_PtgStr(blob, length, opts) { blob.l++; return parse_ShortXLUnicodeString(blob, length-1, opts); }
12404
12405/* [MS-XLS] 2.5.192.112 + 2.5.192.11{3,4,5,6,7} */
12406/* [MS-XLSB] 2.5.97.93 + 2.5.97.9{4,5,6,7} */
12407function parse_SerAr(blob, biff/*:number*/) {
12408 var val = [blob.read_shift(1)];
12409 if(biff == 12) switch(val[0]) {
12410 case 0x02: val[0] = 0x04; break; /* SerBool */
12411 case 0x04: val[0] = 0x10; break; /* SerErr */
12412 case 0x00: val[0] = 0x01; break; /* SerNum */
12413 case 0x01: val[0] = 0x02; break; /* SerStr */
12414 }
12415 switch(val[0]) {
12416 case 0x04: /* SerBool -- boolean */
12417 val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
12418 if(biff != 12) blob.l += 7; break;
12419 case 0x25: /* appears to be an alias */
12420 case 0x10: /* SerErr -- error */
12421 val[1] = BErr[blob[blob.l]];
12422 blob.l += ((biff == 12) ? 4 : 8); break;
12423 case 0x00: /* SerNil -- honestly, I'm not sure how to reproduce this */
12424 blob.l += 8; break;
12425 case 0x01: /* SerNum -- Xnum */
12426 val[1] = parse_Xnum(blob, 8); break;
12427 case 0x02: /* SerStr -- XLUnicodeString (<256 chars) */
12428 val[1] = parse_XLUnicodeString2(blob, 0, {biff:biff > 0 && biff < 8 ? 2 : biff}); break;
12429 default: throw new Error("Bad SerAr: " + val[0]); /* Unreachable */
12430 }
12431 return val;
12432}
12433
12434/* [MS-XLS] 2.5.198.61 ; [MS-XLSB] 2.5.97.44 */
12435function parse_PtgExtraMem(blob, cce, opts) {
12436 var count = blob.read_shift((opts.biff == 12) ? 4 : 2);
12437 var out/*:Array<Range>*/ = [];
12438 for(var i = 0; i != count; ++i) out.push(((opts.biff == 12) ? parse_UncheckedRfX : parse_Ref8U)(blob, 8));
12439 return out;
12440}
12441
12442/* [MS-XLS] 2.5.198.59 ; [MS-XLSB] 2.5.97.41 */
12443function parse_PtgExtraArray(blob, length, opts) {
12444 var rows = 0, cols = 0;
12445 if(opts.biff == 12) {
12446 rows = blob.read_shift(4); // DRw
12447 cols = blob.read_shift(4); // DCol
12448 } else {
12449 cols = 1 + blob.read_shift(1); //DColByteU
12450 rows = 1 + blob.read_shift(2); //DRw
12451 }
12452 if(opts.biff >= 2 && opts.biff < 8) { --rows; if(--cols == 0) cols = 0x100; }
12453 // $FlowIgnore
12454 for(var i = 0, o/*:Array<Array<any>>*/ = []; i != rows && (o[i] = []); ++i)
12455 for(var j = 0; j != cols; ++j) o[i][j] = parse_SerAr(blob, opts.biff);
12456 return o;
12457}
12458
12459/* [MS-XLS] 2.5.198.76 ; [MS-XLSB] 2.5.97.60 */
12460function parse_PtgName(blob, length, opts) {
12461 var type = (blob.read_shift(1) >>> 5) & 0x03;
12462 var w = (!opts || (opts.biff >= 8)) ? 4 : 2;
12463 var nameindex = blob.read_shift(w);
12464 switch(opts.biff) {
12465 case 2: blob.l += 5; break;
12466 case 3: case 4: blob.l += 8; break;
12467 case 5: blob.l += 12; break;
12468 }
12469 return [type, 0, nameindex];
12470}
12471
12472/* [MS-XLS] 2.5.198.77 ; [MS-XLSB] 2.5.97.61 */
12473function parse_PtgNameX(blob, length, opts) {
12474 if(opts.biff == 5) return parse_PtgNameX_BIFF5(blob, length, opts);
12475 var type = (blob.read_shift(1) >>> 5) & 0x03;
12476 var ixti = blob.read_shift(2); // XtiIndex
12477 var nameindex = blob.read_shift(4);
12478 return [type, ixti, nameindex];
12479}
12480function parse_PtgNameX_BIFF5(blob/*::, length, opts*/) {
12481 var type = (blob.read_shift(1) >>> 5) & 0x03;
12482 var ixti = blob.read_shift(2, 'i'); // XtiIndex
12483 blob.l += 8;
12484 var nameindex = blob.read_shift(2);
12485 blob.l += 12;
12486 return [type, ixti, nameindex];
12487}
12488
12489/* [MS-XLS] 2.5.198.70 ; [MS-XLSB] 2.5.97.54 */
12490function parse_PtgMemArea(blob, length, opts) {
12491 var type = (blob.read_shift(1) >>> 5) & 0x03;
12492 blob.l += (opts && opts.biff == 2 ? 3 : 4);
12493 var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
12494 return [type, cce];
12495}
12496
12497/* [MS-XLS] 2.5.198.72 ; [MS-XLSB] 2.5.97.56 */
12498function parse_PtgMemFunc(blob, length, opts) {
12499 var type = (blob.read_shift(1) >>> 5) & 0x03;
12500 var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
12501 return [type, cce];
12502}
12503
12504
12505/* [MS-XLS] 2.5.198.86 ; [MS-XLSB] 2.5.97.69 */
12506function parse_PtgRefErr(blob, length, opts) {
12507 var type = (blob.read_shift(1) >>> 5) & 0x03;
12508 blob.l += 4;
12509 if(opts.biff < 8) blob.l--;
12510 if(opts.biff == 12) blob.l += 2;
12511 return [type];
12512}
12513
12514/* [MS-XLS] 2.5.198.87 ; [MS-XLSB] 2.5.97.71 */
12515function parse_PtgRefErr3d(blob, length, opts) {
12516 var type = (blob[blob.l++] & 0x60) >> 5;
12517 var ixti = blob.read_shift(2);
12518 var w = 4;
12519 if(opts) switch(opts.biff) {
12520 case 5: w = 15; break;
12521 case 12: w = 6; break;
12522 }
12523 blob.l += w;
12524 return [type, ixti];
12525}
12526
12527/* [MS-XLS] 2.5.198.71 ; [MS-XLSB] 2.5.97.55 */
12528var parse_PtgMemErr = parsenoop;
12529/* [MS-XLS] 2.5.198.73 ; [MS-XLSB] 2.5.97.57 */
12530var parse_PtgMemNoMem = parsenoop;
12531/* [MS-XLS] 2.5.198.92 */
12532var parse_PtgTbl = parsenoop;
12533
12534function parse_PtgElfLoc(blob, length, opts) {
12535 blob.l += 2;
12536 return [parse_RgceElfLoc(blob, 4, opts)];
12537}
12538function parse_PtgElfNoop(blob/*::, length, opts*/) {
12539 blob.l += 6;
12540 return [];
12541}
12542/* [MS-XLS] 2.5.198.46 */
12543var parse_PtgElfCol = parse_PtgElfLoc;
12544/* [MS-XLS] 2.5.198.47 */
12545var parse_PtgElfColS = parse_PtgElfNoop;
12546/* [MS-XLS] 2.5.198.48 */
12547var parse_PtgElfColSV = parse_PtgElfNoop;
12548/* [MS-XLS] 2.5.198.49 */
12549var parse_PtgElfColV = parse_PtgElfLoc;
12550/* [MS-XLS] 2.5.198.50 */
12551function parse_PtgElfLel(blob/*::, length, opts*/) {
12552 blob.l += 2;
12553 return [parseuint16(blob), blob.read_shift(2) & 0x01];
12554}
12555/* [MS-XLS] 2.5.198.51 */
12556var parse_PtgElfRadical = parse_PtgElfLoc;
12557/* [MS-XLS] 2.5.198.52 */
12558var parse_PtgElfRadicalLel = parse_PtgElfLel;
12559/* [MS-XLS] 2.5.198.53 */
12560var parse_PtgElfRadicalS = parse_PtgElfNoop;
12561/* [MS-XLS] 2.5.198.54 */
12562var parse_PtgElfRw = parse_PtgElfLoc;
12563/* [MS-XLS] 2.5.198.55 */
12564var parse_PtgElfRwV = parse_PtgElfLoc;
12565
12566/* [MS-XLSB] 2.5.97.52 TODO */
12567var PtgListRT = [
12568 "Data",
12569 "All",
12570 "Headers",
12571 "??",
12572 "?Data2",
12573 "??",
12574 "?DataHeaders",
12575 "??",
12576 "Totals",
12577 "??",
12578 "??",
12579 "??",
12580 "?DataTotals",
12581 "??",
12582 "??",
12583 "??",
12584 "?Current"
12585];
12586function parse_PtgList(blob/*::, length, opts*/) {
12587 blob.l += 2;
12588 var ixti = blob.read_shift(2);
12589 var flags = blob.read_shift(2);
12590 var idx = blob.read_shift(4);
12591 var c = blob.read_shift(2);
12592 var C = blob.read_shift(2);
12593 var rt = PtgListRT[(flags >> 2) & 0x1F];
12594 return {ixti: ixti, coltype:(flags&0x3), rt:rt, idx:idx, c:c, C:C};
12595}
12596/* [MS-XLS] 2.5.198.91 ; [MS-XLSB] 2.5.97.76 */
12597function parse_PtgSxName(blob/*::, length, opts*/) {
12598 blob.l += 2;
12599 return [blob.read_shift(4)];
12600}
12601
12602/* [XLS] old spec */
12603function parse_PtgSheet(blob, length, opts) {
12604 blob.l += 5;
12605 blob.l += 2;
12606 blob.l += (opts.biff == 2 ? 1 : 4);
12607 return ["PTGSHEET"];
12608}
12609function parse_PtgEndSheet(blob, length, opts) {
12610 blob.l += (opts.biff == 2 ? 4 : 5);
12611 return ["PTGENDSHEET"];
12612}
12613function parse_PtgMemAreaN(blob/*::, length, opts*/) {
12614 var type = (blob.read_shift(1) >>> 5) & 0x03;
12615 var cce = blob.read_shift(2);
12616 return [type, cce];
12617}
12618function parse_PtgMemNoMemN(blob/*::, length, opts*/) {
12619 var type = (blob.read_shift(1) >>> 5) & 0x03;
12620 var cce = blob.read_shift(2);
12621 return [type, cce];
12622}
12623function parse_PtgAttrNoop(blob/*::, length, opts*/) {
12624 blob.l += 4;
12625 return [0, 0];
12626}
12627
12628/* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */
12629var PtgTypes = {
12630 /*::[*/0x01/*::]*/: { n:'PtgExp', f:parse_PtgExp },
12631 /*::[*/0x02/*::]*/: { n:'PtgTbl', f:parse_PtgTbl },
12632 /*::[*/0x03/*::]*/: { n:'PtgAdd', f:parseread1 },
12633 /*::[*/0x04/*::]*/: { n:'PtgSub', f:parseread1 },
12634 /*::[*/0x05/*::]*/: { n:'PtgMul', f:parseread1 },
12635 /*::[*/0x06/*::]*/: { n:'PtgDiv', f:parseread1 },
12636 /*::[*/0x07/*::]*/: { n:'PtgPower', f:parseread1 },
12637 /*::[*/0x08/*::]*/: { n:'PtgConcat', f:parseread1 },
12638 /*::[*/0x09/*::]*/: { n:'PtgLt', f:parseread1 },
12639 /*::[*/0x0A/*::]*/: { n:'PtgLe', f:parseread1 },
12640 /*::[*/0x0B/*::]*/: { n:'PtgEq', f:parseread1 },
12641 /*::[*/0x0C/*::]*/: { n:'PtgGe', f:parseread1 },
12642 /*::[*/0x0D/*::]*/: { n:'PtgGt', f:parseread1 },
12643 /*::[*/0x0E/*::]*/: { n:'PtgNe', f:parseread1 },
12644 /*::[*/0x0F/*::]*/: { n:'PtgIsect', f:parseread1 },
12645 /*::[*/0x10/*::]*/: { n:'PtgUnion', f:parseread1 },
12646 /*::[*/0x11/*::]*/: { n:'PtgRange', f:parseread1 },
12647 /*::[*/0x12/*::]*/: { n:'PtgUplus', f:parseread1 },
12648 /*::[*/0x13/*::]*/: { n:'PtgUminus', f:parseread1 },
12649 /*::[*/0x14/*::]*/: { n:'PtgPercent', f:parseread1 },
12650 /*::[*/0x15/*::]*/: { n:'PtgParen', f:parseread1 },
12651 /*::[*/0x16/*::]*/: { n:'PtgMissArg', f:parseread1 },
12652 /*::[*/0x17/*::]*/: { n:'PtgStr', f:parse_PtgStr },
12653 /*::[*/0x1A/*::]*/: { n:'PtgSheet', f:parse_PtgSheet },
12654 /*::[*/0x1B/*::]*/: { n:'PtgEndSheet', f:parse_PtgEndSheet },
12655 /*::[*/0x1C/*::]*/: { n:'PtgErr', f:parse_PtgErr },
12656 /*::[*/0x1D/*::]*/: { n:'PtgBool', f:parse_PtgBool },
12657 /*::[*/0x1E/*::]*/: { n:'PtgInt', f:parse_PtgInt },
12658 /*::[*/0x1F/*::]*/: { n:'PtgNum', f:parse_PtgNum },
12659 /*::[*/0x20/*::]*/: { n:'PtgArray', f:parse_PtgArray },
12660 /*::[*/0x21/*::]*/: { n:'PtgFunc', f:parse_PtgFunc },
12661 /*::[*/0x22/*::]*/: { n:'PtgFuncVar', f:parse_PtgFuncVar },
12662 /*::[*/0x23/*::]*/: { n:'PtgName', f:parse_PtgName },
12663 /*::[*/0x24/*::]*/: { n:'PtgRef', f:parse_PtgRef },
12664 /*::[*/0x25/*::]*/: { n:'PtgArea', f:parse_PtgArea },
12665 /*::[*/0x26/*::]*/: { n:'PtgMemArea', f:parse_PtgMemArea },
12666 /*::[*/0x27/*::]*/: { n:'PtgMemErr', f:parse_PtgMemErr },
12667 /*::[*/0x28/*::]*/: { n:'PtgMemNoMem', f:parse_PtgMemNoMem },
12668 /*::[*/0x29/*::]*/: { n:'PtgMemFunc', f:parse_PtgMemFunc },
12669 /*::[*/0x2A/*::]*/: { n:'PtgRefErr', f:parse_PtgRefErr },
12670 /*::[*/0x2B/*::]*/: { n:'PtgAreaErr', f:parse_PtgAreaErr },
12671 /*::[*/0x2C/*::]*/: { n:'PtgRefN', f:parse_PtgRefN },
12672 /*::[*/0x2D/*::]*/: { n:'PtgAreaN', f:parse_PtgAreaN },
12673 /*::[*/0x2E/*::]*/: { n:'PtgMemAreaN', f:parse_PtgMemAreaN },
12674 /*::[*/0x2F/*::]*/: { n:'PtgMemNoMemN', f:parse_PtgMemNoMemN },
12675 /*::[*/0x39/*::]*/: { n:'PtgNameX', f:parse_PtgNameX },
12676 /*::[*/0x3A/*::]*/: { n:'PtgRef3d', f:parse_PtgRef3d },
12677 /*::[*/0x3B/*::]*/: { n:'PtgArea3d', f:parse_PtgArea3d },
12678 /*::[*/0x3C/*::]*/: { n:'PtgRefErr3d', f:parse_PtgRefErr3d },
12679 /*::[*/0x3D/*::]*/: { n:'PtgAreaErr3d', f:parse_PtgAreaErr3d },
12680 /*::[*/0xFF/*::]*/: {}
12681};
12682/* These are duplicated in the PtgTypes table */
12683var PtgDupes = {
12684 /*::[*/0x40/*::]*/: 0x20, /*::[*/0x60/*::]*/: 0x20,
12685 /*::[*/0x41/*::]*/: 0x21, /*::[*/0x61/*::]*/: 0x21,
12686 /*::[*/0x42/*::]*/: 0x22, /*::[*/0x62/*::]*/: 0x22,
12687 /*::[*/0x43/*::]*/: 0x23, /*::[*/0x63/*::]*/: 0x23,
12688 /*::[*/0x44/*::]*/: 0x24, /*::[*/0x64/*::]*/: 0x24,
12689 /*::[*/0x45/*::]*/: 0x25, /*::[*/0x65/*::]*/: 0x25,
12690 /*::[*/0x46/*::]*/: 0x26, /*::[*/0x66/*::]*/: 0x26,
12691 /*::[*/0x47/*::]*/: 0x27, /*::[*/0x67/*::]*/: 0x27,
12692 /*::[*/0x48/*::]*/: 0x28, /*::[*/0x68/*::]*/: 0x28,
12693 /*::[*/0x49/*::]*/: 0x29, /*::[*/0x69/*::]*/: 0x29,
12694 /*::[*/0x4A/*::]*/: 0x2A, /*::[*/0x6A/*::]*/: 0x2A,
12695 /*::[*/0x4B/*::]*/: 0x2B, /*::[*/0x6B/*::]*/: 0x2B,
12696 /*::[*/0x4C/*::]*/: 0x2C, /*::[*/0x6C/*::]*/: 0x2C,
12697 /*::[*/0x4D/*::]*/: 0x2D, /*::[*/0x6D/*::]*/: 0x2D,
12698 /*::[*/0x4E/*::]*/: 0x2E, /*::[*/0x6E/*::]*/: 0x2E,
12699 /*::[*/0x4F/*::]*/: 0x2F, /*::[*/0x6F/*::]*/: 0x2F,
12700 /*::[*/0x58/*::]*/: 0x22, /*::[*/0x78/*::]*/: 0x22,
12701 /*::[*/0x59/*::]*/: 0x39, /*::[*/0x79/*::]*/: 0x39,
12702 /*::[*/0x5A/*::]*/: 0x3A, /*::[*/0x7A/*::]*/: 0x3A,
12703 /*::[*/0x5B/*::]*/: 0x3B, /*::[*/0x7B/*::]*/: 0x3B,
12704 /*::[*/0x5C/*::]*/: 0x3C, /*::[*/0x7C/*::]*/: 0x3C,
12705 /*::[*/0x5D/*::]*/: 0x3D, /*::[*/0x7D/*::]*/: 0x3D
12706};
12707
12708var Ptg18 = {
12709 /*::[*/0x01/*::]*/: { n:'PtgElfLel', f:parse_PtgElfLel },
12710 /*::[*/0x02/*::]*/: { n:'PtgElfRw', f:parse_PtgElfRw },
12711 /*::[*/0x03/*::]*/: { n:'PtgElfCol', f:parse_PtgElfCol },
12712 /*::[*/0x06/*::]*/: { n:'PtgElfRwV', f:parse_PtgElfRwV },
12713 /*::[*/0x07/*::]*/: { n:'PtgElfColV', f:parse_PtgElfColV },
12714 /*::[*/0x0A/*::]*/: { n:'PtgElfRadical', f:parse_PtgElfRadical },
12715 /*::[*/0x0B/*::]*/: { n:'PtgElfRadicalS', f:parse_PtgElfRadicalS },
12716 /*::[*/0x0D/*::]*/: { n:'PtgElfColS', f:parse_PtgElfColS },
12717 /*::[*/0x0F/*::]*/: { n:'PtgElfColSV', f:parse_PtgElfColSV },
12718 /*::[*/0x10/*::]*/: { n:'PtgElfRadicalLel', f:parse_PtgElfRadicalLel },
12719 /*::[*/0x19/*::]*/: { n:'PtgList', f:parse_PtgList },
12720 /*::[*/0x1D/*::]*/: { n:'PtgSxName', f:parse_PtgSxName },
12721 /*::[*/0xFF/*::]*/: {}
12722};
12723var Ptg19 = {
12724 /*::[*/0x00/*::]*/: { n:'PtgAttrNoop', f:parse_PtgAttrNoop },
12725 /*::[*/0x01/*::]*/: { n:'PtgAttrSemi', f:parse_PtgAttrSemi },
12726 /*::[*/0x02/*::]*/: { n:'PtgAttrIf', f:parse_PtgAttrIf },
12727 /*::[*/0x04/*::]*/: { n:'PtgAttrChoose', f:parse_PtgAttrChoose },
12728 /*::[*/0x08/*::]*/: { n:'PtgAttrGoto', f:parse_PtgAttrGoto },
12729 /*::[*/0x10/*::]*/: { n:'PtgAttrSum', f:parse_PtgAttrSum },
12730 /*::[*/0x20/*::]*/: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
12731 /*::[*/0x21/*::]*/: { n:'PtgAttrBaxcel', f:parse_PtgAttrBaxcel },
12732 /*::[*/0x40/*::]*/: { n:'PtgAttrSpace', f:parse_PtgAttrSpace },
12733 /*::[*/0x41/*::]*/: { n:'PtgAttrSpaceSemi', f:parse_PtgAttrSpaceSemi },
12734 /*::[*/0x80/*::]*/: { n:'PtgAttrIfError', f:parse_PtgAttrIfError },
12735 /*::[*/0xFF/*::]*/: {}
12736};
12737
12738/* [MS-XLS] 2.5.198.103 ; [MS-XLSB] 2.5.97.87 */
12739function parse_RgbExtra(blob, length, rgce, opts) {
12740 if(opts.biff < 8) return parsenoop(blob, length);
12741 var target = blob.l + length;
12742 var o = [];
12743 for(var i = 0; i !== rgce.length; ++i) {
12744 switch(rgce[i][0]) {
12745 case 'PtgArray': /* PtgArray -> PtgExtraArray */
12746 rgce[i][1] = parse_PtgExtraArray(blob, 0, opts);
12747 o.push(rgce[i][1]);
12748 break;
12749 case 'PtgMemArea': /* PtgMemArea -> PtgExtraMem */
12750 rgce[i][2] = parse_PtgExtraMem(blob, rgce[i][1], opts);
12751 o.push(rgce[i][2]);
12752 break;
12753 case 'PtgExp': /* PtgExp -> PtgExtraCol */
12754 if(opts && opts.biff == 12) {
12755 rgce[i][1][1] = blob.read_shift(4);
12756 o.push(rgce[i][1]);
12757 } break;
12758 case 'PtgList': /* TODO: PtgList -> PtgExtraList */
12759 case 'PtgElfRadicalS': /* TODO: PtgElfRadicalS -> PtgExtraElf */
12760 case 'PtgElfColS': /* TODO: PtgElfColS -> PtgExtraElf */
12761 case 'PtgElfColSV': /* TODO: PtgElfColSV -> PtgExtraElf */
12762 throw "Unsupported " + rgce[i][0];
12763 default: break;
12764 }
12765 }
12766 length = target - blob.l;
12767 /* note: this is technically an error but Excel disregards */
12768 //if(target !== blob.l && blob.l !== target - length) throw new Error(target + " != " + blob.l);
12769 if(length !== 0) o.push(parsenoop(blob, length));
12770 return o;
12771}
12772
12773/* [MS-XLS] 2.5.198.104 ; [MS-XLSB] 2.5.97.88 */
12774function parse_Rgce(blob, length, opts) {
12775 var target = blob.l + length;
12776 var R, id, ptgs = [];
12777 while(target != blob.l) {
12778 length = target - blob.l;
12779 id = blob[blob.l];
12780 R = PtgTypes[id] || PtgTypes[PtgDupes[id]];
12781 if(id === 0x18 || id === 0x19) R = (id === 0x18 ? Ptg18 : Ptg19)[blob[blob.l + 1]];
12782 if(!R || !R.f) { /*ptgs.push*/(parsenoop(blob, length)); }
12783 else { ptgs.push([R.n, R.f(blob, length, opts)]); }
12784 }
12785 return ptgs;
12786}
12787
12788function stringify_array(f/*:Array<Array<string>>*/)/*:string*/ {
12789 var o/*:Array<string>*/ = [];
12790 for(var i = 0; i < f.length; ++i) {
12791 var x = f[i], r/*:Array<string>*/ = [];
12792 for(var j = 0; j < x.length; ++j) {
12793 var y = x[j];
12794 if(y) switch(y[0]) {
12795 // TODO: handle embedded quotes
12796 case 0x02:
12797 /*:: if(typeof y[1] != 'string') throw "unreachable"; */
12798 r.push('"' + y[1].replace(/"/g,'""') + '"'); break;
12799 default: r.push(y[1]);
12800 } else r.push("");
12801 }
12802 o.push(r.join(","));
12803 }
12804 return o.join(";");
12805}
12806
12807/* [MS-XLS] 2.2.2 ; [MS-XLSB] 2.2.2 TODO */
12808var PtgBinOp = {
12809 PtgAdd: "+",
12810 PtgConcat: "&",
12811 PtgDiv: "/",
12812 PtgEq: "=",
12813 PtgGe: ">=",
12814 PtgGt: ">",
12815 PtgLe: "<=",
12816 PtgLt: "<",
12817 PtgMul: "*",
12818 PtgNe: "<>",
12819 PtgPower: "^",
12820 PtgSub: "-"
12821};
12822
12823// List of invalid characters needs to be tested further
12824function formula_quote_sheet_name(sname/*:string*/, opts)/*:string*/ {
12825 if(!sname && !(opts && opts.biff <= 5 && opts.biff >= 2)) throw new Error("empty sheet name");
12826 if (/[^\w\u4E00-\u9FFF\u3040-\u30FF]/.test(sname)) return "'" + sname + "'";
12827 return sname;
12828}
12829function get_ixti_raw(supbooks, ixti/*:number*/, opts)/*:string*/ {
12830 if(!supbooks) return "SH33TJSERR0";
12831 if(opts.biff > 8 && (!supbooks.XTI || !supbooks.XTI[ixti])) return supbooks.SheetNames[ixti];
12832 if(!supbooks.XTI) return "SH33TJSERR6";
12833 var XTI = supbooks.XTI[ixti];
12834 if(opts.biff < 8) {
12835 if(ixti > 10000) ixti-= 65536;
12836 if(ixti < 0) ixti = -ixti;
12837 return ixti == 0 ? "" : supbooks.XTI[ixti - 1];
12838 }
12839 if(!XTI) return "SH33TJSERR1";
12840 var o = "";
12841 if(opts.biff > 8) switch(supbooks[XTI[0]][0]) {
12842 case 0x0165: /* 'BrtSupSelf' */
12843 o = XTI[1] == -1 ? "#REF" : supbooks.SheetNames[XTI[1]];
12844 return XTI[1] == XTI[2] ? o : o + ":" + supbooks.SheetNames[XTI[2]];
12845 case 0x0166: /* 'BrtSupSame' */
12846 if(opts.SID != null) return supbooks.SheetNames[opts.SID];
12847 return "SH33TJSSAME" + supbooks[XTI[0]][0];
12848 case 0x0163: /* 'BrtSupBookSrc' */
12849 /* falls through */
12850 default: return "SH33TJSSRC" + supbooks[XTI[0]][0];
12851 }
12852 switch(supbooks[XTI[0]][0][0]) {
12853 case 0x0401:
12854 o = XTI[1] == -1 ? "#REF" : (supbooks.SheetNames[XTI[1]] || "SH33TJSERR3");
12855 return XTI[1] == XTI[2] ? o : o + ":" + supbooks.SheetNames[XTI[2]];
12856 case 0x3A01: return supbooks[XTI[0]].slice(1).map(function(name) { return name.Name; }).join(";;"); //return "SH33TJSERR8";
12857 default:
12858 if(!supbooks[XTI[0]][0][3]) return "SH33TJSERR2";
12859 o = XTI[1] == -1 ? "#REF" : (supbooks[XTI[0]][0][3][XTI[1]] || "SH33TJSERR4");
12860 return XTI[1] == XTI[2] ? o : o + ":" + supbooks[XTI[0]][0][3][XTI[2]];
12861 }
12862}
12863function get_ixti(supbooks, ixti/*:number*/, opts)/*:string*/ {
12864 var ixtiraw = get_ixti_raw(supbooks, ixti, opts);
12865 return ixtiraw == "#REF" ? ixtiraw : formula_quote_sheet_name(ixtiraw, opts);
12866}
12867function stringify_formula(formula/*Array<any>*/, range, cell/*:any*/, supbooks, opts)/*:string*/ {
12868 var biff = (opts && opts.biff) || 8;
12869 var _range = /*range != null ? range :*/ {s:{c:0, r:0},e:{c:0, r:0}};
12870 var stack/*:Array<string>*/ = [], e1, e2, /*::type,*/ c/*:CellAddress*/, ixti=0, nameidx=0, r, sname="";
12871 if(!formula[0] || !formula[0][0]) return "";
12872 var last_sp = -1, sp = "";
12873 for(var ff = 0, fflen = formula[0].length; ff < fflen; ++ff) {
12874 var f = formula[0][ff];
12875 switch(f[0]) {
12876 case 'PtgUminus': /* [MS-XLS] 2.5.198.93 */
12877 stack.push("-" + stack.pop()); break;
12878 case 'PtgUplus': /* [MS-XLS] 2.5.198.95 */
12879 stack.push("+" + stack.pop()); break;
12880 case 'PtgPercent': /* [MS-XLS] 2.5.198.81 */
12881 stack.push(stack.pop() + "%"); break;
12882
12883 case 'PtgAdd': /* [MS-XLS] 2.5.198.26 */
12884 case 'PtgConcat': /* [MS-XLS] 2.5.198.43 */
12885 case 'PtgDiv': /* [MS-XLS] 2.5.198.45 */
12886 case 'PtgEq': /* [MS-XLS] 2.5.198.56 */
12887 case 'PtgGe': /* [MS-XLS] 2.5.198.64 */
12888 case 'PtgGt': /* [MS-XLS] 2.5.198.65 */
12889 case 'PtgLe': /* [MS-XLS] 2.5.198.68 */
12890 case 'PtgLt': /* [MS-XLS] 2.5.198.69 */
12891 case 'PtgMul': /* [MS-XLS] 2.5.198.75 */
12892 case 'PtgNe': /* [MS-XLS] 2.5.198.78 */
12893 case 'PtgPower': /* [MS-XLS] 2.5.198.82 */
12894 case 'PtgSub': /* [MS-XLS] 2.5.198.90 */
12895 e1 = stack.pop(); e2 = stack.pop();
12896 if(last_sp >= 0) {
12897 switch(formula[0][last_sp][1][0]) {
12898 case 0:
12899 // $FlowIgnore
12900 sp = fill(" ", formula[0][last_sp][1][1]); break;
12901 case 1:
12902 // $FlowIgnore
12903 sp = fill("\r", formula[0][last_sp][1][1]); break;
12904 default:
12905 sp = "";
12906 // $FlowIgnore
12907 if(opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + formula[0][last_sp][1][0]);
12908 }
12909 e2 = e2 + sp;
12910 last_sp = -1;
12911 }
12912 stack.push(e2+PtgBinOp[f[0]]+e1);
12913 break;
12914
12915 case 'PtgIsect': /* [MS-XLS] 2.5.198.67 */
12916 e1 = stack.pop(); e2 = stack.pop();
12917 stack.push(e2+" "+e1);
12918 break;
12919 case 'PtgUnion': /* [MS-XLS] 2.5.198.94 */
12920 e1 = stack.pop(); e2 = stack.pop();
12921 stack.push(e2+","+e1);
12922 break;
12923 case 'PtgRange': /* [MS-XLS] 2.5.198.83 */
12924 e1 = stack.pop(); e2 = stack.pop();
12925 stack.push(e2+":"+e1);
12926 break;
12927
12928 case 'PtgAttrChoose': /* [MS-XLS] 2.5.198.34 */
12929 break;
12930 case 'PtgAttrGoto': /* [MS-XLS] 2.5.198.35 */
12931 break;
12932 case 'PtgAttrIf': /* [MS-XLS] 2.5.198.36 */
12933 break;
12934 case 'PtgAttrIfError': /* [MS-XLSB] 2.5.97.28 */
12935 break;
12936
12937
12938 case 'PtgRef': /* [MS-XLS] 2.5.198.84 */
12939 /*::type = f[1][0]; */c = shift_cell_xls((f[1][1]/*:any*/), _range, opts);
12940 stack.push(encode_cell_xls(c, biff));
12941 break;
12942 case 'PtgRefN': /* [MS-XLS] 2.5.198.88 */
12943 /*::type = f[1][0]; */c = cell ? shift_cell_xls((f[1][1]/*:any*/), cell, opts) : (f[1][1]/*:any*/);
12944 stack.push(encode_cell_xls(c, biff));
12945 break;
12946 case 'PtgRef3d': /* [MS-XLS] 2.5.198.85 */
12947 /*::type = f[1][0]; */ixti = /*::Number(*/f[1][1]/*::)*/; c = shift_cell_xls((f[1][2]/*:any*/), _range, opts);
12948 sname = get_ixti(supbooks, ixti, opts);
12949 var w = sname; /* IE9 fails on defined names */ // eslint-disable-line no-unused-vars
12950 stack.push(sname + "!" + encode_cell_xls(c, biff));
12951 break;
12952
12953 case 'PtgFunc': /* [MS-XLS] 2.5.198.62 */
12954 case 'PtgFuncVar': /* [MS-XLS] 2.5.198.63 */
12955 /* f[1] = [argc, func, type] */
12956 var argc/*:number*/ = (f[1][0]/*:any*/), func/*:string*/ = (f[1][1]/*:any*/);
12957 if(!argc) argc = 0;
12958 argc &= 0x7F;
12959 var args = argc == 0 ? [] : stack.slice(-argc);
12960 stack.length -= argc;
12961 if(func === 'User') func = args.shift();
12962 stack.push(func + "(" + args.join(",") + ")");
12963 break;
12964
12965 case 'PtgBool': /* [MS-XLS] 2.5.198.42 */
12966 stack.push(f[1] ? "TRUE" : "FALSE"); break;
12967 case 'PtgInt': /* [MS-XLS] 2.5.198.66 */
12968 stack.push(/*::String(*/f[1]/*::)*/); break;
12969 case 'PtgNum': /* [MS-XLS] 2.5.198.79 TODO: precision? */
12970 stack.push(String(f[1])); break;
12971 case 'PtgStr': /* [MS-XLS] 2.5.198.89 */
12972 // $FlowIgnore
12973 stack.push('"' + f[1].replace(/"/g, '""') + '"'); break;
12974 case 'PtgErr': /* [MS-XLS] 2.5.198.57 */
12975 stack.push(/*::String(*/f[1]/*::)*/); break;
12976 case 'PtgAreaN': /* [MS-XLS] 2.5.198.31 TODO */
12977 /*::type = f[1][0]; */r = shift_range_xls(f[1][1], cell ? {s:cell} : _range, opts);
12978 stack.push(encode_range_xls((r/*:any*/), opts));
12979 break;
12980 case 'PtgArea': /* [MS-XLS] 2.5.198.27 TODO: fixed points */
12981 /*::type = f[1][0]; */r = shift_range_xls(f[1][1], _range, opts);
12982 stack.push(encode_range_xls((r/*:any*/), opts));
12983 break;
12984 case 'PtgArea3d': /* [MS-XLS] 2.5.198.28 TODO */
12985 /*::type = f[1][0]; */ixti = /*::Number(*/f[1][1]/*::)*/; r = f[1][2];
12986 sname = get_ixti(supbooks, ixti, opts);
12987 stack.push(sname + "!" + encode_range_xls((r/*:any*/), opts));
12988 break;
12989 case 'PtgAttrSum': /* [MS-XLS] 2.5.198.41 */
12990 stack.push("SUM(" + stack.pop() + ")");
12991 break;
12992
12993 case 'PtgAttrBaxcel': /* [MS-XLS] 2.5.198.33 */
12994 case 'PtgAttrSemi': /* [MS-XLS] 2.5.198.37 */
12995 break;
12996
12997 case 'PtgName': /* [MS-XLS] 2.5.198.76 ; [MS-XLSB] 2.5.97.60 TODO: revisions */
12998 /* f[1] = type, 0, nameindex */
12999 nameidx = (f[1][2]/*:any*/);
13000 var lbl = (supbooks.names||[])[nameidx-1] || (supbooks[0]||[])[nameidx];
13001 var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
13002 /* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
13003 if(name && name.slice(0,6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
13004 stack.push(name);
13005 break;
13006
13007 case 'PtgNameX': /* [MS-XLS] 2.5.198.77 ; [MS-XLSB] 2.5.97.61 TODO: revisions */
13008 /* f[1] = type, ixti, nameindex */
13009 var bookidx/*:number*/ = (f[1][1]/*:any*/); nameidx = (f[1][2]/*:any*/); var externbook;
13010 /* TODO: Properly handle missing values -- this should be using get_ixti_raw primarily */
13011 if(opts.biff <= 5) {
13012 if(bookidx < 0) bookidx = -bookidx;
13013 if(supbooks[bookidx]) externbook = supbooks[bookidx][nameidx];
13014 } else {
13015 var o = "";
13016 if(((supbooks[bookidx]||[])[0]||[])[0] == 0x3A01){/* empty */}
13017 else if(((supbooks[bookidx]||[])[0]||[])[0] == 0x0401){
13018 if(supbooks[bookidx][nameidx] && supbooks[bookidx][nameidx].itab > 0) {
13019 o = supbooks.SheetNames[supbooks[bookidx][nameidx].itab-1] + "!";
13020 }
13021 }
13022 else o = supbooks.SheetNames[nameidx-1]+ "!";
13023 if(supbooks[bookidx] && supbooks[bookidx][nameidx]) o += supbooks[bookidx][nameidx].Name;
13024 else if(supbooks[0] && supbooks[0][nameidx]) o += supbooks[0][nameidx].Name;
13025 else {
13026 var ixtidata = (get_ixti_raw(supbooks, bookidx, opts)||"").split(";;");
13027 if(ixtidata[nameidx - 1]) o = ixtidata[nameidx - 1]; // TODO: confirm this is correct
13028 else o += "SH33TJSERRX";
13029 }
13030 stack.push(o);
13031 break;
13032 }
13033 if(!externbook) externbook = {Name: "SH33TJSERRY"};
13034 stack.push(externbook.Name);
13035 break;
13036
13037 case 'PtgParen': /* [MS-XLS] 2.5.198.80 */
13038 var lp = '(', rp = ')';
13039 if(last_sp >= 0) {
13040 sp = "";
13041 switch(formula[0][last_sp][1][0]) {
13042 // $FlowIgnore
13043 case 2: lp = fill(" ", formula[0][last_sp][1][1]) + lp; break;
13044 // $FlowIgnore
13045 case 3: lp = fill("\r", formula[0][last_sp][1][1]) + lp; break;
13046 // $FlowIgnore
13047 case 4: rp = fill(" ", formula[0][last_sp][1][1]) + rp; break;
13048 // $FlowIgnore
13049 case 5: rp = fill("\r", formula[0][last_sp][1][1]) + rp; break;
13050 default:
13051 // $FlowIgnore
13052 if(opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + formula[0][last_sp][1][0]);
13053 }
13054 last_sp = -1;
13055 }
13056 stack.push(lp + stack.pop() + rp); break;
13057
13058 case 'PtgRefErr': /* [MS-XLS] 2.5.198.86 */
13059 stack.push('#REF!'); break;
13060
13061 case 'PtgRefErr3d': /* [MS-XLS] 2.5.198.87 */
13062 stack.push('#REF!'); break;
13063
13064 case 'PtgExp': /* [MS-XLS] 2.5.198.58 TODO */
13065 c = {c:(f[1][1]/*:any*/),r:(f[1][0]/*:any*/)};
13066 var q = ({c: cell.c, r:cell.r}/*:any*/);
13067 if(supbooks.sharedf[encode_cell(c)]) {
13068 var parsedf = (supbooks.sharedf[encode_cell(c)]);
13069 stack.push(stringify_formula(parsedf, _range, q, supbooks, opts));
13070 } else {
13071 var fnd = false;
13072 for(e1=0;e1!=supbooks.arrayf.length; ++e1) {
13073 /* TODO: should be something like range_has */
13074 e2 = supbooks.arrayf[e1];
13075 if(c.c < e2[0].s.c || c.c > e2[0].e.c) continue;
13076 if(c.r < e2[0].s.r || c.r > e2[0].e.r) continue;
13077 stack.push(stringify_formula(e2[1], _range, q, supbooks, opts));
13078 fnd = true;
13079 break;
13080 }
13081 if(!fnd) stack.push(/*::String(*/f[1]/*::)*/);
13082 }
13083 break;
13084
13085 case 'PtgArray': /* [MS-XLS] 2.5.198.32 TODO */
13086 stack.push("{" + stringify_array(/*::(*/f[1]/*:: :any)*/) + "}");
13087 break;
13088
13089 case 'PtgMemArea': /* [MS-XLS] 2.5.198.70 TODO: confirm this is a non-display */
13090 //stack.push("(" + f[2].map(encode_range).join(",") + ")");
13091 break;
13092
13093 case 'PtgAttrSpace': /* [MS-XLS] 2.5.198.38 */
13094 case 'PtgAttrSpaceSemi': /* [MS-XLS] 2.5.198.39 */
13095 last_sp = ff;
13096 break;
13097
13098 case 'PtgTbl': /* [MS-XLS] 2.5.198.92 TODO */
13099 break;
13100
13101 case 'PtgMemErr': /* [MS-XLS] 2.5.198.71 */
13102 break;
13103
13104 case 'PtgMissArg': /* [MS-XLS] 2.5.198.74 */
13105 stack.push("");
13106 break;
13107
13108 case 'PtgAreaErr': /* [MS-XLS] 2.5.198.29 */
13109 stack.push("#REF!"); break;
13110
13111 case 'PtgAreaErr3d': /* [MS-XLS] 2.5.198.30 */
13112 stack.push("#REF!"); break;
13113
13114 case 'PtgList': /* [MS-XLSB] 2.5.97.52 */
13115 // $FlowIgnore
13116 stack.push("Table" + f[1].idx + "[#" + f[1].rt + "]");
13117 break;
13118
13119 case 'PtgMemAreaN':
13120 case 'PtgMemNoMemN':
13121 case 'PtgAttrNoop':
13122 case 'PtgSheet':
13123 case 'PtgEndSheet':
13124 break;
13125
13126 case 'PtgMemFunc': /* [MS-XLS] 2.5.198.72 TODO */
13127 break;
13128 case 'PtgMemNoMem': /* [MS-XLS] 2.5.198.73 TODO */
13129 break;
13130
13131 case 'PtgElfCol': /* [MS-XLS] 2.5.198.46 */
13132 case 'PtgElfColS': /* [MS-XLS] 2.5.198.47 */
13133 case 'PtgElfColSV': /* [MS-XLS] 2.5.198.48 */
13134 case 'PtgElfColV': /* [MS-XLS] 2.5.198.49 */
13135 case 'PtgElfLel': /* [MS-XLS] 2.5.198.50 */
13136 case 'PtgElfRadical': /* [MS-XLS] 2.5.198.51 */
13137 case 'PtgElfRadicalLel': /* [MS-XLS] 2.5.198.52 */
13138 case 'PtgElfRadicalS': /* [MS-XLS] 2.5.198.53 */
13139 case 'PtgElfRw': /* [MS-XLS] 2.5.198.54 */
13140 case 'PtgElfRwV': /* [MS-XLS] 2.5.198.55 */
13141 throw new Error("Unsupported ELFs");
13142
13143 case 'PtgSxName': /* [MS-XLS] 2.5.198.91 TODO -- find a test case */
13144 throw new Error('Unrecognized Formula Token: ' + String(f));
13145 default: throw new Error('Unrecognized Formula Token: ' + String(f));
13146 }
13147 var PtgNonDisp = ['PtgAttrSpace', 'PtgAttrSpaceSemi', 'PtgAttrGoto'];
13148 if(opts.biff != 3) if(last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) {
13149 f = formula[0][last_sp];
13150 var _left = true;
13151 switch(f[1][0]) {
13152 /* note: some bad XLSB files omit the PtgParen */
13153 case 4: _left = false;
13154 /* falls through */
13155 case 0:
13156 // $FlowIgnore
13157 sp = fill(" ", f[1][1]); break;
13158 case 5: _left = false;
13159 /* falls through */
13160 case 1:
13161 // $FlowIgnore
13162 sp = fill("\r", f[1][1]); break;
13163 default:
13164 sp = "";
13165 // $FlowIgnore
13166 if(opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + f[1][0]);
13167 }
13168 stack.push((_left ? sp : "") + stack.pop() + (_left ? "" : sp));
13169 last_sp = -1;
13170 }
13171 }
13172 if(stack.length > 1 && opts.WTF) throw new Error("bad formula stack");
13173 return stack[0];
13174}
13175
13176/* [MS-XLS] 2.5.198.1 TODO */
13177function parse_ArrayParsedFormula(blob, length, opts/*::, ref*/) {
13178 var target = blob.l + length, len = opts.biff == 2 ? 1 : 2;
13179 var rgcb, cce = blob.read_shift(len); // length of rgce
13180 if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
13181 var rgce = parse_Rgce(blob, cce, opts);
13182 if(length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
13183 blob.l = target;
13184 return [rgce, rgcb];
13185}
13186
13187/* [MS-XLS] 2.5.198.3 TODO */
13188function parse_XLSCellParsedFormula(blob, length, opts) {
13189 var target = blob.l + length, len = opts.biff == 2 ? 1 : 2;
13190 var rgcb, cce = blob.read_shift(len); // length of rgce
13191 if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
13192 var rgce = parse_Rgce(blob, cce, opts);
13193 if(length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
13194 blob.l = target;
13195 return [rgce, rgcb];
13196}
13197
13198/* [MS-XLS] 2.5.198.21 */
13199function parse_NameParsedFormula(blob, length, opts, cce) {
13200 var target = blob.l + length;
13201 var rgce = parse_Rgce(blob, cce, opts);
13202 var rgcb;
13203 if(target !== blob.l) rgcb = parse_RgbExtra(blob, target - blob.l, rgce, opts);
13204 return [rgce, rgcb];
13205}
13206
13207/* [MS-XLS] 2.5.198.118 TODO */
13208function parse_SharedParsedFormula(blob, length, opts) {
13209 var target = blob.l + length;
13210 var rgcb, cce = blob.read_shift(2); // length of rgce
13211 var rgce = parse_Rgce(blob, cce, opts);
13212 if(cce == 0xFFFF) return [[],parsenoop(blob, length-2)];
13213 if(length !== cce + 2) rgcb = parse_RgbExtra(blob, target - cce - 2, rgce, opts);
13214 return [rgce, rgcb];
13215}
13216
13217/* [MS-XLS] 2.5.133 TODO: how to emit empty strings? */
13218function parse_FormulaValue(blob/*::, length*/) {
13219 var b;
13220 if(__readUInt16LE(blob,blob.l + 6) !== 0xFFFF) return [parse_Xnum(blob),'n'];
13221 switch(blob[blob.l]) {
13222 case 0x00: blob.l += 8; return ["String", 's'];
13223 case 0x01: b = blob[blob.l+2] === 0x1; blob.l += 8; return [b,'b'];
13224 case 0x02: b = blob[blob.l+2]; blob.l += 8; return [b,'e'];
13225 case 0x03: blob.l += 8; return ["",'s'];
13226 }
13227 return [];
13228}
13229function write_FormulaValue(value) {
13230 if(value == null) {
13231 // Blank String Value
13232 var o = new_buf(8);
13233 o.write_shift(1, 0x03);
13234 o.write_shift(1, 0);
13235 o.write_shift(2, 0);
13236 o.write_shift(2, 0);
13237 o.write_shift(2, 0xFFFF);
13238 return o;
13239 } else if(typeof value == "number") return write_Xnum(value);
13240 return write_Xnum(0);
13241}
13242
13243/* [MS-XLS] 2.4.127 TODO */
13244function parse_Formula(blob, length, opts) {
13245 var end = blob.l + length;
13246 var cell = parse_XLSCell(blob, 6);
13247 if(opts.biff == 2) ++blob.l;
13248 var val = parse_FormulaValue(blob,8);
13249 var flags = blob.read_shift(1);
13250 if(opts.biff != 2) {
13251 blob.read_shift(1);
13252 if(opts.biff >= 5) {
13253 /*var chn = */blob.read_shift(4);
13254 }
13255 }
13256 var cbf = parse_XLSCellParsedFormula(blob, end - blob.l, opts);
13257 return {cell:cell, val:val[0], formula:cbf, shared: (flags >> 3) & 1, tt:val[1]};
13258}
13259function write_Formula(cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, os/*:number*/) {
13260 // Cell
13261 var o1 = write_XLSCell(R, C, os);
13262
13263 // FormulaValue
13264 var o2 = write_FormulaValue(cell.v);
13265
13266 // flags + cache
13267 var o3 = new_buf(6);
13268 var flags = 0x01 | 0x20;
13269 o3.write_shift(2, flags);
13270 o3.write_shift(4, 0);
13271
13272 // CellParsedFormula
13273 var bf = new_buf(cell.bf.length);
13274 for(var i = 0; i < cell.bf.length; ++i) bf[i] = cell.bf[i];
13275
13276 var out = bconcat([o1, o2, o3, bf]);
13277 return out;
13278}
13279
13280
13281/* XLSB Parsed Formula records have the same shape */
13282function parse_XLSBParsedFormula(data, length, opts) {
13283 var cce = data.read_shift(4);
13284 var rgce = parse_Rgce(data, cce, opts);
13285 var cb = data.read_shift(4);
13286 var rgcb = cb > 0 ? parse_RgbExtra(data, cb, rgce, opts) : null;
13287 return [rgce, rgcb];
13288}
13289
13290/* [MS-XLSB] 2.5.97.1 ArrayParsedFormula */
13291var parse_XLSBArrayParsedFormula = parse_XLSBParsedFormula;
13292/* [MS-XLSB] 2.5.97.4 CellParsedFormula */
13293var parse_XLSBCellParsedFormula = parse_XLSBParsedFormula;
13294/* [MS-XLSB] 2.5.97.8 DVParsedFormula */
13295//var parse_XLSBDVParsedFormula = parse_XLSBParsedFormula;
13296/* [MS-XLSB] 2.5.97.9 FRTParsedFormula */
13297//var parse_XLSBFRTParsedFormula = parse_XLSBParsedFormula2;
13298/* [MS-XLSB] 2.5.97.12 NameParsedFormula */
13299var parse_XLSBNameParsedFormula = parse_XLSBParsedFormula;
13300/* [MS-XLSB] 2.5.97.98 SharedParsedFormula */
13301var parse_XLSBSharedParsedFormula = parse_XLSBParsedFormula;
13302var Cetab = {
13303 0: "BEEP",
13304 1: "OPEN",
13305 2: "OPEN.LINKS",
13306 3: "CLOSE.ALL",
13307 4: "SAVE",
13308 5: "SAVE.AS",
13309 6: "FILE.DELETE",
13310 7: "PAGE.SETUP",
13311 8: "PRINT",
13312 9: "PRINTER.SETUP",
13313 10: "QUIT",
13314 11: "NEW.WINDOW",
13315 12: "ARRANGE.ALL",
13316 13: "WINDOW.SIZE",
13317 14: "WINDOW.MOVE",
13318 15: "FULL",
13319 16: "CLOSE",
13320 17: "RUN",
13321 22: "SET.PRINT.AREA",
13322 23: "SET.PRINT.TITLES",
13323 24: "SET.PAGE.BREAK",
13324 25: "REMOVE.PAGE.BREAK",
13325 26: "FONT",
13326 27: "DISPLAY",
13327 28: "PROTECT.DOCUMENT",
13328 29: "PRECISION",
13329 30: "A1.R1C1",
13330 31: "CALCULATE.NOW",
13331 32: "CALCULATION",
13332 34: "DATA.FIND",
13333 35: "EXTRACT",
13334 36: "DATA.DELETE",
13335 37: "SET.DATABASE",
13336 38: "SET.CRITERIA",
13337 39: "SORT",
13338 40: "DATA.SERIES",
13339 41: "TABLE",
13340 42: "FORMAT.NUMBER",
13341 43: "ALIGNMENT",
13342 44: "STYLE",
13343 45: "BORDER",
13344 46: "CELL.PROTECTION",
13345 47: "COLUMN.WIDTH",
13346 48: "UNDO",
13347 49: "CUT",
13348 50: "COPY",
13349 51: "PASTE",
13350 52: "CLEAR",
13351 53: "PASTE.SPECIAL",
13352 54: "EDIT.DELETE",
13353 55: "INSERT",
13354 56: "FILL.RIGHT",
13355 57: "FILL.DOWN",
13356 61: "DEFINE.NAME",
13357 62: "CREATE.NAMES",
13358 63: "FORMULA.GOTO",
13359 64: "FORMULA.FIND",
13360 65: "SELECT.LAST.CELL",
13361 66: "SHOW.ACTIVE.CELL",
13362 67: "GALLERY.AREA",
13363 68: "GALLERY.BAR",
13364 69: "GALLERY.COLUMN",
13365 70: "GALLERY.LINE",
13366 71: "GALLERY.PIE",
13367 72: "GALLERY.SCATTER",
13368 73: "COMBINATION",
13369 74: "PREFERRED",
13370 75: "ADD.OVERLAY",
13371 76: "GRIDLINES",
13372 77: "SET.PREFERRED",
13373 78: "AXES",
13374 79: "LEGEND",
13375 80: "ATTACH.TEXT",
13376 81: "ADD.ARROW",
13377 82: "SELECT.CHART",
13378 83: "SELECT.PLOT.AREA",
13379 84: "PATTERNS",
13380 85: "MAIN.CHART",
13381 86: "OVERLAY",
13382 87: "SCALE",
13383 88: "FORMAT.LEGEND",
13384 89: "FORMAT.TEXT",
13385 90: "EDIT.REPEAT",
13386 91: "PARSE",
13387 92: "JUSTIFY",
13388 93: "HIDE",
13389 94: "UNHIDE",
13390 95: "WORKSPACE",
13391 96: "FORMULA",
13392 97: "FORMULA.FILL",
13393 98: "FORMULA.ARRAY",
13394 99: "DATA.FIND.NEXT",
13395 100: "DATA.FIND.PREV",
13396 101: "FORMULA.FIND.NEXT",
13397 102: "FORMULA.FIND.PREV",
13398 103: "ACTIVATE",
13399 104: "ACTIVATE.NEXT",
13400 105: "ACTIVATE.PREV",
13401 106: "UNLOCKED.NEXT",
13402 107: "UNLOCKED.PREV",
13403 108: "COPY.PICTURE",
13404 109: "SELECT",
13405 110: "DELETE.NAME",
13406 111: "DELETE.FORMAT",
13407 112: "VLINE",
13408 113: "HLINE",
13409 114: "VPAGE",
13410 115: "HPAGE",
13411 116: "VSCROLL",
13412 117: "HSCROLL",
13413 118: "ALERT",
13414 119: "NEW",
13415 120: "CANCEL.COPY",
13416 121: "SHOW.CLIPBOARD",
13417 122: "MESSAGE",
13418 124: "PASTE.LINK",
13419 125: "APP.ACTIVATE",
13420 126: "DELETE.ARROW",
13421 127: "ROW.HEIGHT",
13422 128: "FORMAT.MOVE",
13423 129: "FORMAT.SIZE",
13424 130: "FORMULA.REPLACE",
13425 131: "SEND.KEYS",
13426 132: "SELECT.SPECIAL",
13427 133: "APPLY.NAMES",
13428 134: "REPLACE.FONT",
13429 135: "FREEZE.PANES",
13430 136: "SHOW.INFO",
13431 137: "SPLIT",
13432 138: "ON.WINDOW",
13433 139: "ON.DATA",
13434 140: "DISABLE.INPUT",
13435 142: "OUTLINE",
13436 143: "LIST.NAMES",
13437 144: "FILE.CLOSE",
13438 145: "SAVE.WORKBOOK",
13439 146: "DATA.FORM",
13440 147: "COPY.CHART",
13441 148: "ON.TIME",
13442 149: "WAIT",
13443 150: "FORMAT.FONT",
13444 151: "FILL.UP",
13445 152: "FILL.LEFT",
13446 153: "DELETE.OVERLAY",
13447 155: "SHORT.MENUS",
13448 159: "SET.UPDATE.STATUS",
13449 161: "COLOR.PALETTE",
13450 162: "DELETE.STYLE",
13451 163: "WINDOW.RESTORE",
13452 164: "WINDOW.MAXIMIZE",
13453 166: "CHANGE.LINK",
13454 167: "CALCULATE.DOCUMENT",
13455 168: "ON.KEY",
13456 169: "APP.RESTORE",
13457 170: "APP.MOVE",
13458 171: "APP.SIZE",
13459 172: "APP.MINIMIZE",
13460 173: "APP.MAXIMIZE",
13461 174: "BRING.TO.FRONT",
13462 175: "SEND.TO.BACK",
13463 185: "MAIN.CHART.TYPE",
13464 186: "OVERLAY.CHART.TYPE",
13465 187: "SELECT.END",
13466 188: "OPEN.MAIL",
13467 189: "SEND.MAIL",
13468 190: "STANDARD.FONT",
13469 191: "CONSOLIDATE",
13470 192: "SORT.SPECIAL",
13471 193: "GALLERY.3D.AREA",
13472 194: "GALLERY.3D.COLUMN",
13473 195: "GALLERY.3D.LINE",
13474 196: "GALLERY.3D.PIE",
13475 197: "VIEW.3D",
13476 198: "GOAL.SEEK",
13477 199: "WORKGROUP",
13478 200: "FILL.GROUP",
13479 201: "UPDATE.LINK",
13480 202: "PROMOTE",
13481 203: "DEMOTE",
13482 204: "SHOW.DETAIL",
13483 206: "UNGROUP",
13484 207: "OBJECT.PROPERTIES",
13485 208: "SAVE.NEW.OBJECT",
13486 209: "SHARE",
13487 210: "SHARE.NAME",
13488 211: "DUPLICATE",
13489 212: "APPLY.STYLE",
13490 213: "ASSIGN.TO.OBJECT",
13491 214: "OBJECT.PROTECTION",
13492 215: "HIDE.OBJECT",
13493 216: "SET.EXTRACT",
13494 217: "CREATE.PUBLISHER",
13495 218: "SUBSCRIBE.TO",
13496 219: "ATTRIBUTES",
13497 220: "SHOW.TOOLBAR",
13498 222: "PRINT.PREVIEW",
13499 223: "EDIT.COLOR",
13500 224: "SHOW.LEVELS",
13501 225: "FORMAT.MAIN",
13502 226: "FORMAT.OVERLAY",
13503 227: "ON.RECALC",
13504 228: "EDIT.SERIES",
13505 229: "DEFINE.STYLE",
13506 240: "LINE.PRINT",
13507 243: "ENTER.DATA",
13508 249: "GALLERY.RADAR",
13509 250: "MERGE.STYLES",
13510 251: "EDITION.OPTIONS",
13511 252: "PASTE.PICTURE",
13512 253: "PASTE.PICTURE.LINK",
13513 254: "SPELLING",
13514 256: "ZOOM",
13515 259: "INSERT.OBJECT",
13516 260: "WINDOW.MINIMIZE",
13517 265: "SOUND.NOTE",
13518 266: "SOUND.PLAY",
13519 267: "FORMAT.SHAPE",
13520 268: "EXTEND.POLYGON",
13521 269: "FORMAT.AUTO",
13522 272: "GALLERY.3D.BAR",
13523 273: "GALLERY.3D.SURFACE",
13524 274: "FILL.AUTO",
13525 276: "CUSTOMIZE.TOOLBAR",
13526 277: "ADD.TOOL",
13527 278: "EDIT.OBJECT",
13528 279: "ON.DOUBLECLICK",
13529 280: "ON.ENTRY",
13530 281: "WORKBOOK.ADD",
13531 282: "WORKBOOK.MOVE",
13532 283: "WORKBOOK.COPY",
13533 284: "WORKBOOK.OPTIONS",
13534 285: "SAVE.WORKSPACE",
13535 288: "CHART.WIZARD",
13536 289: "DELETE.TOOL",
13537 290: "MOVE.TOOL",
13538 291: "WORKBOOK.SELECT",
13539 292: "WORKBOOK.ACTIVATE",
13540 293: "ASSIGN.TO.TOOL",
13541 295: "COPY.TOOL",
13542 296: "RESET.TOOL",
13543 297: "CONSTRAIN.NUMERIC",
13544 298: "PASTE.TOOL",
13545 302: "WORKBOOK.NEW",
13546 305: "SCENARIO.CELLS",
13547 306: "SCENARIO.DELETE",
13548 307: "SCENARIO.ADD",
13549 308: "SCENARIO.EDIT",
13550 309: "SCENARIO.SHOW",
13551 310: "SCENARIO.SHOW.NEXT",
13552 311: "SCENARIO.SUMMARY",
13553 312: "PIVOT.TABLE.WIZARD",
13554 313: "PIVOT.FIELD.PROPERTIES",
13555 314: "PIVOT.FIELD",
13556 315: "PIVOT.ITEM",
13557 316: "PIVOT.ADD.FIELDS",
13558 318: "OPTIONS.CALCULATION",
13559 319: "OPTIONS.EDIT",
13560 320: "OPTIONS.VIEW",
13561 321: "ADDIN.MANAGER",
13562 322: "MENU.EDITOR",
13563 323: "ATTACH.TOOLBARS",
13564 324: "VBAActivate",
13565 325: "OPTIONS.CHART",
13566 328: "VBA.INSERT.FILE",
13567 330: "VBA.PROCEDURE.DEFINITION",
13568 336: "ROUTING.SLIP",
13569 338: "ROUTE.DOCUMENT",
13570 339: "MAIL.LOGON",
13571 342: "INSERT.PICTURE",
13572 343: "EDIT.TOOL",
13573 344: "GALLERY.DOUGHNUT",
13574 350: "CHART.TREND",
13575 352: "PIVOT.ITEM.PROPERTIES",
13576 354: "WORKBOOK.INSERT",
13577 355: "OPTIONS.TRANSITION",
13578 356: "OPTIONS.GENERAL",
13579 370: "FILTER.ADVANCED",
13580 373: "MAIL.ADD.MAILER",
13581 374: "MAIL.DELETE.MAILER",
13582 375: "MAIL.REPLY",
13583 376: "MAIL.REPLY.ALL",
13584 377: "MAIL.FORWARD",
13585 378: "MAIL.NEXT.LETTER",
13586 379: "DATA.LABEL",
13587 380: "INSERT.TITLE",
13588 381: "FONT.PROPERTIES",
13589 382: "MACRO.OPTIONS",
13590 383: "WORKBOOK.HIDE",
13591 384: "WORKBOOK.UNHIDE",
13592 385: "WORKBOOK.DELETE",
13593 386: "WORKBOOK.NAME",
13594 388: "GALLERY.CUSTOM",
13595 390: "ADD.CHART.AUTOFORMAT",
13596 391: "DELETE.CHART.AUTOFORMAT",
13597 392: "CHART.ADD.DATA",
13598 393: "AUTO.OUTLINE",
13599 394: "TAB.ORDER",
13600 395: "SHOW.DIALOG",
13601 396: "SELECT.ALL",
13602 397: "UNGROUP.SHEETS",
13603 398: "SUBTOTAL.CREATE",
13604 399: "SUBTOTAL.REMOVE",
13605 400: "RENAME.OBJECT",
13606 412: "WORKBOOK.SCROLL",
13607 413: "WORKBOOK.NEXT",
13608 414: "WORKBOOK.PREV",
13609 415: "WORKBOOK.TAB.SPLIT",
13610 416: "FULL.SCREEN",
13611 417: "WORKBOOK.PROTECT",
13612 420: "SCROLLBAR.PROPERTIES",
13613 421: "PIVOT.SHOW.PAGES",
13614 422: "TEXT.TO.COLUMNS",
13615 423: "FORMAT.CHARTTYPE",
13616 424: "LINK.FORMAT",
13617 425: "TRACER.DISPLAY",
13618 430: "TRACER.NAVIGATE",
13619 431: "TRACER.CLEAR",
13620 432: "TRACER.ERROR",
13621 433: "PIVOT.FIELD.GROUP",
13622 434: "PIVOT.FIELD.UNGROUP",
13623 435: "CHECKBOX.PROPERTIES",
13624 436: "LABEL.PROPERTIES",
13625 437: "LISTBOX.PROPERTIES",
13626 438: "EDITBOX.PROPERTIES",
13627 439: "PIVOT.REFRESH",
13628 440: "LINK.COMBO",
13629 441: "OPEN.TEXT",
13630 442: "HIDE.DIALOG",
13631 443: "SET.DIALOG.FOCUS",
13632 444: "ENABLE.OBJECT",
13633 445: "PUSHBUTTON.PROPERTIES",
13634 446: "SET.DIALOG.DEFAULT",
13635 447: "FILTER",
13636 448: "FILTER.SHOW.ALL",
13637 449: "CLEAR.OUTLINE",
13638 450: "FUNCTION.WIZARD",
13639 451: "ADD.LIST.ITEM",
13640 452: "SET.LIST.ITEM",
13641 453: "REMOVE.LIST.ITEM",
13642 454: "SELECT.LIST.ITEM",
13643 455: "SET.CONTROL.VALUE",
13644 456: "SAVE.COPY.AS",
13645 458: "OPTIONS.LISTS.ADD",
13646 459: "OPTIONS.LISTS.DELETE",
13647 460: "SERIES.AXES",
13648 461: "SERIES.X",
13649 462: "SERIES.Y",
13650 463: "ERRORBAR.X",
13651 464: "ERRORBAR.Y",
13652 465: "FORMAT.CHART",
13653 466: "SERIES.ORDER",
13654 467: "MAIL.LOGOFF",
13655 468: "CLEAR.ROUTING.SLIP",
13656 469: "APP.ACTIVATE.MICROSOFT",
13657 470: "MAIL.EDIT.MAILER",
13658 471: "ON.SHEET",
13659 472: "STANDARD.WIDTH",
13660 473: "SCENARIO.MERGE",
13661 474: "SUMMARY.INFO",
13662 475: "FIND.FILE",
13663 476: "ACTIVE.CELL.FONT",
13664 477: "ENABLE.TIPWIZARD",
13665 478: "VBA.MAKE.ADDIN",
13666 480: "INSERTDATATABLE",
13667 481: "WORKGROUP.OPTIONS",
13668 482: "MAIL.SEND.MAILER",
13669 485: "AUTOCORRECT",
13670 489: "POST.DOCUMENT",
13671 491: "PICKLIST",
13672 493: "VIEW.SHOW",
13673 494: "VIEW.DEFINE",
13674 495: "VIEW.DELETE",
13675 509: "SHEET.BACKGROUND",
13676 510: "INSERT.MAP.OBJECT",
13677 511: "OPTIONS.MENONO",
13678 517: "MSOCHECKS",
13679 518: "NORMAL",
13680 519: "LAYOUT",
13681 520: "RM.PRINT.AREA",
13682 521: "CLEAR.PRINT.AREA",
13683 522: "ADD.PRINT.AREA",
13684 523: "MOVE.BRK",
13685 545: "HIDECURR.NOTE",
13686 546: "HIDEALL.NOTES",
13687 547: "DELETE.NOTE",
13688 548: "TRAVERSE.NOTES",
13689 549: "ACTIVATE.NOTES",
13690 620: "PROTECT.REVISIONS",
13691 621: "UNPROTECT.REVISIONS",
13692 647: "OPTIONS.ME",
13693 653: "WEB.PUBLISH",
13694 667: "NEWWEBQUERY",
13695 673: "PIVOT.TABLE.CHART",
13696 753: "OPTIONS.SAVE",
13697 755: "OPTIONS.SPELL",
13698 808: "HIDEALL.INKANNOTS"
13699};
13700var Ftab = {
13701 0: "COUNT",
13702 1: "IF",
13703 2: "ISNA",
13704 3: "ISERROR",
13705 4: "SUM",
13706 5: "AVERAGE",
13707 6: "MIN",
13708 7: "MAX",
13709 8: "ROW",
13710 9: "COLUMN",
13711 10: "NA",
13712 11: "NPV",
13713 12: "STDEV",
13714 13: "DOLLAR",
13715 14: "FIXED",
13716 15: "SIN",
13717 16: "COS",
13718 17: "TAN",
13719 18: "ATAN",
13720 19: "PI",
13721 20: "SQRT",
13722 21: "EXP",
13723 22: "LN",
13724 23: "LOG10",
13725 24: "ABS",
13726 25: "INT",
13727 26: "SIGN",
13728 27: "ROUND",
13729 28: "LOOKUP",
13730 29: "INDEX",
13731 30: "REPT",
13732 31: "MID",
13733 32: "LEN",
13734 33: "VALUE",
13735 34: "TRUE",
13736 35: "FALSE",
13737 36: "AND",
13738 37: "OR",
13739 38: "NOT",
13740 39: "MOD",
13741 40: "DCOUNT",
13742 41: "DSUM",
13743 42: "DAVERAGE",
13744 43: "DMIN",
13745 44: "DMAX",
13746 45: "DSTDEV",
13747 46: "VAR",
13748 47: "DVAR",
13749 48: "TEXT",
13750 49: "LINEST",
13751 50: "TREND",
13752 51: "LOGEST",
13753 52: "GROWTH",
13754 53: "GOTO",
13755 54: "HALT",
13756 55: "RETURN",
13757 56: "PV",
13758 57: "FV",
13759 58: "NPER",
13760 59: "PMT",
13761 60: "RATE",
13762 61: "MIRR",
13763 62: "IRR",
13764 63: "RAND",
13765 64: "MATCH",
13766 65: "DATE",
13767 66: "TIME",
13768 67: "DAY",
13769 68: "MONTH",
13770 69: "YEAR",
13771 70: "WEEKDAY",
13772 71: "HOUR",
13773 72: "MINUTE",
13774 73: "SECOND",
13775 74: "NOW",
13776 75: "AREAS",
13777 76: "ROWS",
13778 77: "COLUMNS",
13779 78: "OFFSET",
13780 79: "ABSREF",
13781 80: "RELREF",
13782 81: "ARGUMENT",
13783 82: "SEARCH",
13784 83: "TRANSPOSE",
13785 84: "ERROR",
13786 85: "STEP",
13787 86: "TYPE",
13788 87: "ECHO",
13789 88: "SET.NAME",
13790 89: "CALLER",
13791 90: "DEREF",
13792 91: "WINDOWS",
13793 92: "SERIES",
13794 93: "DOCUMENTS",
13795 94: "ACTIVE.CELL",
13796 95: "SELECTION",
13797 96: "RESULT",
13798 97: "ATAN2",
13799 98: "ASIN",
13800 99: "ACOS",
13801 100: "CHOOSE",
13802 101: "HLOOKUP",
13803 102: "VLOOKUP",
13804 103: "LINKS",
13805 104: "INPUT",
13806 105: "ISREF",
13807 106: "GET.FORMULA",
13808 107: "GET.NAME",
13809 108: "SET.VALUE",
13810 109: "LOG",
13811 110: "EXEC",
13812 111: "CHAR",
13813 112: "LOWER",
13814 113: "UPPER",
13815 114: "PROPER",
13816 115: "LEFT",
13817 116: "RIGHT",
13818 117: "EXACT",
13819 118: "TRIM",
13820 119: "REPLACE",
13821 120: "SUBSTITUTE",
13822 121: "CODE",
13823 122: "NAMES",
13824 123: "DIRECTORY",
13825 124: "FIND",
13826 125: "CELL",
13827 126: "ISERR",
13828 127: "ISTEXT",
13829 128: "ISNUMBER",
13830 129: "ISBLANK",
13831 130: "T",
13832 131: "N",
13833 132: "FOPEN",
13834 133: "FCLOSE",
13835 134: "FSIZE",
13836 135: "FREADLN",
13837 136: "FREAD",
13838 137: "FWRITELN",
13839 138: "FWRITE",
13840 139: "FPOS",
13841 140: "DATEVALUE",
13842 141: "TIMEVALUE",
13843 142: "SLN",
13844 143: "SYD",
13845 144: "DDB",
13846 145: "GET.DEF",
13847 146: "REFTEXT",
13848 147: "TEXTREF",
13849 148: "INDIRECT",
13850 149: "REGISTER",
13851 150: "CALL",
13852 151: "ADD.BAR",
13853 152: "ADD.MENU",
13854 153: "ADD.COMMAND",
13855 154: "ENABLE.COMMAND",
13856 155: "CHECK.COMMAND",
13857 156: "RENAME.COMMAND",
13858 157: "SHOW.BAR",
13859 158: "DELETE.MENU",
13860 159: "DELETE.COMMAND",
13861 160: "GET.CHART.ITEM",
13862 161: "DIALOG.BOX",
13863 162: "CLEAN",
13864 163: "MDETERM",
13865 164: "MINVERSE",
13866 165: "MMULT",
13867 166: "FILES",
13868 167: "IPMT",
13869 168: "PPMT",
13870 169: "COUNTA",
13871 170: "CANCEL.KEY",
13872 171: "FOR",
13873 172: "WHILE",
13874 173: "BREAK",
13875 174: "NEXT",
13876 175: "INITIATE",
13877 176: "REQUEST",
13878 177: "POKE",
13879 178: "EXECUTE",
13880 179: "TERMINATE",
13881 180: "RESTART",
13882 181: "HELP",
13883 182: "GET.BAR",
13884 183: "PRODUCT",
13885 184: "FACT",
13886 185: "GET.CELL",
13887 186: "GET.WORKSPACE",
13888 187: "GET.WINDOW",
13889 188: "GET.DOCUMENT",
13890 189: "DPRODUCT",
13891 190: "ISNONTEXT",
13892 191: "GET.NOTE",
13893 192: "NOTE",
13894 193: "STDEVP",
13895 194: "VARP",
13896 195: "DSTDEVP",
13897 196: "DVARP",
13898 197: "TRUNC",
13899 198: "ISLOGICAL",
13900 199: "DCOUNTA",
13901 200: "DELETE.BAR",
13902 201: "UNREGISTER",
13903 204: "USDOLLAR",
13904 205: "FINDB",
13905 206: "SEARCHB",
13906 207: "REPLACEB",
13907 208: "LEFTB",
13908 209: "RIGHTB",
13909 210: "MIDB",
13910 211: "LENB",
13911 212: "ROUNDUP",
13912 213: "ROUNDDOWN",
13913 214: "ASC",
13914 215: "DBCS",
13915 216: "RANK",
13916 219: "ADDRESS",
13917 220: "DAYS360",
13918 221: "TODAY",
13919 222: "VDB",
13920 223: "ELSE",
13921 224: "ELSE.IF",
13922 225: "END.IF",
13923 226: "FOR.CELL",
13924 227: "MEDIAN",
13925 228: "SUMPRODUCT",
13926 229: "SINH",
13927 230: "COSH",
13928 231: "TANH",
13929 232: "ASINH",
13930 233: "ACOSH",
13931 234: "ATANH",
13932 235: "DGET",
13933 236: "CREATE.OBJECT",
13934 237: "VOLATILE",
13935 238: "LAST.ERROR",
13936 239: "CUSTOM.UNDO",
13937 240: "CUSTOM.REPEAT",
13938 241: "FORMULA.CONVERT",
13939 242: "GET.LINK.INFO",
13940 243: "TEXT.BOX",
13941 244: "INFO",
13942 245: "GROUP",
13943 246: "GET.OBJECT",
13944 247: "DB",
13945 248: "PAUSE",
13946 251: "RESUME",
13947 252: "FREQUENCY",
13948 253: "ADD.TOOLBAR",
13949 254: "DELETE.TOOLBAR",
13950 255: "User",
13951 256: "RESET.TOOLBAR",
13952 257: "EVALUATE",
13953 258: "GET.TOOLBAR",
13954 259: "GET.TOOL",
13955 260: "SPELLING.CHECK",
13956 261: "ERROR.TYPE",
13957 262: "APP.TITLE",
13958 263: "WINDOW.TITLE",
13959 264: "SAVE.TOOLBAR",
13960 265: "ENABLE.TOOL",
13961 266: "PRESS.TOOL",
13962 267: "REGISTER.ID",
13963 268: "GET.WORKBOOK",
13964 269: "AVEDEV",
13965 270: "BETADIST",
13966 271: "GAMMALN",
13967 272: "BETAINV",
13968 273: "BINOMDIST",
13969 274: "CHIDIST",
13970 275: "CHIINV",
13971 276: "COMBIN",
13972 277: "CONFIDENCE",
13973 278: "CRITBINOM",
13974 279: "EVEN",
13975 280: "EXPONDIST",
13976 281: "FDIST",
13977 282: "FINV",
13978 283: "FISHER",
13979 284: "FISHERINV",
13980 285: "FLOOR",
13981 286: "GAMMADIST",
13982 287: "GAMMAINV",
13983 288: "CEILING",
13984 289: "HYPGEOMDIST",
13985 290: "LOGNORMDIST",
13986 291: "LOGINV",
13987 292: "NEGBINOMDIST",
13988 293: "NORMDIST",
13989 294: "NORMSDIST",
13990 295: "NORMINV",
13991 296: "NORMSINV",
13992 297: "STANDARDIZE",
13993 298: "ODD",
13994 299: "PERMUT",
13995 300: "POISSON",
13996 301: "TDIST",
13997 302: "WEIBULL",
13998 303: "SUMXMY2",
13999 304: "SUMX2MY2",
14000 305: "SUMX2PY2",
14001 306: "CHITEST",
14002 307: "CORREL",
14003 308: "COVAR",
14004 309: "FORECAST",
14005 310: "FTEST",
14006 311: "INTERCEPT",
14007 312: "PEARSON",
14008 313: "RSQ",
14009 314: "STEYX",
14010 315: "SLOPE",
14011 316: "TTEST",
14012 317: "PROB",
14013 318: "DEVSQ",
14014 319: "GEOMEAN",
14015 320: "HARMEAN",
14016 321: "SUMSQ",
14017 322: "KURT",
14018 323: "SKEW",
14019 324: "ZTEST",
14020 325: "LARGE",
14021 326: "SMALL",
14022 327: "QUARTILE",
14023 328: "PERCENTILE",
14024 329: "PERCENTRANK",
14025 330: "MODE",
14026 331: "TRIMMEAN",
14027 332: "TINV",
14028 334: "MOVIE.COMMAND",
14029 335: "GET.MOVIE",
14030 336: "CONCATENATE",
14031 337: "POWER",
14032 338: "PIVOT.ADD.DATA",
14033 339: "GET.PIVOT.TABLE",
14034 340: "GET.PIVOT.FIELD",
14035 341: "GET.PIVOT.ITEM",
14036 342: "RADIANS",
14037 343: "DEGREES",
14038 344: "SUBTOTAL",
14039 345: "SUMIF",
14040 346: "COUNTIF",
14041 347: "COUNTBLANK",
14042 348: "SCENARIO.GET",
14043 349: "OPTIONS.LISTS.GET",
14044 350: "ISPMT",
14045 351: "DATEDIF",
14046 352: "DATESTRING",
14047 353: "NUMBERSTRING",
14048 354: "ROMAN",
14049 355: "OPEN.DIALOG",
14050 356: "SAVE.DIALOG",
14051 357: "VIEW.GET",
14052 358: "GETPIVOTDATA",
14053 359: "HYPERLINK",
14054 360: "PHONETIC",
14055 361: "AVERAGEA",
14056 362: "MAXA",
14057 363: "MINA",
14058 364: "STDEVPA",
14059 365: "VARPA",
14060 366: "STDEVA",
14061 367: "VARA",
14062 368: "BAHTTEXT",
14063 369: "THAIDAYOFWEEK",
14064 370: "THAIDIGIT",
14065 371: "THAIMONTHOFYEAR",
14066 372: "THAINUMSOUND",
14067 373: "THAINUMSTRING",
14068 374: "THAISTRINGLENGTH",
14069 375: "ISTHAIDIGIT",
14070 376: "ROUNDBAHTDOWN",
14071 377: "ROUNDBAHTUP",
14072 378: "THAIYEAR",
14073 379: "RTD",
14074 380: "CUBEVALUE",
14075 381: "CUBEMEMBER",
14076 382: "CUBEMEMBERPROPERTY",
14077 383: "CUBERANKEDMEMBER",
14078 384: "HEX2BIN",
14079 385: "HEX2DEC",
14080 386: "HEX2OCT",
14081 387: "DEC2BIN",
14082 388: "DEC2HEX",
14083 389: "DEC2OCT",
14084 390: "OCT2BIN",
14085 391: "OCT2HEX",
14086 392: "OCT2DEC",
14087 393: "BIN2DEC",
14088 394: "BIN2OCT",
14089 395: "BIN2HEX",
14090 396: "IMSUB",
14091 397: "IMDIV",
14092 398: "IMPOWER",
14093 399: "IMABS",
14094 400: "IMSQRT",
14095 401: "IMLN",
14096 402: "IMLOG2",
14097 403: "IMLOG10",
14098 404: "IMSIN",
14099 405: "IMCOS",
14100 406: "IMEXP",
14101 407: "IMARGUMENT",
14102 408: "IMCONJUGATE",
14103 409: "IMAGINARY",
14104 410: "IMREAL",
14105 411: "COMPLEX",
14106 412: "IMSUM",
14107 413: "IMPRODUCT",
14108 414: "SERIESSUM",
14109 415: "FACTDOUBLE",
14110 416: "SQRTPI",
14111 417: "QUOTIENT",
14112 418: "DELTA",
14113 419: "GESTEP",
14114 420: "ISEVEN",
14115 421: "ISODD",
14116 422: "MROUND",
14117 423: "ERF",
14118 424: "ERFC",
14119 425: "BESSELJ",
14120 426: "BESSELK",
14121 427: "BESSELY",
14122 428: "BESSELI",
14123 429: "XIRR",
14124 430: "XNPV",
14125 431: "PRICEMAT",
14126 432: "YIELDMAT",
14127 433: "INTRATE",
14128 434: "RECEIVED",
14129 435: "DISC",
14130 436: "PRICEDISC",
14131 437: "YIELDDISC",
14132 438: "TBILLEQ",
14133 439: "TBILLPRICE",
14134 440: "TBILLYIELD",
14135 441: "PRICE",
14136 442: "YIELD",
14137 443: "DOLLARDE",
14138 444: "DOLLARFR",
14139 445: "NOMINAL",
14140 446: "EFFECT",
14141 447: "CUMPRINC",
14142 448: "CUMIPMT",
14143 449: "EDATE",
14144 450: "EOMONTH",
14145 451: "YEARFRAC",
14146 452: "COUPDAYBS",
14147 453: "COUPDAYS",
14148 454: "COUPDAYSNC",
14149 455: "COUPNCD",
14150 456: "COUPNUM",
14151 457: "COUPPCD",
14152 458: "DURATION",
14153 459: "MDURATION",
14154 460: "ODDLPRICE",
14155 461: "ODDLYIELD",
14156 462: "ODDFPRICE",
14157 463: "ODDFYIELD",
14158 464: "RANDBETWEEN",
14159 465: "WEEKNUM",
14160 466: "AMORDEGRC",
14161 467: "AMORLINC",
14162 468: "CONVERT",
14163 724: "SHEETJS",
14164 469: "ACCRINT",
14165 470: "ACCRINTM",
14166 471: "WORKDAY",
14167 472: "NETWORKDAYS",
14168 473: "GCD",
14169 474: "MULTINOMIAL",
14170 475: "LCM",
14171 476: "FVSCHEDULE",
14172 477: "CUBEKPIMEMBER",
14173 478: "CUBESET",
14174 479: "CUBESETCOUNT",
14175 480: "IFERROR",
14176 481: "COUNTIFS",
14177 482: "SUMIFS",
14178 483: "AVERAGEIF",
14179 484: "AVERAGEIFS"
14180};
14181var FtabArgc = {
14182 2: 1,
14183 3: 1,
14184 10: 0,
14185 15: 1,
14186 16: 1,
14187 17: 1,
14188 18: 1,
14189 19: 0,
14190 20: 1,
14191 21: 1,
14192 22: 1,
14193 23: 1,
14194 24: 1,
14195 25: 1,
14196 26: 1,
14197 27: 2,
14198 30: 2,
14199 31: 3,
14200 32: 1,
14201 33: 1,
14202 34: 0,
14203 35: 0,
14204 38: 1,
14205 39: 2,
14206 40: 3,
14207 41: 3,
14208 42: 3,
14209 43: 3,
14210 44: 3,
14211 45: 3,
14212 47: 3,
14213 48: 2,
14214 53: 1,
14215 61: 3,
14216 63: 0,
14217 65: 3,
14218 66: 3,
14219 67: 1,
14220 68: 1,
14221 69: 1,
14222 70: 1,
14223 71: 1,
14224 72: 1,
14225 73: 1,
14226 74: 0,
14227 75: 1,
14228 76: 1,
14229 77: 1,
14230 79: 2,
14231 80: 2,
14232 83: 1,
14233 85: 0,
14234 86: 1,
14235 89: 0,
14236 90: 1,
14237 94: 0,
14238 95: 0,
14239 97: 2,
14240 98: 1,
14241 99: 1,
14242 101: 3,
14243 102: 3,
14244 105: 1,
14245 106: 1,
14246 108: 2,
14247 111: 1,
14248 112: 1,
14249 113: 1,
14250 114: 1,
14251 117: 2,
14252 118: 1,
14253 119: 4,
14254 121: 1,
14255 126: 1,
14256 127: 1,
14257 128: 1,
14258 129: 1,
14259 130: 1,
14260 131: 1,
14261 133: 1,
14262 134: 1,
14263 135: 1,
14264 136: 2,
14265 137: 2,
14266 138: 2,
14267 140: 1,
14268 141: 1,
14269 142: 3,
14270 143: 4,
14271 144: 4,
14272 161: 1,
14273 162: 1,
14274 163: 1,
14275 164: 1,
14276 165: 2,
14277 172: 1,
14278 175: 2,
14279 176: 2,
14280 177: 3,
14281 178: 2,
14282 179: 1,
14283 184: 1,
14284 186: 1,
14285 189: 3,
14286 190: 1,
14287 195: 3,
14288 196: 3,
14289 197: 1,
14290 198: 1,
14291 199: 3,
14292 201: 1,
14293 207: 4,
14294 210: 3,
14295 211: 1,
14296 212: 2,
14297 213: 2,
14298 214: 1,
14299 215: 1,
14300 225: 0,
14301 229: 1,
14302 230: 1,
14303 231: 1,
14304 232: 1,
14305 233: 1,
14306 234: 1,
14307 235: 3,
14308 244: 1,
14309 247: 4,
14310 252: 2,
14311 257: 1,
14312 261: 1,
14313 271: 1,
14314 273: 4,
14315 274: 2,
14316 275: 2,
14317 276: 2,
14318 277: 3,
14319 278: 3,
14320 279: 1,
14321 280: 3,
14322 281: 3,
14323 282: 3,
14324 283: 1,
14325 284: 1,
14326 285: 2,
14327 286: 4,
14328 287: 3,
14329 288: 2,
14330 289: 4,
14331 290: 3,
14332 291: 3,
14333 292: 3,
14334 293: 4,
14335 294: 1,
14336 295: 3,
14337 296: 1,
14338 297: 3,
14339 298: 1,
14340 299: 2,
14341 300: 3,
14342 301: 3,
14343 302: 4,
14344 303: 2,
14345 304: 2,
14346 305: 2,
14347 306: 2,
14348 307: 2,
14349 308: 2,
14350 309: 3,
14351 310: 2,
14352 311: 2,
14353 312: 2,
14354 313: 2,
14355 314: 2,
14356 315: 2,
14357 316: 4,
14358 325: 2,
14359 326: 2,
14360 327: 2,
14361 328: 2,
14362 331: 2,
14363 332: 2,
14364 337: 2,
14365 342: 1,
14366 343: 1,
14367 346: 2,
14368 347: 1,
14369 350: 4,
14370 351: 3,
14371 352: 1,
14372 353: 2,
14373 360: 1,
14374 368: 1,
14375 369: 1,
14376 370: 1,
14377 371: 1,
14378 372: 1,
14379 373: 1,
14380 374: 1,
14381 375: 1,
14382 376: 1,
14383 377: 1,
14384 378: 1,
14385 382: 3,
14386 385: 1,
14387 392: 1,
14388 393: 1,
14389 396: 2,
14390 397: 2,
14391 398: 2,
14392 399: 1,
14393 400: 1,
14394 401: 1,
14395 402: 1,
14396 403: 1,
14397 404: 1,
14398 405: 1,
14399 406: 1,
14400 407: 1,
14401 408: 1,
14402 409: 1,
14403 410: 1,
14404 414: 4,
14405 415: 1,
14406 416: 1,
14407 417: 2,
14408 420: 1,
14409 421: 1,
14410 422: 2,
14411 424: 1,
14412 425: 2,
14413 426: 2,
14414 427: 2,
14415 428: 2,
14416 430: 3,
14417 438: 3,
14418 439: 3,
14419 440: 3,
14420 443: 2,
14421 444: 2,
14422 445: 2,
14423 446: 2,
14424 447: 6,
14425 448: 6,
14426 449: 2,
14427 450: 2,
14428 464: 2,
14429 468: 3,
14430 476: 2,
14431 479: 1,
14432 480: 2,
14433 65535: 0
14434};
14435/* Part 3 TODO: actually parse formulae */
14436function ods_to_csf_formula(f/*:string*/)/*:string*/ {
14437 if(f.slice(0,3) == "of:") f = f.slice(3);
14438 /* 5.2 Basic Expressions */
14439 if(f.charCodeAt(0) == 61) {
14440 f = f.slice(1);
14441 if(f.charCodeAt(0) == 61) f = f.slice(1);
14442 }
14443 f = f.replace(/COM\.MICROSOFT\./g, "");
14444 /* Part 3 Section 5.8 References */
14445 f = f.replace(/\[((?:\.[A-Z]+[0-9]+)(?::\.[A-Z]+[0-9]+)?)\]/g, function($$, $1) { return $1.replace(/\./g,""); });
14446 /* TODO: something other than this */
14447 f = f.replace(/\[.(#[A-Z]*[?!])\]/g, "$1");
14448 return f.replace(/[;~]/g,",").replace(/\|/g,";");
14449}
14450
14451function csf_to_ods_formula(f/*:string*/)/*:string*/ {
14452 var o = "of:=" + f.replace(crefregex, "$1[.$2$3$4$5]").replace(/\]:\[/g,":");
14453 /* TODO: something other than this */
14454 return o.replace(/;/g, "|").replace(/,/g,";");
14455}
14456
14457function ods_to_csf_3D(r/*:string*/)/*:[string, string]*/ {
14458 var a = r.split(":");
14459 var s = a[0].split(".")[0];
14460 return [s, a[0].split(".")[1] + (a.length > 1 ? (":" + (a[1].split(".")[1] || a[1].split(".")[0])) : "")];
14461}
14462
14463function csf_to_ods_3D(r/*:string*/)/*:string*/ {
14464 return r.replace(/\./,"!");
14465}
14466
14467var strs = {}; // shared strings
14468var _ssfopts = {}; // spreadsheet formatting options
14469
14470
14471/*global Map */
14472var browser_has_Map = typeof Map !== 'undefined';
14473
14474function get_sst_id(sst/*:SST*/, str/*:string*/, rev)/*:number*/ {
14475 var i = 0, len = sst.length;
14476 if(rev) {
14477 if(browser_has_Map ? rev.has(str) : Object.prototype.hasOwnProperty.call(rev, str)) {
14478 var revarr = browser_has_Map ? rev.get(str) : rev[str];
14479 for(; i < revarr.length; ++i) {
14480 if(sst[revarr[i]].t === str) { sst.Count ++; return revarr[i]; }
14481 }
14482 }
14483 } else for(; i < len; ++i) {
14484 if(sst[i].t === str) { sst.Count ++; return i; }
14485 }
14486 sst[len] = ({t:str}/*:any*/); sst.Count ++; sst.Unique ++;
14487 if(rev) {
14488 if(browser_has_Map) {
14489 if(!rev.has(str)) rev.set(str, []);
14490 rev.get(str).push(len);
14491 } else {
14492 if(!Object.prototype.hasOwnProperty.call(rev, str)) rev[str] = [];
14493 rev[str].push(len);
14494 }
14495 }
14496 return len;
14497}
14498
14499function col_obj_w(C/*:number*/, col) {
14500 var p = ({min:C+1,max:C+1}/*:any*/);
14501 /* wch (chars), wpx (pixels) */
14502 var wch = -1;
14503 if(col.MDW) MDW = col.MDW;
14504 if(col.width != null) p.customWidth = 1;
14505 else if(col.wpx != null) wch = px2char(col.wpx);
14506 else if(col.wch != null) wch = col.wch;
14507 if(wch > -1) { p.width = char2width(wch); p.customWidth = 1; }
14508 else if(col.width != null) p.width = col.width;
14509 if(col.hidden) p.hidden = true;
14510 if(col.level != null) { p.outlineLevel = p.level = col.level; }
14511 return p;
14512}
14513
14514function default_margins(margins/*:Margins*/, mode/*:?string*/) {
14515 if(!margins) return;
14516 var defs = [0.7, 0.7, 0.75, 0.75, 0.3, 0.3];
14517 if(mode == 'xlml') defs = [1, 1, 1, 1, 0.5, 0.5];
14518 if(margins.left == null) margins.left = defs[0];
14519 if(margins.right == null) margins.right = defs[1];
14520 if(margins.top == null) margins.top = defs[2];
14521 if(margins.bottom == null) margins.bottom = defs[3];
14522 if(margins.header == null) margins.header = defs[4];
14523 if(margins.footer == null) margins.footer = defs[5];
14524}
14525
14526function get_cell_style(styles/*:Array<any>*/, cell/*:Cell*/, opts) {
14527 var z = opts.revssf[cell.z != null ? cell.z : "General"];
14528 var i = 0x3c, len = styles.length;
14529 if(z == null && opts.ssf) {
14530 for(; i < 0x188; ++i) if(opts.ssf[i] == null) {
14531 SSF_load(cell.z, i);
14532 // $FlowIgnore
14533 opts.ssf[i] = cell.z;
14534 opts.revssf[cell.z] = z = i;
14535 break;
14536 }
14537 }
14538 for(i = 0; i != len; ++i) if(styles[i].numFmtId === z) return i;
14539 styles[len] = {
14540 numFmtId:z,
14541 fontId:0,
14542 fillId:0,
14543 borderId:0,
14544 xfId:0,
14545 applyNumberFormat:1
14546 };
14547 return len;
14548}
14549
14550function safe_format(p/*:Cell*/, fmtid/*:number*/, fillid/*:?number*/, opts, themes, styles) {
14551 try {
14552 if(opts.cellNF) p.z = table_fmt[fmtid];
14553 } catch(e) { if(opts.WTF) throw e; }
14554 if(p.t === 'z' && !opts.cellStyles) return;
14555 if(p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v);
14556 if((!opts || opts.cellText !== false) && p.t !== 'z') try {
14557 if(table_fmt[fmtid] == null) SSF_load(SSFImplicit[fmtid] || "General", fmtid);
14558 if(p.t === 'e') p.w = p.w || BErr[p.v];
14559 else if(fmtid === 0) {
14560 if(p.t === 'n') {
14561 if((p.v|0) === p.v) p.w = p.v.toString(10);
14562 else p.w = SSF_general_num(p.v);
14563 }
14564 else if(p.t === 'd') {
14565 var dd = datenum(p.v);
14566 if((dd|0) === dd) p.w = dd.toString(10);
14567 else p.w = SSF_general_num(dd);
14568 }
14569 else if(p.v === undefined) return "";
14570 else p.w = SSF_general(p.v,_ssfopts);
14571 }
14572 else if(p.t === 'd') p.w = SSF_format(fmtid,datenum(p.v),_ssfopts);
14573 else p.w = SSF_format(fmtid,p.v,_ssfopts);
14574 } catch(e) { if(opts.WTF) throw e; }
14575 if(!opts.cellStyles) return;
14576 if(fillid != null) try {
14577 p.s = styles.Fills[fillid];
14578 if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
14579 p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
14580 if(opts.WTF) p.s.fgColor.raw_rgb = themes.themeElements.clrScheme[p.s.fgColor.theme].rgb;
14581 }
14582 if (p.s.bgColor && p.s.bgColor.theme) {
14583 p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
14584 if(opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
14585 }
14586 } catch(e) { if(opts.WTF && styles.Fills) throw e; }
14587}
14588
14589function check_ws(ws/*:Worksheet*/, sname/*:string*/, i/*:number*/) {
14590 if(ws && ws['!ref']) {
14591 var range = safe_decode_range(ws['!ref']);
14592 if(range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
14593 }
14594}
14595function parse_ws_xml_dim(ws/*:Worksheet*/, s/*:string*/) {
14596 var d = safe_decode_range(s);
14597 if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
14598}
14599var mergecregex = /<(?:\w:)?mergeCell ref="[A-Z0-9:]+"\s*[\/]?>/g;
14600var sheetdataregex = /<(?:\w+:)?sheetData[^>]*>([\s\S]*)<\/(?:\w+:)?sheetData>/;
14601var hlinkregex = /<(?:\w:)?hyperlink [^>]*>/mg;
14602var dimregex = /"(\w*:\w*)"/;
14603var colregex = /<(?:\w:)?col\b[^>]*[\/]?>/g;
14604var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
14605var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
14606var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
14607var sheetprregex2= /<(?:\w:)?sheetPr[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetPr)>/;
14608var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
14609
14610/* 18.3 Worksheets */
14611function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
14612 if(!data) return data;
14613 if(!rels) rels = {'!id':{}};
14614 if(DENSE != null && opts.dense == null) opts.dense = DENSE;
14615
14616 /* 18.3.1.99 worksheet CT_Worksheet */
14617 var s = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
14618 var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
14619
14620 var data1 = "", data2 = "";
14621 var mtch/*:?any*/ = data.match(sheetdataregex);
14622 if(mtch) {
14623 data1 = data.slice(0, mtch.index);
14624 data2 = data.slice(mtch.index + mtch[0].length);
14625 } else data1 = data2 = data;
14626
14627 /* 18.3.1.82 sheetPr CT_SheetPr */
14628 var sheetPr = data1.match(sheetprregex);
14629 if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
14630 else if((sheetPr = data1.match(sheetprregex2))) parse_ws_xml_sheetpr2(sheetPr[0], sheetPr[1]||"", s, wb, idx, styles, themes);
14631
14632 /* 18.3.1.35 dimension CT_SheetDimension */
14633 var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
14634 if(ridx > 0) {
14635 var ref = data1.slice(ridx,ridx+50).match(dimregex);
14636 if(ref) parse_ws_xml_dim(s, ref[1]);
14637 }
14638
14639 /* 18.3.1.88 sheetViews CT_SheetViews */
14640 var svs = data1.match(svsregex);
14641 if(svs && svs[1]) parse_ws_xml_sheetviews(svs[1], wb);
14642
14643 /* 18.3.1.17 cols CT_Cols */
14644 var columns/*:Array<ColInfo>*/ = [];
14645 if(opts.cellStyles) {
14646 /* 18.3.1.13 col CT_Col */
14647 var cols = data1.match(colregex);
14648 if(cols) parse_ws_xml_cols(columns, cols);
14649 }
14650
14651 /* 18.3.1.80 sheetData CT_SheetData ? */
14652 if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles);
14653
14654 /* 18.3.1.2 autoFilter CT_AutoFilter */
14655 var afilter = data2.match(afregex);
14656 if(afilter) s['!autofilter'] = parse_ws_xml_autofilter(afilter[0]);
14657
14658 /* 18.3.1.55 mergeCells CT_MergeCells */
14659 var merges/*:Array<Range>*/ = [];
14660 var _merge = data2.match(mergecregex);
14661 if(_merge) for(ridx = 0; ridx != _merge.length; ++ridx)
14662 merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"")+1));
14663
14664 /* 18.3.1.48 hyperlinks CT_Hyperlinks */
14665 var hlink = data2.match(hlinkregex);
14666 if(hlink) parse_ws_xml_hlinks(s, hlink, rels);
14667
14668 /* 18.3.1.62 pageMargins CT_PageMargins */
14669 var margins = data2.match(marginregex);
14670 if(margins) s['!margins'] = parse_ws_xml_margins(parsexmltag(margins[0]));
14671
14672 if(!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
14673 if(opts.sheetRows > 0 && s["!ref"]) {
14674 var tmpref = safe_decode_range(s["!ref"]);
14675 if(opts.sheetRows <= +tmpref.e.r) {
14676 tmpref.e.r = opts.sheetRows - 1;
14677 if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
14678 if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
14679 if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
14680 if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
14681 s["!fullref"] = s["!ref"];
14682 s["!ref"] = encode_range(tmpref);
14683 }
14684 }
14685 if(columns.length > 0) s["!cols"] = columns;
14686 if(merges.length > 0) s["!merges"] = merges;
14687 return s;
14688}
14689
14690function write_ws_xml_merges(merges/*:Array<Range>*/)/*:string*/ {
14691 if(merges.length === 0) return "";
14692 var o = '<mergeCells count="' + merges.length + '">';
14693 for(var i = 0; i != merges.length; ++i) o += '<mergeCell ref="' + encode_range(merges[i]) + '"/>';
14694 return o + '</mergeCells>';
14695}
14696
14697/* 18.3.1.82-3 sheetPr CT_ChartsheetPr / CT_SheetPr */
14698function parse_ws_xml_sheetpr(sheetPr/*:string*/, s, wb/*:WBWBProps*/, idx/*:number*/) {
14699 var data = parsexmltag(sheetPr);
14700 if(!wb.Sheets[idx]) wb.Sheets[idx] = {};
14701 if(data.codeName) wb.Sheets[idx].CodeName = unescapexml(utf8read(data.codeName));
14702}
14703function parse_ws_xml_sheetpr2(sheetPr/*:string*/, body/*:string*/, s, wb/*:WBWBProps*/, idx/*:number*/) {
14704 parse_ws_xml_sheetpr(sheetPr.slice(0, sheetPr.indexOf(">")), s, wb, idx);
14705}
14706function write_ws_xml_sheetpr(ws, wb, idx, opts, o) {
14707 var needed = false;
14708 var props = {}, payload = null;
14709 if(opts.bookType !== 'xlsx' && wb.vbaraw) {
14710 var cname = wb.SheetNames[idx];
14711 try { if(wb.Workbook) cname = wb.Workbook.Sheets[idx].CodeName || cname; } catch(e) {}
14712 needed = true;
14713 props.codeName = utf8write(escapexml(cname));
14714 }
14715
14716 if(ws && ws["!outline"]) {
14717 var outlineprops = {summaryBelow:1, summaryRight:1};
14718 if(ws["!outline"].above) outlineprops.summaryBelow = 0;
14719 if(ws["!outline"].left) outlineprops.summaryRight = 0;
14720 payload = (payload||"") + writextag('outlinePr', null, outlineprops);
14721 }
14722
14723 if(!needed && !payload) return;
14724 o[o.length] = (writextag('sheetPr', payload, props));
14725}
14726
14727/* 18.3.1.85 sheetProtection CT_SheetProtection */
14728var sheetprot_deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
14729var sheetprot_deftrue = [
14730 "formatColumns", "formatRows", "formatCells",
14731 "insertColumns", "insertRows", "insertHyperlinks",
14732 "deleteColumns", "deleteRows",
14733 "sort", "autoFilter", "pivotTables"
14734];
14735function write_ws_xml_protection(sp)/*:string*/ {
14736 // algorithmName, hashValue, saltValue, spinCount
14737 var o = ({sheet:1}/*:any*/);
14738 sheetprot_deffalse.forEach(function(n) { if(sp[n] != null && sp[n]) o[n] = "1"; });
14739 sheetprot_deftrue.forEach(function(n) { if(sp[n] != null && !sp[n]) o[n] = "0"; });
14740 /* TODO: algorithm */
14741 if(sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
14742 return writextag('sheetProtection', null, o);
14743}
14744
14745function parse_ws_xml_hlinks(s, data/*:Array<string>*/, rels) {
14746 var dense = Array.isArray(s);
14747 for(var i = 0; i != data.length; ++i) {
14748 var val = parsexmltag(utf8read(data[i]), true);
14749 if(!val.ref) return;
14750 var rel = ((rels || {})['!id']||[])[val.id];
14751 if(rel) {
14752 val.Target = rel.Target;
14753 if(val.location) val.Target += "#"+unescapexml(val.location);
14754 } else {
14755 val.Target = "#" + unescapexml(val.location);
14756 rel = {Target: val.Target, TargetMode: 'Internal'};
14757 }
14758 val.Rel = rel;
14759 if(val.tooltip) { val.Tooltip = val.tooltip; delete val.tooltip; }
14760 var rng = safe_decode_range(val.ref);
14761 for(var R=rng.s.r;R<=rng.e.r;++R) for(var C=rng.s.c;C<=rng.e.c;++C) {
14762 var addr = encode_cell({c:C,r:R});
14763 if(dense) {
14764 if(!s[R]) s[R] = [];
14765 if(!s[R][C]) s[R][C] = {t:"z",v:undefined};
14766 s[R][C].l = val;
14767 } else {
14768 if(!s[addr]) s[addr] = {t:"z",v:undefined};
14769 s[addr].l = val;
14770 }
14771 }
14772 }
14773}
14774
14775function parse_ws_xml_margins(margin) {
14776 var o = {};
14777 ["left", "right", "top", "bottom", "header", "footer"].forEach(function(k) {
14778 if(margin[k]) o[k] = parseFloat(margin[k]);
14779 });
14780 return o;
14781}
14782function write_ws_xml_margins(margin)/*:string*/ {
14783 default_margins(margin);
14784 return writextag('pageMargins', null, margin);
14785}
14786
14787function parse_ws_xml_cols(columns, cols) {
14788 var seencol = false;
14789 for(var coli = 0; coli != cols.length; ++coli) {
14790 var coll = parsexmltag(cols[coli], true);
14791 if(coll.hidden) coll.hidden = parsexmlbool(coll.hidden);
14792 var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
14793 if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
14794 delete coll.min; delete coll.max; coll.width = +coll.width;
14795 if(!seencol && coll.width) { seencol = true; find_mdw_colw(coll.width); }
14796 process_col(coll);
14797 while(colm <= colM) columns[colm++] = dup(coll);
14798 }
14799}
14800function write_ws_xml_cols(ws, cols)/*:string*/ {
14801 var o = ["<cols>"], col;
14802 for(var i = 0; i != cols.length; ++i) {
14803 if(!(col = cols[i])) continue;
14804 o[o.length] = (writextag('col', null, col_obj_w(i, col)));
14805 }
14806 o[o.length] = "</cols>";
14807 return o.join("");
14808}
14809
14810function parse_ws_xml_autofilter(data/*:string*/) {
14811 var o = { ref: (data.match(/ref="([^"]*)"/)||[])[1]};
14812 return o;
14813}
14814function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
14815 var ref = typeof data.ref == "string" ? data.ref : encode_range(data.ref);
14816 if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
14817 if(!wb.Workbook.Names) wb.Workbook.Names = [];
14818 var names/*: Array<any> */ = wb.Workbook.Names;
14819 var range = decode_range(ref);
14820 if(range.s.r == range.e.r) { range.e.r = decode_range(ws["!ref"]).e.r; ref = encode_range(range); }
14821 for(var i = 0; i < names.length; ++i) {
14822 var name = names[i];
14823 if(name.Name != '_xlnm._FilterDatabase') continue;
14824 if(name.Sheet != idx) continue;
14825 name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref; break;
14826 }
14827 if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: "'" + wb.SheetNames[idx] + "'!" + ref });
14828 return writextag("autoFilter", null, {ref:ref});
14829}
14830
14831/* 18.3.1.88 sheetViews CT_SheetViews */
14832/* 18.3.1.87 sheetView CT_SheetView */
14833var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/;
14834function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
14835 if(!wb.Views) wb.Views = [{}];
14836 (data.match(sviewregex)||[]).forEach(function(r/*:string*/, i/*:number*/) {
14837 var tag = parsexmltag(r);
14838 // $FlowIgnore
14839 if(!wb.Views[i]) wb.Views[i] = {};
14840 // $FlowIgnore
14841 if(+tag.zoomScale) wb.Views[i].zoom = +tag.zoomScale;
14842 // $FlowIgnore
14843 if(parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
14844 });
14845}
14846function write_ws_xml_sheetviews(ws, opts, idx, wb)/*:string*/ {
14847 var sview = ({workbookViewId:"0"}/*:any*/);
14848 // $FlowIgnore
14849 if((((wb||{}).Workbook||{}).Views||[])[0]) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
14850 return writextag("sheetViews", writextag("sheetView", null, sview), {});
14851}
14852
14853function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts/*::, idx, wb*/)/*:string*/ {
14854 if(cell.c) ws['!comments'].push([ref, cell.c]);
14855 if(cell.v === undefined && typeof cell.f !== "string" || cell.t === 'z' && !cell.f) return "";
14856 var vv = "";
14857 var oldt = cell.t, oldv = cell.v;
14858 if(cell.t !== "z") switch(cell.t) {
14859 case 'b': vv = cell.v ? "1" : "0"; break;
14860 case 'n': vv = ''+cell.v; break;
14861 case 'e': vv = BErr[cell.v]; break;
14862 case 'd':
14863 if(opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();
14864 else {
14865 cell = dup(cell);
14866 cell.t = 'n';
14867 vv = ''+(cell.v = datenum(parseDate(cell.v)));
14868 }
14869 if(typeof cell.z === 'undefined') cell.z = table_fmt[14];
14870 break;
14871 default: vv = cell.v; break;
14872 }
14873 var v = writetag('v', escapexml(vv)), o = ({r:ref}/*:any*/);
14874 /* TODO: cell style */
14875 var os = get_cell_style(opts.cellXfs, cell, opts);
14876 if(os !== 0) o.s = os;
14877 switch(cell.t) {
14878 case 'n': break;
14879 case 'd': o.t = "d"; break;
14880 case 'b': o.t = "b"; break;
14881 case 'e': o.t = "e"; break;
14882 case 'z': break;
14883 default: if(cell.v == null) { delete cell.t; break; }
14884 if(cell.v.length > 32767) throw new Error("Text length must not exceed 32767 characters");
14885 if(opts && opts.bookSST) {
14886 v = writetag('v', ''+get_sst_id(opts.Strings, cell.v, opts.revStrings));
14887 o.t = "s"; break;
14888 }
14889 o.t = "str"; break;
14890 }
14891 if(cell.t != oldt) { cell.t = oldt; cell.v = oldv; }
14892 if(typeof cell.f == "string" && cell.f) {
14893 var ff = cell.F && cell.F.slice(0, ref.length) == ref ? {t:"array", ref:cell.F} : null;
14894 v = writextag('f', escapexml(cell.f), ff) + (cell.v != null ? v : "");
14895 }
14896 if(cell.l) ws['!links'].push([ref, cell.l]);
14897 if(cell.D) o.cm = 1;
14898 return writextag('c', v, o);
14899}
14900
14901var parse_ws_xml_data = /*#__PURE__*/(function() {
14902 var cellregex = /<(?:\w+:)?c[ \/>]/, rowregex = /<\/(?:\w+:)?row>/;
14903 var rregex = /r=["']([^"']*)["']/, isregex = /<(?:\w+:)?is>([\S\s]*?)<\/(?:\w+:)?is>/;
14904 var refregex = /ref=["']([^"']*)["']/;
14905 var match_v = matchtag("v"), match_f = matchtag("f");
14906
14907return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, themes, styles) {
14908 var ri = 0, x = "", cells/*:Array<string>*/ = [], cref/*:?Array<string>*/ = [], idx=0, i=0, cc=0, d="", p/*:any*/;
14909 var tag, tagr = 0, tagc = 0;
14910 var sstr, ftag;
14911 var fmtid = 0, fillid = 0;
14912 var do_format = Array.isArray(styles.CellXf), cf;
14913 var arrayf/*:Array<[Range, string]>*/ = [];
14914 var sharedf = [];
14915 var dense = Array.isArray(s);
14916 var rows/*:Array<RowInfo>*/ = [], rowobj = {}, rowrite = false;
14917 var sheetStubs = !!opts.sheetStubs;
14918 for(var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
14919 x = marr[mt].trim();
14920 var xlen = x.length;
14921 if(xlen === 0) continue;
14922
14923 /* 18.3.1.73 row CT_Row */
14924 var rstarti = 0;
14925 outa: for(ri = 0; ri < xlen; ++ri) switch(/*x.charCodeAt(ri)*/x[ri]) {
14926 case ">" /*62*/:
14927 if(/*x.charCodeAt(ri-1) != 47*/x[ri-1] != "/") { ++ri; break outa; }
14928 if(opts && opts.cellStyles) {
14929 // TODO: avoid duplication
14930 tag = parsexmltag(x.slice(rstarti,ri), true);
14931 tagr = tag.r != null ? parseInt(tag.r, 10) : tagr+1; tagc = -1;
14932 if(opts.sheetRows && opts.sheetRows < tagr) continue;
14933 rowobj = {}; rowrite = false;
14934 if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
14935 if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
14936 if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
14937 if(rowrite) rows[tagr-1] = rowobj;
14938 }
14939 break;
14940 case "<" /*60*/: rstarti = ri; break;
14941 }
14942 if(rstarti >= ri) break;
14943 tag = parsexmltag(x.slice(rstarti,ri), true);
14944 tagr = tag.r != null ? parseInt(tag.r, 10) : tagr+1; tagc = -1;
14945 if(opts.sheetRows && opts.sheetRows < tagr) continue;
14946 if(guess.s.r > tagr - 1) guess.s.r = tagr - 1;
14947 if(guess.e.r < tagr - 1) guess.e.r = tagr - 1;
14948
14949 if(opts && opts.cellStyles) {
14950 rowobj = {}; rowrite = false;
14951 if(tag.ht) { rowrite = true; rowobj.hpt = parseFloat(tag.ht); rowobj.hpx = pt2px(rowobj.hpt); }
14952 if(tag.hidden == "1") { rowrite = true; rowobj.hidden = true; }
14953 if(tag.outlineLevel != null) { rowrite = true; rowobj.level = +tag.outlineLevel; }
14954 if(rowrite) rows[tagr-1] = rowobj;
14955 }
14956
14957 /* 18.3.1.4 c CT_Cell */
14958 cells = x.slice(ri).split(cellregex);
14959 for(var rslice = 0; rslice != cells.length; ++rslice) if(cells[rslice].trim().charAt(0) != "<") break;
14960 cells = cells.slice(rslice);
14961 for(ri = 0; ri != cells.length; ++ri) {
14962 x = cells[ri].trim();
14963 if(x.length === 0) continue;
14964 cref = x.match(rregex); idx = ri; i=0; cc=0;
14965 x = "<c " + (x.slice(0,1)=="<"?">":"") + x;
14966 if(cref != null && cref.length === 2) {
14967 idx = 0; d=cref[1];
14968 for(i=0; i != d.length; ++i) {
14969 if((cc=d.charCodeAt(i)-64) < 1 || cc > 26) break;
14970 idx = 26*idx + cc;
14971 }
14972 --idx;
14973 tagc = idx;
14974 } else ++tagc;
14975 for(i = 0; i != x.length; ++i) if(x.charCodeAt(i) === 62) break; ++i;
14976 tag = parsexmltag(x.slice(0,i), true);
14977 if(!tag.r) tag.r = encode_cell({r:tagr-1, c:tagc});
14978 d = x.slice(i);
14979 p = ({t:""}/*:any*/);
14980
14981 if((cref=d.match(match_v))!= null && /*::cref != null && */cref[1] !== '') p.v=unescapexml(cref[1]);
14982 if(opts.cellFormula) {
14983 if((cref=d.match(match_f))!= null && /*::cref != null && */cref[1] !== '') {
14984 /* TODO: match against XLSXFutureFunctions */
14985 p.f=unescapexml(utf8read(cref[1])).replace(/\r\n/g, "\n");
14986 if(!opts.xlfn) p.f = _xlfn(p.f);
14987 if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="array"') > -1) {
14988 p.F = (d.match(refregex)||[])[1];
14989 if(p.F.indexOf(":") > -1) arrayf.push([safe_decode_range(p.F), p.F]);
14990 } else if(/*::cref != null && cref[0] != null && */cref[0].indexOf('t="shared"') > -1) {
14991 // TODO: parse formula
14992 ftag = parsexmltag(cref[0]);
14993 var ___f = unescapexml(utf8read(cref[1]));
14994 if(!opts.xlfn) ___f = _xlfn(___f);
14995 sharedf[parseInt(ftag.si, 10)] = [ftag, ___f, tag.r];
14996 }
14997 } else if((cref=d.match(/<f[^>]*\/>/))) {
14998 ftag = parsexmltag(cref[0]);
14999 if(sharedf[ftag.si]) p.f = shift_formula_xlsx(sharedf[ftag.si][1], sharedf[ftag.si][2]/*[0].ref*/, tag.r);
15000 }
15001 /* TODO: factor out contains logic */
15002 var _tag = decode_cell(tag.r);
15003 for(i = 0; i < arrayf.length; ++i)
15004 if(_tag.r >= arrayf[i][0].s.r && _tag.r <= arrayf[i][0].e.r)
15005 if(_tag.c >= arrayf[i][0].s.c && _tag.c <= arrayf[i][0].e.c)
15006 p.F = arrayf[i][1];
15007 }
15008
15009 if(tag.t == null && p.v === undefined) {
15010 if(p.f || p.F) {
15011 p.v = 0; p.t = "n";
15012 } else if(!sheetStubs) continue;
15013 else p.t = "z";
15014 }
15015 else p.t = tag.t || "n";
15016 if(guess.s.c > tagc) guess.s.c = tagc;
15017 if(guess.e.c < tagc) guess.e.c = tagc;
15018 /* 18.18.11 t ST_CellType */
15019 switch(p.t) {
15020 case 'n':
15021 if(p.v == "" || p.v == null) {
15022 if(!sheetStubs) continue;
15023 p.t = 'z';
15024 } else p.v = parseFloat(p.v);
15025 break;
15026 case 's':
15027 if(typeof p.v == 'undefined') {
15028 if(!sheetStubs) continue;
15029 p.t = 'z';
15030 } else {
15031 sstr = strs[parseInt(p.v, 10)];
15032 p.v = sstr.t;
15033 p.r = sstr.r;
15034 if(opts.cellHTML) p.h = sstr.h;
15035 }
15036 break;
15037 case 'str':
15038 p.t = "s";
15039 p.v = (p.v!=null) ? utf8read(p.v) : '';
15040 if(opts.cellHTML) p.h = escapehtml(p.v);
15041 break;
15042 case 'inlineStr':
15043 cref = d.match(isregex);
15044 p.t = 's';
15045 if(cref != null && (sstr = parse_si(cref[1]))) {
15046 p.v = sstr.t;
15047 if(opts.cellHTML) p.h = sstr.h;
15048 } else p.v = "";
15049 break;
15050 case 'b': p.v = parsexmlbool(p.v); break;
15051 case 'd':
15052 if(opts.cellDates) p.v = parseDate(p.v, 1);
15053 else { p.v = datenum(parseDate(p.v, 1)); p.t = 'n'; }
15054 break;
15055 /* error string in .w, number in .v */
15056 case 'e':
15057 if(!opts || opts.cellText !== false) p.w = p.v;
15058 p.v = RBErr[p.v]; break;
15059 }
15060 /* formatting */
15061 fmtid = fillid = 0;
15062 cf = null;
15063 if(do_format && tag.s !== undefined) {
15064 cf = styles.CellXf[tag.s];
15065 if(cf != null) {
15066 if(cf.numFmtId != null) fmtid = cf.numFmtId;
15067 if(opts.cellStyles) {
15068 if(cf.fillId != null) fillid = cf.fillId;
15069 }
15070 }
15071 }
15072 safe_format(p, fmtid, fillid, opts, themes, styles);
15073 if(opts.cellDates && do_format && p.t == 'n' && fmt_is_date(table_fmt[fmtid])) { p.t = 'd'; p.v = numdate(p.v); }
15074 if(tag.cm && opts.xlmeta) {
15075 var cm = (opts.xlmeta.Cell||[])[+tag.cm-1];
15076 if(cm && cm.type == 'XLDAPR') p.D = true;
15077 }
15078 if(dense) {
15079 var _r = decode_cell(tag.r);
15080 if(!s[_r.r]) s[_r.r] = [];
15081 s[_r.r][_r.c] = p;
15082 } else s[tag.r] = p;
15083 }
15084 }
15085 if(rows.length > 0) s['!rows'] = rows;
15086}; })();
15087
15088function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*//*::, rels*/)/*:string*/ {
15089 var o/*:Array<string>*/ = [], r/*:Array<string>*/ = [], range = safe_decode_range(ws['!ref']), cell="", ref, rr = "", cols/*:Array<string>*/ = [], R=0, C=0, rows = ws['!rows'];
15090 var dense = Array.isArray(ws);
15091 var params = ({r:rr}/*:any*/), row/*:RowInfo*/, height = -1;
15092 for(C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
15093 for(R = range.s.r; R <= range.e.r; ++R) {
15094 r = [];
15095 rr = encode_row(R);
15096 for(C = range.s.c; C <= range.e.c; ++C) {
15097 ref = cols[C] + rr;
15098 var _cell = dense ? (ws[R]||[])[C]: ws[ref];
15099 if(_cell === undefined) continue;
15100 if((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
15101 }
15102 if(r.length > 0 || (rows && rows[R])) {
15103 params = ({r:rr}/*:any*/);
15104 if(rows && rows[R]) {
15105 row = rows[R];
15106 if(row.hidden) params.hidden = 1;
15107 height = -1;
15108 if(row.hpx) height = px2pt(row.hpx);
15109 else if(row.hpt) height = row.hpt;
15110 if(height > -1) { params.ht = height; params.customHeight = 1; }
15111 if(row.level) { params.outlineLevel = row.level; }
15112 }
15113 o[o.length] = (writextag('row', r.join(""), params));
15114 }
15115 }
15116 if(rows) for(; R < rows.length; ++R) {
15117 if(rows && rows[R]) {
15118 params = ({r:R+1}/*:any*/);
15119 row = rows[R];
15120 if(row.hidden) params.hidden = 1;
15121 height = -1;
15122 if (row.hpx) height = px2pt(row.hpx);
15123 else if (row.hpt) height = row.hpt;
15124 if (height > -1) { params.ht = height; params.customHeight = 1; }
15125 if (row.level) { params.outlineLevel = row.level; }
15126 o[o.length] = (writextag('row', "", params));
15127 }
15128 }
15129 return o.join("");
15130}
15131
15132function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
15133 var o = [XML_HEADER, writextag('worksheet', null, {
15134 'xmlns': XMLNS_main[0],
15135 'xmlns:r': XMLNS.r
15136 })];
15137 var s = wb.SheetNames[idx], sidx = 0, rdata = "";
15138 var ws = wb.Sheets[s];
15139 if(ws == null) ws = {};
15140 var ref = ws['!ref'] || 'A1';
15141 var range = safe_decode_range(ref);
15142 if(range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
15143 if(opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
15144 range.e.c = Math.min(range.e.c, 0x3FFF);
15145 range.e.r = Math.min(range.e.c, 0xFFFFF);
15146 ref = encode_range(range);
15147 }
15148 if(!rels) rels = {};
15149 ws['!comments'] = [];
15150 var _drawing = [];
15151
15152 write_ws_xml_sheetpr(ws, wb, idx, opts, o);
15153
15154 o[o.length] = (writextag('dimension', null, {'ref': ref}));
15155
15156 o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);
15157
15158 /* TODO: store in WB, process styles */
15159 if(opts.sheetFormat) o[o.length] = (writextag('sheetFormatPr', null, {
15160 defaultRowHeight:opts.sheetFormat.defaultRowHeight||'16',
15161 baseColWidth:opts.sheetFormat.baseColWidth||'10',
15162 outlineLevelRow:opts.sheetFormat.outlineLevelRow||'7'
15163 }));
15164
15165 if(ws['!cols'] != null && ws['!cols'].length > 0) o[o.length] = (write_ws_xml_cols(ws, ws['!cols']));
15166
15167 o[sidx = o.length] = '<sheetData/>';
15168 ws['!links'] = [];
15169 if(ws['!ref'] != null) {
15170 rdata = write_ws_xml_data(ws, opts, idx, wb, rels);
15171 if(rdata.length > 0) o[o.length] = (rdata);
15172 }
15173 if(o.length>sidx+1) { o[o.length] = ('</sheetData>'); o[sidx]=o[sidx].replace("/>",">"); }
15174
15175 /* sheetCalcPr */
15176
15177 if(ws['!protect']) o[o.length] = write_ws_xml_protection(ws['!protect']);
15178
15179 /* protectedRanges */
15180 /* scenarios */
15181
15182 if(ws['!autofilter'] != null) o[o.length] = write_ws_xml_autofilter(ws['!autofilter'], ws, wb, idx);
15183
15184 /* sortState */
15185 /* dataConsolidate */
15186 /* customSheetViews */
15187
15188 if(ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = (write_ws_xml_merges(ws['!merges']));
15189
15190 /* phoneticPr */
15191 /* conditionalFormatting */
15192 /* dataValidations */
15193
15194 var relc = -1, rel, rId = -1;
15195 if(/*::(*/ws['!links']/*::||[])*/.length > 0) {
15196 o[o.length] = "<hyperlinks>";
15197 /*::(*/ws['!links']/*::||[])*/.forEach(function(l) {
15198 if(!l[1].Target) return;
15199 rel = ({"ref":l[0]}/*:any*/);
15200 if(l[1].Target.charAt(0) != "#") {
15201 rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#.*$/, ""), RELS.HLINK);
15202 rel["r:id"] = "rId"+rId;
15203 }
15204 if((relc = l[1].Target.indexOf("#")) > -1) rel.location = escapexml(l[1].Target.slice(relc+1));
15205 if(l[1].Tooltip) rel.tooltip = escapexml(l[1].Tooltip);
15206 o[o.length] = writextag("hyperlink",null,rel);
15207 });
15208 o[o.length] = "</hyperlinks>";
15209 }
15210 delete ws['!links'];
15211
15212 /* printOptions */
15213
15214 if(ws['!margins'] != null) o[o.length] = write_ws_xml_margins(ws['!margins']);
15215
15216 /* pageSetup */
15217 /* headerFooter */
15218 /* rowBreaks */
15219 /* colBreaks */
15220 /* customProperties */
15221 /* cellWatches */
15222
15223 if(!opts || opts.ignoreEC || (opts.ignoreEC == (void 0))) o[o.length] = writetag("ignoredErrors", writextag("ignoredError", null, {numberStoredAsText:1, sqref:ref}));
15224
15225 /* smartTags */
15226
15227 if(_drawing.length > 0) {
15228 rId = add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
15229 o[o.length] = writextag("drawing", null, {"r:id":"rId" + rId});
15230 ws['!drawing'] = _drawing;
15231 }
15232
15233 if(ws['!comments'].length > 0) {
15234 rId = add_rels(rels, -1, "../drawings/vmlDrawing" + (idx+1) + ".vml", RELS.VML);
15235 o[o.length] = writextag("legacyDrawing", null, {"r:id":"rId" + rId});
15236 ws['!legacy'] = rId;
15237 }
15238
15239 /* legacyDrawingHF */
15240 /* picture */
15241 /* oleObjects */
15242 /* controls */
15243 /* webPublishItems */
15244 /* tableParts */
15245 /* extLst */
15246
15247 if(o.length>1) { o[o.length] = ('</worksheet>'); o[1]=o[1].replace("/>",">"); }
15248 return o.join("");
15249}
15250
15251/* [MS-XLSB] 2.4.726 BrtRowHdr */
15252function parse_BrtRowHdr(data, length) {
15253 var z = ({}/*:any*/);
15254 var tgt = data.l + length;
15255 z.r = data.read_shift(4);
15256 data.l += 4; // TODO: ixfe
15257 var miyRw = data.read_shift(2);
15258 data.l += 1; // TODO: top/bot padding
15259 var flags = data.read_shift(1);
15260 data.l = tgt;
15261 if(flags & 0x07) z.level = flags & 0x07;
15262 if(flags & 0x10) z.hidden = true;
15263 if(flags & 0x20) z.hpt = miyRw / 20;
15264 return z;
15265}
15266function write_BrtRowHdr(R/*:number*/, range, ws) {
15267 var o = new_buf(17+8*16);
15268 var row = (ws['!rows']||[])[R]||{};
15269 o.write_shift(4, R);
15270
15271 o.write_shift(4, 0); /* TODO: ixfe */
15272
15273 var miyRw = 0x0140;
15274 if(row.hpx) miyRw = px2pt(row.hpx) * 20;
15275 else if(row.hpt) miyRw = row.hpt * 20;
15276 o.write_shift(2, miyRw);
15277
15278 o.write_shift(1, 0); /* top/bot padding */
15279
15280 var flags = 0x0;
15281 if(row.level) flags |= row.level;
15282 if(row.hidden) flags |= 0x10;
15283 if(row.hpx || row.hpt) flags |= 0x20;
15284 o.write_shift(1, flags);
15285
15286 o.write_shift(1, 0); /* phonetic guide */
15287
15288 /* [MS-XLSB] 2.5.8 BrtColSpan explains the mechanism */
15289 var ncolspan = 0, lcs = o.l;
15290 o.l += 4;
15291
15292 var caddr = {r:R, c:0};
15293 for(var i = 0; i < 16; ++i) {
15294 if((range.s.c > ((i+1) << 10)) || (range.e.c < (i << 10))) continue;
15295 var first = -1, last = -1;
15296 for(var j = (i<<10); j < ((i+1)<<10); ++j) {
15297 caddr.c = j;
15298 var cell = Array.isArray(ws) ? (ws[caddr.r]||[])[caddr.c] : ws[encode_cell(caddr)];
15299 if(cell) { if(first < 0) first = j; last = j; }
15300 }
15301 if(first < 0) continue;
15302 ++ncolspan;
15303 o.write_shift(4, first);
15304 o.write_shift(4, last);
15305 }
15306
15307 var l = o.l;
15308 o.l = lcs;
15309 o.write_shift(4, ncolspan);
15310 o.l = l;
15311
15312 return o.length > o.l ? o.slice(0, o.l) : o;
15313}
15314function write_row_header(ba, ws, range, R) {
15315 var o = write_BrtRowHdr(R, range, ws);
15316 if((o.length > 17) || (ws['!rows']||[])[R]) write_record(ba, 0x0000 /* BrtRowHdr */, o);
15317}
15318
15319/* [MS-XLSB] 2.4.820 BrtWsDim */
15320var parse_BrtWsDim = parse_UncheckedRfX;
15321var write_BrtWsDim = write_UncheckedRfX;
15322
15323/* [MS-XLSB] 2.4.821 BrtWsFmtInfo */
15324function parse_BrtWsFmtInfo(/*::data, length*/) {
15325}
15326//function write_BrtWsFmtInfo(ws, o) { }
15327
15328/* [MS-XLSB] 2.4.823 BrtWsProp */
15329function parse_BrtWsProp(data, length) {
15330 var z = {};
15331 var f = data[data.l]; ++data.l;
15332 z.above = !(f & 0x40);
15333 z.left = !(f & 0x80);
15334 /* TODO: pull flags */
15335 data.l += 18;
15336 z.name = parse_XLSBCodeName(data, length - 19);
15337 return z;
15338}
15339function write_BrtWsProp(str, outl, o) {
15340 if(o == null) o = new_buf(84+4*str.length);
15341 var f = 0xC0;
15342 if(outl) {
15343 if(outl.above) f &= ~0x40;
15344 if(outl.left) f &= ~0x80;
15345 }
15346 o.write_shift(1, f);
15347 for(var i = 1; i < 3; ++i) o.write_shift(1,0);
15348 write_BrtColor({auto:1}, o);
15349 o.write_shift(-4,-1);
15350 o.write_shift(-4,-1);
15351 write_XLSBCodeName(str, o);
15352 return o.slice(0, o.l);
15353}
15354
15355/* [MS-XLSB] 2.4.306 BrtCellBlank */
15356function parse_BrtCellBlank(data) {
15357 var cell = parse_XLSBCell(data);
15358 return [cell];
15359}
15360function write_BrtCellBlank(cell, ncell, o) {
15361 if(o == null) o = new_buf(8);
15362 return write_XLSBCell(ncell, o);
15363}
15364function parse_BrtShortBlank(data) {
15365 var cell = parse_XLSBShortCell(data);
15366 return [cell];
15367}
15368function write_BrtShortBlank(cell, ncell, o) {
15369 if(o == null) o = new_buf(4);
15370 return write_XLSBShortCell(ncell, o);
15371}
15372
15373/* [MS-XLSB] 2.4.307 BrtCellBool */
15374function parse_BrtCellBool(data) {
15375 var cell = parse_XLSBCell(data);
15376 var fBool = data.read_shift(1);
15377 return [cell, fBool, 'b'];
15378}
15379function write_BrtCellBool(cell, ncell, o) {
15380 if(o == null) o = new_buf(9);
15381 write_XLSBCell(ncell, o);
15382 o.write_shift(1, cell.v ? 1 : 0);
15383 return o;
15384}
15385function parse_BrtShortBool(data) {
15386 var cell = parse_XLSBShortCell(data);
15387 var fBool = data.read_shift(1);
15388 return [cell, fBool, 'b'];
15389}
15390function write_BrtShortBool(cell, ncell, o) {
15391 if(o == null) o = new_buf(5);
15392 write_XLSBShortCell(ncell, o);
15393 o.write_shift(1, cell.v ? 1 : 0);
15394 return o;
15395}
15396
15397/* [MS-XLSB] 2.4.308 BrtCellError */
15398function parse_BrtCellError(data) {
15399 var cell = parse_XLSBCell(data);
15400 var bError = data.read_shift(1);
15401 return [cell, bError, 'e'];
15402}
15403function write_BrtCellError(cell, ncell, o) {
15404 if(o == null) o = new_buf(9);
15405 write_XLSBCell(ncell, o);
15406 o.write_shift(1, cell.v);
15407 return o;
15408}
15409function parse_BrtShortError(data) {
15410 var cell = parse_XLSBShortCell(data);
15411 var bError = data.read_shift(1);
15412 return [cell, bError, 'e'];
15413}
15414function write_BrtShortError(cell, ncell, o) {
15415 if(o == null) o = new_buf(8);
15416 write_XLSBShortCell(ncell, o);
15417 o.write_shift(1, cell.v);
15418 o.write_shift(2, 0);
15419 o.write_shift(1, 0);
15420 return o;
15421}
15422
15423
15424/* [MS-XLSB] 2.4.311 BrtCellIsst */
15425function parse_BrtCellIsst(data) {
15426 var cell = parse_XLSBCell(data);
15427 var isst = data.read_shift(4);
15428 return [cell, isst, 's'];
15429}
15430function write_BrtCellIsst(cell, ncell, o) {
15431 if(o == null) o = new_buf(12);
15432 write_XLSBCell(ncell, o);
15433 o.write_shift(4, ncell.v);
15434 return o;
15435}
15436function parse_BrtShortIsst(data) {
15437 var cell = parse_XLSBShortCell(data);
15438 var isst = data.read_shift(4);
15439 return [cell, isst, 's'];
15440}
15441function write_BrtShortIsst(cell, ncell, o) {
15442 if(o == null) o = new_buf(8);
15443 write_XLSBShortCell(ncell, o);
15444 o.write_shift(4, ncell.v);
15445 return o;
15446}
15447
15448/* [MS-XLSB] 2.4.313 BrtCellReal */
15449function parse_BrtCellReal(data) {
15450 var cell = parse_XLSBCell(data);
15451 var value = parse_Xnum(data);
15452 return [cell, value, 'n'];
15453}
15454function write_BrtCellReal(cell, ncell, o) {
15455 if(o == null) o = new_buf(16);
15456 write_XLSBCell(ncell, o);
15457 write_Xnum(cell.v, o);
15458 return o;
15459}
15460function parse_BrtShortReal(data) {
15461 var cell = parse_XLSBShortCell(data);
15462 var value = parse_Xnum(data);
15463 return [cell, value, 'n'];
15464}
15465function write_BrtShortReal(cell, ncell, o) {
15466 if(o == null) o = new_buf(12);
15467 write_XLSBShortCell(ncell, o);
15468 write_Xnum(cell.v, o);
15469 return o;
15470}
15471
15472/* [MS-XLSB] 2.4.314 BrtCellRk */
15473function parse_BrtCellRk(data) {
15474 var cell = parse_XLSBCell(data);
15475 var value = parse_RkNumber(data);
15476 return [cell, value, 'n'];
15477}
15478function write_BrtCellRk(cell, ncell, o) {
15479 if(o == null) o = new_buf(12);
15480 write_XLSBCell(ncell, o);
15481 write_RkNumber(cell.v, o);
15482 return o;
15483}
15484function parse_BrtShortRk(data) {
15485 var cell = parse_XLSBShortCell(data);
15486 var value = parse_RkNumber(data);
15487 return [cell, value, 'n'];
15488}
15489function write_BrtShortRk(cell, ncell, o) {
15490 if(o == null) o = new_buf(8);
15491 write_XLSBShortCell(ncell, o);
15492 write_RkNumber(cell.v, o);
15493 return o;
15494}
15495
15496/* [MS-XLSB] 2.4.323 BrtCellRString */
15497function parse_BrtCellRString(data) {
15498 var cell = parse_XLSBCell(data);
15499 var value = parse_RichStr(data);
15500 return [cell, value, 'is'];
15501}
15502
15503/* [MS-XLSB] 2.4.317 BrtCellSt */
15504function parse_BrtCellSt(data) {
15505 var cell = parse_XLSBCell(data);
15506 var value = parse_XLWideString(data);
15507 return [cell, value, 'str'];
15508}
15509function write_BrtCellSt(cell, ncell, o) {
15510 if(o == null) o = new_buf(12 + 4 * cell.v.length);
15511 write_XLSBCell(ncell, o);
15512 write_XLWideString(cell.v, o);
15513 return o.length > o.l ? o.slice(0, o.l) : o;
15514}
15515function parse_BrtShortSt(data) {
15516 var cell = parse_XLSBShortCell(data);
15517 var value = parse_XLWideString(data);
15518 return [cell, value, 'str'];
15519}
15520function write_BrtShortSt(cell, ncell, o) {
15521 if(o == null) o = new_buf(8 + 4 * cell.v.length);
15522 write_XLSBShortCell(ncell, o);
15523 write_XLWideString(cell.v, o);
15524 return o.length > o.l ? o.slice(0, o.l) : o;
15525}
15526
15527/* [MS-XLSB] 2.4.653 BrtFmlaBool */
15528function parse_BrtFmlaBool(data, length, opts) {
15529 var end = data.l + length;
15530 var cell = parse_XLSBCell(data);
15531 cell.r = opts['!row'];
15532 var value = data.read_shift(1);
15533 var o = [cell, value, 'b'];
15534 if(opts.cellFormula) {
15535 data.l += 2;
15536 var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
15537 o[3] = stringify_formula(formula, null/*range*/, cell, opts.supbooks, opts);/* TODO */
15538 }
15539 else data.l = end;
15540 return o;
15541}
15542
15543/* [MS-XLSB] 2.4.654 BrtFmlaError */
15544function parse_BrtFmlaError(data, length, opts) {
15545 var end = data.l + length;
15546 var cell = parse_XLSBCell(data);
15547 cell.r = opts['!row'];
15548 var value = data.read_shift(1);
15549 var o = [cell, value, 'e'];
15550 if(opts.cellFormula) {
15551 data.l += 2;
15552 var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
15553 o[3] = stringify_formula(formula, null/*range*/, cell, opts.supbooks, opts);/* TODO */
15554 }
15555 else data.l = end;
15556 return o;
15557}
15558
15559/* [MS-XLSB] 2.4.655 BrtFmlaNum */
15560function parse_BrtFmlaNum(data, length, opts) {
15561 var end = data.l + length;
15562 var cell = parse_XLSBCell(data);
15563 cell.r = opts['!row'];
15564 var value = parse_Xnum(data);
15565 var o = [cell, value, 'n'];
15566 if(opts.cellFormula) {
15567 data.l += 2;
15568 var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
15569 o[3] = stringify_formula(formula, null/*range*/, cell, opts.supbooks, opts);/* TODO */
15570 }
15571 else data.l = end;
15572 return o;
15573}
15574
15575/* [MS-XLSB] 2.4.656 BrtFmlaString */
15576function parse_BrtFmlaString(data, length, opts) {
15577 var end = data.l + length;
15578 var cell = parse_XLSBCell(data);
15579 cell.r = opts['!row'];
15580 var value = parse_XLWideString(data);
15581 var o = [cell, value, 'str'];
15582 if(opts.cellFormula) {
15583 data.l += 2;
15584 var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
15585 o[3] = stringify_formula(formula, null/*range*/, cell, opts.supbooks, opts);/* TODO */
15586 }
15587 else data.l = end;
15588 return o;
15589}
15590
15591/* [MS-XLSB] 2.4.682 BrtMergeCell */
15592var parse_BrtMergeCell = parse_UncheckedRfX;
15593var write_BrtMergeCell = write_UncheckedRfX;
15594/* [MS-XLSB] 2.4.107 BrtBeginMergeCells */
15595function write_BrtBeginMergeCells(cnt, o) {
15596 if(o == null) o = new_buf(4);
15597 o.write_shift(4, cnt);
15598 return o;
15599}
15600
15601/* [MS-XLSB] 2.4.662 BrtHLink */
15602function parse_BrtHLink(data, length/*::, opts*/) {
15603 var end = data.l + length;
15604 var rfx = parse_UncheckedRfX(data, 16);
15605 var relId = parse_XLNullableWideString(data);
15606 var loc = parse_XLWideString(data);
15607 var tooltip = parse_XLWideString(data);
15608 var display = parse_XLWideString(data);
15609 data.l = end;
15610 var o = ({rfx:rfx, relId:relId, loc:loc, display:display}/*:any*/);
15611 if(tooltip) o.Tooltip = tooltip;
15612 return o;
15613}
15614function write_BrtHLink(l, rId) {
15615 var o = new_buf(50+4*(l[1].Target.length + (l[1].Tooltip || "").length));
15616 write_UncheckedRfX({s:decode_cell(l[0]), e:decode_cell(l[0])}, o);
15617 write_RelID("rId" + rId, o);
15618 var locidx = l[1].Target.indexOf("#");
15619 var loc = locidx == -1 ? "" : l[1].Target.slice(locidx+1);
15620 write_XLWideString(loc || "", o);
15621 write_XLWideString(l[1].Tooltip || "", o);
15622 write_XLWideString("", o);
15623 return o.slice(0, o.l);
15624}
15625
15626/* [MS-XLSB] 2.4.692 BrtPane */
15627function parse_BrtPane(/*data, length, opts*/) {
15628}
15629
15630/* [MS-XLSB] 2.4.6 BrtArrFmla */
15631function parse_BrtArrFmla(data, length, opts) {
15632 var end = data.l + length;
15633 var rfx = parse_RfX(data, 16);
15634 var fAlwaysCalc = data.read_shift(1);
15635 var o = [rfx]; o[2] = fAlwaysCalc;
15636 if(opts.cellFormula) {
15637 var formula = parse_XLSBArrayParsedFormula(data, end - data.l, opts);
15638 o[1] = formula;
15639 } else data.l = end;
15640 return o;
15641}
15642
15643/* [MS-XLSB] 2.4.750 BrtShrFmla */
15644function parse_BrtShrFmla(data, length, opts) {
15645 var end = data.l + length;
15646 var rfx = parse_UncheckedRfX(data, 16);
15647 var o = [rfx];
15648 if(opts.cellFormula) {
15649 var formula = parse_XLSBSharedParsedFormula(data, end - data.l, opts);
15650 o[1] = formula;
15651 data.l = end;
15652 } else data.l = end;
15653 return o;
15654}
15655
15656/* [MS-XLSB] 2.4.323 BrtColInfo */
15657/* TODO: once XLS ColInfo is set, combine the functions */
15658function write_BrtColInfo(C/*:number*/, col, o) {
15659 if(o == null) o = new_buf(18);
15660 var p = col_obj_w(C, col);
15661 o.write_shift(-4, C);
15662 o.write_shift(-4, C);
15663 o.write_shift(4, (p.width || 10) * 256);
15664 o.write_shift(4, 0/*ixfe*/); // style
15665 var flags = 0;
15666 if(col.hidden) flags |= 0x01;
15667 if(typeof p.width == 'number') flags |= 0x02;
15668 if(col.level) flags |= (col.level << 8);
15669 o.write_shift(2, flags); // bit flag
15670 return o;
15671}
15672
15673/* [MS-XLSB] 2.4.678 BrtMargins */
15674var BrtMarginKeys = ["left","right","top","bottom","header","footer"];
15675function parse_BrtMargins(data/*::, length, opts*/)/*:Margins*/ {
15676 var margins = ({}/*:any*/);
15677 BrtMarginKeys.forEach(function(k) { margins[k] = parse_Xnum(data, 8); });
15678 return margins;
15679}
15680function write_BrtMargins(margins/*:Margins*/, o) {
15681 if(o == null) o = new_buf(6*8);
15682 default_margins(margins);
15683 BrtMarginKeys.forEach(function(k) { write_Xnum((margins/*:any*/)[k], o); });
15684 return o;
15685}
15686
15687/* [MS-XLSB] 2.4.299 BrtBeginWsView */
15688function parse_BrtBeginWsView(data/*::, length, opts*/) {
15689 var f = data.read_shift(2);
15690 data.l += 28;
15691 return { RTL: f & 0x20 };
15692}
15693function write_BrtBeginWsView(ws, Workbook, o) {
15694 if(o == null) o = new_buf(30);
15695 var f = 0x39c;
15696 if((((Workbook||{}).Views||[])[0]||{}).RTL) f |= 0x20;
15697 o.write_shift(2, f); // bit flag
15698 o.write_shift(4, 0);
15699 o.write_shift(4, 0); // view first row
15700 o.write_shift(4, 0); // view first col
15701 o.write_shift(1, 0); // gridline color ICV
15702 o.write_shift(1, 0);
15703 o.write_shift(2, 0);
15704 o.write_shift(2, 100); // zoom scale
15705 o.write_shift(2, 0);
15706 o.write_shift(2, 0);
15707 o.write_shift(2, 0);
15708 o.write_shift(4, 0); // workbook view id
15709 return o;
15710}
15711
15712/* [MS-XLSB] 2.4.309 BrtCellIgnoreEC */
15713function write_BrtCellIgnoreEC(ref) {
15714 var o = new_buf(24);
15715 o.write_shift(4, 4);
15716 o.write_shift(4, 1);
15717 write_UncheckedRfX(ref, o);
15718 return o;
15719}
15720
15721/* [MS-XLSB] 2.4.748 BrtSheetProtection */
15722function write_BrtSheetProtection(sp, o) {
15723 if(o == null) o = new_buf(16*4+2);
15724 o.write_shift(2, sp.password ? crypto_CreatePasswordVerifier_Method1(sp.password) : 0);
15725 o.write_shift(4, 1); // this record should not be written if no protection
15726 [
15727 ["objects", false], // fObjects
15728 ["scenarios", false], // fScenarios
15729 ["formatCells", true], // fFormatCells
15730 ["formatColumns", true], // fFormatColumns
15731 ["formatRows", true], // fFormatRows
15732 ["insertColumns", true], // fInsertColumns
15733 ["insertRows", true], // fInsertRows
15734 ["insertHyperlinks", true], // fInsertHyperlinks
15735 ["deleteColumns", true], // fDeleteColumns
15736 ["deleteRows", true], // fDeleteRows
15737 ["selectLockedCells", false], // fSelLockedCells
15738 ["sort", true], // fSort
15739 ["autoFilter", true], // fAutoFilter
15740 ["pivotTables", true], // fPivotTables
15741 ["selectUnlockedCells", false] // fSelUnlockedCells
15742 ].forEach(function(n) {
15743 /*:: if(o == null) throw "unreachable"; */
15744 if(n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0);
15745 else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1);
15746 });
15747 return o;
15748}
15749
15750function parse_BrtDVal(/*data, length, opts*/) {
15751}
15752function parse_BrtDVal14(/*data, length, opts*/) {
15753}
15754/* [MS-XLSB] 2.1.7.61 Worksheet */
15755function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
15756 if(!data) return data;
15757 var opts = _opts || {};
15758 if(!rels) rels = {'!id':{}};
15759 if(DENSE != null && opts.dense == null) opts.dense = DENSE;
15760 var s/*:Worksheet*/ = (opts.dense ? [] : {});
15761
15762 var ref;
15763 var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
15764
15765 var state/*:Array<string>*/ = [];
15766 var pass = false, end = false;
15767 var row, p, cf, R, C, addr, sstr, rr, cell/*:Cell*/;
15768 var merges/*:Array<Range>*/ = [];
15769 opts.biff = 12;
15770 opts['!row'] = 0;
15771
15772 var ai = 0, af = false;
15773
15774 var arrayf/*:Array<[Range, string]>*/ = [];
15775 var sharedf = {};
15776 var supbooks = opts.supbooks || /*::(*/wb/*:: :any)*/.supbooks || ([[]]/*:any*/);
15777 supbooks.sharedf = sharedf;
15778 supbooks.arrayf = arrayf;
15779 supbooks.SheetNames = wb.SheetNames || wb.Sheets.map(function(x) { return x.name; });
15780 if(!opts.supbooks) {
15781 opts.supbooks = supbooks;
15782 if(wb.Names) for(var i = 0; i < wb.Names.length; ++i) supbooks[0][i+1] = wb.Names[i];
15783 }
15784
15785 var colinfo/*:Array<ColInfo>*/ = [], rowinfo/*:Array<RowInfo>*/ = [];
15786 var seencol = false;
15787
15788 XLSBRecordEnum[0x0010] = { n:"BrtShortReal", f:parse_BrtShortReal };
15789
15790 var cm, vm;
15791
15792 recordhopper(data, function ws_parse(val, RR, RT) {
15793 if(end) return;
15794 switch(RT) {
15795 case 0x0094: /* 'BrtWsDim' */
15796 ref = val; break;
15797 case 0x0000: /* 'BrtRowHdr' */
15798 row = val;
15799 if(opts.sheetRows && opts.sheetRows <= row.r) end=true;
15800 rr = encode_row(R = row.r);
15801 opts['!row'] = row.r;
15802 if(val.hidden || val.hpt || val.level != null) {
15803 if(val.hpt) val.hpx = pt2px(val.hpt);
15804 rowinfo[val.r] = val;
15805 }
15806 break;
15807
15808 case 0x0002: /* 'BrtCellRk' */
15809 case 0x0003: /* 'BrtCellError' */
15810 case 0x0004: /* 'BrtCellBool' */
15811 case 0x0005: /* 'BrtCellReal' */
15812 case 0x0006: /* 'BrtCellSt' */
15813 case 0x0007: /* 'BrtCellIsst' */
15814 case 0x0008: /* 'BrtFmlaString' */
15815 case 0x0009: /* 'BrtFmlaNum' */
15816 case 0x000A: /* 'BrtFmlaBool' */
15817 case 0x000B: /* 'BrtFmlaError' */
15818 case 0x000D: /* 'BrtShortRk' */
15819 case 0x000E: /* 'BrtShortError' */
15820 case 0x000F: /* 'BrtShortBool' */
15821 case 0x0010: /* 'BrtShortReal' */
15822 case 0x0011: /* 'BrtShortSt' */
15823 case 0x0012: /* 'BrtShortIsst' */
15824 case 0x003E: /* 'BrtCellRString' */
15825 p = ({t:val[2]}/*:any*/);
15826 switch(val[2]) {
15827 case 'n': p.v = val[1]; break;
15828 case 's': sstr = strs[val[1]]; p.v = sstr.t; p.r = sstr.r; break;
15829 case 'b': p.v = val[1] ? true : false; break;
15830 case 'e': p.v = val[1]; if(opts.cellText !== false) p.w = BErr[p.v]; break;
15831 case 'str': p.t = 's'; p.v = val[1]; break;
15832 case 'is': p.t = 's'; p.v = val[1].t; break;
15833 }
15834 if((cf = styles.CellXf[val[0].iStyleRef])) safe_format(p,cf.numFmtId,null,opts, themes, styles);
15835 C = val[0].c == -1 ? C + 1 : val[0].c;
15836 if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
15837 else s[encode_col(C) + rr] = p;
15838 if(opts.cellFormula) {
15839 af = false;
15840 for(ai = 0; ai < arrayf.length; ++ai) {
15841 var aii = arrayf[ai];
15842 if(row.r >= aii[0].s.r && row.r <= aii[0].e.r)
15843 if(C >= aii[0].s.c && C <= aii[0].e.c) {
15844 p.F = encode_range(aii[0]); af = true;
15845 }
15846 }
15847 if(!af && val.length > 3) p.f = val[3];
15848 }
15849
15850 if(refguess.s.r > row.r) refguess.s.r = row.r;
15851 if(refguess.s.c > C) refguess.s.c = C;
15852 if(refguess.e.r < row.r) refguess.e.r = row.r;
15853 if(refguess.e.c < C) refguess.e.c = C;
15854 if(opts.cellDates && cf && p.t == 'n' && fmt_is_date(table_fmt[cf.numFmtId])) {
15855 var _d = SSF_parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
15856 }
15857 if(cm) {
15858 if(cm.type == 'XLDAPR') p.D = true;
15859 cm = void 0;
15860 }
15861 if(vm) vm = void 0;
15862 break;
15863
15864 case 0x0001: /* 'BrtCellBlank' */
15865 case 0x000C: /* 'BrtShortBlank' */
15866 if(!opts.sheetStubs || pass) break;
15867 p = ({t:'z',v:void 0}/*:any*/);
15868 C = val[0].c == -1 ? C + 1 : val[0].c;
15869 if(opts.dense) { if(!s[R]) s[R] = []; s[R][C] = p; }
15870 else s[encode_col(C) + rr] = p;
15871 if(refguess.s.r > row.r) refguess.s.r = row.r;
15872 if(refguess.s.c > C) refguess.s.c = C;
15873 if(refguess.e.r < row.r) refguess.e.r = row.r;
15874 if(refguess.e.c < C) refguess.e.c = C;
15875 if(cm) {
15876 if(cm.type == 'XLDAPR') p.D = true;
15877 cm = void 0;
15878 }
15879 if(vm) vm = void 0;
15880 break;
15881
15882 case 0x00B0: /* 'BrtMergeCell' */
15883 merges.push(val); break;
15884
15885 case 0x0031: { /* 'BrtCellMeta' */
15886 cm = ((opts.xlmeta||{}).Cell||[])[val-1];
15887 } break;
15888
15889 case 0x01EE: /* 'BrtHLink' */
15890 var rel = rels['!id'][val.relId];
15891 if(rel) {
15892 val.Target = rel.Target;
15893 if(val.loc) val.Target += "#"+val.loc;
15894 val.Rel = rel;
15895 } else if(val.relId == '') {
15896 val.Target = "#" + val.loc;
15897 }
15898 for(R=val.rfx.s.r;R<=val.rfx.e.r;++R) for(C=val.rfx.s.c;C<=val.rfx.e.c;++C) {
15899 if(opts.dense) {
15900 if(!s[R]) s[R] = [];
15901 if(!s[R][C]) s[R][C] = {t:'z',v:undefined};
15902 s[R][C].l = val;
15903 } else {
15904 addr = encode_cell({c:C,r:R});
15905 if(!s[addr]) s[addr] = {t:'z',v:undefined};
15906 s[addr].l = val;
15907 }
15908 }
15909 break;
15910
15911 case 0x01AA: /* 'BrtArrFmla' */
15912 if(!opts.cellFormula) break;
15913 arrayf.push(val);
15914 cell = ((opts.dense ? s[R][C] : s[encode_col(C) + rr])/*:any*/);
15915 cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts);
15916 cell.F = encode_range(val[0]);
15917 break;
15918 case 0x01AB: /* 'BrtShrFmla' */
15919 if(!opts.cellFormula) break;
15920 sharedf[encode_cell(val[0].s)] = val[1];
15921 cell = (opts.dense ? s[R][C] : s[encode_col(C) + rr]);
15922 cell.f = stringify_formula(val[1], refguess, {r:row.r, c:C}, supbooks, opts);
15923 break;
15924
15925 /* identical to 'ColInfo' in XLS */
15926 case 0x003C: /* 'BrtColInfo' */
15927 if(!opts.cellStyles) break;
15928 while(val.e >= val.s) {
15929 colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01), level: val.level };
15930 if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
15931 process_col(colinfo[val.e+1]);
15932 }
15933 break;
15934
15935 case 0x00A1: /* 'BrtBeginAFilter' */
15936 s['!autofilter'] = { ref:encode_range(val) };
15937 break;
15938
15939 case 0x01DC: /* 'BrtMargins' */
15940 s['!margins'] = val;
15941 break;
15942
15943 case 0x0093: /* 'BrtWsProp' */
15944 if(!wb.Sheets[idx]) wb.Sheets[idx] = {};
15945 if(val.name) wb.Sheets[idx].CodeName = val.name;
15946 if(val.above || val.left) s['!outline'] = { above: val.above, left: val.left };
15947 break;
15948
15949 case 0x0089: /* 'BrtBeginWsView' */
15950 if(!wb.Views) wb.Views = [{}];
15951 if(!wb.Views[0]) wb.Views[0] = {};
15952 if(val.RTL) wb.Views[0].RTL = true;
15953 break;
15954
15955 case 0x01E5: /* 'BrtWsFmtInfo' */
15956 break;
15957
15958 case 0x0040: /* 'BrtDVal' */
15959 case 0x041D: /* 'BrtDVal14' */
15960 break;
15961
15962 case 0x0097: /* 'BrtPane' */
15963 break;
15964 case 0x0098: /* 'BrtSel' */
15965 case 0x00AF: /* 'BrtAFilterDateGroupItem' */
15966 case 0x0284: /* 'BrtActiveX' */
15967 case 0x0271: /* 'BrtBigName' */
15968 case 0x0232: /* 'BrtBkHim' */
15969 case 0x018C: /* 'BrtBrk' */
15970 case 0x0458: /* 'BrtCFIcon' */
15971 case 0x047A: /* 'BrtCFRuleExt' */
15972 case 0x01D7: /* 'BrtCFVO' */
15973 case 0x041A: /* 'BrtCFVO14' */
15974 case 0x0289: /* 'BrtCellIgnoreEC' */
15975 case 0x0451: /* 'BrtCellIgnoreEC14' */
15976 case 0x024D: /* 'BrtCellSmartTagProperty' */
15977 case 0x025F: /* 'BrtCellWatch' */
15978 case 0x0234: /* 'BrtColor' */
15979 case 0x041F: /* 'BrtColor14' */
15980 case 0x00A8: /* 'BrtColorFilter' */
15981 case 0x00AE: /* 'BrtCustomFilter' */
15982 case 0x049C: /* 'BrtCustomFilter14' */
15983 case 0x01F3: /* 'BrtDRef' */
15984 case 0x01FB: /* 'BrtDXF' */
15985 case 0x0226: /* 'BrtDrawing' */
15986 case 0x00AB: /* 'BrtDynamicFilter' */
15987 case 0x00A7: /* 'BrtFilter' */
15988 case 0x0499: /* 'BrtFilter14' */
15989 case 0x00A9: /* 'BrtIconFilter' */
15990 case 0x049D: /* 'BrtIconFilter14' */
15991 case 0x0227: /* 'BrtLegacyDrawing' */
15992 case 0x0228: /* 'BrtLegacyDrawingHF' */
15993 case 0x0295: /* 'BrtListPart' */
15994 case 0x027F: /* 'BrtOleObject' */
15995 case 0x01DE: /* 'BrtPageSetup' */
15996 case 0x0219: /* 'BrtPhoneticInfo' */
15997 case 0x01DD: /* 'BrtPrintOptions' */
15998 case 0x0218: /* 'BrtRangeProtection' */
15999 case 0x044F: /* 'BrtRangeProtection14' */
16000 case 0x02A8: /* 'BrtRangeProtectionIso' */
16001 case 0x0450: /* 'BrtRangeProtectionIso14' */
16002 case 0x0400: /* 'BrtRwDescent' */
16003 case 0x0297: /* 'BrtSheetCalcProp' */
16004 case 0x0217: /* 'BrtSheetProtection' */
16005 case 0x02A6: /* 'BrtSheetProtectionIso' */
16006 case 0x01F8: /* 'BrtSlc' */
16007 case 0x0413: /* 'BrtSparkline' */
16008 case 0x01AC: /* 'BrtTable' */
16009 case 0x00AA: /* 'BrtTop10Filter' */
16010 case 0x0C00: /* 'BrtUid' */
16011 case 0x0032: /* 'BrtValueMeta' */
16012 case 0x0816: /* 'BrtWebExtension' */
16013 case 0x0415: /* 'BrtWsFmtInfoEx14' */
16014 break;
16015
16016 case 0x0023: /* 'BrtFRTBegin' */
16017 pass = true; break;
16018 case 0x0024: /* 'BrtFRTEnd' */
16019 pass = false; break;
16020 case 0x0025: /* 'BrtACBegin' */
16021 state.push(RT); pass = true; break;
16022 case 0x0026: /* 'BrtACEnd' */
16023 state.pop(); pass = false; break;
16024
16025 default:
16026 if(RR.T){/* empty */}
16027 else if(!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
16028 }
16029 }, opts);
16030
16031 delete opts.supbooks;
16032 delete opts['!row'];
16033
16034 if(!s["!ref"] && (refguess.s.r < 2000000 || ref && (ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0))) s["!ref"] = encode_range(ref || refguess);
16035 if(opts.sheetRows && s["!ref"]) {
16036 var tmpref = safe_decode_range(s["!ref"]);
16037 if(opts.sheetRows <= +tmpref.e.r) {
16038 tmpref.e.r = opts.sheetRows - 1;
16039 if(tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
16040 if(tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
16041 if(tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
16042 if(tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
16043 s["!fullref"] = s["!ref"];
16044 s["!ref"] = encode_range(tmpref);
16045 }
16046 }
16047 if(merges.length > 0) s["!merges"] = merges;
16048 if(colinfo.length > 0) s["!cols"] = colinfo;
16049 if(rowinfo.length > 0) s["!rows"] = rowinfo;
16050 return s;
16051}
16052
16053/* TODO: something useful -- this is a stub */
16054function write_ws_bin_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts, ws/*:Worksheet*/, last_seen/*:boolean*/)/*:boolean*/ {
16055 if(cell.v === undefined) return false;
16056 var vv = "";
16057 switch(cell.t) {
16058 case 'b': vv = cell.v ? "1" : "0"; break;
16059 case 'd': // no BrtCellDate :(
16060 cell = dup(cell);
16061 cell.z = cell.z || table_fmt[14];
16062 cell.v = datenum(parseDate(cell.v)); cell.t = 'n';
16063 break;
16064 /* falls through */
16065 case 'n': case 'e': vv = ''+cell.v; break;
16066 default: vv = cell.v; break;
16067 }
16068 var o/*:any*/ = ({r:R, c:C}/*:any*/);
16069 /* TODO: cell style */
16070 o.s = get_cell_style(opts.cellXfs, cell, opts);
16071 if(cell.l) ws['!links'].push([encode_cell(o), cell.l]);
16072 if(cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
16073 switch(cell.t) {
16074 case 's': case 'str':
16075 if(opts.bookSST) {
16076 vv = get_sst_id(opts.Strings, (cell.v/*:any*/), opts.revStrings);
16077 o.t = "s"; o.v = vv;
16078 if(last_seen) write_record(ba, 0x0012 /* BrtShortIsst */, write_BrtShortIsst(cell, o));
16079 else write_record(ba, 0x0007 /* BrtCellIsst */, write_BrtCellIsst(cell, o));
16080 } else {
16081 o.t = "str";
16082 if(last_seen) write_record(ba, 0x0011 /* BrtShortSt */, write_BrtShortSt(cell, o));
16083 else write_record(ba, 0x0006 /* BrtCellSt */, write_BrtCellSt(cell, o));
16084 }
16085 return true;
16086 case 'n':
16087 /* TODO: determine threshold for Real vs RK */
16088 if(cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
16089 if(last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));
16090 else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
16091 } else {
16092 if(last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));
16093 else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
16094 } return true;
16095 case 'b':
16096 o.t = "b";
16097 if(last_seen) write_record(ba, 0x000F /* BrtShortBool */, write_BrtShortBool(cell, o));
16098 else write_record(ba, 0x0004 /* BrtCellBool */, write_BrtCellBool(cell, o));
16099 return true;
16100 case 'e':
16101 o.t = "e";
16102 if(last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError(cell, o));
16103 else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError(cell, o));
16104 return true;
16105 }
16106 if(last_seen) write_record(ba, 0x000C /* BrtShortBlank */, write_BrtShortBlank(cell, o));
16107 else write_record(ba, 0x0001 /* BrtCellBlank */, write_BrtCellBlank(cell, o));
16108 return true;
16109}
16110
16111function write_CELLTABLE(ba, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) {
16112 var range = safe_decode_range(ws['!ref'] || "A1"), ref, rr = "", cols/*:Array<string>*/ = [];
16113 write_record(ba, 0x0091 /* BrtBeginSheetData */);
16114 var dense = Array.isArray(ws);
16115 var cap = range.e.r;
16116 if(ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
16117 for(var R = range.s.r; R <= cap; ++R) {
16118 rr = encode_row(R);
16119 /* [ACCELLTABLE] */
16120 /* BrtRowHdr */
16121 write_row_header(ba, ws, range, R);
16122 var last_seen = false;
16123 if(R <= range.e.r) for(var C = range.s.c; C <= range.e.c; ++C) {
16124 /* *16384CELL */
16125 if(R === range.s.r) cols[C] = encode_col(C);
16126 ref = cols[C] + rr;
16127 var cell = dense ? (ws[R]||[])[C] : ws[ref];
16128 if(!cell) { last_seen = false; continue; }
16129 /* write cell */
16130 last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen);
16131 }
16132 }
16133 write_record(ba, 0x0092 /* BrtEndSheetData */);
16134}
16135
16136function write_MERGECELLS(ba, ws/*:Worksheet*/) {
16137 if(!ws || !ws['!merges']) return;
16138 write_record(ba, 0x00B1 /* BrtBeginMergeCells */, write_BrtBeginMergeCells(ws['!merges'].length));
16139 ws['!merges'].forEach(function(m) { write_record(ba, 0x00B0 /* BrtMergeCell */, write_BrtMergeCell(m)); });
16140 write_record(ba, 0x00B2 /* BrtEndMergeCells */);
16141}
16142
16143function write_COLINFOS(ba, ws/*:Worksheet*//*::, idx:number, opts, wb:Workbook*/) {
16144 if(!ws || !ws['!cols']) return;
16145 write_record(ba, 0x0186 /* BrtBeginColInfos */);
16146 ws['!cols'].forEach(function(m, i) { if(m) write_record(ba, 0x003C /* 'BrtColInfo' */, write_BrtColInfo(i, m)); });
16147 write_record(ba, 0x0187 /* BrtEndColInfos */);
16148}
16149
16150function write_IGNOREECS(ba, ws/*:Worksheet*/) {
16151 if(!ws || !ws['!ref']) return;
16152 write_record(ba, 0x0288 /* BrtBeginCellIgnoreECs */);
16153 write_record(ba, 0x0289 /* BrtCellIgnoreEC */, write_BrtCellIgnoreEC(safe_decode_range(ws['!ref'])));
16154 write_record(ba, 0x028A /* BrtEndCellIgnoreECs */);
16155}
16156
16157function write_HLINKS(ba, ws/*:Worksheet*/, rels) {
16158 /* *BrtHLink */
16159 ws['!links'].forEach(function(l) {
16160 if(!l[1].Target) return;
16161 var rId = add_rels(rels, -1, l[1].Target.replace(/#.*$/, ""), RELS.HLINK);
16162 write_record(ba, 0x01EE /* BrtHLink */, write_BrtHLink(l, rId));
16163 });
16164 delete ws['!links'];
16165}
16166function write_LEGACYDRAWING(ba, ws/*:Worksheet*/, idx/*:number*/, rels) {
16167 /* [BrtLegacyDrawing] */
16168 if(ws['!comments'].length > 0) {
16169 var rId = add_rels(rels, -1, "../drawings/vmlDrawing" + (idx+1) + ".vml", RELS.VML);
16170 write_record(ba, 0x0227 /* BrtLegacyDrawing */, write_RelID("rId" + rId));
16171 ws['!legacy'] = rId;
16172 }
16173}
16174
16175function write_AUTOFILTER(ba, ws, wb, idx) {
16176 if(!ws['!autofilter']) return;
16177 var data = ws['!autofilter'];
16178 var ref = typeof data.ref === "string" ? data.ref : encode_range(data.ref);
16179
16180 /* Update FilterDatabase defined name for the worksheet */
16181 if(!wb.Workbook) wb.Workbook = ({Sheets:[]}/*:any*/);
16182 if(!wb.Workbook.Names) wb.Workbook.Names = [];
16183 var names/*: Array<any> */ = wb.Workbook.Names;
16184 var range = decode_range(ref);
16185 if(range.s.r == range.e.r) { range.e.r = decode_range(ws["!ref"]).e.r; ref = encode_range(range); }
16186 for(var i = 0; i < names.length; ++i) {
16187 var name = names[i];
16188 if(name.Name != '_xlnm._FilterDatabase') continue;
16189 if(name.Sheet != idx) continue;
16190 name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref; break;
16191 }
16192 if(i == names.length) names.push({ Name: '_xlnm._FilterDatabase', Sheet: idx, Ref: "'" + wb.SheetNames[idx] + "'!" + ref });
16193
16194 write_record(ba, 0x00A1 /* BrtBeginAFilter */, write_UncheckedRfX(safe_decode_range(ref)));
16195 /* *FILTERCOLUMN */
16196 /* [SORTSTATE] */
16197 /* BrtEndAFilter */
16198 write_record(ba, 0x00A2 /* BrtEndAFilter */);
16199}
16200
16201function write_WSVIEWS2(ba, ws, Workbook) {
16202 write_record(ba, 0x0085 /* BrtBeginWsViews */);
16203 { /* 1*WSVIEW2 */
16204 /* [ACUID] */
16205 write_record(ba, 0x0089 /* BrtBeginWsView */, write_BrtBeginWsView(ws, Workbook));
16206 /* [BrtPane] */
16207 /* *4BrtSel */
16208 /* *4SXSELECT */
16209 /* *FRT */
16210 write_record(ba, 0x008A /* BrtEndWsView */);
16211 }
16212 /* *FRT */
16213 write_record(ba, 0x0086 /* BrtEndWsViews */);
16214}
16215
16216function write_WSFMTINFO(/*::ba, ws*/) {
16217 /* [ACWSFMTINFO] */
16218 // write_record(ba, 0x01E5 /* BrtWsFmtInfo */, write_BrtWsFmtInfo(ws));
16219}
16220
16221function write_SHEETPROTECT(ba, ws) {
16222 if(!ws['!protect']) return;
16223 /* [BrtSheetProtectionIso] */
16224 write_record(ba, 0x0217 /* BrtSheetProtection */, write_BrtSheetProtection(ws['!protect']));
16225}
16226
16227function write_ws_bin(idx/*:number*/, opts, wb/*:Workbook*/, rels) {
16228 var ba = buf_array();
16229 var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
16230 var c/*:string*/ = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
16231 var r = safe_decode_range(ws['!ref'] || "A1");
16232 if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
16233 if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
16234 r.e.c = Math.min(r.e.c, 0x3FFF);
16235 r.e.r = Math.min(r.e.c, 0xFFFFF);
16236 }
16237 ws['!links'] = [];
16238 /* passed back to write_zip and removed there */
16239 ws['!comments'] = [];
16240 write_record(ba, 0x0081 /* BrtBeginSheet */);
16241 if(wb.vbaraw || ws['!outline']) write_record(ba, 0x0093 /* BrtWsProp */, write_BrtWsProp(c, ws['!outline']));
16242 write_record(ba, 0x0094 /* BrtWsDim */, write_BrtWsDim(r));
16243 write_WSVIEWS2(ba, ws, wb.Workbook);
16244 write_WSFMTINFO(ba, ws);
16245 write_COLINFOS(ba, ws, idx, opts, wb);
16246 write_CELLTABLE(ba, ws, idx, opts, wb);
16247 /* [BrtSheetCalcProp] */
16248 write_SHEETPROTECT(ba, ws);
16249 /* *([BrtRangeProtectionIso] BrtRangeProtection) */
16250 /* [SCENMAN] */
16251 write_AUTOFILTER(ba, ws, wb, idx);
16252 /* [SORTSTATE] */
16253 /* [DCON] */
16254 /* [USERSHVIEWS] */
16255 write_MERGECELLS(ba, ws);
16256 /* [BrtPhoneticInfo] */
16257 /* *CONDITIONALFORMATTING */
16258 /* [DVALS] */
16259 write_HLINKS(ba, ws, rels);
16260 /* [BrtPrintOptions] */
16261 if(ws['!margins']) write_record(ba, 0x01DC /* BrtMargins */, write_BrtMargins(ws['!margins']));
16262 /* [BrtPageSetup] */
16263 /* [HEADERFOOTER] */
16264 /* [RWBRK] */
16265 /* [COLBRK] */
16266 /* *BrtBigName */
16267 /* [CELLWATCHES] */
16268 if(!opts || opts.ignoreEC || (opts.ignoreEC == (void 0))) write_IGNOREECS(ba, ws);
16269 /* [SMARTTAGS] */
16270 /* [BrtDrawing] */
16271 write_LEGACYDRAWING(ba, ws, idx, rels);
16272 /* [BrtLegacyDrawingHF] */
16273 /* [BrtBkHim] */
16274 /* [OLEOBJECTS] */
16275 /* [ACTIVEXCONTROLS] */
16276 /* [WEBPUBITEMS] */
16277 /* [LISTPARTS] */
16278 /* FRTWORKSHEET */
16279 write_record(ba, 0x0082 /* BrtEndSheet */);
16280 return ba.end();
16281}
16282function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*/ {
16283 var col/*:Array<number|string>*/ = [];
16284 var num = data.match(/^<c:numCache>/);
16285 var f;
16286
16287 /* 21.2.2.150 pt CT_NumVal */
16288 (data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
16289 var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
16290 if(!q) return;
16291 col[+q[1]] = num ? +q[2] : q[2];
16292 });
16293
16294 /* 21.2.2.71 formatCode CT_Xstring */
16295 var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
16296
16297 (data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
16298
16299 return [col, nf, f];
16300}
16301
16302/* 21.2 DrawingML - Charts */
16303function parse_chart(data/*:?string*/, name/*:string*/, opts, rels, wb, csheet) {
16304 var cs/*:Worksheet*/ = ((csheet || {"!type":"chart"})/*:any*/);
16305 if(!data) return csheet;
16306 /* 21.2.2.27 chart CT_Chart */
16307
16308 var C = 0, R = 0, col = "A";
16309 var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
16310
16311 /* 21.2.2.120 numCache CT_NumData */
16312 (data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
16313 var cache = parse_Cache(nc);
16314 refguess.s.r = refguess.s.c = 0;
16315 refguess.e.c = C;
16316 col = encode_col(C);
16317 cache[0].forEach(function(n,i) {
16318 cs[col + encode_row(i)] = {t:'n', v:n, z:cache[1] };
16319 R = i;
16320 });
16321 if(refguess.e.r < R) refguess.e.r = R;
16322 ++C;
16323 });
16324 if(C > 0) cs["!ref"] = encode_range(refguess);
16325 return cs;
16326}
16327/* 18.3 Worksheets also covers Chartsheets */
16328function parse_cs_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*::, themes, styles*/)/*:Worksheet*/ {
16329 if(!data) return data;
16330 /* 18.3.1.12 chartsheet CT_ChartSheet */
16331 if(!rels) rels = {'!id':{}};
16332 var s = ({'!type':"chart", '!drawel':null, '!rel':""}/*:any*/);
16333 var m;
16334
16335 /* 18.3.1.83 sheetPr CT_ChartsheetPr */
16336 var sheetPr = data.match(sheetprregex);
16337 if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
16338
16339 /* 18.3.1.36 drawing CT_Drawing */
16340 if((m = data.match(/drawing r:id="(.*?)"/))) s['!rel'] = m[1];
16341
16342 if(rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
16343 return s;
16344}
16345function write_cs_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
16346 var o = [XML_HEADER, writextag('chartsheet', null, {
16347 'xmlns': XMLNS_main[0],
16348 'xmlns:r': XMLNS.r
16349 })];
16350 o[o.length] = writextag("drawing", null, {"r:id": "rId1"});
16351 add_rels(rels, -1, "../drawings/drawing" + (idx+1) + ".xml", RELS.DRAW);
16352 if(o.length>2) { o[o.length] = ('</chartsheet>'); o[1]=o[1].replace("/>",">"); }
16353 return o.join("");
16354}
16355
16356/* [MS-XLSB] 2.4.331 BrtCsProp */
16357function parse_BrtCsProp(data, length/*:number*/) {
16358 data.l += 10;
16359 var name = parse_XLWideString(data, length - 10);
16360 return { name: name };
16361}
16362
16363/* [MS-XLSB] 2.1.7.7 Chart Sheet */
16364function parse_cs_bin(data, opts, idx/*:number*/, rels, wb/*::, themes, styles*/)/*:Worksheet*/ {
16365 if(!data) return data;
16366 if(!rels) rels = {'!id':{}};
16367 var s = {'!type':"chart", '!drawel':null, '!rel':""};
16368 var state/*:Array<string>*/ = [];
16369 var pass = false;
16370 recordhopper(data, function cs_parse(val, R, RT) {
16371 switch(RT) {
16372
16373 case 0x0226: /* 'BrtDrawing' */
16374 s['!rel'] = val; break;
16375
16376 case 0x028B: /* 'BrtCsProp' */
16377 if(!wb.Sheets[idx]) wb.Sheets[idx] = {};
16378 if(val.name) wb.Sheets[idx].CodeName = val.name;
16379 break;
16380
16381 case 0x0232: /* 'BrtBkHim' */
16382 case 0x028C: /* 'BrtCsPageSetup' */
16383 case 0x029D: /* 'BrtCsProtection' */
16384 case 0x02A7: /* 'BrtCsProtectionIso' */
16385 case 0x0227: /* 'BrtLegacyDrawing' */
16386 case 0x0228: /* 'BrtLegacyDrawingHF' */
16387 case 0x01DC: /* 'BrtMargins' */
16388 case 0x0C00: /* 'BrtUid' */
16389 break;
16390
16391 case 0x0023: /* 'BrtFRTBegin' */
16392 pass = true; break;
16393 case 0x0024: /* 'BrtFRTEnd' */
16394 pass = false; break;
16395 case 0x0025: /* 'BrtACBegin' */
16396 state.push(RT); break;
16397 case 0x0026: /* 'BrtACEnd' */
16398 state.pop(); break;
16399
16400 default:
16401 if(R.T > 0) state.push(RT);
16402 else if(R.T < 0) state.pop();
16403 else if(!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
16404 }
16405 }, opts);
16406
16407 if(rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
16408 return s;
16409}
16410function write_cs_bin(/*::idx:number, opts, wb:Workbook, rels*/) {
16411 var ba = buf_array();
16412 write_record(ba, 0x0081 /* BrtBeginSheet */);
16413 /* [BrtCsProp] */
16414 /* CSVIEWS */
16415 /* [[BrtCsProtectionIso] BrtCsProtection] */
16416 /* [USERCSVIEWS] */
16417 /* [BrtMargins] */
16418 /* [BrtCsPageSetup] */
16419 /* [HEADERFOOTER] */
16420 /* BrtDrawing */
16421 /* [BrtLegacyDrawing] */
16422 /* [BrtLegacyDrawingHF] */
16423 /* [BrtBkHim] */
16424 /* [WEBPUBITEMS] */
16425 /* FRTCHARTSHEET */
16426 write_record(ba, 0x0082 /* BrtEndSheet */);
16427 return ba.end();
16428}
16429/* 18.2.28 (CT_WorkbookProtection) Defaults */
16430var WBPropsDef = [
16431 ['allowRefreshQuery', false, "bool"],
16432 ['autoCompressPictures', true, "bool"],
16433 ['backupFile', false, "bool"],
16434 ['checkCompatibility', false, "bool"],
16435 ['CodeName', ''],
16436 ['date1904', false, "bool"],
16437 ['defaultThemeVersion', 0, "int"],
16438 ['filterPrivacy', false, "bool"],
16439 ['hidePivotFieldList', false, "bool"],
16440 ['promptedSolutions', false, "bool"],
16441 ['publishItems', false, "bool"],
16442 ['refreshAllConnections', false, "bool"],
16443 ['saveExternalLinkValues', true, "bool"],
16444 ['showBorderUnselectedTables', true, "bool"],
16445 ['showInkAnnotation', true, "bool"],
16446 ['showObjects', 'all'],
16447 ['showPivotChartFilter', false, "bool"],
16448 ['updateLinks', 'userSet']
16449];
16450
16451/* 18.2.30 (CT_BookView) Defaults */
16452var WBViewDef = [
16453 ['activeTab', 0, "int"],
16454 ['autoFilterDateGrouping', true, "bool"],
16455 ['firstSheet', 0, "int"],
16456 ['minimized', false, "bool"],
16457 ['showHorizontalScroll', true, "bool"],
16458 ['showSheetTabs', true, "bool"],
16459 ['showVerticalScroll', true, "bool"],
16460 ['tabRatio', 600, "int"],
16461 ['visibility', 'visible']
16462 //window{Height,Width}, {x,y}Window
16463];
16464
16465/* 18.2.19 (CT_Sheet) Defaults */
16466var SheetDef = [
16467 //['state', 'visible']
16468];
16469
16470/* 18.2.2 (CT_CalcPr) Defaults */
16471var CalcPrDef = [
16472 ['calcCompleted', 'true'],
16473 ['calcMode', 'auto'],
16474 ['calcOnSave', 'true'],
16475 ['concurrentCalc', 'true'],
16476 ['fullCalcOnLoad', 'false'],
16477 ['fullPrecision', 'true'],
16478 ['iterate', 'false'],
16479 ['iterateCount', '100'],
16480 ['iterateDelta', '0.001'],
16481 ['refMode', 'A1']
16482];
16483
16484/* 18.2.3 (CT_CustomWorkbookView) Defaults */
16485/*var CustomWBViewDef = [
16486 ['autoUpdate', 'false'],
16487 ['changesSavedWin', 'false'],
16488 ['includeHiddenRowCol', 'true'],
16489 ['includePrintSettings', 'true'],
16490 ['maximized', 'false'],
16491 ['minimized', 'false'],
16492 ['onlySync', 'false'],
16493 ['personalView', 'false'],
16494 ['showComments', 'commIndicator'],
16495 ['showFormulaBar', 'true'],
16496 ['showHorizontalScroll', 'true'],
16497 ['showObjects', 'all'],
16498 ['showSheetTabs', 'true'],
16499 ['showStatusbar', 'true'],
16500 ['showVerticalScroll', 'true'],
16501 ['tabRatio', '600'],
16502 ['xWindow', '0'],
16503 ['yWindow', '0']
16504];*/
16505
16506function push_defaults_array(target, defaults) {
16507 for(var j = 0; j != target.length; ++j) { var w = target[j];
16508 for(var i=0; i != defaults.length; ++i) { var z = defaults[i];
16509 if(w[z[0]] == null) w[z[0]] = z[1];
16510 else switch(z[2]) {
16511 case "bool": if(typeof w[z[0]] == "string") w[z[0]] = parsexmlbool(w[z[0]]); break;
16512 case "int": if(typeof w[z[0]] == "string") w[z[0]] = parseInt(w[z[0]], 10); break;
16513 }
16514 }
16515 }
16516}
16517function push_defaults(target, defaults) {
16518 for(var i = 0; i != defaults.length; ++i) { var z = defaults[i];
16519 if(target[z[0]] == null) target[z[0]] = z[1];
16520 else switch(z[2]) {
16521 case "bool": if(typeof target[z[0]] == "string") target[z[0]] = parsexmlbool(target[z[0]]); break;
16522 case "int": if(typeof target[z[0]] == "string") target[z[0]] = parseInt(target[z[0]], 10); break;
16523 }
16524 }
16525}
16526
16527function parse_wb_defaults(wb) {
16528 push_defaults(wb.WBProps, WBPropsDef);
16529 push_defaults(wb.CalcPr, CalcPrDef);
16530
16531 push_defaults_array(wb.WBView, WBViewDef);
16532 push_defaults_array(wb.Sheets, SheetDef);
16533
16534 _ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904);
16535}
16536
16537function safe1904(wb/*:Workbook*/)/*:string*/ {
16538 /* TODO: store date1904 somewhere else */
16539 if(!wb.Workbook) return "false";
16540 if(!wb.Workbook.WBProps) return "false";
16541 return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false";
16542}
16543
16544var badchars = /*#__PURE__*/"][*?\/\\".split("");
16545function check_ws_name(n/*:string*/, safe/*:?boolean*/)/*:boolean*/ {
16546 if(n.length > 31) { if(safe) return false; throw new Error("Sheet names cannot exceed 31 chars"); }
16547 var _good = true;
16548 badchars.forEach(function(c) {
16549 if(n.indexOf(c) == -1) return;
16550 if(!safe) throw new Error("Sheet name cannot contain : \\ / ? * [ ]");
16551 _good = false;
16552 });
16553 return _good;
16554}
16555function check_wb_names(N, S, codes) {
16556 N.forEach(function(n,i) {
16557 check_ws_name(n);
16558 for(var j = 0; j < i; ++j) if(n == N[j]) throw new Error("Duplicate Sheet Name: " + n);
16559 if(codes) {
16560 var cn = (S && S[i] && S[i].CodeName) || n;
16561 if(cn.charCodeAt(0) == 95 && cn.length > 22) throw new Error("Bad Code Name: Worksheet" + cn);
16562 }
16563 });
16564}
16565function check_wb(wb) {
16566 if(!wb || !wb.SheetNames || !wb.Sheets) throw new Error("Invalid Workbook");
16567 if(!wb.SheetNames.length) throw new Error("Workbook is empty");
16568 var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
16569 check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
16570 for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
16571 /* TODO: validate workbook */
16572}
16573/* 18.2 Workbook */
16574var wbnsregex = /<\w+:workbook/;
16575function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
16576 if(!data) throw new Error("Could not find file");
16577 var wb = /*::(*/{ AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, Names:[], xmlns: "" }/*::)*/;
16578 var pass = false, xmlns = "xmlns";
16579 var dname = {}, dnstart = 0;
16580 data.replace(tagregex, function xml_wb(x, idx) {
16581 var y/*:any*/ = parsexmltag(x);
16582 switch(strip_ns(y[0])) {
16583 case '<?xml': break;
16584
16585 /* 18.2.27 workbook CT_Workbook 1 */
16586 case '<workbook':
16587 if(x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
16588 wb.xmlns = y[xmlns];
16589 break;
16590 case '</workbook>': break;
16591
16592 /* 18.2.13 fileVersion CT_FileVersion ? */
16593 case '<fileVersion': delete y[0]; wb.AppVersion = y; break;
16594 case '<fileVersion/>': case '</fileVersion>': break;
16595
16596 /* 18.2.12 fileSharing CT_FileSharing ? */
16597 case '<fileSharing':
16598 break;
16599 case '<fileSharing/>': break;
16600
16601 /* 18.2.28 workbookPr CT_WorkbookPr ? */
16602 case '<workbookPr':
16603 case '<workbookPr/>':
16604 WBPropsDef.forEach(function(w) {
16605 if(y[w[0]] == null) return;
16606 switch(w[2]) {
16607 case "bool": wb.WBProps[w[0]] = parsexmlbool(y[w[0]]); break;
16608 case "int": wb.WBProps[w[0]] = parseInt(y[w[0]], 10); break;
16609 default: wb.WBProps[w[0]] = y[w[0]];
16610 }
16611 });
16612 if(y.codeName) wb.WBProps.CodeName = utf8read(y.codeName);
16613 break;
16614 case '</workbookPr>': break;
16615
16616 /* 18.2.29 workbookProtection CT_WorkbookProtection ? */
16617 case '<workbookProtection':
16618 break;
16619 case '<workbookProtection/>': break;
16620
16621 /* 18.2.1 bookViews CT_BookViews ? */
16622 case '<bookViews': case '<bookViews>': case '</bookViews>': break;
16623 /* 18.2.30 workbookView CT_BookView + */
16624 case '<workbookView': case '<workbookView/>': delete y[0]; wb.WBView.push(y); break;
16625 case '</workbookView>': break;
16626
16627 /* 18.2.20 sheets CT_Sheets 1 */
16628 case '<sheets': case '<sheets>': case '</sheets>': break; // aggregate sheet
16629 /* 18.2.19 sheet CT_Sheet + */
16630 case '<sheet':
16631 switch(y.state) {
16632 case "hidden": y.Hidden = 1; break;
16633 case "veryHidden": y.Hidden = 2; break;
16634 default: y.Hidden = 0;
16635 }
16636 delete y.state;
16637 y.name = unescapexml(utf8read(y.name));
16638 delete y[0]; wb.Sheets.push(y); break;
16639 case '</sheet>': break;
16640
16641 /* 18.2.15 functionGroups CT_FunctionGroups ? */
16642 case '<functionGroups': case '<functionGroups/>': break;
16643 /* 18.2.14 functionGroup CT_FunctionGroup + */
16644 case '<functionGroup': break;
16645
16646 /* 18.2.9 externalReferences CT_ExternalReferences ? */
16647 case '<externalReferences': case '</externalReferences>': case '<externalReferences>': break;
16648 /* 18.2.8 externalReference CT_ExternalReference + */
16649 case '<externalReference': break;
16650
16651 /* 18.2.6 definedNames CT_DefinedNames ? */
16652 case '<definedNames/>': break;
16653 case '<definedNames>': case '<definedNames': pass=true; break;
16654 case '</definedNames>': pass=false; break;
16655 /* 18.2.5 definedName CT_DefinedName + */
16656 case '<definedName': {
16657 dname = {};
16658 dname.Name = utf8read(y.name);
16659 if(y.comment) dname.Comment = y.comment;
16660 if(y.localSheetId) dname.Sheet = +y.localSheetId;
16661 if(parsexmlbool(y.hidden||"0")) dname.Hidden = true;
16662 dnstart = idx + x.length;
16663 } break;
16664 case '</definedName>': {
16665 dname.Ref = unescapexml(utf8read(data.slice(dnstart, idx)));
16666 wb.Names.push(dname);
16667 } break;
16668 case '<definedName/>': break;
16669
16670 /* 18.2.2 calcPr CT_CalcPr ? */
16671 case '<calcPr': delete y[0]; wb.CalcPr = y; break;
16672 case '<calcPr/>': delete y[0]; wb.CalcPr = y; break;
16673 case '</calcPr>': break;
16674
16675 /* 18.2.16 oleSize CT_OleSize ? (ref required) */
16676 case '<oleSize': break;
16677
16678 /* 18.2.4 customWorkbookViews CT_CustomWorkbookViews ? */
16679 case '<customWorkbookViews>': case '</customWorkbookViews>': case '<customWorkbookViews': break;
16680 /* 18.2.3 customWorkbookView CT_CustomWorkbookView + */
16681 case '<customWorkbookView': case '</customWorkbookView>': break;
16682
16683 /* 18.2.18 pivotCaches CT_PivotCaches ? */
16684 case '<pivotCaches>': case '</pivotCaches>': case '<pivotCaches': break;
16685 /* 18.2.17 pivotCache CT_PivotCache ? */
16686 case '<pivotCache': break;
16687
16688 /* 18.2.21 smartTagPr CT_SmartTagPr ? */
16689 case '<smartTagPr': case '<smartTagPr/>': break;
16690
16691 /* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
16692 case '<smartTagTypes': case '<smartTagTypes>': case '</smartTagTypes>': break;
16693 /* 18.2.22 smartTagType CT_SmartTagType ? */
16694 case '<smartTagType': break;
16695
16696 /* 18.2.24 webPublishing CT_WebPublishing ? */
16697 case '<webPublishing': case '<webPublishing/>': break;
16698
16699 /* 18.2.11 fileRecoveryPr CT_FileRecoveryPr ? */
16700 case '<fileRecoveryPr': case '<fileRecoveryPr/>': break;
16701
16702 /* 18.2.26 webPublishObjects CT_WebPublishObjects ? */
16703 case '<webPublishObjects>': case '<webPublishObjects': case '</webPublishObjects>': break;
16704 /* 18.2.25 webPublishObject CT_WebPublishObject ? */
16705 case '<webPublishObject': break;
16706
16707 /* 18.2.10 extLst CT_ExtensionList ? */
16708 case '<extLst': case '<extLst>': case '</extLst>': case '<extLst/>': break;
16709 /* 18.2.7 ext CT_Extension + */
16710 case '<ext': pass=true; break; //TODO: check with versions of excel
16711 case '</ext>': pass=false; break;
16712
16713 /* Others */
16714 case '<ArchID': break;
16715 case '<AlternateContent':
16716 case '<AlternateContent>': pass=true; break;
16717 case '</AlternateContent>': pass=false; break;
16718
16719 /* TODO */
16720 case '<revisionPtr': break;
16721
16722 default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook');
16723 }
16724 return x;
16725 });
16726 if(XMLNS_main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns);
16727
16728 parse_wb_defaults(wb);
16729
16730 return wb;
16731}
16732
16733function write_wb_xml(wb/*:Workbook*//*::, opts:?WriteOpts*/)/*:string*/ {
16734 var o = [XML_HEADER];
16735 o[o.length] = writextag('workbook', null, {
16736 'xmlns': XMLNS_main[0],
16737 //'xmlns:mx': XMLNS.mx,
16738 //'xmlns:s': XMLNS_main[0],
16739 'xmlns:r': XMLNS.r
16740 });
16741
16742 var write_names = (wb.Workbook && (wb.Workbook.Names||[]).length > 0);
16743
16744 /* fileVersion */
16745 /* fileSharing */
16746
16747 var workbookPr/*:any*/ = ({codeName:"ThisWorkbook"}/*:any*/);
16748 if(wb.Workbook && wb.Workbook.WBProps) {
16749 WBPropsDef.forEach(function(x) {
16750 /*:: if(!wb.Workbook || !wb.Workbook.WBProps) throw "unreachable"; */
16751 if((wb.Workbook.WBProps[x[0]]/*:any*/) == null) return;
16752 if((wb.Workbook.WBProps[x[0]]/*:any*/) == x[1]) return;
16753 workbookPr[x[0]] = (wb.Workbook.WBProps[x[0]]/*:any*/);
16754 });
16755 /*:: if(!wb.Workbook || !wb.Workbook.WBProps) throw "unreachable"; */
16756 if(wb.Workbook.WBProps.CodeName) { workbookPr.codeName = wb.Workbook.WBProps.CodeName; delete workbookPr.CodeName; }
16757 }
16758 o[o.length] = (writextag('workbookPr', null, workbookPr));
16759
16760 /* workbookProtection */
16761
16762 var sheets = wb.Workbook && wb.Workbook.Sheets || [];
16763 var i = 0;
16764
16765 /* bookViews only written if first worksheet is hidden */
16766 if(sheets && sheets[0] && !!sheets[0].Hidden) {
16767 o[o.length] = "<bookViews>";
16768 for(i = 0; i != wb.SheetNames.length; ++i) {
16769 if(!sheets[i]) break;
16770 if(!sheets[i].Hidden) break;
16771 }
16772 if(i == wb.SheetNames.length) i = 0;
16773 o[o.length] = '<workbookView firstSheet="' + i + '" activeTab="' + i + '"/>';
16774 o[o.length] = "</bookViews>";
16775 }
16776
16777 o[o.length] = "<sheets>";
16778 for(i = 0; i != wb.SheetNames.length; ++i) {
16779 var sht = ({name:escapexml(wb.SheetNames[i].slice(0,31))}/*:any*/);
16780 sht.sheetId = ""+(i+1);
16781 sht["r:id"] = "rId"+(i+1);
16782 if(sheets[i]) switch(sheets[i].Hidden) {
16783 case 1: sht.state = "hidden"; break;
16784 case 2: sht.state = "veryHidden"; break;
16785 }
16786 o[o.length] = (writextag('sheet',null,sht));
16787 }
16788 o[o.length] = "</sheets>";
16789
16790 /* functionGroups */
16791 /* externalReferences */
16792
16793 if(write_names) {
16794 o[o.length] = "<definedNames>";
16795 if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) {
16796 var d/*:any*/ = {name:n.Name};
16797 if(n.Comment) d.comment = n.Comment;
16798 if(n.Sheet != null) d.localSheetId = ""+n.Sheet;
16799 if(n.Hidden) d.hidden = "1";
16800 if(!n.Ref) return;
16801 o[o.length] = writextag('definedName', escapexml(n.Ref), d);
16802 });
16803 o[o.length] = "</definedNames>";
16804 }
16805
16806 /* calcPr */
16807 /* oleSize */
16808 /* customWorkbookViews */
16809 /* pivotCaches */
16810 /* smartTagPr */
16811 /* smartTagTypes */
16812 /* webPublishing */
16813 /* fileRecoveryPr */
16814 /* webPublishObjects */
16815 /* extLst */
16816
16817 if(o.length>2){ o[o.length] = '</workbook>'; o[1]=o[1].replace("/>",">"); }
16818 return o.join("");
16819}
16820/* [MS-XLSB] 2.4.304 BrtBundleSh */
16821function parse_BrtBundleSh(data, length/*:number*/) {
16822 var z = {};
16823 z.Hidden = data.read_shift(4); //hsState ST_SheetState
16824 z.iTabID = data.read_shift(4);
16825 z.strRelID = parse_RelID(data,length-8);
16826 z.name = parse_XLWideString(data);
16827 return z;
16828}
16829function write_BrtBundleSh(data, o) {
16830 if(!o) o = new_buf(127);
16831 o.write_shift(4, data.Hidden);
16832 o.write_shift(4, data.iTabID);
16833 write_RelID(data.strRelID, o);
16834 write_XLWideString(data.name.slice(0,31), o);
16835 return o.length > o.l ? o.slice(0, o.l) : o;
16836}
16837
16838/* [MS-XLSB] 2.4.815 BrtWbProp */
16839function parse_BrtWbProp(data, length)/*:WBProps*/ {
16840 var o/*:WBProps*/ = ({}/*:any*/);
16841 var flags = data.read_shift(4);
16842 o.defaultThemeVersion = data.read_shift(4);
16843 var strName = (length > 8) ? parse_XLWideString(data) : "";
16844 if(strName.length > 0) o.CodeName = strName;
16845 o.autoCompressPictures = !!(flags & 0x10000);
16846 o.backupFile = !!(flags & 0x40);
16847 o.checkCompatibility = !!(flags & 0x1000);
16848 o.date1904 = !!(flags & 0x01);
16849 o.filterPrivacy = !!(flags & 0x08);
16850 o.hidePivotFieldList = !!(flags & 0x400);
16851 o.promptedSolutions = !!(flags & 0x10);
16852 o.publishItems = !!(flags & 0x800);
16853 o.refreshAllConnections = !!(flags & 0x40000);
16854 o.saveExternalLinkValues = !!(flags & 0x80);
16855 o.showBorderUnselectedTables = !!(flags & 0x04);
16856 o.showInkAnnotation = !!(flags & 0x20);
16857 o.showObjects = ["all", "placeholders", "none"][(flags >> 13) & 0x03];
16858 o.showPivotChartFilter = !!(flags & 0x8000);
16859 o.updateLinks = ["userSet", "never", "always"][(flags >> 8) & 0x03];
16860 return o;
16861}
16862function write_BrtWbProp(data/*:?WBProps*/, o) {
16863 if(!o) o = new_buf(72);
16864 var flags = 0;
16865 if(data) {
16866 /* TODO: mirror parse_BrtWbProp fields */
16867 if(data.filterPrivacy) flags |= 0x08;
16868 }
16869 o.write_shift(4, flags);
16870 o.write_shift(4, 0);
16871 write_XLSBCodeName(data && data.CodeName || "ThisWorkbook", o);
16872 return o.slice(0, o.l);
16873}
16874
16875function parse_BrtFRTArchID$(data, length) {
16876 var o = {};
16877 data.read_shift(4);
16878 o.ArchID = data.read_shift(4);
16879 data.l += length - 8;
16880 return o;
16881}
16882
16883/* [MS-XLSB] 2.4.687 BrtName */
16884function parse_BrtName(data, length, opts) {
16885 var end = data.l + length;
16886 data.l += 4; //var flags = data.read_shift(4);
16887 data.l += 1; //var chKey = data.read_shift(1);
16888 var itab = data.read_shift(4);
16889 var name = parse_XLNameWideString(data);
16890 var formula = parse_XLSBNameParsedFormula(data, 0, opts);
16891 var comment = parse_XLNullableWideString(data);
16892 //if(0 /* fProc */) {
16893 // unusedstring1: XLNullableWideString
16894 // description: XLNullableWideString
16895 // helpTopic: XLNullableWideString
16896 // unusedstring2: XLNullableWideString
16897 //}
16898 data.l = end;
16899 var out = ({Name:name, Ptg:formula}/*:any*/);
16900 if(itab < 0xFFFFFFF) out.Sheet = itab;
16901 if(comment) out.Comment = comment;
16902 return out;
16903}
16904
16905/* [MS-XLSB] 2.1.7.61 Workbook */
16906function parse_wb_bin(data, opts)/*:WorkbookFile*/ {
16907 var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, xmlns: "" };
16908 var state/*:Array<string>*/ = [];
16909 var pass = false;
16910
16911 if(!opts) opts = {};
16912 opts.biff = 12;
16913
16914 var Names = [];
16915 var supbooks = ([[]]/*:any*/);
16916 supbooks.SheetNames = [];
16917 supbooks.XTI = [];
16918
16919 XLSBRecordEnum[0x0010] = { n:"BrtFRTArchID$", f:parse_BrtFRTArchID$ };
16920
16921 recordhopper(data, function hopper_wb(val, R, RT) {
16922 switch(RT) {
16923 case 0x009C: /* 'BrtBundleSh' */
16924 supbooks.SheetNames.push(val.name);
16925 wb.Sheets.push(val); break;
16926
16927 case 0x0099: /* 'BrtWbProp' */
16928 wb.WBProps = val; break;
16929
16930 case 0x0027: /* 'BrtName' */
16931 if(val.Sheet != null) opts.SID = val.Sheet;
16932 val.Ref = stringify_formula(val.Ptg, null, null, supbooks, opts);
16933 delete opts.SID;
16934 delete val.Ptg;
16935 Names.push(val);
16936 break;
16937 case 0x040C: /* 'BrtNameExt' */ break;
16938
16939 case 0x0165: /* 'BrtSupSelf' */
16940 case 0x0166: /* 'BrtSupSame' */
16941 case 0x0163: /* 'BrtSupBookSrc' */
16942 case 0x029B: /* 'BrtSupAddin' */
16943 if(!supbooks[0].length) supbooks[0] = [RT, val];
16944 else supbooks.push([RT, val]);
16945 supbooks[supbooks.length - 1].XTI = [];
16946 break;
16947 case 0x016A: /* 'BrtExternSheet' */
16948 if(supbooks.length === 0) { supbooks[0] = []; supbooks[0].XTI = []; }
16949 supbooks[supbooks.length - 1].XTI = supbooks[supbooks.length - 1].XTI.concat(val);
16950 supbooks.XTI = supbooks.XTI.concat(val);
16951 break;
16952 case 0x0169: /* 'BrtPlaceholderName' */
16953 break;
16954
16955 case 0x0817: /* 'BrtAbsPath15' */
16956 case 0x009E: /* 'BrtBookView' */
16957 case 0x008F: /* 'BrtBeginBundleShs' */
16958 case 0x0298: /* 'BrtBeginFnGroup' */
16959 case 0x0161: /* 'BrtBeginExternals' */
16960 break;
16961
16962 /* case 'BrtModelTimeGroupingCalcCol' */
16963 case 0x0C00: /* 'BrtUid' */
16964 case 0x0C01: /* 'BrtRevisionPtr' */
16965 case 0x0216: /* 'BrtBookProtection' */
16966 case 0x02A5: /* 'BrtBookProtectionIso' */
16967 case 0x009D: /* 'BrtCalcProp' */
16968 case 0x0262: /* 'BrtCrashRecErr' */
16969 case 0x0802: /* 'BrtDecoupledPivotCacheID' */
16970 case 0x009B: /* 'BrtFileRecover' */
16971 case 0x0224: /* 'BrtFileSharing' */
16972 case 0x02A4: /* 'BrtFileSharingIso' */
16973 case 0x0080: /* 'BrtFileVersion' */
16974 case 0x0299: /* 'BrtFnGroup' */
16975 case 0x0850: /* 'BrtModelRelationship' */
16976 case 0x084D: /* 'BrtModelTable' */
16977 case 0x0225: /* 'BrtOleSize' */
16978 case 0x0805: /* 'BrtPivotTableRef' */
16979 case 0x0254: /* 'BrtSmartTagType' */
16980 case 0x081C: /* 'BrtTableSlicerCacheID' */
16981 case 0x081B: /* 'BrtTableSlicerCacheIDs' */
16982 case 0x0822: /* 'BrtTimelineCachePivotCacheID' */
16983 case 0x018D: /* 'BrtUserBookView' */
16984 case 0x009A: /* 'BrtWbFactoid' */
16985 case 0x045D: /* 'BrtWbProp14' */
16986 case 0x0229: /* 'BrtWebOpt' */
16987 case 0x082B: /* 'BrtWorkBookPr15' */
16988 break;
16989
16990 case 0x0023: /* 'BrtFRTBegin' */
16991 state.push(RT); pass = true; break;
16992 case 0x0024: /* 'BrtFRTEnd' */
16993 state.pop(); pass = false; break;
16994 case 0x0025: /* 'BrtACBegin' */
16995 state.push(RT); pass = true; break;
16996 case 0x0026: /* 'BrtACEnd' */
16997 state.pop(); pass = false; break;
16998
16999 case 0x0010: /* 'BrtFRTArchID$' */ break;
17000
17001 default:
17002 if(R.T){/* empty */}
17003 else if(!pass || (opts.WTF && state[state.length-1] != 0x0025 /* BrtACBegin */ && state[state.length-1] != 0x0023 /* BrtFRTBegin */)) throw new Error("Unexpected record 0x" + RT.toString(16));
17004 }
17005 }, opts);
17006
17007 parse_wb_defaults(wb);
17008
17009 // $FlowIgnore
17010 wb.Names = Names;
17011
17012 (wb/*:any*/).supbooks = supbooks;
17013 return wb;
17014}
17015
17016function write_BUNDLESHS(ba, wb/*::, opts*/) {
17017 write_record(ba, 0x008F /* BrtBeginBundleShs */);
17018 for(var idx = 0; idx != wb.SheetNames.length; ++idx) {
17019 var viz = wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx] && wb.Workbook.Sheets[idx].Hidden || 0;
17020 var d = { Hidden: viz, iTabID: idx+1, strRelID: 'rId' + (idx+1), name: wb.SheetNames[idx] };
17021 write_record(ba, 0x009C /* BrtBundleSh */, write_BrtBundleSh(d));
17022 }
17023 write_record(ba, 0x0090 /* BrtEndBundleShs */);
17024}
17025
17026/* [MS-XLSB] 2.4.649 BrtFileVersion */
17027function write_BrtFileVersion(data, o) {
17028 if(!o) o = new_buf(127);
17029 for(var i = 0; i != 4; ++i) o.write_shift(4, 0);
17030 write_XLWideString("SheetJS", o);
17031 write_XLWideString(XLSX.version, o);
17032 write_XLWideString(XLSX.version, o);
17033 write_XLWideString("7262", o);
17034 return o.length > o.l ? o.slice(0, o.l) : o;
17035}
17036
17037/* [MS-XLSB] 2.4.301 BrtBookView */
17038function write_BrtBookView(idx, o) {
17039 if(!o) o = new_buf(29);
17040 o.write_shift(-4, 0);
17041 o.write_shift(-4, 460);
17042 o.write_shift(4, 28800);
17043 o.write_shift(4, 17600);
17044 o.write_shift(4, 500);
17045 o.write_shift(4, idx);
17046 o.write_shift(4, idx);
17047 var flags = 0x78;
17048 o.write_shift(1, flags);
17049 return o.length > o.l ? o.slice(0, o.l) : o;
17050}
17051
17052function write_BOOKVIEWS(ba, wb/*::, opts*/) {
17053 /* required if hidden tab appears before visible tab */
17054 if(!wb.Workbook || !wb.Workbook.Sheets) return;
17055 var sheets = wb.Workbook.Sheets;
17056 var i = 0, vistab = -1, hidden = -1;
17057 for(; i < sheets.length; ++i) {
17058 if(!sheets[i] || !sheets[i].Hidden && vistab == -1) vistab = i;
17059 else if(sheets[i].Hidden == 1 && hidden == -1) hidden = i;
17060 }
17061 if(hidden > vistab) return;
17062 write_record(ba, 0x0087 /* BrtBeginBookViews */);
17063 write_record(ba, 0x009E /* BrtBookView */, write_BrtBookView(vistab));
17064 /* 1*(BrtBookView *FRT) */
17065 write_record(ba, 0x0088 /* BrtEndBookViews */);
17066}
17067
17068/* [MS-XLSB] 2.4.305 BrtCalcProp */
17069/*function write_BrtCalcProp(data, o) {
17070 if(!o) o = new_buf(26);
17071 o.write_shift(4,0); // force recalc
17072 o.write_shift(4,1);
17073 o.write_shift(4,0);
17074 write_Xnum(0, o);
17075 o.write_shift(-4, 1023);
17076 o.write_shift(1, 0x33);
17077 o.write_shift(1, 0x00);
17078 return o;
17079}*/
17080
17081/* [MS-XLSB] 2.4.646 BrtFileRecover */
17082/*function write_BrtFileRecover(data, o) {
17083 if(!o) o = new_buf(1);
17084 o.write_shift(1,0);
17085 return o;
17086}*/
17087
17088/* [MS-XLSB] 2.1.7.61 Workbook */
17089function write_wb_bin(wb, opts) {
17090 var ba = buf_array();
17091 write_record(ba, 0x0083 /* BrtBeginBook */);
17092 write_record(ba, 0x0080 /* BrtFileVersion */, write_BrtFileVersion());
17093 /* [[BrtFileSharingIso] BrtFileSharing] */
17094 write_record(ba, 0x0099 /* BrtWbProp */, write_BrtWbProp(wb.Workbook && wb.Workbook.WBProps || null));
17095 /* [ACABSPATH] */
17096 /* [[BrtBookProtectionIso] BrtBookProtection] */
17097 write_BOOKVIEWS(ba, wb, opts);
17098 write_BUNDLESHS(ba, wb, opts);
17099 /* [FNGROUP] */
17100 /* [EXTERNALS] */
17101 /* *BrtName */
17102 /* write_record(ba, 0x009D BrtCalcProp, write_BrtCalcProp()); */
17103 /* [BrtOleSize] */
17104 /* *(BrtUserBookView *FRT) */
17105 /* [PIVOTCACHEIDS] */
17106 /* [BrtWbFactoid] */
17107 /* [SMARTTAGTYPES] */
17108 /* [BrtWebOpt] */
17109 /* write_record(ba, 0x009B BrtFileRecover, write_BrtFileRecover()); */
17110 /* [WEBPUBITEMS] */
17111 /* [CRERRS] */
17112 /* FRTWORKBOOK */
17113 write_record(ba, 0x0084 /* BrtEndBook */);
17114
17115 return ba.end();
17116}
17117function parse_wb(data, name/*:string*/, opts)/*:WorkbookFile*/ {
17118 if(name.slice(-4)===".bin") return parse_wb_bin((data/*:any*/), opts);
17119 return parse_wb_xml((data/*:any*/), opts);
17120}
17121
17122function parse_ws(data, name/*:string*/, idx/*:number*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
17123 if(name.slice(-4)===".bin") return parse_ws_bin((data/*:any*/), opts, idx, rels, wb, themes, styles);
17124 return parse_ws_xml((data/*:any*/), opts, idx, rels, wb, themes, styles);
17125}
17126
17127function parse_cs(data, name/*:string*/, idx/*:number*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
17128 if(name.slice(-4)===".bin") return parse_cs_bin((data/*:any*/), opts, idx, rels, wb, themes, styles);
17129 return parse_cs_xml((data/*:any*/), opts, idx, rels, wb, themes, styles);
17130}
17131
17132function parse_ms(data, name/*:string*/, idx/*:number*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
17133 if(name.slice(-4)===".bin") return parse_ms_bin((data/*:any*/), opts, idx, rels, wb, themes, styles);
17134 return parse_ms_xml((data/*:any*/), opts, idx, rels, wb, themes, styles);
17135}
17136
17137function parse_ds(data, name/*:string*/, idx/*:number*/, opts, rels, wb, themes, styles)/*:Worksheet*/ {
17138 if(name.slice(-4)===".bin") return parse_ds_bin((data/*:any*/), opts, idx, rels, wb, themes, styles);
17139 return parse_ds_xml((data/*:any*/), opts, idx, rels, wb, themes, styles);
17140}
17141
17142function parse_sty(data, name/*:string*/, themes, opts) {
17143 if(name.slice(-4)===".bin") return parse_sty_bin((data/*:any*/), themes, opts);
17144 return parse_sty_xml((data/*:any*/), themes, opts);
17145}
17146
17147function parse_theme(data/*:string*/, name/*:string*/, opts) {
17148 return parse_theme_xml(data, opts);
17149}
17150
17151function parse_sst(data, name/*:string*/, opts)/*:SST*/ {
17152 if(name.slice(-4)===".bin") return parse_sst_bin((data/*:any*/), opts);
17153 return parse_sst_xml((data/*:any*/), opts);
17154}
17155
17156function parse_cmnt(data, name/*:string*/, opts)/*:Array<RawComment>*/ {
17157 if(name.slice(-4)===".bin") return parse_comments_bin((data/*:any*/), opts);
17158 return parse_comments_xml((data/*:any*/), opts);
17159}
17160
17161function parse_cc(data, name/*:string*/, opts) {
17162 if(name.slice(-4)===".bin") return parse_cc_bin((data/*:any*/), name, opts);
17163 return parse_cc_xml((data/*:any*/), name, opts);
17164}
17165
17166function parse_xlink(data, rel, name/*:string*/, opts) {
17167 if(name.slice(-4)===".bin") return parse_xlink_bin((data/*:any*/), rel, name, opts);
17168 return parse_xlink_xml((data/*:any*/), rel, name, opts);
17169}
17170
17171function parse_xlmeta(data, name/*:string*/, opts) {
17172 if(name.slice(-4)===".bin") return parse_xlmeta_bin((data/*:any*/), name, opts);
17173 return parse_xlmeta_xml((data/*:any*/), name, opts);
17174}
17175
17176function write_wb(wb, name/*:string*/, opts) {
17177 return (name.slice(-4)===".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
17178}
17179
17180function write_ws(data/*:number*/, name/*:string*/, opts, wb/*:Workbook*/, rels) {
17181 return (name.slice(-4)===".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb, rels);
17182}
17183
17184// eslint-disable-next-line no-unused-vars
17185function write_cs(data/*:number*/, name/*:string*/, opts, wb/*:Workbook*/, rels) {
17186 return (name.slice(-4)===".bin" ? write_cs_bin : write_cs_xml)(data, opts, wb, rels);
17187}
17188
17189function write_sty(data, name/*:string*/, opts) {
17190 return (name.slice(-4)===".bin" ? write_sty_bin : write_sty_xml)(data, opts);
17191}
17192
17193function write_sst(data/*:SST*/, name/*:string*/, opts) {
17194 return (name.slice(-4)===".bin" ? write_sst_bin : write_sst_xml)(data, opts);
17195}
17196
17197function write_cmnt(data/*:Array<any>*/, name/*:string*/, opts) {
17198 return (name.slice(-4)===".bin" ? write_comments_bin : write_comments_xml)(data, opts);
17199}
17200/*
17201function write_cc(data, name:string, opts) {
17202 return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
17203}
17204*/
17205
17206function write_xlmeta(name/*:string*/) {
17207 return (name.slice(-4)===".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
17208}
17209var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
17210var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
17211function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
17212 var words = tag.split(/\s+/);
17213 var z/*:any*/ = ([]/*:any*/); if(!skip_root) z[0] = words[0];
17214 if(words.length === 1) return z;
17215 var m = tag.match(attregexg2), y, j, w, i;
17216 if(m) for(i = 0; i != m.length; ++i) {
17217 y = m[i].match(attregex2);
17218/*:: if(!y || !y[2]) continue; */
17219 if((j=y[1].indexOf(":")) === -1) z[y[1]] = y[2].slice(1,y[2].length-1);
17220 else {
17221 if(y[1].slice(0,6) === "xmlns:") w = "xmlns"+y[1].slice(6);
17222 else w = y[1].slice(j+1);
17223 z[w] = y[2].slice(1,y[2].length-1);
17224 }
17225 }
17226 return z;
17227}
17228function xlml_parsexmltagobj(tag/*:string*/) {
17229 var words = tag.split(/\s+/);
17230 var z = {};
17231 if(words.length === 1) return z;
17232 var m = tag.match(attregexg2), y, j, w, i;
17233 if(m) for(i = 0; i != m.length; ++i) {
17234 y = m[i].match(attregex2);
17235/*:: if(!y || !y[2]) continue; */
17236 if((j=y[1].indexOf(":")) === -1) z[y[1]] = y[2].slice(1,y[2].length-1);
17237 else {
17238 if(y[1].slice(0,6) === "xmlns:") w = "xmlns"+y[1].slice(6);
17239 else w = y[1].slice(j+1);
17240 z[w] = y[2].slice(1,y[2].length-1);
17241 }
17242 }
17243 return z;
17244}
17245
17246// ----
17247
17248/* map from xlml named formats to SSF TODO: localize */
17249var XLMLFormatMap/*: {[string]:string}*/;
17250
17251function xlml_format(format, value)/*:string*/ {
17252 var fmt = XLMLFormatMap[format] || unescapexml(format);
17253 if(fmt === "General") return SSF_general(value);
17254 return SSF_format(fmt, value);
17255}
17256
17257function xlml_set_custprop(Custprops, key, cp, val/*:string*/) {
17258 var oval/*:any*/ = val;
17259 switch((cp[0].match(/dt:dt="([\w.]+)"/)||["",""])[1]) {
17260 case "boolean": oval = parsexmlbool(val); break;
17261 case "i2": case "int": oval = parseInt(val, 10); break;
17262 case "r4": case "float": oval = parseFloat(val); break;
17263 case "date": case "dateTime.tz": oval = parseDate(val); break;
17264 case "i8": case "string": case "fixed": case "uuid": case "bin.base64": break;
17265 default: throw new Error("bad custprop:" + cp[0]);
17266 }
17267 Custprops[unescapexml(key)] = oval;
17268}
17269
17270function safe_format_xlml(cell/*:Cell*/, nf, o) {
17271 if(cell.t === 'z') return;
17272 if(!o || o.cellText !== false) try {
17273 if(cell.t === 'e') { cell.w = cell.w || BErr[cell.v]; }
17274 else if(nf === "General") {
17275 if(cell.t === 'n') {
17276 if((cell.v|0) === cell.v) cell.w = cell.v.toString(10);
17277 else cell.w = SSF_general_num(cell.v);
17278 }
17279 else cell.w = SSF_general(cell.v);
17280 }
17281 else cell.w = xlml_format(nf||"General", cell.v);
17282 } catch(e) { if(o.WTF) throw e; }
17283 try {
17284 var z = XLMLFormatMap[nf]||nf||"General";
17285 if(o.cellNF) cell.z = z;
17286 if(o.cellDates && cell.t == 'n' && fmt_is_date(z)) {
17287 var _d = SSF_parse_date_code(cell.v); if(_d) { cell.t = 'd'; cell.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
17288 }
17289 } catch(e) { if(o.WTF) throw e; }
17290}
17291
17292function process_style_xlml(styles, stag, opts) {
17293 if(opts.cellStyles) {
17294 if(stag.Interior) {
17295 var I = stag.Interior;
17296 if(I.Pattern) I.patternType = XLMLPatternTypeMap[I.Pattern] || I.Pattern;
17297 }
17298 }
17299 styles[stag.ID] = stag;
17300}
17301
17302/* TODO: there must exist some form of OSP-blessed spec */
17303function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, arrayf, o) {
17304 var nf = "General", sid = cell.StyleID, S = {}; o = o || {};
17305 var interiors = [];
17306 var i = 0;
17307 if(sid === undefined && row) sid = row.StyleID;
17308 if(sid === undefined && csty) sid = csty.StyleID;
17309 while(styles[sid] !== undefined) {
17310 if(styles[sid].nf) nf = styles[sid].nf;
17311 if(styles[sid].Interior) interiors.push(styles[sid].Interior);
17312 if(!styles[sid].Parent) break;
17313 sid = styles[sid].Parent;
17314 }
17315 switch(data.Type) {
17316 case 'Boolean':
17317 cell.t = 'b';
17318 cell.v = parsexmlbool(xml);
17319 break;
17320 case 'String':
17321 cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
17322 cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<.*?>/g, "") : cell.r); // todo: BR etc
17323 break;
17324 case 'DateTime':
17325 if(xml.slice(-1) != "Z") xml += "Z";
17326 cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
17327 if(cell.v !== cell.v) cell.v = unescapexml(xml);
17328 else if(cell.v<60) cell.v = cell.v -1;
17329 if(!nf || nf == "General") nf = "yyyy-mm-dd";
17330 /* falls through */
17331 case 'Number':
17332 if(cell.v === undefined) cell.v=+xml;
17333 if(!cell.t) cell.t = 'n';
17334 break;
17335 case 'Error': cell.t = 'e'; cell.v = RBErr[xml]; if(o.cellText !== false) cell.w = xml; break;
17336 default:
17337 if(xml == "" && ss == "") { cell.t = 'z'; }
17338 else { cell.t = 's'; cell.v = xlml_fixstr(ss||xml); }
17339 break;
17340 }
17341 safe_format_xlml(cell, nf, o);
17342 if(o.cellFormula !== false) {
17343 if(cell.Formula) {
17344 var fstr = unescapexml(cell.Formula);
17345 /* strictly speaking, the leading = is required but some writers omit */
17346 if(fstr.charCodeAt(0) == 61 /* = */) fstr = fstr.slice(1);
17347 cell.f = rc_to_a1(fstr, base);
17348 delete cell.Formula;
17349 if(cell.ArrayRange == "RC") cell.F = rc_to_a1("RC:RC", base);
17350 else if(cell.ArrayRange) {
17351 cell.F = rc_to_a1(cell.ArrayRange, base);
17352 arrayf.push([safe_decode_range(cell.F), cell.F]);
17353 }
17354 } else {
17355 for(i = 0; i < arrayf.length; ++i)
17356 if(base.r >= arrayf[i][0].s.r && base.r <= arrayf[i][0].e.r)
17357 if(base.c >= arrayf[i][0].s.c && base.c <= arrayf[i][0].e.c)
17358 cell.F = arrayf[i][1];
17359 }
17360 }
17361 if(o.cellStyles) {
17362 interiors.forEach(function(x) {
17363 if(!S.patternType && x.patternType) S.patternType = x.patternType;
17364 });
17365 cell.s = S;
17366 }
17367 if(cell.StyleID !== undefined) cell.ixfe = cell.StyleID;
17368}
17369
17370function xlml_clean_comment(comment/*:any*/) {
17371 comment.t = comment.v || "";
17372 comment.t = comment.t.replace(/\r\n/g,"\n").replace(/\r/g,"\n");
17373 comment.v = comment.w = comment.ixfe = undefined;
17374}
17375
17376/* TODO: Everything */
17377function parse_xlml_xml(d, _opts)/*:Workbook*/ {
17378 var opts = _opts || {};
17379 make_ssf();
17380 var str = debom(xlml_normalize(d));
17381 if(opts.type == 'binary' || opts.type == 'array' || opts.type == 'base64') {
17382 if(typeof $cptable !== 'undefined') str = $cptable.utils.decode(65001, char_codes(str));
17383 else str = utf8read(str);
17384 }
17385 var opening = str.slice(0, 1024).toLowerCase(), ishtml = false;
17386 opening = opening.replace(/".*?"/g, "");
17387 if((opening.indexOf(">") & 1023) > Math.min((opening.indexOf(",") & 1023), (opening.indexOf(";")&1023))) { var _o = dup(opts); _o.type = "string"; return PRN.to_workbook(str, _o); }
17388 if(opening.indexOf("<?xml") == -1) ["html", "table", "head", "meta", "script", "style", "div"].forEach(function(tag) { if(opening.indexOf("<" + tag) >= 0) ishtml = true; });
17389 if(ishtml) return html_to_workbook(str, opts);
17390
17391 XLMLFormatMap = ({
17392 "General Number": "General",
17393 "General Date": table_fmt[22],
17394 "Long Date": "dddd, mmmm dd, yyyy",
17395 "Medium Date": table_fmt[15],
17396 "Short Date": table_fmt[14],
17397 "Long Time": table_fmt[19],
17398 "Medium Time": table_fmt[18],
17399 "Short Time": table_fmt[20],
17400 "Currency": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
17401 "Fixed": table_fmt[2],
17402 "Standard": table_fmt[4],
17403 "Percent": table_fmt[10],
17404 "Scientific": table_fmt[11],
17405 "Yes/No": '"Yes";"Yes";"No";@',
17406 "True/False": '"True";"True";"False";@',
17407 "On/Off": '"Yes";"Yes";"No";@'
17408 }/*:any*/);
17409
17410
17411 var Rn;
17412 var state = [], tmp;
17413 if(DENSE != null && opts.dense == null) opts.dense = DENSE;
17414 var sheets = {}, sheetnames/*:Array<string>*/ = [], cursheet/*:Worksheet*/ = (opts.dense ? [] : {}), sheetname = "";
17415 var cell = ({}/*:any*/), row = {};// eslint-disable-line no-unused-vars
17416 var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0;
17417 var c = 0, r = 0;
17418 var refguess/*:Range*/ = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
17419 var styles = {}, stag = {};
17420 var ss = "", fidx = 0;
17421 var merges/*:Array<Range>*/ = [];
17422 var Props = {}, Custprops = {}, pidx = 0, cp = [];
17423 var comments/*:Array<Comment>*/ = [], comment/*:Comment*/ = ({}/*:any*/);
17424 var cstys = [], csty, seencol = false;
17425 var arrayf/*:Array<[Range, string]>*/ = [];
17426 var rowinfo/*:Array<RowInfo>*/ = [], rowobj = {}, cc = 0, rr = 0;
17427 var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false} }/*:any*/), wsprops = {};
17428 xlmlregex.lastIndex = 0;
17429 str = str.replace(/<!--([\s\S]*?)-->/mg,"");
17430 var raw_Rn3 = "";
17431 while((Rn = xlmlregex.exec(str))) switch((Rn[3] = (raw_Rn3 = Rn[3]).toLowerCase())) {
17432 case 'data' /*case 'Data'*/:
17433 if(raw_Rn3 == "data") {
17434 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
17435 else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
17436 break;
17437 }
17438 if(state[state.length-1][1]) break;
17439 if(Rn[1]==='/') parse_xlml_data(str.slice(didx, Rn.index), ss, dtag, state[state.length-1][0]==/*"Comment"*/"comment"?comment:cell, {c:c,r:r}, styles, cstys[c], row, arrayf, opts);
17440 else { ss = ""; dtag = xlml_parsexmltag(Rn[0]); didx = Rn.index + Rn[0].length; }
17441 break;
17442 case 'cell' /*case 'Cell'*/:
17443 if(Rn[1]==='/'){
17444 if(comments.length > 0) cell.c = comments;
17445 if((!opts.sheetRows || opts.sheetRows > r) && cell.v !== undefined) {
17446 if(opts.dense) {
17447 if(!cursheet[r]) cursheet[r] = [];
17448 cursheet[r][c] = cell;
17449 } else cursheet[encode_col(c) + encode_row(r)] = cell;
17450 }
17451 if(cell.HRef) {
17452 cell.l = ({Target:unescapexml(cell.HRef)}/*:any*/);
17453 if(cell.HRefScreenTip) cell.l.Tooltip = cell.HRefScreenTip;
17454 delete cell.HRef; delete cell.HRefScreenTip;
17455 }
17456 if(cell.MergeAcross || cell.MergeDown) {
17457 cc = c + (parseInt(cell.MergeAcross,10)|0);
17458 rr = r + (parseInt(cell.MergeDown,10)|0);
17459 merges.push({s:{c:c,r:r},e:{c:cc,r:rr}});
17460 }
17461 if(!opts.sheetStubs) { if(cell.MergeAcross) c = cc + 1; else ++c; }
17462 else if(cell.MergeAcross || cell.MergeDown) {
17463 /*:: if(!cc) cc = 0; if(!rr) rr = 0; */
17464 for(var cma = c; cma <= cc; ++cma) {
17465 for(var cmd = r; cmd <= rr; ++cmd) {
17466 if(cma > c || cmd > r) {
17467 if(opts.dense) {
17468 if(!cursheet[cmd]) cursheet[cmd] = [];
17469 cursheet[cmd][cma] = {t:'z'};
17470 } else cursheet[encode_col(cma) + encode_row(cmd)] = {t:'z'};
17471 }
17472 }
17473 }
17474 c = cc + 1;
17475 }
17476 else ++c;
17477 } else {
17478 cell = xlml_parsexmltagobj(Rn[0]);
17479 if(cell.Index) c = +cell.Index - 1;
17480 if(c < refguess.s.c) refguess.s.c = c;
17481 if(c > refguess.e.c) refguess.e.c = c;
17482 if(Rn[0].slice(-2) === "/>") ++c;
17483 comments = [];
17484 }
17485 break;
17486 case 'row' /*case 'Row'*/:
17487 if(Rn[1]==='/' || Rn[0].slice(-2) === "/>") {
17488 if(r < refguess.s.r) refguess.s.r = r;
17489 if(r > refguess.e.r) refguess.e.r = r;
17490 if(Rn[0].slice(-2) === "/>") {
17491 row = xlml_parsexmltag(Rn[0]);
17492 if(row.Index) r = +row.Index - 1;
17493 }
17494 c = 0; ++r;
17495 } else {
17496 row = xlml_parsexmltag(Rn[0]);
17497 if(row.Index) r = +row.Index - 1;
17498 rowobj = {};
17499 if(row.AutoFitHeight == "0" || row.Height) {
17500 rowobj.hpx = parseInt(row.Height, 10); rowobj.hpt = px2pt(rowobj.hpx);
17501 rowinfo[r] = rowobj;
17502 }
17503 if(row.Hidden == "1") { rowobj.hidden = true; rowinfo[r] = rowobj; }
17504 }
17505 break;
17506 case 'worksheet' /*case 'Worksheet'*/: /* TODO: read range from FullRows/FullColumns */
17507 if(Rn[1]==='/'){
17508 if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));
17509 sheetnames.push(sheetname);
17510 if(refguess.s.r <= refguess.e.r && refguess.s.c <= refguess.e.c) {
17511 cursheet["!ref"] = encode_range(refguess);
17512 if(opts.sheetRows && opts.sheetRows <= refguess.e.r) {
17513 cursheet["!fullref"] = cursheet["!ref"];
17514 refguess.e.r = opts.sheetRows - 1;
17515 cursheet["!ref"] = encode_range(refguess);
17516 }
17517 }
17518 if(merges.length) cursheet["!merges"] = merges;
17519 if(cstys.length > 0) cursheet["!cols"] = cstys;
17520 if(rowinfo.length > 0) cursheet["!rows"] = rowinfo;
17521 sheets[sheetname] = cursheet;
17522 } else {
17523 refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
17524 r = c = 0;
17525 state.push([Rn[3], false]);
17526 tmp = xlml_parsexmltag(Rn[0]);
17527 sheetname = unescapexml(tmp.Name);
17528 cursheet = (opts.dense ? [] : {});
17529 merges = [];
17530 arrayf = [];
17531 rowinfo = [];
17532 wsprops = {name:sheetname, Hidden:0};
17533 Workbook.Sheets.push(wsprops);
17534 }
17535 break;
17536 case 'table' /*case 'Table'*/:
17537 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
17538 else if(Rn[0].slice(-2) == "/>") break;
17539 else {
17540 state.push([Rn[3], false]);
17541 cstys = []; seencol = false;
17542 }
17543 break;
17544
17545 case 'style' /*case 'Style'*/:
17546 if(Rn[1]==='/') process_style_xlml(styles, stag, opts);
17547 else stag = xlml_parsexmltag(Rn[0]);
17548 break;
17549
17550 case 'numberformat' /*case 'NumberFormat'*/:
17551 stag.nf = unescapexml(xlml_parsexmltag(Rn[0]).Format || "General");
17552 if(XLMLFormatMap[stag.nf]) stag.nf = XLMLFormatMap[stag.nf];
17553 for(var ssfidx = 0; ssfidx != 0x188; ++ssfidx) if(table_fmt[ssfidx] == stag.nf) break;
17554 if(ssfidx == 0x188) for(ssfidx = 0x39; ssfidx != 0x188; ++ssfidx) if(table_fmt[ssfidx] == null) { SSF_load(stag.nf, ssfidx); break; }
17555 break;
17556
17557 case 'column' /*case 'Column'*/:
17558 if(state[state.length-1][0] !== /*'Table'*/'table') break;
17559 csty = xlml_parsexmltag(Rn[0]);
17560 if(csty.Hidden) { csty.hidden = true; delete csty.Hidden; }
17561 if(csty.Width) csty.wpx = parseInt(csty.Width, 10);
17562 if(!seencol && csty.wpx > 10) {
17563 seencol = true; MDW = DEF_MDW; //find_mdw_wpx(csty.wpx);
17564 for(var _col = 0; _col < cstys.length; ++_col) if(cstys[_col]) process_col(cstys[_col]);
17565 }
17566 if(seencol) process_col(csty);
17567 cstys[(csty.Index-1||cstys.length)] = csty;
17568 for(var i = 0; i < +csty.Span; ++i) cstys[cstys.length] = dup(csty);
17569 break;
17570
17571 case 'namedrange' /*case 'NamedRange'*/:
17572 if(Rn[1]==='/') break;
17573 if(!Workbook.Names) Workbook.Names = [];
17574 var _NamedRange = parsexmltag(Rn[0]);
17575 var _DefinedName/*:DefinedName*/ = ({
17576 Name: _NamedRange.Name,
17577 Ref: rc_to_a1(_NamedRange.RefersTo.slice(1), {r:0, c:0})
17578 }/*:any*/);
17579 if(Workbook.Sheets.length>0) _DefinedName.Sheet=Workbook.Sheets.length-1;
17580 /*:: if(Workbook.Names) */Workbook.Names.push(_DefinedName);
17581 break;
17582
17583 case 'namedcell' /*case 'NamedCell'*/: break;
17584 case 'b' /*case 'B'*/: break;
17585 case 'i' /*case 'I'*/: break;
17586 case 'u' /*case 'U'*/: break;
17587 case 's' /*case 'S'*/: break;
17588 case 'em' /*case 'EM'*/: break;
17589 case 'h2' /*case 'H2'*/: break;
17590 case 'h3' /*case 'H3'*/: break;
17591 case 'sub' /*case 'Sub'*/: break;
17592 case 'sup' /*case 'Sup'*/: break;
17593 case 'span' /*case 'Span'*/: break;
17594 case 'alignment' /*case 'Alignment'*/:
17595 break;
17596 case 'borders' /*case 'Borders'*/: break;
17597 case 'border' /*case 'Border'*/: break;
17598 case 'font' /*case 'Font'*/:
17599 if(Rn[0].slice(-2) === "/>") break;
17600 else if(Rn[1]==="/") ss += str.slice(fidx, Rn.index);
17601 else fidx = Rn.index + Rn[0].length;
17602 break;
17603 case 'interior' /*case 'Interior'*/:
17604 if(!opts.cellStyles) break;
17605 stag.Interior = xlml_parsexmltag(Rn[0]);
17606 break;
17607 case 'protection' /*case 'Protection'*/: break;
17608
17609 case 'author' /*case 'Author'*/:
17610 case 'title' /*case 'Title'*/:
17611 case 'description' /*case 'Description'*/:
17612 case 'created' /*case 'Created'*/:
17613 case 'keywords' /*case 'Keywords'*/:
17614 case 'subject' /*case 'Subject'*/:
17615 case 'category' /*case 'Category'*/:
17616 case 'company' /*case 'Company'*/:
17617 case 'lastauthor' /*case 'LastAuthor'*/:
17618 case 'lastsaved' /*case 'LastSaved'*/:
17619 case 'lastprinted' /*case 'LastPrinted'*/:
17620 case 'version' /*case 'Version'*/:
17621 case 'revision' /*case 'Revision'*/:
17622 case 'totaltime' /*case 'TotalTime'*/:
17623 case 'hyperlinkbase' /*case 'HyperlinkBase'*/:
17624 case 'manager' /*case 'Manager'*/:
17625 case 'contentstatus' /*case 'ContentStatus'*/:
17626 case 'identifier' /*case 'Identifier'*/:
17627 case 'language' /*case 'Language'*/:
17628 case 'appname' /*case 'AppName'*/:
17629 if(Rn[0].slice(-2) === "/>") break;
17630 else if(Rn[1]==="/") xlml_set_prop(Props, raw_Rn3, str.slice(pidx, Rn.index));
17631 else pidx = Rn.index + Rn[0].length;
17632 break;
17633 case 'paragraphs' /*case 'Paragraphs'*/: break;
17634
17635 case 'styles' /*case 'Styles'*/:
17636 case 'workbook' /*case 'Workbook'*/:
17637 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
17638 else state.push([Rn[3], false]);
17639 break;
17640
17641 case 'comment' /*case 'Comment'*/:
17642 if(Rn[1]==='/'){
17643 if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));
17644 xlml_clean_comment(comment);
17645 comments.push(comment);
17646 } else {
17647 state.push([Rn[3], false]);
17648 tmp = xlml_parsexmltag(Rn[0]);
17649 comment = ({a:tmp.Author}/*:any*/);
17650 }
17651 break;
17652
17653 case 'autofilter' /*case 'AutoFilter'*/:
17654 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
17655 else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
17656 var AutoFilter = xlml_parsexmltag(Rn[0]);
17657 cursheet['!autofilter'] = { ref:rc_to_a1(AutoFilter.Range).replace(/\$/g,"") };
17658 state.push([Rn[3], true]);
17659 }
17660 break;
17661
17662 case 'name' /*case 'Name'*/: break;
17663
17664 case 'datavalidation' /*case 'DataValidation'*/:
17665 if(Rn[1]==='/'){
17666 if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));
17667 } else {
17668 if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
17669 }
17670 break;
17671
17672 case 'pixelsperinch' /*case 'PixelsPerInch'*/:
17673 break;
17674 case 'componentoptions' /*case 'ComponentOptions'*/:
17675 case 'documentproperties' /*case 'DocumentProperties'*/:
17676 case 'customdocumentproperties' /*case 'CustomDocumentProperties'*/:
17677 case 'officedocumentsettings' /*case 'OfficeDocumentSettings'*/:
17678 case 'pivottable' /*case 'PivotTable'*/:
17679 case 'pivotcache' /*case 'PivotCache'*/:
17680 case 'names' /*case 'Names'*/:
17681 case 'mapinfo' /*case 'MapInfo'*/:
17682 case 'pagebreaks' /*case 'PageBreaks'*/:
17683 case 'querytable' /*case 'QueryTable'*/:
17684 case 'sorting' /*case 'Sorting'*/:
17685 case 'schema' /*case 'Schema'*/: //case 'data' /*case 'data'*/:
17686 case 'conditionalformatting' /*case 'ConditionalFormatting'*/:
17687 case 'smarttagtype' /*case 'SmartTagType'*/:
17688 case 'smarttags' /*case 'SmartTags'*/:
17689 case 'excelworkbook' /*case 'ExcelWorkbook'*/:
17690 case 'workbookoptions' /*case 'WorkbookOptions'*/:
17691 case 'worksheetoptions' /*case 'WorksheetOptions'*/:
17692 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw new Error("Bad state: "+tmp.join("|"));}
17693 else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
17694 break;
17695
17696 case 'null' /*case 'Null'*/: break;
17697
17698 default:
17699 /* FODS file root is <office:document> */
17700 if(state.length == 0 && Rn[3] == "document") return parse_fods(str, opts);
17701 /* UOS file root is <uof:UOF> */
17702 if(state.length == 0 && Rn[3] == "uof"/*"UOF"*/) return parse_fods(str, opts);
17703
17704 var seen = true;
17705 switch(state[state.length-1][0]) {
17706 /* OfficeDocumentSettings */
17707 case 'officedocumentsettings' /*case 'OfficeDocumentSettings'*/: switch(Rn[3]) {
17708 case 'allowpng' /*case 'AllowPNG'*/: break;
17709 case 'removepersonalinformation' /*case 'RemovePersonalInformation'*/: break;
17710 case 'downloadcomponents' /*case 'DownloadComponents'*/: break;
17711 case 'locationofcomponents' /*case 'LocationOfComponents'*/: break;
17712 case 'colors' /*case 'Colors'*/: break;
17713 case 'color' /*case 'Color'*/: break;
17714 case 'index' /*case 'Index'*/: break;
17715 case 'rgb' /*case 'RGB'*/: break;
17716 case 'targetscreensize' /*case 'TargetScreenSize'*/: break;
17717 case 'readonlyrecommended' /*case 'ReadOnlyRecommended'*/: break;
17718 default: seen = false;
17719 } break;
17720
17721 /* ComponentOptions */
17722 case 'componentoptions' /*case 'ComponentOptions'*/: switch(Rn[3]) {
17723 case 'toolbar' /*case 'Toolbar'*/: break;
17724 case 'hideofficelogo' /*case 'HideOfficeLogo'*/: break;
17725 case 'spreadsheetautofit' /*case 'SpreadsheetAutoFit'*/: break;
17726 case 'label' /*case 'Label'*/: break;
17727 case 'caption' /*case 'Caption'*/: break;
17728 case 'maxheight' /*case 'MaxHeight'*/: break;
17729 case 'maxwidth' /*case 'MaxWidth'*/: break;
17730 case 'nextsheetnumber' /*case 'NextSheetNumber'*/: break;
17731 default: seen = false;
17732 } break;
17733
17734 /* ExcelWorkbook */
17735 case 'excelworkbook' /*case 'ExcelWorkbook'*/: switch(Rn[3]) {
17736 case 'date1904' /*case 'Date1904'*/:
17737 /*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
17738 Workbook.WBProps.date1904 = true;
17739 break;
17740 case 'windowheight' /*case 'WindowHeight'*/: break;
17741 case 'windowwidth' /*case 'WindowWidth'*/: break;
17742 case 'windowtopx' /*case 'WindowTopX'*/: break;
17743 case 'windowtopy' /*case 'WindowTopY'*/: break;
17744 case 'tabratio' /*case 'TabRatio'*/: break;
17745 case 'protectstructure' /*case 'ProtectStructure'*/: break;
17746 case 'protectwindow' /*case 'ProtectWindow'*/: break;
17747 case 'protectwindows' /*case 'ProtectWindows'*/: break;
17748 case 'activesheet' /*case 'ActiveSheet'*/: break;
17749 case 'displayinknotes' /*case 'DisplayInkNotes'*/: break;
17750 case 'firstvisiblesheet' /*case 'FirstVisibleSheet'*/: break;
17751 case 'supbook' /*case 'SupBook'*/: break;
17752 case 'sheetname' /*case 'SheetName'*/: break;
17753 case 'sheetindex' /*case 'SheetIndex'*/: break;
17754 case 'sheetindexfirst' /*case 'SheetIndexFirst'*/: break;
17755 case 'sheetindexlast' /*case 'SheetIndexLast'*/: break;
17756 case 'dll' /*case 'Dll'*/: break;
17757 case 'acceptlabelsinformulas' /*case 'AcceptLabelsInFormulas'*/: break;
17758 case 'donotsavelinkvalues' /*case 'DoNotSaveLinkValues'*/: break;
17759 case 'iteration' /*case 'Iteration'*/: break;
17760 case 'maxiterations' /*case 'MaxIterations'*/: break;
17761 case 'maxchange' /*case 'MaxChange'*/: break;
17762 case 'path' /*case 'Path'*/: break;
17763 case 'xct' /*case 'Xct'*/: break;
17764 case 'count' /*case 'Count'*/: break;
17765 case 'selectedsheets' /*case 'SelectedSheets'*/: break;
17766 case 'calculation' /*case 'Calculation'*/: break;
17767 case 'uncalced' /*case 'Uncalced'*/: break;
17768 case 'startupprompt' /*case 'StartupPrompt'*/: break;
17769 case 'crn' /*case 'Crn'*/: break;
17770 case 'externname' /*case 'ExternName'*/: break;
17771 case 'formula' /*case 'Formula'*/: break;
17772 case 'colfirst' /*case 'ColFirst'*/: break;
17773 case 'collast' /*case 'ColLast'*/: break;
17774 case 'wantadvise' /*case 'WantAdvise'*/: break;
17775 case 'boolean' /*case 'Boolean'*/: break;
17776 case 'error' /*case 'Error'*/: break;
17777 case 'text' /*case 'Text'*/: break;
17778 case 'ole' /*case 'OLE'*/: break;
17779 case 'noautorecover' /*case 'NoAutoRecover'*/: break;
17780 case 'publishobjects' /*case 'PublishObjects'*/: break;
17781 case 'donotcalculatebeforesave' /*case 'DoNotCalculateBeforeSave'*/: break;
17782 case 'number' /*case 'Number'*/: break;
17783 case 'refmoder1c1' /*case 'RefModeR1C1'*/: break;
17784 case 'embedsavesmarttags' /*case 'EmbedSaveSmartTags'*/: break;
17785 default: seen = false;
17786 } break;
17787
17788 /* WorkbookOptions */
17789 case 'workbookoptions' /*case 'WorkbookOptions'*/: switch(Rn[3]) {
17790 case 'owcversion' /*case 'OWCVersion'*/: break;
17791 case 'height' /*case 'Height'*/: break;
17792 case 'width' /*case 'Width'*/: break;
17793 default: seen = false;
17794 } break;
17795
17796 /* WorksheetOptions */
17797 case 'worksheetoptions' /*case 'WorksheetOptions'*/: switch(Rn[3]) {
17798 case 'visible' /*case 'Visible'*/:
17799 if(Rn[0].slice(-2) === "/>"){/* empty */}
17800 else if(Rn[1]==="/") switch(str.slice(pidx, Rn.index)) {
17801 case "SheetHidden": wsprops.Hidden = 1; break;
17802 case "SheetVeryHidden": wsprops.Hidden = 2; break;
17803 }
17804 else pidx = Rn.index + Rn[0].length;
17805 break;
17806 case 'header' /*case 'Header'*/:
17807 if(!cursheet['!margins']) default_margins(cursheet['!margins']={}, 'xlml');
17808 if(!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].header = +parsexmltag(Rn[0]).Margin;
17809 break;
17810 case 'footer' /*case 'Footer'*/:
17811 if(!cursheet['!margins']) default_margins(cursheet['!margins']={}, 'xlml');
17812 if(!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].footer = +parsexmltag(Rn[0]).Margin;
17813 break;
17814 case 'pagemargins' /*case 'PageMargins'*/:
17815 var pagemargins = parsexmltag(Rn[0]);
17816 if(!cursheet['!margins']) default_margins(cursheet['!margins']={},'xlml');
17817 if(!isNaN(+pagemargins.Top)) cursheet['!margins'].top = +pagemargins.Top;
17818 if(!isNaN(+pagemargins.Left)) cursheet['!margins'].left = +pagemargins.Left;
17819 if(!isNaN(+pagemargins.Right)) cursheet['!margins'].right = +pagemargins.Right;
17820 if(!isNaN(+pagemargins.Bottom)) cursheet['!margins'].bottom = +pagemargins.Bottom;
17821 break;
17822 case 'displayrighttoleft' /*case 'DisplayRightToLeft'*/:
17823 if(!Workbook.Views) Workbook.Views = [];
17824 if(!Workbook.Views[0]) Workbook.Views[0] = {};
17825 Workbook.Views[0].RTL = true;
17826 break;
17827
17828 case 'freezepanes' /*case 'FreezePanes'*/: break;
17829 case 'frozennosplit' /*case 'FrozenNoSplit'*/: break;
17830
17831 case 'splithorizontal' /*case 'SplitHorizontal'*/:
17832 case 'splitvertical' /*case 'SplitVertical'*/:
17833 break;
17834
17835 case 'donotdisplaygridlines' /*case 'DoNotDisplayGridlines'*/:
17836 break;
17837
17838 case 'activerow' /*case 'ActiveRow'*/: break;
17839 case 'activecol' /*case 'ActiveCol'*/: break;
17840 case 'toprowbottompane' /*case 'TopRowBottomPane'*/: break;
17841 case 'leftcolumnrightpane' /*case 'LeftColumnRightPane'*/: break;
17842
17843 case 'unsynced' /*case 'Unsynced'*/: break;
17844 case 'print' /*case 'Print'*/: break;
17845 case 'printerrors' /*case 'PrintErrors'*/: break;
17846 case 'panes' /*case 'Panes'*/: break;
17847 case 'scale' /*case 'Scale'*/: break;
17848 case 'pane' /*case 'Pane'*/: break;
17849 case 'number' /*case 'Number'*/: break;
17850 case 'layout' /*case 'Layout'*/: break;
17851 case 'pagesetup' /*case 'PageSetup'*/: break;
17852 case 'selected' /*case 'Selected'*/: break;
17853 case 'protectobjects' /*case 'ProtectObjects'*/: break;
17854 case 'enableselection' /*case 'EnableSelection'*/: break;
17855 case 'protectscenarios' /*case 'ProtectScenarios'*/: break;
17856 case 'validprinterinfo' /*case 'ValidPrinterInfo'*/: break;
17857 case 'horizontalresolution' /*case 'HorizontalResolution'*/: break;
17858 case 'verticalresolution' /*case 'VerticalResolution'*/: break;
17859 case 'numberofcopies' /*case 'NumberofCopies'*/: break;
17860 case 'activepane' /*case 'ActivePane'*/: break;
17861 case 'toprowvisible' /*case 'TopRowVisible'*/: break;
17862 case 'leftcolumnvisible' /*case 'LeftColumnVisible'*/: break;
17863 case 'fittopage' /*case 'FitToPage'*/: break;
17864 case 'rangeselection' /*case 'RangeSelection'*/: break;
17865 case 'papersizeindex' /*case 'PaperSizeIndex'*/: break;
17866 case 'pagelayoutzoom' /*case 'PageLayoutZoom'*/: break;
17867 case 'pagebreakzoom' /*case 'PageBreakZoom'*/: break;
17868 case 'filteron' /*case 'FilterOn'*/: break;
17869 case 'fitwidth' /*case 'FitWidth'*/: break;
17870 case 'fitheight' /*case 'FitHeight'*/: break;
17871 case 'commentslayout' /*case 'CommentsLayout'*/: break;
17872 case 'zoom' /*case 'Zoom'*/: break;
17873 case 'lefttoright' /*case 'LeftToRight'*/: break;
17874 case 'gridlines' /*case 'Gridlines'*/: break;
17875 case 'allowsort' /*case 'AllowSort'*/: break;
17876 case 'allowfilter' /*case 'AllowFilter'*/: break;
17877 case 'allowinsertrows' /*case 'AllowInsertRows'*/: break;
17878 case 'allowdeleterows' /*case 'AllowDeleteRows'*/: break;
17879 case 'allowinsertcols' /*case 'AllowInsertCols'*/: break;
17880 case 'allowdeletecols' /*case 'AllowDeleteCols'*/: break;
17881 case 'allowinserthyperlinks' /*case 'AllowInsertHyperlinks'*/: break;
17882 case 'allowformatcells' /*case 'AllowFormatCells'*/: break;
17883 case 'allowsizecols' /*case 'AllowSizeCols'*/: break;
17884 case 'allowsizerows' /*case 'AllowSizeRows'*/: break;
17885 case 'nosummaryrowsbelowdetail' /*case 'NoSummaryRowsBelowDetail'*/:
17886 if(!cursheet["!outline"]) cursheet["!outline"] = {};
17887 cursheet["!outline"].above = true;
17888 break;
17889 case 'tabcolorindex' /*case 'TabColorIndex'*/: break;
17890 case 'donotdisplayheadings' /*case 'DoNotDisplayHeadings'*/: break;
17891 case 'showpagelayoutzoom' /*case 'ShowPageLayoutZoom'*/: break;
17892 case 'nosummarycolumnsrightdetail' /*case 'NoSummaryColumnsRightDetail'*/:
17893 if(!cursheet["!outline"]) cursheet["!outline"] = {};
17894 cursheet["!outline"].left = true;
17895 break;
17896 case 'blackandwhite' /*case 'BlackAndWhite'*/: break;
17897 case 'donotdisplayzeros' /*case 'DoNotDisplayZeros'*/: break;
17898 case 'displaypagebreak' /*case 'DisplayPageBreak'*/: break;
17899 case 'rowcolheadings' /*case 'RowColHeadings'*/: break;
17900 case 'donotdisplayoutline' /*case 'DoNotDisplayOutline'*/: break;
17901 case 'noorientation' /*case 'NoOrientation'*/: break;
17902 case 'allowusepivottables' /*case 'AllowUsePivotTables'*/: break;
17903 case 'zeroheight' /*case 'ZeroHeight'*/: break;
17904 case 'viewablerange' /*case 'ViewableRange'*/: break;
17905 case 'selection' /*case 'Selection'*/: break;
17906 case 'protectcontents' /*case 'ProtectContents'*/: break;
17907 default: seen = false;
17908 } break;
17909
17910 /* PivotTable */
17911 case 'pivottable' /*case 'PivotTable'*/: case 'pivotcache' /*case 'PivotCache'*/: switch(Rn[3]) {
17912 case 'immediateitemsondrop' /*case 'ImmediateItemsOnDrop'*/: break;
17913 case 'showpagemultipleitemlabel' /*case 'ShowPageMultipleItemLabel'*/: break;
17914 case 'compactrowindent' /*case 'CompactRowIndent'*/: break;
17915 case 'location' /*case 'Location'*/: break;
17916 case 'pivotfield' /*case 'PivotField'*/: break;
17917 case 'orientation' /*case 'Orientation'*/: break;
17918 case 'layoutform' /*case 'LayoutForm'*/: break;
17919 case 'layoutsubtotallocation' /*case 'LayoutSubtotalLocation'*/: break;
17920 case 'layoutcompactrow' /*case 'LayoutCompactRow'*/: break;
17921 case 'position' /*case 'Position'*/: break;
17922 case 'pivotitem' /*case 'PivotItem'*/: break;
17923 case 'datatype' /*case 'DataType'*/: break;
17924 case 'datafield' /*case 'DataField'*/: break;
17925 case 'sourcename' /*case 'SourceName'*/: break;
17926 case 'parentfield' /*case 'ParentField'*/: break;
17927 case 'ptlineitems' /*case 'PTLineItems'*/: break;
17928 case 'ptlineitem' /*case 'PTLineItem'*/: break;
17929 case 'countofsameitems' /*case 'CountOfSameItems'*/: break;
17930 case 'item' /*case 'Item'*/: break;
17931 case 'itemtype' /*case 'ItemType'*/: break;
17932 case 'ptsource' /*case 'PTSource'*/: break;
17933 case 'cacheindex' /*case 'CacheIndex'*/: break;
17934 case 'consolidationreference' /*case 'ConsolidationReference'*/: break;
17935 case 'filename' /*case 'FileName'*/: break;
17936 case 'reference' /*case 'Reference'*/: break;
17937 case 'nocolumngrand' /*case 'NoColumnGrand'*/: break;
17938 case 'norowgrand' /*case 'NoRowGrand'*/: break;
17939 case 'blanklineafteritems' /*case 'BlankLineAfterItems'*/: break;
17940 case 'hidden' /*case 'Hidden'*/: break;
17941 case 'subtotal' /*case 'Subtotal'*/: break;
17942 case 'basefield' /*case 'BaseField'*/: break;
17943 case 'mapchilditems' /*case 'MapChildItems'*/: break;
17944 case 'function' /*case 'Function'*/: break;
17945 case 'refreshonfileopen' /*case 'RefreshOnFileOpen'*/: break;
17946 case 'printsettitles' /*case 'PrintSetTitles'*/: break;
17947 case 'mergelabels' /*case 'MergeLabels'*/: break;
17948 case 'defaultversion' /*case 'DefaultVersion'*/: break;
17949 case 'refreshname' /*case 'RefreshName'*/: break;
17950 case 'refreshdate' /*case 'RefreshDate'*/: break;
17951 case 'refreshdatecopy' /*case 'RefreshDateCopy'*/: break;
17952 case 'versionlastrefresh' /*case 'VersionLastRefresh'*/: break;
17953 case 'versionlastupdate' /*case 'VersionLastUpdate'*/: break;
17954 case 'versionupdateablemin' /*case 'VersionUpdateableMin'*/: break;
17955 case 'versionrefreshablemin' /*case 'VersionRefreshableMin'*/: break;
17956 case 'calculation' /*case 'Calculation'*/: break;
17957 default: seen = false;
17958 } break;
17959
17960 /* PageBreaks */
17961 case 'pagebreaks' /*case 'PageBreaks'*/: switch(Rn[3]) {
17962 case 'colbreaks' /*case 'ColBreaks'*/: break;
17963 case 'colbreak' /*case 'ColBreak'*/: break;
17964 case 'rowbreaks' /*case 'RowBreaks'*/: break;
17965 case 'rowbreak' /*case 'RowBreak'*/: break;
17966 case 'colstart' /*case 'ColStart'*/: break;
17967 case 'colend' /*case 'ColEnd'*/: break;
17968 case 'rowend' /*case 'RowEnd'*/: break;
17969 default: seen = false;
17970 } break;
17971
17972 /* AutoFilter */
17973 case 'autofilter' /*case 'AutoFilter'*/: switch(Rn[3]) {
17974 case 'autofiltercolumn' /*case 'AutoFilterColumn'*/: break;
17975 case 'autofiltercondition' /*case 'AutoFilterCondition'*/: break;
17976 case 'autofilterand' /*case 'AutoFilterAnd'*/: break;
17977 case 'autofilteror' /*case 'AutoFilterOr'*/: break;
17978 default: seen = false;
17979 } break;
17980
17981 /* QueryTable */
17982 case 'querytable' /*case 'QueryTable'*/: switch(Rn[3]) {
17983 case 'id' /*case 'Id'*/: break;
17984 case 'autoformatfont' /*case 'AutoFormatFont'*/: break;
17985 case 'autoformatpattern' /*case 'AutoFormatPattern'*/: break;
17986 case 'querysource' /*case 'QuerySource'*/: break;
17987 case 'querytype' /*case 'QueryType'*/: break;
17988 case 'enableredirections' /*case 'EnableRedirections'*/: break;
17989 case 'refreshedinxl9' /*case 'RefreshedInXl9'*/: break;
17990 case 'urlstring' /*case 'URLString'*/: break;
17991 case 'htmltables' /*case 'HTMLTables'*/: break;
17992 case 'connection' /*case 'Connection'*/: break;
17993 case 'commandtext' /*case 'CommandText'*/: break;
17994 case 'refreshinfo' /*case 'RefreshInfo'*/: break;
17995 case 'notitles' /*case 'NoTitles'*/: break;
17996 case 'nextid' /*case 'NextId'*/: break;
17997 case 'columninfo' /*case 'ColumnInfo'*/: break;
17998 case 'overwritecells' /*case 'OverwriteCells'*/: break;
17999 case 'donotpromptforfile' /*case 'DoNotPromptForFile'*/: break;
18000 case 'textwizardsettings' /*case 'TextWizardSettings'*/: break;
18001 case 'source' /*case 'Source'*/: break;
18002 case 'number' /*case 'Number'*/: break;
18003 case 'decimal' /*case 'Decimal'*/: break;
18004 case 'thousandseparator' /*case 'ThousandSeparator'*/: break;
18005 case 'trailingminusnumbers' /*case 'TrailingMinusNumbers'*/: break;
18006 case 'formatsettings' /*case 'FormatSettings'*/: break;
18007 case 'fieldtype' /*case 'FieldType'*/: break;
18008 case 'delimiters' /*case 'Delimiters'*/: break;
18009 case 'tab' /*case 'Tab'*/: break;
18010 case 'comma' /*case 'Comma'*/: break;
18011 case 'autoformatname' /*case 'AutoFormatName'*/: break;
18012 case 'versionlastedit' /*case 'VersionLastEdit'*/: break;
18013 case 'versionlastrefresh' /*case 'VersionLastRefresh'*/: break;
18014 default: seen = false;
18015 } break;
18016
18017 case 'datavalidation' /*case 'DataValidation'*/:
18018 switch(Rn[3]) {
18019 case 'range' /*case 'Range'*/: break;
18020
18021 case 'type' /*case 'Type'*/: break;
18022 case 'min' /*case 'Min'*/: break;
18023 case 'max' /*case 'Max'*/: break;
18024 case 'sort' /*case 'Sort'*/: break;
18025 case 'descending' /*case 'Descending'*/: break;
18026 case 'order' /*case 'Order'*/: break;
18027 case 'casesensitive' /*case 'CaseSensitive'*/: break;
18028 case 'value' /*case 'Value'*/: break;
18029 case 'errorstyle' /*case 'ErrorStyle'*/: break;
18030 case 'errormessage' /*case 'ErrorMessage'*/: break;
18031 case 'errortitle' /*case 'ErrorTitle'*/: break;
18032 case 'inputmessage' /*case 'InputMessage'*/: break;
18033 case 'inputtitle' /*case 'InputTitle'*/: break;
18034 case 'combohide' /*case 'ComboHide'*/: break;
18035 case 'inputhide' /*case 'InputHide'*/: break;
18036 case 'condition' /*case 'Condition'*/: break;
18037 case 'qualifier' /*case 'Qualifier'*/: break;
18038 case 'useblank' /*case 'UseBlank'*/: break;
18039 case 'value1' /*case 'Value1'*/: break;
18040 case 'value2' /*case 'Value2'*/: break;
18041 case 'format' /*case 'Format'*/: break;
18042
18043 case 'cellrangelist' /*case 'CellRangeList'*/: break;
18044 default: seen = false;
18045 } break;
18046
18047 case 'sorting' /*case 'Sorting'*/:
18048 case 'conditionalformatting' /*case 'ConditionalFormatting'*/:
18049 switch(Rn[3]) {
18050 case 'range' /*case 'Range'*/: break;
18051 case 'type' /*case 'Type'*/: break;
18052 case 'min' /*case 'Min'*/: break;
18053 case 'max' /*case 'Max'*/: break;
18054 case 'sort' /*case 'Sort'*/: break;
18055 case 'descending' /*case 'Descending'*/: break;
18056 case 'order' /*case 'Order'*/: break;
18057 case 'casesensitive' /*case 'CaseSensitive'*/: break;
18058 case 'value' /*case 'Value'*/: break;
18059 case 'errorstyle' /*case 'ErrorStyle'*/: break;
18060 case 'errormessage' /*case 'ErrorMessage'*/: break;
18061 case 'errortitle' /*case 'ErrorTitle'*/: break;
18062 case 'cellrangelist' /*case 'CellRangeList'*/: break;
18063 case 'inputmessage' /*case 'InputMessage'*/: break;
18064 case 'inputtitle' /*case 'InputTitle'*/: break;
18065 case 'combohide' /*case 'ComboHide'*/: break;
18066 case 'inputhide' /*case 'InputHide'*/: break;
18067 case 'condition' /*case 'Condition'*/: break;
18068 case 'qualifier' /*case 'Qualifier'*/: break;
18069 case 'useblank' /*case 'UseBlank'*/: break;
18070 case 'value1' /*case 'Value1'*/: break;
18071 case 'value2' /*case 'Value2'*/: break;
18072 case 'format' /*case 'Format'*/: break;
18073 default: seen = false;
18074 } break;
18075
18076 /* MapInfo (schema) */
18077 case 'mapinfo' /*case 'MapInfo'*/: case 'schema' /*case 'Schema'*/: case 'data' /*case 'data'*/: switch(Rn[3]) {
18078 case 'map' /*case 'Map'*/: break;
18079 case 'entry' /*case 'Entry'*/: break;
18080 case 'range' /*case 'Range'*/: break;
18081 case 'xpath' /*case 'XPath'*/: break;
18082 case 'field' /*case 'Field'*/: break;
18083 case 'xsdtype' /*case 'XSDType'*/: break;
18084 case 'filteron' /*case 'FilterOn'*/: break;
18085 case 'aggregate' /*case 'Aggregate'*/: break;
18086 case 'elementtype' /*case 'ElementType'*/: break;
18087 case 'attributetype' /*case 'AttributeType'*/: break;
18088 /* These are from xsd (XML Schema Definition) */
18089 case 'schema' /*case 'schema'*/:
18090 case 'element' /*case 'element'*/:
18091 case 'complextype' /*case 'complexType'*/:
18092 case 'datatype' /*case 'datatype'*/:
18093 case 'all' /*case 'all'*/:
18094 case 'attribute' /*case 'attribute'*/:
18095 case 'extends' /*case 'extends'*/: break;
18096
18097 case 'row' /*case 'row'*/: break;
18098 default: seen = false;
18099 } break;
18100
18101 /* SmartTags (can be anything) */
18102 case 'smarttags' /*case 'SmartTags'*/: break;
18103
18104 default: seen = false; break;
18105 }
18106 if(seen) break;
18107 /* CustomDocumentProperties */
18108 if(Rn[3].match(/!\[CDATA/)) break;
18109 if(!state[state.length-1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
18110 if(state[state.length-1][0]===/*'CustomDocumentProperties'*/'customdocumentproperties') {
18111 if(Rn[0].slice(-2) === "/>") break;
18112 else if(Rn[1]==="/") xlml_set_custprop(Custprops, raw_Rn3, cp, str.slice(pidx, Rn.index));
18113 else { cp = Rn; pidx = Rn.index + Rn[0].length; }
18114 break;
18115 }
18116 if(opts.WTF) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
18117 }
18118 var out = ({}/*:any*/);
18119 if(!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
18120 out.SheetNames = sheetnames;
18121 out.Workbook = Workbook;
18122 out.SSF = dup(table_fmt);
18123 out.Props = Props;
18124 out.Custprops = Custprops;
18125 return out;
18126}
18127
18128function parse_xlml(data/*:RawBytes|string*/, opts)/*:Workbook*/ {
18129 fix_read_opts(opts=opts||{});
18130 switch(opts.type||"base64") {
18131 case "base64": return parse_xlml_xml(Base64_decode(data), opts);
18132 case "binary": case "buffer": case "file": return parse_xlml_xml(data, opts);
18133 case "array": return parse_xlml_xml(a2s(data), opts);
18134 }
18135 /*:: throw new Error("unsupported type " + opts.type); */
18136}
18137
18138/* TODO */
18139function write_props_xlml(wb/*:Workbook*/, opts)/*:string*/ {
18140 var o/*:Array<string>*/ = [];
18141 /* DocumentProperties */
18142 if(wb.Props) o.push(xlml_write_docprops(wb.Props, opts));
18143 /* CustomDocumentProperties */
18144 if(wb.Custprops) o.push(xlml_write_custprops(wb.Props, wb.Custprops, opts));
18145 return o.join("");
18146}
18147/* TODO */
18148function write_wb_xlml(/*::wb, opts*/)/*:string*/ {
18149 /* OfficeDocumentSettings */
18150 /* ExcelWorkbook */
18151 return "";
18152}
18153/* TODO */
18154function write_sty_xlml(wb, opts)/*:string*/ {
18155 /* Styles */
18156 var styles/*:Array<string>*/ = ['<Style ss:ID="Default" ss:Name="Normal"><NumberFormat/></Style>'];
18157 opts.cellXfs.forEach(function(xf, id) {
18158 var payload/*:Array<string>*/ = [];
18159 payload.push(writextag('NumberFormat', null, {"ss:Format": escapexml(table_fmt[xf.numFmtId])}));
18160
18161 var o = /*::(*/{"ss:ID": "s" + (21+id)}/*:: :any)*/;
18162 styles.push(writextag('Style', payload.join(""), o));
18163 });
18164 return writextag("Styles", styles.join(""));
18165}
18166function write_name_xlml(n) { return writextag("NamedRange", null, {"ss:Name": n.Name, "ss:RefersTo":"=" + a1_to_rc(n.Ref, {r:0,c:0})}); }
18167function write_names_xlml(wb/*::, opts*/)/*:string*/ {
18168 if(!((wb||{}).Workbook||{}).Names) return "";
18169 /*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
18170 var names/*:Array<any>*/ = wb.Workbook.Names;
18171 var out/*:Array<string>*/ = [];
18172 for(var i = 0; i < names.length; ++i) {
18173 var n = names[i];
18174 if(n.Sheet != null) continue;
18175 if(n.Name.match(/^_xlfn\./)) continue;
18176 out.push(write_name_xlml(n));
18177 }
18178 return writextag("Names", out.join(""));
18179}
18180function write_ws_xlml_names(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
18181 if(!ws) return "";
18182 if(!((wb||{}).Workbook||{}).Names) return "";
18183 /*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
18184 var names/*:Array<any>*/ = wb.Workbook.Names;
18185 var out/*:Array<string>*/ = [];
18186 for(var i = 0; i < names.length; ++i) {
18187 var n = names[i];
18188 if(n.Sheet != idx) continue;
18189 /*switch(n.Name) {
18190 case "_": continue;
18191 }*/
18192 if(n.Name.match(/^_xlfn\./)) continue;
18193 out.push(write_name_xlml(n));
18194 }
18195 return out.join("");
18196}
18197/* WorksheetOptions */
18198function write_ws_xlml_wsopts(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
18199 if(!ws) return "";
18200 var o/*:Array<string>*/ = [];
18201 /* NOTE: spec technically allows any order, but stick with implied order */
18202
18203 /* FitToPage */
18204 /* DoNotDisplayColHeaders */
18205 /* DoNotDisplayRowHeaders */
18206 /* ViewableRange */
18207 /* Selection */
18208 /* GridlineColor */
18209 /* Name */
18210 /* ExcelWorksheetType */
18211 /* IntlMacro */
18212 /* Unsynced */
18213 /* Selected */
18214 /* CodeName */
18215
18216 if(ws['!margins']) {
18217 o.push("<PageSetup>");
18218 if(ws['!margins'].header) o.push(writextag("Header", null, {'x:Margin':ws['!margins'].header}));
18219 if(ws['!margins'].footer) o.push(writextag("Footer", null, {'x:Margin':ws['!margins'].footer}));
18220 o.push(writextag("PageMargins", null, {
18221 'x:Bottom': ws['!margins'].bottom || "0.75",
18222 'x:Left': ws['!margins'].left || "0.7",
18223 'x:Right': ws['!margins'].right || "0.7",
18224 'x:Top': ws['!margins'].top || "0.75"
18225 }));
18226 o.push("</PageSetup>");
18227 }
18228
18229 /* PageSetup */
18230 /* DisplayPageBreak */
18231 /* TransitionExpressionEvaluation */
18232 /* TransitionFormulaEntry */
18233 /* Print */
18234 /* Zoom */
18235 /* PageLayoutZoom */
18236 /* PageBreakZoom */
18237 /* ShowPageBreakZoom */
18238 /* DefaultRowHeight */
18239 /* DefaultColumnWidth */
18240 /* StandardWidth */
18241
18242 if(wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
18243 /* Visible */
18244 if(wb.Workbook.Sheets[idx].Hidden) o.push(writextag("Visible", (wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden"), {}));
18245 else {
18246 /* Selected */
18247 for(var i = 0; i < idx; ++i) if(wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
18248 if(i == idx) o.push("<Selected/>");
18249 }
18250 }
18251
18252 /* LeftColumnVisible */
18253
18254 if(((((wb||{}).Workbook||{}).Views||[])[0]||{}).RTL) o.push("<DisplayRightToLeft/>");
18255
18256 /* GridlineColorIndex */
18257 /* DisplayFormulas */
18258 /* DoNotDisplayGridlines */
18259 /* DoNotDisplayHeadings */
18260 /* DoNotDisplayOutline */
18261 /* ApplyAutomaticOutlineStyles */
18262 /* NoSummaryRowsBelowDetail */
18263 /* NoSummaryColumnsRightDetail */
18264 /* DoNotDisplayZeros */
18265 /* ActiveRow */
18266 /* ActiveColumn */
18267 /* FilterOn */
18268 /* RangeSelection */
18269 /* TopRowVisible */
18270 /* TopRowBottomPane */
18271 /* LeftColumnRightPane */
18272 /* ActivePane */
18273 /* SplitHorizontal */
18274 /* SplitVertical */
18275 /* FreezePanes */
18276 /* FrozenNoSplit */
18277 /* TabColorIndex */
18278 /* Panes */
18279
18280 /* NOTE: Password not supported in XLML Format */
18281 if(ws['!protect']) {
18282 o.push(writetag("ProtectContents", "True"));
18283 if(ws['!protect'].objects) o.push(writetag("ProtectObjects", "True"));
18284 if(ws['!protect'].scenarios) o.push(writetag("ProtectScenarios", "True"));
18285 if(ws['!protect'].selectLockedCells != null && !ws['!protect'].selectLockedCells) o.push(writetag("EnableSelection", "NoSelection"));
18286 else if(ws['!protect'].selectUnlockedCells != null && !ws['!protect'].selectUnlockedCells) o.push(writetag("EnableSelection", "UnlockedCells"));
18287 [
18288 [ "formatCells", "AllowFormatCells" ],
18289 [ "formatColumns", "AllowSizeCols" ],
18290 [ "formatRows", "AllowSizeRows" ],
18291 [ "insertColumns", "AllowInsertCols" ],
18292 [ "insertRows", "AllowInsertRows" ],
18293 [ "insertHyperlinks", "AllowInsertHyperlinks" ],
18294 [ "deleteColumns", "AllowDeleteCols" ],
18295 [ "deleteRows", "AllowDeleteRows" ],
18296 [ "sort", "AllowSort" ],
18297 [ "autoFilter", "AllowFilter" ],
18298 [ "pivotTables", "AllowUsePivotTables" ]
18299 ].forEach(function(x) { if(ws['!protect'][x[0]]) o.push("<"+x[1]+"/>"); });
18300 }
18301
18302 if(o.length == 0) return "";
18303 return writextag("WorksheetOptions", o.join(""), {xmlns:XLMLNS.x});
18304}
18305function write_ws_xlml_comment(comments/*:Array<any>*/)/*:string*/ {
18306 return comments.map(function(c) {
18307 // TODO: formatted text
18308 var t = xlml_unfixstr(c.t||"");
18309 var d =writextag("ss:Data", t, {"xmlns":"http://www.w3.org/TR/REC-html40"});
18310 return writextag("Comment", d, {"ss:Author":c.a});
18311 }).join("");
18312}
18313function write_ws_xlml_cell(cell, ref/*:string*/, ws, opts, idx/*:number*/, wb, addr)/*:string*/{
18314 if(!cell || (cell.v == undefined && cell.f == undefined)) return "";
18315
18316 var attr = {};
18317 if(cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
18318 if(cell.F && cell.F.slice(0, ref.length) == ref) {
18319 var end = decode_cell(cell.F.slice(ref.length + 1));
18320 attr["ss:ArrayRange"] = "RC:R" + (end.r == addr.r ? "" : "[" + (end.r - addr.r) + "]") + "C" + (end.c == addr.c ? "" : "[" + (end.c - addr.c) + "]");
18321 }
18322
18323 if(cell.l && cell.l.Target) {
18324 attr["ss:HRef"] = escapexml(cell.l.Target);
18325 if(cell.l.Tooltip) attr["x:HRefScreenTip"] = escapexml(cell.l.Tooltip);
18326 }
18327
18328 if(ws['!merges']) {
18329 var marr = ws['!merges'];
18330 for(var mi = 0; mi != marr.length; ++mi) {
18331 if(marr[mi].s.c != addr.c || marr[mi].s.r != addr.r) continue;
18332 if(marr[mi].e.c > marr[mi].s.c) attr['ss:MergeAcross'] = marr[mi].e.c - marr[mi].s.c;
18333 if(marr[mi].e.r > marr[mi].s.r) attr['ss:MergeDown'] = marr[mi].e.r - marr[mi].s.r;
18334 }
18335 }
18336
18337 var t = "", p = "";
18338 switch(cell.t) {
18339 case 'z': if(!opts.sheetStubs) return ""; break;
18340 case 'n': t = 'Number'; p = String(cell.v); break;
18341 case 'b': t = 'Boolean'; p = (cell.v ? "1" : "0"); break;
18342 case 'e': t = 'Error'; p = BErr[cell.v]; break;
18343 case 'd': t = 'DateTime'; p = new Date(cell.v).toISOString(); if(cell.z == null) cell.z = cell.z || table_fmt[14]; break;
18344 case 's': t = 'String'; p = escapexlml(cell.v||""); break;
18345 }
18346 /* TODO: cell style */
18347 var os = get_cell_style(opts.cellXfs, cell, opts);
18348 attr["ss:StyleID"] = "s" + (21+os);
18349 attr["ss:Index"] = addr.c + 1;
18350 var _v = (cell.v != null ? p : "");
18351 var m = cell.t == 'z' ? "" : ('<Data ss:Type="' + t + '">' + _v + '</Data>');
18352
18353 if((cell.c||[]).length > 0) m += write_ws_xlml_comment(cell.c);
18354
18355 return writextag("Cell", m, attr);
18356}
18357function write_ws_xlml_row(R/*:number*/, row)/*:string*/ {
18358 var o = '<Row ss:Index="' + (R+1) + '"';
18359 if(row) {
18360 if(row.hpt && !row.hpx) row.hpx = pt2px(row.hpt);
18361 if(row.hpx) o += ' ss:AutoFitHeight="0" ss:Height="' + row.hpx + '"';
18362 if(row.hidden) o += ' ss:Hidden="1"';
18363 }
18364 return o + '>';
18365}
18366/* TODO */
18367function write_ws_xlml_table(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook*/)/*:string*/ {
18368 if(!ws['!ref']) return "";
18369 var range/*:Range*/ = safe_decode_range(ws['!ref']);
18370 var marr/*:Array<Range>*/ = ws['!merges'] || [], mi = 0;
18371 var o/*:Array<string>*/ = [];
18372 if(ws['!cols']) ws['!cols'].forEach(function(n, i) {
18373 process_col(n);
18374 var w = !!n.width;
18375 var p = col_obj_w(i, n);
18376 var k/*:any*/ = {"ss:Index":i+1};
18377 if(w) k['ss:Width'] = width2px(p.width);
18378 if(n.hidden) k['ss:Hidden']="1";
18379 o.push(writextag("Column",null,k));
18380 });
18381 var dense = Array.isArray(ws);
18382 for(var R = range.s.r; R <= range.e.r; ++R) {
18383 var row = [write_ws_xlml_row(R, (ws['!rows']||[])[R])];
18384 for(var C = range.s.c; C <= range.e.c; ++C) {
18385 var skip = false;
18386 for(mi = 0; mi != marr.length; ++mi) {
18387 if(marr[mi].s.c > C) continue;
18388 if(marr[mi].s.r > R) continue;
18389 if(marr[mi].e.c < C) continue;
18390 if(marr[mi].e.r < R) continue;
18391 if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
18392 break;
18393 }
18394 if(skip) continue;
18395 var addr = {r:R,c:C};
18396 var ref = encode_cell(addr), cell = dense ? (ws[R]||[])[C] : ws[ref];
18397 row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
18398 }
18399 row.push("</Row>");
18400 if(row.length > 2) o.push(row.join(""));
18401 }
18402 return o.join("");
18403}
18404function write_ws_xlml(idx/*:number*/, opts, wb/*:Workbook*/)/*:string*/ {
18405 var o/*:Array<string>*/ = [];
18406 var s = wb.SheetNames[idx];
18407 var ws = wb.Sheets[s];
18408
18409 var t/*:string*/ = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
18410 if(t.length > 0) o.push("<Names>" + t + "</Names>");
18411
18412 /* Table */
18413 t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
18414 if(t.length > 0) o.push("<Table>" + t + "</Table>");
18415
18416 /* WorksheetOptions */
18417 o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
18418
18419 return o.join("");
18420}
18421function write_xlml(wb, opts)/*:string*/ {
18422 if(!opts) opts = {};
18423 if(!wb.SSF) wb.SSF = dup(table_fmt);
18424 if(wb.SSF) {
18425 make_ssf(); SSF_load_table(wb.SSF);
18426 // $FlowIgnore
18427 opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
18428 opts.ssf = wb.SSF;
18429 opts.cellXfs = [];
18430 get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
18431 }
18432 var d/*:Array<string>*/ = [];
18433 d.push(write_props_xlml(wb, opts));
18434 d.push(write_wb_xlml(wb, opts));
18435 d.push("");
18436 d.push("");
18437 for(var i = 0; i < wb.SheetNames.length; ++i)
18438 d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {"ss:Name":escapexml(wb.SheetNames[i])}));
18439 d[2] = write_sty_xlml(wb, opts);
18440 d[3] = write_names_xlml(wb, opts);
18441 return XML_HEADER + writextag("Workbook", d.join(""), {
18442 'xmlns': XLMLNS.ss,
18443 'xmlns:o': XLMLNS.o,
18444 'xmlns:x': XLMLNS.x,
18445 'xmlns:ss': XLMLNS.ss,
18446 'xmlns:dt': XLMLNS.dt,
18447 'xmlns:html': XLMLNS.html
18448 });
18449}
18450/* [MS-OLEDS] 2.3.8 CompObjStream */
18451function parse_compobj(obj/*:CFBEntry*/) {
18452 var v = {};
18453 var o = obj.content;
18454 /*:: if(o == null) return; */
18455
18456 /* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
18457 o.l = 28;
18458
18459 v.AnsiUserType = o.read_shift(0, "lpstr-ansi");
18460 v.AnsiClipboardFormat = parse_ClipboardFormatOrAnsiString(o);
18461
18462 if(o.length - o.l <= 4) return v;
18463
18464 var m/*:number*/ = o.read_shift(4);
18465 if(m == 0 || m > 40) return v;
18466 o.l-=4; v.Reserved1 = o.read_shift(0, "lpstr-ansi");
18467
18468 if(o.length - o.l <= 4) return v;
18469 m = o.read_shift(4);
18470 if(m !== 0x71b239f4) return v;
18471 v.UnicodeClipboardFormat = parse_ClipboardFormatOrUnicodeString(o);
18472
18473 m = o.read_shift(4);
18474 if(m == 0 || m > 40) return v;
18475 o.l-=4; v.Reserved2 = o.read_shift(0, "lpwstr");
18476}
18477
18478/*
18479 Continue logic for:
18480 - 2.4.58 Continue 0x003c
18481 - 2.4.59 ContinueBigName 0x043c
18482 - 2.4.60 ContinueFrt 0x0812
18483 - 2.4.61 ContinueFrt11 0x0875
18484 - 2.4.62 ContinueFrt12 0x087f
18485*/
18486var CONTINUE_RT = [ 0x003c, 0x043c, 0x0812, 0x0875, 0x087f ];
18487function slurp(RecordType, R, blob, length/*:number*/, opts)/*:any*/ {
18488 var l = length;
18489 var bufs = [];
18490 var d = blob.slice(blob.l,blob.l+l);
18491 if(opts && opts.enc && opts.enc.insitu && d.length > 0) switch(RecordType) {
18492 case 0x0009: case 0x0209: case 0x0409: case 0x0809/* BOF */: case 0x002f /* FilePass */: case 0x0195 /* FileLock */: case 0x00e1 /* InterfaceHdr */: case 0x0196 /* RRDInfo */: case 0x0138 /* RRDHead */: case 0x0194 /* UsrExcl */: case 0x000a /* EOF */:
18493 break;
18494 case 0x0085 /* BoundSheet8 */:
18495 break;
18496 default:
18497 opts.enc.insitu(d);
18498 }
18499 bufs.push(d);
18500 blob.l += l;
18501 var nextrt = __readUInt16LE(blob,blob.l), next = XLSRecordEnum[nextrt];
18502 var start = 0;
18503 while(next != null && CONTINUE_RT.indexOf(nextrt) > -1) {
18504 l = __readUInt16LE(blob,blob.l+2);
18505 start = blob.l + 4;
18506 if(nextrt == 0x0812 /* ContinueFrt */) start += 4;
18507 else if(nextrt == 0x0875 || nextrt == 0x087f) {
18508 start += 12;
18509 }
18510 d = blob.slice(start,blob.l+4+l);
18511 bufs.push(d);
18512 blob.l += 4+l;
18513 next = (XLSRecordEnum[nextrt = __readUInt16LE(blob, blob.l)]);
18514 }
18515 var b = (bconcat(bufs)/*:any*/);
18516 prep_blob(b, 0);
18517 var ll = 0; b.lens = [];
18518 for(var j = 0; j < bufs.length; ++j) { b.lens.push(ll); ll += bufs[j].length; }
18519 if(b.length < length) throw "XLS Record 0x" + RecordType.toString(16) + " Truncated: " + b.length + " < " + length;
18520 return R.f(b, b.length, opts);
18521}
18522
18523function safe_format_xf(p/*:any*/, opts/*:ParseOpts*/, date1904/*:?boolean*/) {
18524 if(p.t === 'z') return;
18525 if(!p.XF) return;
18526 var fmtid = 0;
18527 try {
18528 fmtid = p.z || p.XF.numFmtId || 0;
18529 if(opts.cellNF) p.z = table_fmt[fmtid];
18530 } catch(e) { if(opts.WTF) throw e; }
18531 if(!opts || opts.cellText !== false) try {
18532 if(p.t === 'e') { p.w = p.w || BErr[p.v]; }
18533 else if(fmtid === 0 || fmtid == "General") {
18534 if(p.t === 'n') {
18535 if((p.v|0) === p.v) p.w = p.v.toString(10);
18536 else p.w = SSF_general_num(p.v);
18537 }
18538 else p.w = SSF_general(p.v);
18539 }
18540 else p.w = SSF_format(fmtid,p.v, {date1904:!!date1904, dateNF: opts && opts.dateNF});
18541 } catch(e) { if(opts.WTF) throw e; }
18542 if(opts.cellDates && fmtid && p.t == 'n' && fmt_is_date(table_fmt[fmtid] || String(fmtid))) {
18543 var _d = SSF_parse_date_code(p.v); if(_d) { p.t = 'd'; p.v = new Date(_d.y, _d.m-1,_d.d,_d.H,_d.M,_d.S,_d.u); }
18544 }
18545}
18546
18547function make_cell(val, ixfe, t)/*:Cell*/ {
18548 return ({v:val, ixfe:ixfe, t:t}/*:any*/);
18549}
18550
18551// 2.3.2
18552function parse_workbook(blob, options/*:ParseOpts*/)/*:Workbook*/ {
18553 var wb = ({opts:{}}/*:any*/);
18554 var Sheets = {};
18555 if(DENSE != null && options.dense == null) options.dense = DENSE;
18556 var out/*:Worksheet*/ = ((options.dense ? [] : {})/*:any*/);
18557 var Directory = {};
18558 var range/*:Range*/ = ({}/*:any*/);
18559 var last_formula = null;
18560 var sst/*:SST*/ = ([]/*:any*/);
18561 var cur_sheet = "";
18562 var Preamble = {};
18563 var lastcell, last_cell = "", cc/*:Cell*/, cmnt, rngC, rngR;
18564 var sharedf = {};
18565 var arrayf/*:Array<[Range, string]>*/ = [];
18566 var temp_val/*:Cell*/;
18567 var country;
18568 var XFs = []; /* XF records */
18569 var palette/*:Array<[number, number, number]>*/ = [];
18570 var Workbook/*:WBWBProps*/ = ({ Sheets:[], WBProps:{date1904:false}, Views:[{}] }/*:any*/), wsprops = {};
18571 var get_rgb = function getrgb(icv/*:number*/)/*:[number, number, number]*/ {
18572 if(icv < 8) return XLSIcv[icv];
18573 if(icv < 64) return palette[icv-8] || XLSIcv[icv];
18574 return XLSIcv[icv];
18575 };
18576 var process_cell_style = function pcs(cell, line/*:any*/, options) {
18577 var xfd = line.XF.data;
18578 if(!xfd || !xfd.patternType || !options || !options.cellStyles) return;
18579 line.s = ({}/*:any*/);
18580 line.s.patternType = xfd.patternType;
18581 var t;
18582 if((t = rgb2Hex(get_rgb(xfd.icvFore)))) { line.s.fgColor = {rgb:t}; }
18583 if((t = rgb2Hex(get_rgb(xfd.icvBack)))) { line.s.bgColor = {rgb:t}; }
18584 };
18585 var addcell = function addcell(cell/*:any*/, line/*:any*/, options/*:any*/) {
18586 if(file_depth > 1) return;
18587 if(options.sheetRows && cell.r >= options.sheetRows) return;
18588 if(options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line, options);
18589 delete line.ixfe; delete line.XF;
18590 lastcell = cell;
18591 last_cell = encode_cell(cell);
18592 if(!range || !range.s || !range.e) range = {s:{r:0,c:0},e:{r:0,c:0}};
18593 if(cell.r < range.s.r) range.s.r = cell.r;
18594 if(cell.c < range.s.c) range.s.c = cell.c;
18595 if(cell.r + 1 > range.e.r) range.e.r = cell.r + 1;
18596 if(cell.c + 1 > range.e.c) range.e.c = cell.c + 1;
18597 if(options.cellFormula && line.f) {
18598 for(var afi = 0; afi < arrayf.length; ++afi) {
18599 if(arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue;
18600 if(arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue;
18601 line.F = encode_range(arrayf[afi][0]);
18602 if(arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f;
18603 if(line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts);
18604 break;
18605 }
18606 }
18607 {
18608 if(options.dense) {
18609 if(!out[cell.r]) out[cell.r] = [];
18610 out[cell.r][cell.c] = line;
18611 } else out[last_cell] = line;
18612 }
18613 };
18614 var opts = ({
18615 enc: false, // encrypted
18616 sbcch: 0, // cch in the preceding SupBook
18617 snames: [], // sheetnames
18618 sharedf: sharedf, // shared formulae by address
18619 arrayf: arrayf, // array formulae array
18620 rrtabid: [], // RRTabId
18621 lastuser: "", // Last User from WriteAccess
18622 biff: 8, // BIFF version
18623 codepage: 0, // CP from CodePage record
18624 winlocked: 0, // fLockWn from WinProtect
18625 cellStyles: !!options && !!options.cellStyles,
18626 WTF: !!options && !!options.wtf
18627 }/*:any*/);
18628 if(options.password) opts.password = options.password;
18629 var themes;
18630 var merges/*:Array<Range>*/ = [];
18631 var objects = [];
18632 var colinfo/*:Array<ColInfo>*/ = [], rowinfo/*:Array<RowInfo>*/ = [];
18633 var seencol = false;
18634 var supbooks = ([]/*:any*/); // 1-indexed, will hold extern names
18635 supbooks.SheetNames = opts.snames;
18636 supbooks.sharedf = opts.sharedf;
18637 supbooks.arrayf = opts.arrayf;
18638 supbooks.names = [];
18639 supbooks.XTI = [];
18640 var last_RT = 0;
18641 var file_depth = 0; /* TODO: make a real stack */
18642 var BIFF2Fmt = 0, BIFF2FmtTable/*:Array<string>*/ = [];
18643 var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */
18644 var last_lbl/*:?DefinedName*/;
18645
18646 /* explicit override for some broken writers */
18647 opts.codepage = 1200;
18648 set_cp(1200);
18649 var seen_codepage = false;
18650 while(blob.l < blob.length - 1) {
18651 var s = blob.l;
18652 var RecordType = blob.read_shift(2);
18653 if(RecordType === 0 && last_RT === 0x000a /* EOF */) break;
18654 var length = (blob.l === blob.length ? 0 : blob.read_shift(2));
18655 var R = XLSRecordEnum[RecordType];
18656 //console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length);
18657 //if(!R) console.log(blob.slice(blob.l, blob.l + length));
18658 if(R && R.f) {
18659 if(options.bookSheets) {
18660 if(last_RT === 0x0085 /* BoundSheet8 */ && RecordType !== 0x0085 /* R.n !== 'BoundSheet8' */) break;
18661 }
18662 last_RT = RecordType;
18663 if(R.r === 2 || R.r == 12) {
18664 var rt = blob.read_shift(2); length -= 2;
18665 if(!opts.enc && rt !== RecordType && (((rt&0xFF)<<8)|(rt>>8)) !== RecordType) throw new Error("rt mismatch: " + rt + "!=" + RecordType);
18666 if(R.r == 12){
18667 blob.l += 10; length -= 10;
18668 } // skip FRT
18669 }
18670 //console.error(R,blob.l,length,blob.length);
18671 var val/*:any*/ = ({}/*:any*/);
18672 if(RecordType === 0x000a /* EOF */) val = /*::(*/R.f(blob, length, opts)/*:: :any)*/;
18673 else val = /*::(*/slurp(RecordType, R, blob, length, opts)/*:: :any)*/;
18674 /*:: val = (val:any); */
18675 if(file_depth == 0 && [0x0009, 0x0209, 0x0409, 0x0809].indexOf(last_RT) === -1 /* 'BOF' */) continue;
18676 switch(RecordType) {
18677 case 0x0022 /* Date1904 */:
18678 /*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
18679 wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
18680 case 0x0086 /* WriteProtect */: wb.opts.WriteProtect = true; break;
18681 case 0x002f /* FilePass */:
18682 if(!opts.enc) blob.l = 0;
18683 opts.enc = val;
18684 if(!options.password) throw new Error("File is password-protected");
18685 if(val.valid == null) throw new Error("Encryption scheme unsupported");
18686 if(!val.valid) throw new Error("Password is incorrect");
18687 break;
18688 case 0x005c /* WriteAccess */: opts.lastuser = val; break;
18689 case 0x0042 /* CodePage */:
18690 var cpval = Number(val);
18691 /* overrides based on test cases */
18692 switch(cpval) {
18693 case 0x5212: cpval = 1200; break;
18694 case 0x8000: cpval = 10000; break;
18695 case 0x8001: cpval = 1252; break;
18696 }
18697 set_cp(opts.codepage = cpval);
18698 seen_codepage = true;
18699 break;
18700 case 0x013d /* RRTabId */: opts.rrtabid = val; break;
18701 case 0x0019 /* WinProtect */: opts.winlocked = val; break;
18702 case 0x01b7 /* RefreshAll */: wb.opts["RefreshAll"] = val; break;
18703 case 0x000c /* CalcCount */: wb.opts["CalcCount"] = val; break;
18704 case 0x0010 /* CalcDelta */: wb.opts["CalcDelta"] = val; break;
18705 case 0x0011 /* CalcIter */: wb.opts["CalcIter"] = val; break;
18706 case 0x000d /* CalcMode */: wb.opts["CalcMode"] = val; break;
18707 case 0x000e /* CalcPrecision */: wb.opts["CalcPrecision"] = val; break;
18708 case 0x005f /* CalcSaveRecalc */: wb.opts["CalcSaveRecalc"] = val; break;
18709 case 0x000f /* CalcRefMode */: opts.CalcRefMode = val; break; // TODO: implement R1C1
18710 case 0x08a3 /* ForceFullCalculation */: wb.opts.FullCalc = val; break;
18711 case 0x0081 /* WsBool */:
18712 if(val.fDialog) out["!type"] = "dialog";
18713 if(!val.fBelow) (out["!outline"] || (out["!outline"] = {})).above = true;
18714 if(!val.fRight) (out["!outline"] || (out["!outline"] = {})).left = true;
18715 break; // TODO
18716 case 0x00e0 /* XF */:
18717 XFs.push(val); break;
18718 case 0x01ae /* SupBook */:
18719 supbooks.push([val]);
18720 supbooks[supbooks.length-1].XTI = [];
18721 break;
18722 case 0x0023: case 0x0223 /* ExternName */:
18723 supbooks[supbooks.length-1].push(val);
18724 break;
18725 case 0x0018: case 0x0218 /* Lbl */:
18726 last_lbl = ({
18727 Name: val.Name,
18728 Ref: stringify_formula(val.rgce,range,null,supbooks,opts)
18729 }/*:DefinedName*/);
18730 if(val.itab > 0) last_lbl.Sheet = val.itab - 1;
18731 supbooks.names.push(last_lbl);
18732 if(!supbooks[0]) { supbooks[0] = []; supbooks[0].XTI = []; }
18733 supbooks[supbooks.length-1].push(val);
18734 if(val.Name == "_xlnm._FilterDatabase" && val.itab > 0)
18735 if(val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d')
18736 FilterDatabases[val.itab - 1] = { ref: encode_range(val.rgce[0][0][1][2]) };
18737 break;
18738 case 0x0016 /* ExternCount */: opts.ExternCount = val; break;
18739 case 0x0017 /* ExternSheet */:
18740 if(supbooks.length == 0) { supbooks[0] = []; supbooks[0].XTI = []; }
18741 supbooks[supbooks.length - 1].XTI = supbooks[supbooks.length - 1].XTI.concat(val); supbooks.XTI = supbooks.XTI.concat(val); break;
18742 case 0x0894 /* NameCmt */:
18743 /* TODO: search for correct name */
18744 if(opts.biff < 8) break;
18745 if(last_lbl != null) last_lbl.Comment = val[1];
18746 break;
18747 case 0x0012 /* Protect */: out["!protect"] = val; break; /* for sheet or book */
18748 case 0x0013 /* Password */: if(val !== 0 && opts.WTF) console.error("Password verifier: " + val); break;
18749 case 0x0085 /* BoundSheet8 */: {
18750 Directory[val.pos] = val;
18751 opts.snames.push(val.name);
18752 } break;
18753 case 0x000a /* EOF */: {
18754 if(--file_depth) break;
18755 if(range.e) {
18756 if(range.e.r > 0 && range.e.c > 0) {
18757 range.e.r--; range.e.c--;
18758 out["!ref"] = encode_range(range);
18759 if(options.sheetRows && options.sheetRows <= range.e.r) {
18760 var tmpri = range.e.r;
18761 range.e.r = options.sheetRows - 1;
18762 out["!fullref"] = out["!ref"];
18763 out["!ref"] = encode_range(range);
18764 range.e.r = tmpri;
18765 }
18766 range.e.r++; range.e.c++;
18767 }
18768 if(merges.length > 0) out["!merges"] = merges;
18769 if(objects.length > 0) out["!objects"] = objects;
18770 if(colinfo.length > 0) out["!cols"] = colinfo;
18771 if(rowinfo.length > 0) out["!rows"] = rowinfo;
18772 Workbook.Sheets.push(wsprops);
18773 }
18774 if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
18775 out = ((options.dense ? [] : {})/*:any*/);
18776 } break;
18777 case 0x0009: case 0x0209: case 0x0409: case 0x0809 /* BOF */: {
18778 if(opts.biff === 8) opts.biff = {
18779 /*::[*/0x0009/*::]*/:2,
18780 /*::[*/0x0209/*::]*/:3,
18781 /*::[*/0x0409/*::]*/:4
18782 }[RecordType] || {
18783 /*::[*/0x0200/*::]*/:2,
18784 /*::[*/0x0300/*::]*/:3,
18785 /*::[*/0x0400/*::]*/:4,
18786 /*::[*/0x0500/*::]*/:5,
18787 /*::[*/0x0600/*::]*/:8,
18788 /*::[*/0x0002/*::]*/:2,
18789 /*::[*/0x0007/*::]*/:2
18790 }[val.BIFFVer] || 8;
18791 opts.biffguess = val.BIFFVer == 0;
18792 if(val.BIFFVer == 0 && val.dt == 0x1000) { opts.biff = 5; seen_codepage = true; set_cp(opts.codepage = 28591); }
18793 if(opts.biff == 8 && val.BIFFVer == 0 && val.dt == 16) opts.biff = 2;
18794 if(file_depth++) break;
18795 out = ((options.dense ? [] : {})/*:any*/);
18796
18797 if(opts.biff < 8 && !seen_codepage) { seen_codepage = true; set_cp(opts.codepage = options.codepage || 1252); }
18798
18799 if(opts.biff < 5 || val.BIFFVer == 0 && val.dt == 0x1000) {
18800 if(cur_sheet === "") cur_sheet = "Sheet1";
18801 range = {s:{r:0,c:0},e:{r:0,c:0}};
18802 /* fake BoundSheet8 */
18803 var fakebs8 = {pos: blob.l - length, name:cur_sheet};
18804 Directory[fakebs8.pos] = fakebs8;
18805 opts.snames.push(cur_sheet);
18806 }
18807 else cur_sheet = (Directory[s] || {name:""}).name;
18808 if(val.dt == 0x20) out["!type"] = "chart";
18809 if(val.dt == 0x40) out["!type"] = "macro";
18810 merges = [];
18811 objects = [];
18812 opts.arrayf = arrayf = [];
18813 colinfo = []; rowinfo = [];
18814 seencol = false;
18815 wsprops = {Hidden:(Directory[s]||{hs:0}).hs, name:cur_sheet };
18816 } break;
18817 case 0x0203 /* Number */: case 0x0003 /* BIFF2NUM */: case 0x0002 /* BIFF2INT */: {
18818 if(out["!type"] == "chart") if(options.dense ? (out[val.r]||[])[val.c]: out[encode_cell({c:val.c, r:val.r})]) ++val.c;
18819 temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe]||{}, v:val.val, t:'n'}/*:any*/);
18820 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18821 safe_format_xf(temp_val, options, wb.opts.Date1904);
18822 addcell({c:val.c, r:val.r}, temp_val, options);
18823 } break;
18824 case 0x0005: case 0x0205 /* BoolErr */: {
18825 temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.val, t:val.t}/*:any*/);
18826 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18827 safe_format_xf(temp_val, options, wb.opts.Date1904);
18828 addcell({c:val.c, r:val.r}, temp_val, options);
18829 } break;
18830 case 0x027e /* RK */: {
18831 temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], v:val.rknum, t:'n'}/*:any*/);
18832 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18833 safe_format_xf(temp_val, options, wb.opts.Date1904);
18834 addcell({c:val.c, r:val.r}, temp_val, options);
18835 } break;
18836 case 0x00bd /* MulRk */: {
18837 for(var j = val.c; j <= val.C; ++j) {
18838 var ixfe = val.rkrec[j-val.c][0];
18839 temp_val= ({ixfe:ixfe, XF:XFs[ixfe], v:val.rkrec[j-val.c][1], t:'n'}/*:any*/);
18840 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18841 safe_format_xf(temp_val, options, wb.opts.Date1904);
18842 addcell({c:j, r:val.r}, temp_val, options);
18843 }
18844 } break;
18845 case 0x0006: case 0x0206: case 0x0406 /* Formula */: {
18846 if(val.val == 'String') { last_formula = val; break; }
18847 temp_val = make_cell(val.val, val.cell.ixfe, val.tt);
18848 temp_val.XF = XFs[temp_val.ixfe];
18849 if(options.cellFormula) {
18850 var _f = val.formula;
18851 if(_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
18852 var _fr = _f[0][0][1][0], _fc = _f[0][0][1][1];
18853 var _fe = encode_cell({r:_fr, c:_fc});
18854 if(sharedf[_fe]) temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
18855 else temp_val.F = ((options.dense ? (out[_fr]||[])[_fc]: out[_fe]) || {}).F;
18856 } else temp_val.f = ""+stringify_formula(val.formula,range,val.cell,supbooks, opts);
18857 }
18858 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18859 safe_format_xf(temp_val, options, wb.opts.Date1904);
18860 addcell(val.cell, temp_val, options);
18861 last_formula = val;
18862 } break;
18863 case 0x0007: case 0x0207 /* String */: {
18864 if(last_formula) { /* technically always true */
18865 last_formula.val = val;
18866 temp_val = make_cell(val, last_formula.cell.ixfe, 's');
18867 temp_val.XF = XFs[temp_val.ixfe];
18868 if(options.cellFormula) {
18869 temp_val.f = ""+stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
18870 }
18871 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18872 safe_format_xf(temp_val, options, wb.opts.Date1904);
18873 addcell(last_formula.cell, temp_val, options);
18874 last_formula = null;
18875 } else throw new Error("String record expects Formula");
18876 } break;
18877 case 0x0021: case 0x0221 /* Array */: {
18878 arrayf.push(val);
18879 var _arraystart = encode_cell(val[0].s);
18880 cc = options.dense ? (out[val[0].s.r]||[])[val[0].s.c] : out[_arraystart];
18881 if(options.cellFormula && cc) {
18882 if(!last_formula) break; /* technically unreachable */
18883 if(!_arraystart || !cc) break;
18884 cc.f = ""+stringify_formula(val[1], range, val[0], supbooks, opts);
18885 cc.F = encode_range(val[0]);
18886 }
18887 } break;
18888 case 0x04bc /* ShrFmla */: {
18889 if(!options.cellFormula) break;
18890 if(last_cell) {
18891 /* TODO: capture range */
18892 if(!last_formula) break; /* technically unreachable */
18893 sharedf[encode_cell(last_formula.cell)]= val[0];
18894 cc = options.dense ? (out[last_formula.cell.r]||[])[last_formula.cell.c] : out[encode_cell(last_formula.cell)];
18895 (cc||{}).f = ""+stringify_formula(val[0], range, lastcell, supbooks, opts);
18896 }
18897 } break;
18898 case 0x00fd /* LabelSst */:
18899 temp_val=make_cell(sst[val.isst].t, val.ixfe, 's');
18900 if(sst[val.isst].h) temp_val.h = sst[val.isst].h;
18901 temp_val.XF = XFs[temp_val.ixfe];
18902 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18903 safe_format_xf(temp_val, options, wb.opts.Date1904);
18904 addcell({c:val.c, r:val.r}, temp_val, options);
18905 break;
18906 case 0x0201 /* Blank */: if(options.sheetStubs) {
18907 temp_val = ({ixfe: val.ixfe, XF: XFs[val.ixfe], t:'z'}/*:any*/);
18908 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18909 safe_format_xf(temp_val, options, wb.opts.Date1904);
18910 addcell({c:val.c, r:val.r}, temp_val, options);
18911 } break;
18912 case 0x00be /* MulBlank */: if(options.sheetStubs) {
18913 for(var _j = val.c; _j <= val.C; ++_j) {
18914 var _ixfe = val.ixfe[_j-val.c];
18915 temp_val= ({ixfe:_ixfe, XF:XFs[_ixfe], t:'z'}/*:any*/);
18916 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18917 safe_format_xf(temp_val, options, wb.opts.Date1904);
18918 addcell({c:_j, r:val.r}, temp_val, options);
18919 }
18920 } break;
18921 case 0x00d6 /* RString */:
18922 case 0x0204 /* Label */: case 0x0004 /* BIFF2STR */:
18923 temp_val=make_cell(val.val, val.ixfe, 's');
18924 temp_val.XF = XFs[temp_val.ixfe];
18925 if(BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[(temp_val.ixfe>>8) & 0x3F];
18926 safe_format_xf(temp_val, options, wb.opts.Date1904);
18927 addcell({c:val.c, r:val.r}, temp_val, options);
18928 break;
18929
18930 case 0x0000: case 0x0200 /* Dimensions */: {
18931 if(file_depth === 1) range = val; /* TODO: stack */
18932 } break;
18933 case 0x00fc /* SST */: {
18934 sst = val;
18935 } break;
18936 case 0x041e /* Format */: { /* val = [id, fmt] */
18937 if(opts.biff == 4) {
18938 BIFF2FmtTable[BIFF2Fmt++] = val[1];
18939 for(var b4idx = 0; b4idx < BIFF2Fmt + 163; ++b4idx) if(table_fmt[b4idx] == val[1]) break;
18940 if(b4idx >= 163) SSF_load(val[1], BIFF2Fmt + 163);
18941 }
18942 else SSF_load(val[1], val[0]);
18943 } break;
18944 case 0x001e /* BIFF2FORMAT */: {
18945 BIFF2FmtTable[BIFF2Fmt++] = val;
18946 for(var b2idx = 0; b2idx < BIFF2Fmt + 163; ++b2idx) if(table_fmt[b2idx] == val) break;
18947 if(b2idx >= 163) SSF_load(val, BIFF2Fmt + 163);
18948 } break;
18949
18950 case 0x00e5 /* MergeCells */: merges = merges.concat(val); break;
18951
18952 case 0x005d /* Obj */: objects[val.cmo[0]] = opts.lastobj = val; break;
18953 case 0x01b6 /* TxO */: opts.lastobj.TxO = val; break;
18954 case 0x007f /* ImData */: opts.lastobj.ImData = val; break;
18955
18956 case 0x01b8 /* HLink */: {
18957 for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR)
18958 for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) {
18959 cc = options.dense ? (out[rngR]||[])[rngC] : out[encode_cell({c:rngC,r:rngR})];
18960 if(cc) cc.l = val[1];
18961 }
18962 } break;
18963 case 0x0800 /* HLinkTooltip */: {
18964 for(rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR)
18965 for(rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) {
18966 cc = options.dense ? (out[rngR]||[])[rngC] : out[encode_cell({c:rngC,r:rngR})];
18967 if(cc && cc.l) cc.l.Tooltip = val[1];
18968 }
18969 } break;
18970 case 0x001c /* Note */: {
18971 if(opts.biff <= 5 && opts.biff >= 2) break; /* TODO: BIFF5 */
18972 cc = options.dense ? (out[val[0].r]||[])[val[0].c] : out[encode_cell(val[0])];
18973 var noteobj = objects[val[2]];
18974 if(!cc) {
18975 if(options.dense) {
18976 if(!out[val[0].r]) out[val[0].r] = [];
18977 cc = out[val[0].r][val[0].c] = ({t:"z"}/*:any*/);
18978 } else {
18979 cc = out[encode_cell(val[0])] = ({t:"z"}/*:any*/);
18980 }
18981 range.e.r = Math.max(range.e.r, val[0].r);
18982 range.s.r = Math.min(range.s.r, val[0].r);
18983 range.e.c = Math.max(range.e.c, val[0].c);
18984 range.s.c = Math.min(range.s.c, val[0].c);
18985 }
18986 if(!cc.c) cc.c = [];
18987 cmnt = {a:val[1],t:noteobj.TxO.t};
18988 cc.c.push(cmnt);
18989 } break;
18990 case 0x087d /* XFExt */: update_xfext(XFs[val.ixfe], val.ext); break;
18991 case 0x007d /* ColInfo */: {
18992 if(!opts.cellStyles) break;
18993 while(val.e >= val.s) {
18994 colinfo[val.e--] = { width: val.w/256, level: (val.level || 0), hidden: !!(val.flags & 1) };
18995 if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
18996 process_col(colinfo[val.e+1]);
18997 }
18998 } break;
18999 case 0x0208 /* Row */: {
19000 var rowobj = {};
19001 if(val.level != null) { rowinfo[val.r] = rowobj; rowobj.level = val.level; }
19002 if(val.hidden) { rowinfo[val.r] = rowobj; rowobj.hidden = true; }
19003 if(val.hpt) {
19004 rowinfo[val.r] = rowobj;
19005 rowobj.hpt = val.hpt; rowobj.hpx = pt2px(val.hpt);
19006 }
19007 } break;
19008 case 0x0026 /* LeftMargin */:
19009 case 0x0027 /* RightMargin */:
19010 case 0x0028 /* TopMargin */:
19011 case 0x0029 /* BottomMargin */:
19012 if(!out['!margins']) default_margins(out['!margins'] = {});
19013 out['!margins'][({0x26: "left", 0x27:"right", 0x28:"top", 0x29:"bottom"})[RecordType]] = val;
19014 break;
19015 case 0x00a1 /* Setup */: // TODO
19016 if(!out['!margins']) default_margins(out['!margins'] = {});
19017 out['!margins'].header = val.header;
19018 out['!margins'].footer = val.footer;
19019 break;
19020 case 0x023e /* Window2 */: // TODO
19021 // $FlowIgnore
19022 if(val.RTL) Workbook.Views[0].RTL = true;
19023 break;
19024 case 0x0092 /* Palette */: palette = val; break;
19025 case 0x0896 /* Theme */: themes = val; break;
19026 case 0x008c /* Country */: country = val; break;
19027 case 0x01ba /* CodeName */: {
19028 /*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
19029 if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";
19030 else wsprops.CodeName = val || wsprops.name;
19031 } break;
19032 }
19033 } else {
19034 if(!R) console.error("Missing Info for XLS Record 0x" + RecordType.toString(16));
19035 blob.l += length;
19036 }
19037 }
19038 wb.SheetNames=keys(Directory).sort(function(a,b) { return Number(a) - Number(b); }).map(function(x){return Directory[x].name;});
19039 if(!options.bookSheets) wb.Sheets=Sheets;
19040 if(!wb.SheetNames.length && Preamble["!ref"]) {
19041 wb.SheetNames.push("Sheet1");
19042 /*jshint -W069 */
19043 if(wb.Sheets) wb.Sheets["Sheet1"] = Preamble;
19044 /*jshint +W069 */
19045 } else wb.Preamble=Preamble;
19046 if(wb.Sheets) FilterDatabases.forEach(function(r,i) { wb.Sheets[wb.SheetNames[i]]['!autofilter'] = r; });
19047 wb.Strings = sst;
19048 wb.SSF = dup(table_fmt);
19049 if(opts.enc) wb.Encryption = opts.enc;
19050 if(themes) wb.Themes = themes;
19051 wb.Metadata = {};
19052 if(country !== undefined) wb.Metadata.Country = country;
19053 if(supbooks.names.length > 0) Workbook.Names = supbooks.names;
19054 wb.Workbook = Workbook;
19055 return wb;
19056}
19057
19058/* TODO: split props*/
19059var PSCLSID = {
19060 SI: "e0859ff2f94f6810ab9108002b27b3d9",
19061 DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
19062 UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
19063};
19064function parse_xls_props(cfb/*:CFBContainer*/, props, o) {
19065 /* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
19066 var DSI = CFB.find(cfb, '/!DocumentSummaryInformation');
19067 if(DSI && DSI.size > 0) try {
19068 var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
19069 for(var d in DocSummary) props[d] = DocSummary[d];
19070 } catch(e) {if(o.WTF) throw e;/* empty */}
19071
19072 /* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
19073 var SI = CFB.find(cfb, '/!SummaryInformation');
19074 if(SI && SI.size > 0) try {
19075 var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
19076 for(var s in Summary) if(props[s] == null) props[s] = Summary[s];
19077 } catch(e) {if(o.WTF) throw e;/* empty */}
19078
19079 if(props.HeadingPairs && props.TitlesOfParts) {
19080 load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
19081 delete props.HeadingPairs; delete props.TitlesOfParts;
19082 }
19083}
19084function write_xls_props(wb/*:Workbook*/, cfb/*:CFBContainer*/) {
19085 var DSEntries = [], SEntries = [], CEntries = [];
19086 var i = 0, Keys;
19087 var DocSummaryRE/*:{[key:string]:string}*/ = evert_key(DocSummaryPIDDSI, "n");
19088 var SummaryRE/*:{[key:string]:string}*/ = evert_key(SummaryPIDSI, "n");
19089 if(wb.Props) {
19090 Keys = keys(wb.Props);
19091 // $FlowIgnore
19092 for(i = 0; i < Keys.length; ++i) (Object.prototype.hasOwnProperty.call(DocSummaryRE, Keys[i]) ? DSEntries : Object.prototype.hasOwnProperty.call(SummaryRE, Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
19093 }
19094 if(wb.Custprops) {
19095 Keys = keys(wb.Custprops);
19096 // $FlowIgnore
19097 for(i = 0; i < Keys.length; ++i) if(!Object.prototype.hasOwnProperty.call((wb.Props||{}), Keys[i])) (Object.prototype.hasOwnProperty.call(DocSummaryRE, Keys[i]) ? DSEntries : Object.prototype.hasOwnProperty.call(SummaryRE, Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
19098 }
19099 var CEntries2 = [];
19100 for(i = 0; i < CEntries.length; ++i) {
19101 if(XLSPSSkip.indexOf(CEntries[i][0]) > -1 || PseudoPropsPairs.indexOf(CEntries[i][0]) > -1) continue;
19102 if(CEntries[i][1] == null) continue;
19103 CEntries2.push(CEntries[i]);
19104 }
19105 if(SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
19106 if(DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
19107}
19108
19109function parse_xlscfb(cfb/*:any*/, options/*:?ParseOpts*/)/*:Workbook*/ {
19110if(!options) options = {};
19111fix_read_opts(options);
19112reset_cp();
19113if(options.codepage) set_ansi(options.codepage);
19114var CompObj/*:?CFBEntry*/, WB/*:?any*/;
19115if(cfb.FullPaths) {
19116 if(CFB.find(cfb, '/encryption')) throw new Error("File is password-protected");
19117 CompObj = CFB.find(cfb, '!CompObj');
19118 WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book');
19119} else {
19120 switch(options.type) {
19121 case 'base64': cfb = s2a(Base64_decode(cfb)); break;
19122 case 'binary': cfb = s2a(cfb); break;
19123 case 'buffer': break;
19124 case 'array': if(!Array.isArray(cfb)) cfb = Array.prototype.slice.call(cfb); break;
19125 }
19126 prep_blob(cfb, 0);
19127 WB = ({content: cfb}/*:any*/);
19128}
19129var /*::CompObjP, */WorkbookP/*:: :Workbook = XLSX.utils.book_new(); */;
19130
19131var _data/*:?any*/;
19132if(CompObj) /*::CompObjP = */parse_compobj(CompObj);
19133if(options.bookProps && !options.bookSheets) WorkbookP = ({}/*:any*/);
19134else/*:: if(cfb instanceof CFBContainer) */ {
19135 var T = has_buf ? 'buffer' : 'array';
19136 if(WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
19137 /* Quattro Pro 7-8 */
19138 else if((_data=CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
19139 /* Quattro Pro 9 */
19140 else if((_data=CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
19141 /* Works 4 for Mac */
19142 else if((_data=CFB.find(cfb, 'MN0')) && _data.content) throw new Error("Unsupported Works 4 for Mac file");
19143 else throw new Error("Cannot find Workbook stream");
19144 if(options.bookVBA && cfb.FullPaths && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb);
19145}
19146
19147var props = {};
19148if(cfb.FullPaths) parse_xls_props(/*::((*/cfb/*:: :any):CFBContainer)*/, props, options);
19149
19150WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
19151if(options.bookFiles) WorkbookP.cfb = cfb;
19152/*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
19153return WorkbookP;
19154}
19155
19156
19157function write_xlscfb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:CFBContainer*/ {
19158 var o = opts || {};
19159 var cfb = CFB.utils.cfb_new({root:"R"});
19160 var wbpath = "/Workbook";
19161 switch(o.bookType || "xls") {
19162 case "xls": o.bookType = "biff8";
19163 /* falls through */
19164 case "xla": if(!o.bookType) o.bookType = "xla";
19165 /* falls through */
19166 case "biff8": wbpath = "/Workbook"; o.biff = 8; break;
19167 case "biff5": wbpath = "/Book"; o.biff = 5; break;
19168 default: throw new Error("invalid type " + o.bookType + " for XLS CFB");
19169 }
19170 CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
19171 if(o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
19172 // TODO: SI, DSI, CO
19173 if(o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {type: typeof wb.vbaraw == "string" ? "binary" : "buffer"}));
19174 return cfb;
19175}
19176/* [MS-XLSB] 2.3 Record Enumeration */
19177var XLSBRecordEnum = {
19178 /*::[*/0x0000/*::]*/: { /* n:"BrtRowHdr", */ f:parse_BrtRowHdr },
19179 /*::[*/0x0001/*::]*/: { /* n:"BrtCellBlank", */ f:parse_BrtCellBlank },
19180 /*::[*/0x0002/*::]*/: { /* n:"BrtCellRk", */ f:parse_BrtCellRk },
19181 /*::[*/0x0003/*::]*/: { /* n:"BrtCellError", */ f:parse_BrtCellError },
19182 /*::[*/0x0004/*::]*/: { /* n:"BrtCellBool", */ f:parse_BrtCellBool },
19183 /*::[*/0x0005/*::]*/: { /* n:"BrtCellReal", */ f:parse_BrtCellReal },
19184 /*::[*/0x0006/*::]*/: { /* n:"BrtCellSt", */ f:parse_BrtCellSt },
19185 /*::[*/0x0007/*::]*/: { /* n:"BrtCellIsst", */ f:parse_BrtCellIsst },
19186 /*::[*/0x0008/*::]*/: { /* n:"BrtFmlaString", */ f:parse_BrtFmlaString },
19187 /*::[*/0x0009/*::]*/: { /* n:"BrtFmlaNum", */ f:parse_BrtFmlaNum },
19188 /*::[*/0x000A/*::]*/: { /* n:"BrtFmlaBool", */ f:parse_BrtFmlaBool },
19189 /*::[*/0x000B/*::]*/: { /* n:"BrtFmlaError", */ f:parse_BrtFmlaError },
19190 /*::[*/0x000C/*::]*/: { /* n:"BrtShortBlank", */ f:parse_BrtShortBlank },
19191 /*::[*/0x000D/*::]*/: { /* n:"BrtShortRk", */ f:parse_BrtShortRk },
19192 /*::[*/0x000E/*::]*/: { /* n:"BrtShortError", */ f:parse_BrtShortError },
19193 /*::[*/0x000F/*::]*/: { /* n:"BrtShortBool", */ f:parse_BrtShortBool },
19194 /*::[*/0x0010/*::]*/: { /* n:"BrtShortReal", */ f:parse_BrtShortReal },
19195 /*::[*/0x0011/*::]*/: { /* n:"BrtShortSt", */ f:parse_BrtShortSt },
19196 /*::[*/0x0012/*::]*/: { /* n:"BrtShortIsst", */ f:parse_BrtShortIsst },
19197 /*::[*/0x0013/*::]*/: { /* n:"BrtSSTItem", */ f:parse_RichStr },
19198 /*::[*/0x0014/*::]*/: { /* n:"BrtPCDIMissing" */ },
19199 /*::[*/0x0015/*::]*/: { /* n:"BrtPCDINumber" */ },
19200 /*::[*/0x0016/*::]*/: { /* n:"BrtPCDIBoolean" */ },
19201 /*::[*/0x0017/*::]*/: { /* n:"BrtPCDIError" */ },
19202 /*::[*/0x0018/*::]*/: { /* n:"BrtPCDIString" */ },
19203 /*::[*/0x0019/*::]*/: { /* n:"BrtPCDIDatetime" */ },
19204 /*::[*/0x001A/*::]*/: { /* n:"BrtPCDIIndex" */ },
19205 /*::[*/0x001B/*::]*/: { /* n:"BrtPCDIAMissing" */ },
19206 /*::[*/0x001C/*::]*/: { /* n:"BrtPCDIANumber" */ },
19207 /*::[*/0x001D/*::]*/: { /* n:"BrtPCDIABoolean" */ },
19208 /*::[*/0x001E/*::]*/: { /* n:"BrtPCDIAError" */ },
19209 /*::[*/0x001F/*::]*/: { /* n:"BrtPCDIAString" */ },
19210 /*::[*/0x0020/*::]*/: { /* n:"BrtPCDIADatetime" */ },
19211 /*::[*/0x0021/*::]*/: { /* n:"BrtPCRRecord" */ },
19212 /*::[*/0x0022/*::]*/: { /* n:"BrtPCRRecordDt" */ },
19213 /*::[*/0x0023/*::]*/: { /* n:"BrtFRTBegin", */ T:1 },
19214 /*::[*/0x0024/*::]*/: { /* n:"BrtFRTEnd", */ T:-1 },
19215 /*::[*/0x0025/*::]*/: { /* n:"BrtACBegin", */ T:1 },
19216 /*::[*/0x0026/*::]*/: { /* n:"BrtACEnd", */ T:-1 },
19217 /*::[*/0x0027/*::]*/: { /* n:"BrtName", */ f:parse_BrtName },
19218 /*::[*/0x0028/*::]*/: { /* n:"BrtIndexRowBlock" */ },
19219 /*::[*/0x002A/*::]*/: { /* n:"BrtIndexBlock" */ },
19220 /*::[*/0x002B/*::]*/: { /* n:"BrtFont", */ f:parse_BrtFont },
19221 /*::[*/0x002C/*::]*/: { /* n:"BrtFmt", */ f:parse_BrtFmt },
19222 /*::[*/0x002D/*::]*/: { /* n:"BrtFill", */ f:parse_BrtFill },
19223 /*::[*/0x002E/*::]*/: { /* n:"BrtBorder", */ f:parse_BrtBorder },
19224 /*::[*/0x002F/*::]*/: { /* n:"BrtXF", */ f:parse_BrtXF },
19225 /*::[*/0x0030/*::]*/: { /* n:"BrtStyle" */ },
19226 /*::[*/0x0031/*::]*/: { /* n:"BrtCellMeta", */ f:parse_Int32LE },
19227 /*::[*/0x0032/*::]*/: { /* n:"BrtValueMeta" */ },
19228 /*::[*/0x0033/*::]*/: { /* n:"BrtMdb" */ f:parse_BrtMdb },
19229 /*::[*/0x0034/*::]*/: { /* n:"BrtBeginFmd", */ T:1 },
19230 /*::[*/0x0035/*::]*/: { /* n:"BrtEndFmd", */ T:-1 },
19231 /*::[*/0x0036/*::]*/: { /* n:"BrtBeginMdx", */ T:1 },
19232 /*::[*/0x0037/*::]*/: { /* n:"BrtEndMdx", */ T:-1 },
19233 /*::[*/0x0038/*::]*/: { /* n:"BrtBeginMdxTuple", */ T:1 },
19234 /*::[*/0x0039/*::]*/: { /* n:"BrtEndMdxTuple", */ T:-1 },
19235 /*::[*/0x003A/*::]*/: { /* n:"BrtMdxMbrIstr" */ },
19236 /*::[*/0x003B/*::]*/: { /* n:"BrtStr" */ },
19237 /*::[*/0x003C/*::]*/: { /* n:"BrtColInfo", */ f:parse_ColInfo },
19238 /*::[*/0x003E/*::]*/: { /* n:"BrtCellRString", */ f:parse_BrtCellRString },
19239 /*::[*/0x003F/*::]*/: { /* n:"BrtCalcChainItem$", */ f:parse_BrtCalcChainItem$ },
19240 /*::[*/0x0040/*::]*/: { /* n:"BrtDVal", */ f:parse_BrtDVal },
19241 /*::[*/0x0041/*::]*/: { /* n:"BrtSxvcellNum" */ },
19242 /*::[*/0x0042/*::]*/: { /* n:"BrtSxvcellStr" */ },
19243 /*::[*/0x0043/*::]*/: { /* n:"BrtSxvcellBool" */ },
19244 /*::[*/0x0044/*::]*/: { /* n:"BrtSxvcellErr" */ },
19245 /*::[*/0x0045/*::]*/: { /* n:"BrtSxvcellDate" */ },
19246 /*::[*/0x0046/*::]*/: { /* n:"BrtSxvcellNil" */ },
19247 /*::[*/0x0080/*::]*/: { /* n:"BrtFileVersion" */ },
19248 /*::[*/0x0081/*::]*/: { /* n:"BrtBeginSheet", */ T:1 },
19249 /*::[*/0x0082/*::]*/: { /* n:"BrtEndSheet", */ T:-1 },
19250 /*::[*/0x0083/*::]*/: { /* n:"BrtBeginBook", */ T:1, f:parsenoop, p:0 },
19251 /*::[*/0x0084/*::]*/: { /* n:"BrtEndBook", */ T:-1 },
19252 /*::[*/0x0085/*::]*/: { /* n:"BrtBeginWsViews", */ T:1 },
19253 /*::[*/0x0086/*::]*/: { /* n:"BrtEndWsViews", */ T:-1 },
19254 /*::[*/0x0087/*::]*/: { /* n:"BrtBeginBookViews", */ T:1 },
19255 /*::[*/0x0088/*::]*/: { /* n:"BrtEndBookViews", */ T:-1 },
19256 /*::[*/0x0089/*::]*/: { /* n:"BrtBeginWsView", */ T:1, f:parse_BrtBeginWsView },
19257 /*::[*/0x008A/*::]*/: { /* n:"BrtEndWsView", */ T:-1 },
19258 /*::[*/0x008B/*::]*/: { /* n:"BrtBeginCsViews", */ T:1 },
19259 /*::[*/0x008C/*::]*/: { /* n:"BrtEndCsViews", */ T:-1 },
19260 /*::[*/0x008D/*::]*/: { /* n:"BrtBeginCsView", */ T:1 },
19261 /*::[*/0x008E/*::]*/: { /* n:"BrtEndCsView", */ T:-1 },
19262 /*::[*/0x008F/*::]*/: { /* n:"BrtBeginBundleShs", */ T:1 },
19263 /*::[*/0x0090/*::]*/: { /* n:"BrtEndBundleShs", */ T:-1 },
19264 /*::[*/0x0091/*::]*/: { /* n:"BrtBeginSheetData", */ T:1 },
19265 /*::[*/0x0092/*::]*/: { /* n:"BrtEndSheetData", */ T:-1 },
19266 /*::[*/0x0093/*::]*/: { /* n:"BrtWsProp", */ f:parse_BrtWsProp },
19267 /*::[*/0x0094/*::]*/: { /* n:"BrtWsDim", */ f:parse_BrtWsDim, p:16 },
19268 /*::[*/0x0097/*::]*/: { /* n:"BrtPane", */ f:parse_BrtPane },
19269 /*::[*/0x0098/*::]*/: { /* n:"BrtSel" */ },
19270 /*::[*/0x0099/*::]*/: { /* n:"BrtWbProp", */ f:parse_BrtWbProp },
19271 /*::[*/0x009A/*::]*/: { /* n:"BrtWbFactoid" */ },
19272 /*::[*/0x009B/*::]*/: { /* n:"BrtFileRecover" */ },
19273 /*::[*/0x009C/*::]*/: { /* n:"BrtBundleSh", */ f:parse_BrtBundleSh },
19274 /*::[*/0x009D/*::]*/: { /* n:"BrtCalcProp" */ },
19275 /*::[*/0x009E/*::]*/: { /* n:"BrtBookView" */ },
19276 /*::[*/0x009F/*::]*/: { /* n:"BrtBeginSst", */ T:1, f:parse_BrtBeginSst },
19277 /*::[*/0x00A0/*::]*/: { /* n:"BrtEndSst", */ T:-1 },
19278 /*::[*/0x00A1/*::]*/: { /* n:"BrtBeginAFilter", */ T:1, f:parse_UncheckedRfX },
19279 /*::[*/0x00A2/*::]*/: { /* n:"BrtEndAFilter", */ T:-1 },
19280 /*::[*/0x00A3/*::]*/: { /* n:"BrtBeginFilterColumn", */ T:1 },
19281 /*::[*/0x00A4/*::]*/: { /* n:"BrtEndFilterColumn", */ T:-1 },
19282 /*::[*/0x00A5/*::]*/: { /* n:"BrtBeginFilters", */ T:1 },
19283 /*::[*/0x00A6/*::]*/: { /* n:"BrtEndFilters", */ T:-1 },
19284 /*::[*/0x00A7/*::]*/: { /* n:"BrtFilter" */ },
19285 /*::[*/0x00A8/*::]*/: { /* n:"BrtColorFilter" */ },
19286 /*::[*/0x00A9/*::]*/: { /* n:"BrtIconFilter" */ },
19287 /*::[*/0x00AA/*::]*/: { /* n:"BrtTop10Filter" */ },
19288 /*::[*/0x00AB/*::]*/: { /* n:"BrtDynamicFilter" */ },
19289 /*::[*/0x00AC/*::]*/: { /* n:"BrtBeginCustomFilters", */ T:1 },
19290 /*::[*/0x00AD/*::]*/: { /* n:"BrtEndCustomFilters", */ T:-1 },
19291 /*::[*/0x00AE/*::]*/: { /* n:"BrtCustomFilter" */ },
19292 /*::[*/0x00AF/*::]*/: { /* n:"BrtAFilterDateGroupItem" */ },
19293 /*::[*/0x00B0/*::]*/: { /* n:"BrtMergeCell", */ f:parse_BrtMergeCell },
19294 /*::[*/0x00B1/*::]*/: { /* n:"BrtBeginMergeCells", */ T:1 },
19295 /*::[*/0x00B2/*::]*/: { /* n:"BrtEndMergeCells", */ T:-1 },
19296 /*::[*/0x00B3/*::]*/: { /* n:"BrtBeginPivotCacheDef", */ T:1 },
19297 /*::[*/0x00B4/*::]*/: { /* n:"BrtEndPivotCacheDef", */ T:-1 },
19298 /*::[*/0x00B5/*::]*/: { /* n:"BrtBeginPCDFields", */ T:1 },
19299 /*::[*/0x00B6/*::]*/: { /* n:"BrtEndPCDFields", */ T:-1 },
19300 /*::[*/0x00B7/*::]*/: { /* n:"BrtBeginPCDField", */ T:1 },
19301 /*::[*/0x00B8/*::]*/: { /* n:"BrtEndPCDField", */ T:-1 },
19302 /*::[*/0x00B9/*::]*/: { /* n:"BrtBeginPCDSource", */ T:1 },
19303 /*::[*/0x00BA/*::]*/: { /* n:"BrtEndPCDSource", */ T:-1 },
19304 /*::[*/0x00BB/*::]*/: { /* n:"BrtBeginPCDSRange", */ T:1 },
19305 /*::[*/0x00BC/*::]*/: { /* n:"BrtEndPCDSRange", */ T:-1 },
19306 /*::[*/0x00BD/*::]*/: { /* n:"BrtBeginPCDFAtbl", */ T:1 },
19307 /*::[*/0x00BE/*::]*/: { /* n:"BrtEndPCDFAtbl", */ T:-1 },
19308 /*::[*/0x00BF/*::]*/: { /* n:"BrtBeginPCDIRun", */ T:1 },
19309 /*::[*/0x00C0/*::]*/: { /* n:"BrtEndPCDIRun", */ T:-1 },
19310 /*::[*/0x00C1/*::]*/: { /* n:"BrtBeginPivotCacheRecords", */ T:1 },
19311 /*::[*/0x00C2/*::]*/: { /* n:"BrtEndPivotCacheRecords", */ T:-1 },
19312 /*::[*/0x00C3/*::]*/: { /* n:"BrtBeginPCDHierarchies", */ T:1 },
19313 /*::[*/0x00C4/*::]*/: { /* n:"BrtEndPCDHierarchies", */ T:-1 },
19314 /*::[*/0x00C5/*::]*/: { /* n:"BrtBeginPCDHierarchy", */ T:1 },
19315 /*::[*/0x00C6/*::]*/: { /* n:"BrtEndPCDHierarchy", */ T:-1 },
19316 /*::[*/0x00C7/*::]*/: { /* n:"BrtBeginPCDHFieldsUsage", */ T:1 },
19317 /*::[*/0x00C8/*::]*/: { /* n:"BrtEndPCDHFieldsUsage", */ T:-1 },
19318 /*::[*/0x00C9/*::]*/: { /* n:"BrtBeginExtConnection", */ T:1 },
19319 /*::[*/0x00CA/*::]*/: { /* n:"BrtEndExtConnection", */ T:-1 },
19320 /*::[*/0x00CB/*::]*/: { /* n:"BrtBeginECDbProps", */ T:1 },
19321 /*::[*/0x00CC/*::]*/: { /* n:"BrtEndECDbProps", */ T:-1 },
19322 /*::[*/0x00CD/*::]*/: { /* n:"BrtBeginECOlapProps", */ T:1 },
19323 /*::[*/0x00CE/*::]*/: { /* n:"BrtEndECOlapProps", */ T:-1 },
19324 /*::[*/0x00CF/*::]*/: { /* n:"BrtBeginPCDSConsol", */ T:1 },
19325 /*::[*/0x00D0/*::]*/: { /* n:"BrtEndPCDSConsol", */ T:-1 },
19326 /*::[*/0x00D1/*::]*/: { /* n:"BrtBeginPCDSCPages", */ T:1 },
19327 /*::[*/0x00D2/*::]*/: { /* n:"BrtEndPCDSCPages", */ T:-1 },
19328 /*::[*/0x00D3/*::]*/: { /* n:"BrtBeginPCDSCPage", */ T:1 },
19329 /*::[*/0x00D4/*::]*/: { /* n:"BrtEndPCDSCPage", */ T:-1 },
19330 /*::[*/0x00D5/*::]*/: { /* n:"BrtBeginPCDSCPItem", */ T:1 },
19331 /*::[*/0x00D6/*::]*/: { /* n:"BrtEndPCDSCPItem", */ T:-1 },
19332 /*::[*/0x00D7/*::]*/: { /* n:"BrtBeginPCDSCSets", */ T:1 },
19333 /*::[*/0x00D8/*::]*/: { /* n:"BrtEndPCDSCSets", */ T:-1 },
19334 /*::[*/0x00D9/*::]*/: { /* n:"BrtBeginPCDSCSet", */ T:1 },
19335 /*::[*/0x00DA/*::]*/: { /* n:"BrtEndPCDSCSet", */ T:-1 },
19336 /*::[*/0x00DB/*::]*/: { /* n:"BrtBeginPCDFGroup", */ T:1 },
19337 /*::[*/0x00DC/*::]*/: { /* n:"BrtEndPCDFGroup", */ T:-1 },
19338 /*::[*/0x00DD/*::]*/: { /* n:"BrtBeginPCDFGItems", */ T:1 },
19339 /*::[*/0x00DE/*::]*/: { /* n:"BrtEndPCDFGItems", */ T:-1 },
19340 /*::[*/0x00DF/*::]*/: { /* n:"BrtBeginPCDFGRange", */ T:1 },
19341 /*::[*/0x00E0/*::]*/: { /* n:"BrtEndPCDFGRange", */ T:-1 },
19342 /*::[*/0x00E1/*::]*/: { /* n:"BrtBeginPCDFGDiscrete", */ T:1 },
19343 /*::[*/0x00E2/*::]*/: { /* n:"BrtEndPCDFGDiscrete", */ T:-1 },
19344 /*::[*/0x00E3/*::]*/: { /* n:"BrtBeginPCDSDTupleCache", */ T:1 },
19345 /*::[*/0x00E4/*::]*/: { /* n:"BrtEndPCDSDTupleCache", */ T:-1 },
19346 /*::[*/0x00E5/*::]*/: { /* n:"BrtBeginPCDSDTCEntries", */ T:1 },
19347 /*::[*/0x00E6/*::]*/: { /* n:"BrtEndPCDSDTCEntries", */ T:-1 },
19348 /*::[*/0x00E7/*::]*/: { /* n:"BrtBeginPCDSDTCEMembers", */ T:1 },
19349 /*::[*/0x00E8/*::]*/: { /* n:"BrtEndPCDSDTCEMembers", */ T:-1 },
19350 /*::[*/0x00E9/*::]*/: { /* n:"BrtBeginPCDSDTCEMember", */ T:1 },
19351 /*::[*/0x00EA/*::]*/: { /* n:"BrtEndPCDSDTCEMember", */ T:-1 },
19352 /*::[*/0x00EB/*::]*/: { /* n:"BrtBeginPCDSDTCQueries", */ T:1 },
19353 /*::[*/0x00EC/*::]*/: { /* n:"BrtEndPCDSDTCQueries", */ T:-1 },
19354 /*::[*/0x00ED/*::]*/: { /* n:"BrtBeginPCDSDTCQuery", */ T:1 },
19355 /*::[*/0x00EE/*::]*/: { /* n:"BrtEndPCDSDTCQuery", */ T:-1 },
19356 /*::[*/0x00EF/*::]*/: { /* n:"BrtBeginPCDSDTCSets", */ T:1 },
19357 /*::[*/0x00F0/*::]*/: { /* n:"BrtEndPCDSDTCSets", */ T:-1 },
19358 /*::[*/0x00F1/*::]*/: { /* n:"BrtBeginPCDSDTCSet", */ T:1 },
19359 /*::[*/0x00F2/*::]*/: { /* n:"BrtEndPCDSDTCSet", */ T:-1 },
19360 /*::[*/0x00F3/*::]*/: { /* n:"BrtBeginPCDCalcItems", */ T:1 },
19361 /*::[*/0x00F4/*::]*/: { /* n:"BrtEndPCDCalcItems", */ T:-1 },
19362 /*::[*/0x00F5/*::]*/: { /* n:"BrtBeginPCDCalcItem", */ T:1 },
19363 /*::[*/0x00F6/*::]*/: { /* n:"BrtEndPCDCalcItem", */ T:-1 },
19364 /*::[*/0x00F7/*::]*/: { /* n:"BrtBeginPRule", */ T:1 },
19365 /*::[*/0x00F8/*::]*/: { /* n:"BrtEndPRule", */ T:-1 },
19366 /*::[*/0x00F9/*::]*/: { /* n:"BrtBeginPRFilters", */ T:1 },
19367 /*::[*/0x00FA/*::]*/: { /* n:"BrtEndPRFilters", */ T:-1 },
19368 /*::[*/0x00FB/*::]*/: { /* n:"BrtBeginPRFilter", */ T:1 },
19369 /*::[*/0x00FC/*::]*/: { /* n:"BrtEndPRFilter", */ T:-1 },
19370 /*::[*/0x00FD/*::]*/: { /* n:"BrtBeginPNames", */ T:1 },
19371 /*::[*/0x00FE/*::]*/: { /* n:"BrtEndPNames", */ T:-1 },
19372 /*::[*/0x00FF/*::]*/: { /* n:"BrtBeginPName", */ T:1 },
19373 /*::[*/0x0100/*::]*/: { /* n:"BrtEndPName", */ T:-1 },
19374 /*::[*/0x0101/*::]*/: { /* n:"BrtBeginPNPairs", */ T:1 },
19375 /*::[*/0x0102/*::]*/: { /* n:"BrtEndPNPairs", */ T:-1 },
19376 /*::[*/0x0103/*::]*/: { /* n:"BrtBeginPNPair", */ T:1 },
19377 /*::[*/0x0104/*::]*/: { /* n:"BrtEndPNPair", */ T:-1 },
19378 /*::[*/0x0105/*::]*/: { /* n:"BrtBeginECWebProps", */ T:1 },
19379 /*::[*/0x0106/*::]*/: { /* n:"BrtEndECWebProps", */ T:-1 },
19380 /*::[*/0x0107/*::]*/: { /* n:"BrtBeginEcWpTables", */ T:1 },
19381 /*::[*/0x0108/*::]*/: { /* n:"BrtEndECWPTables", */ T:-1 },
19382 /*::[*/0x0109/*::]*/: { /* n:"BrtBeginECParams", */ T:1 },
19383 /*::[*/0x010A/*::]*/: { /* n:"BrtEndECParams", */ T:-1 },
19384 /*::[*/0x010B/*::]*/: { /* n:"BrtBeginECParam", */ T:1 },
19385 /*::[*/0x010C/*::]*/: { /* n:"BrtEndECParam", */ T:-1 },
19386 /*::[*/0x010D/*::]*/: { /* n:"BrtBeginPCDKPIs", */ T:1 },
19387 /*::[*/0x010E/*::]*/: { /* n:"BrtEndPCDKPIs", */ T:-1 },
19388 /*::[*/0x010F/*::]*/: { /* n:"BrtBeginPCDKPI", */ T:1 },
19389 /*::[*/0x0110/*::]*/: { /* n:"BrtEndPCDKPI", */ T:-1 },
19390 /*::[*/0x0111/*::]*/: { /* n:"BrtBeginDims", */ T:1 },
19391 /*::[*/0x0112/*::]*/: { /* n:"BrtEndDims", */ T:-1 },
19392 /*::[*/0x0113/*::]*/: { /* n:"BrtBeginDim", */ T:1 },
19393 /*::[*/0x0114/*::]*/: { /* n:"BrtEndDim", */ T:-1 },
19394 /*::[*/0x0115/*::]*/: { /* n:"BrtIndexPartEnd" */ },
19395 /*::[*/0x0116/*::]*/: { /* n:"BrtBeginStyleSheet", */ T:1 },
19396 /*::[*/0x0117/*::]*/: { /* n:"BrtEndStyleSheet", */ T:-1 },
19397 /*::[*/0x0118/*::]*/: { /* n:"BrtBeginSXView", */ T:1 },
19398 /*::[*/0x0119/*::]*/: { /* n:"BrtEndSXVI", */ T:-1 },
19399 /*::[*/0x011A/*::]*/: { /* n:"BrtBeginSXVI", */ T:1 },
19400 /*::[*/0x011B/*::]*/: { /* n:"BrtBeginSXVIs", */ T:1 },
19401 /*::[*/0x011C/*::]*/: { /* n:"BrtEndSXVIs", */ T:-1 },
19402 /*::[*/0x011D/*::]*/: { /* n:"BrtBeginSXVD", */ T:1 },
19403 /*::[*/0x011E/*::]*/: { /* n:"BrtEndSXVD", */ T:-1 },
19404 /*::[*/0x011F/*::]*/: { /* n:"BrtBeginSXVDs", */ T:1 },
19405 /*::[*/0x0120/*::]*/: { /* n:"BrtEndSXVDs", */ T:-1 },
19406 /*::[*/0x0121/*::]*/: { /* n:"BrtBeginSXPI", */ T:1 },
19407 /*::[*/0x0122/*::]*/: { /* n:"BrtEndSXPI", */ T:-1 },
19408 /*::[*/0x0123/*::]*/: { /* n:"BrtBeginSXPIs", */ T:1 },
19409 /*::[*/0x0124/*::]*/: { /* n:"BrtEndSXPIs", */ T:-1 },
19410 /*::[*/0x0125/*::]*/: { /* n:"BrtBeginSXDI", */ T:1 },
19411 /*::[*/0x0126/*::]*/: { /* n:"BrtEndSXDI", */ T:-1 },
19412 /*::[*/0x0127/*::]*/: { /* n:"BrtBeginSXDIs", */ T:1 },
19413 /*::[*/0x0128/*::]*/: { /* n:"BrtEndSXDIs", */ T:-1 },
19414 /*::[*/0x0129/*::]*/: { /* n:"BrtBeginSXLI", */ T:1 },
19415 /*::[*/0x012A/*::]*/: { /* n:"BrtEndSXLI", */ T:-1 },
19416 /*::[*/0x012B/*::]*/: { /* n:"BrtBeginSXLIRws", */ T:1 },
19417 /*::[*/0x012C/*::]*/: { /* n:"BrtEndSXLIRws", */ T:-1 },
19418 /*::[*/0x012D/*::]*/: { /* n:"BrtBeginSXLICols", */ T:1 },
19419 /*::[*/0x012E/*::]*/: { /* n:"BrtEndSXLICols", */ T:-1 },
19420 /*::[*/0x012F/*::]*/: { /* n:"BrtBeginSXFormat", */ T:1 },
19421 /*::[*/0x0130/*::]*/: { /* n:"BrtEndSXFormat", */ T:-1 },
19422 /*::[*/0x0131/*::]*/: { /* n:"BrtBeginSXFormats", */ T:1 },
19423 /*::[*/0x0132/*::]*/: { /* n:"BrtEndSxFormats", */ T:-1 },
19424 /*::[*/0x0133/*::]*/: { /* n:"BrtBeginSxSelect", */ T:1 },
19425 /*::[*/0x0134/*::]*/: { /* n:"BrtEndSxSelect", */ T:-1 },
19426 /*::[*/0x0135/*::]*/: { /* n:"BrtBeginISXVDRws", */ T:1 },
19427 /*::[*/0x0136/*::]*/: { /* n:"BrtEndISXVDRws", */ T:-1 },
19428 /*::[*/0x0137/*::]*/: { /* n:"BrtBeginISXVDCols", */ T:1 },
19429 /*::[*/0x0138/*::]*/: { /* n:"BrtEndISXVDCols", */ T:-1 },
19430 /*::[*/0x0139/*::]*/: { /* n:"BrtEndSXLocation", */ T:-1 },
19431 /*::[*/0x013A/*::]*/: { /* n:"BrtBeginSXLocation", */ T:1 },
19432 /*::[*/0x013B/*::]*/: { /* n:"BrtEndSXView", */ T:-1 },
19433 /*::[*/0x013C/*::]*/: { /* n:"BrtBeginSXTHs", */ T:1 },
19434 /*::[*/0x013D/*::]*/: { /* n:"BrtEndSXTHs", */ T:-1 },
19435 /*::[*/0x013E/*::]*/: { /* n:"BrtBeginSXTH", */ T:1 },
19436 /*::[*/0x013F/*::]*/: { /* n:"BrtEndSXTH", */ T:-1 },
19437 /*::[*/0x0140/*::]*/: { /* n:"BrtBeginISXTHRws", */ T:1 },
19438 /*::[*/0x0141/*::]*/: { /* n:"BrtEndISXTHRws", */ T:-1 },
19439 /*::[*/0x0142/*::]*/: { /* n:"BrtBeginISXTHCols", */ T:1 },
19440 /*::[*/0x0143/*::]*/: { /* n:"BrtEndISXTHCols", */ T:-1 },
19441 /*::[*/0x0144/*::]*/: { /* n:"BrtBeginSXTDMPS", */ T:1 },
19442 /*::[*/0x0145/*::]*/: { /* n:"BrtEndSXTDMPs", */ T:-1 },
19443 /*::[*/0x0146/*::]*/: { /* n:"BrtBeginSXTDMP", */ T:1 },
19444 /*::[*/0x0147/*::]*/: { /* n:"BrtEndSXTDMP", */ T:-1 },
19445 /*::[*/0x0148/*::]*/: { /* n:"BrtBeginSXTHItems", */ T:1 },
19446 /*::[*/0x0149/*::]*/: { /* n:"BrtEndSXTHItems", */ T:-1 },
19447 /*::[*/0x014A/*::]*/: { /* n:"BrtBeginSXTHItem", */ T:1 },
19448 /*::[*/0x014B/*::]*/: { /* n:"BrtEndSXTHItem", */ T:-1 },
19449 /*::[*/0x014C/*::]*/: { /* n:"BrtBeginMetadata", */ T:1 },
19450 /*::[*/0x014D/*::]*/: { /* n:"BrtEndMetadata", */ T:-1 },
19451 /*::[*/0x014E/*::]*/: { /* n:"BrtBeginEsmdtinfo", */ T:1 },
19452 /*::[*/0x014F/*::]*/: { /* n:"BrtMdtinfo", */ f:parse_BrtMdtinfo },
19453 /*::[*/0x0150/*::]*/: { /* n:"BrtEndEsmdtinfo", */ T:-1 },
19454 /*::[*/0x0151/*::]*/: { /* n:"BrtBeginEsmdb", */ f:parse_BrtBeginEsmdb, T:1 },
19455 /*::[*/0x0152/*::]*/: { /* n:"BrtEndEsmdb", */ T:-1 },
19456 /*::[*/0x0153/*::]*/: { /* n:"BrtBeginEsfmd", */ T:1 },
19457 /*::[*/0x0154/*::]*/: { /* n:"BrtEndEsfmd", */ T:-1 },
19458 /*::[*/0x0155/*::]*/: { /* n:"BrtBeginSingleCells", */ T:1 },
19459 /*::[*/0x0156/*::]*/: { /* n:"BrtEndSingleCells", */ T:-1 },
19460 /*::[*/0x0157/*::]*/: { /* n:"BrtBeginList", */ T:1 },
19461 /*::[*/0x0158/*::]*/: { /* n:"BrtEndList", */ T:-1 },
19462 /*::[*/0x0159/*::]*/: { /* n:"BrtBeginListCols", */ T:1 },
19463 /*::[*/0x015A/*::]*/: { /* n:"BrtEndListCols", */ T:-1 },
19464 /*::[*/0x015B/*::]*/: { /* n:"BrtBeginListCol", */ T:1 },
19465 /*::[*/0x015C/*::]*/: { /* n:"BrtEndListCol", */ T:-1 },
19466 /*::[*/0x015D/*::]*/: { /* n:"BrtBeginListXmlCPr", */ T:1 },
19467 /*::[*/0x015E/*::]*/: { /* n:"BrtEndListXmlCPr", */ T:-1 },
19468 /*::[*/0x015F/*::]*/: { /* n:"BrtListCCFmla" */ },
19469 /*::[*/0x0160/*::]*/: { /* n:"BrtListTrFmla" */ },
19470 /*::[*/0x0161/*::]*/: { /* n:"BrtBeginExternals", */ T:1 },
19471 /*::[*/0x0162/*::]*/: { /* n:"BrtEndExternals", */ T:-1 },
19472 /*::[*/0x0163/*::]*/: { /* n:"BrtSupBookSrc", */ f:parse_RelID},
19473 /*::[*/0x0165/*::]*/: { /* n:"BrtSupSelf" */ },
19474 /*::[*/0x0166/*::]*/: { /* n:"BrtSupSame" */ },
19475 /*::[*/0x0167/*::]*/: { /* n:"BrtSupTabs" */ },
19476 /*::[*/0x0168/*::]*/: { /* n:"BrtBeginSupBook", */ T:1 },
19477 /*::[*/0x0169/*::]*/: { /* n:"BrtPlaceholderName" */ },
19478 /*::[*/0x016A/*::]*/: { /* n:"BrtExternSheet", */ f:parse_ExternSheet },
19479 /*::[*/0x016B/*::]*/: { /* n:"BrtExternTableStart" */ },
19480 /*::[*/0x016C/*::]*/: { /* n:"BrtExternTableEnd" */ },
19481 /*::[*/0x016E/*::]*/: { /* n:"BrtExternRowHdr" */ },
19482 /*::[*/0x016F/*::]*/: { /* n:"BrtExternCellBlank" */ },
19483 /*::[*/0x0170/*::]*/: { /* n:"BrtExternCellReal" */ },
19484 /*::[*/0x0171/*::]*/: { /* n:"BrtExternCellBool" */ },
19485 /*::[*/0x0172/*::]*/: { /* n:"BrtExternCellError" */ },
19486 /*::[*/0x0173/*::]*/: { /* n:"BrtExternCellString" */ },
19487 /*::[*/0x0174/*::]*/: { /* n:"BrtBeginEsmdx", */ T:1 },
19488 /*::[*/0x0175/*::]*/: { /* n:"BrtEndEsmdx", */ T:-1 },
19489 /*::[*/0x0176/*::]*/: { /* n:"BrtBeginMdxSet", */ T:1 },
19490 /*::[*/0x0177/*::]*/: { /* n:"BrtEndMdxSet", */ T:-1 },
19491 /*::[*/0x0178/*::]*/: { /* n:"BrtBeginMdxMbrProp", */ T:1 },
19492 /*::[*/0x0179/*::]*/: { /* n:"BrtEndMdxMbrProp", */ T:-1 },
19493 /*::[*/0x017A/*::]*/: { /* n:"BrtBeginMdxKPI", */ T:1 },
19494 /*::[*/0x017B/*::]*/: { /* n:"BrtEndMdxKPI", */ T:-1 },
19495 /*::[*/0x017C/*::]*/: { /* n:"BrtBeginEsstr", */ T:1 },
19496 /*::[*/0x017D/*::]*/: { /* n:"BrtEndEsstr", */ T:-1 },
19497 /*::[*/0x017E/*::]*/: { /* n:"BrtBeginPRFItem", */ T:1 },
19498 /*::[*/0x017F/*::]*/: { /* n:"BrtEndPRFItem", */ T:-1 },
19499 /*::[*/0x0180/*::]*/: { /* n:"BrtBeginPivotCacheIDs", */ T:1 },
19500 /*::[*/0x0181/*::]*/: { /* n:"BrtEndPivotCacheIDs", */ T:-1 },
19501 /*::[*/0x0182/*::]*/: { /* n:"BrtBeginPivotCacheID", */ T:1 },
19502 /*::[*/0x0183/*::]*/: { /* n:"BrtEndPivotCacheID", */ T:-1 },
19503 /*::[*/0x0184/*::]*/: { /* n:"BrtBeginISXVIs", */ T:1 },
19504 /*::[*/0x0185/*::]*/: { /* n:"BrtEndISXVIs", */ T:-1 },
19505 /*::[*/0x0186/*::]*/: { /* n:"BrtBeginColInfos", */ T:1 },
19506 /*::[*/0x0187/*::]*/: { /* n:"BrtEndColInfos", */ T:-1 },
19507 /*::[*/0x0188/*::]*/: { /* n:"BrtBeginRwBrk", */ T:1 },
19508 /*::[*/0x0189/*::]*/: { /* n:"BrtEndRwBrk", */ T:-1 },
19509 /*::[*/0x018A/*::]*/: { /* n:"BrtBeginColBrk", */ T:1 },
19510 /*::[*/0x018B/*::]*/: { /* n:"BrtEndColBrk", */ T:-1 },
19511 /*::[*/0x018C/*::]*/: { /* n:"BrtBrk" */ },
19512 /*::[*/0x018D/*::]*/: { /* n:"BrtUserBookView" */ },
19513 /*::[*/0x018E/*::]*/: { /* n:"BrtInfo" */ },
19514 /*::[*/0x018F/*::]*/: { /* n:"BrtCUsr" */ },
19515 /*::[*/0x0190/*::]*/: { /* n:"BrtUsr" */ },
19516 /*::[*/0x0191/*::]*/: { /* n:"BrtBeginUsers", */ T:1 },
19517 /*::[*/0x0193/*::]*/: { /* n:"BrtEOF" */ },
19518 /*::[*/0x0194/*::]*/: { /* n:"BrtUCR" */ },
19519 /*::[*/0x0195/*::]*/: { /* n:"BrtRRInsDel" */ },
19520 /*::[*/0x0196/*::]*/: { /* n:"BrtRREndInsDel" */ },
19521 /*::[*/0x0197/*::]*/: { /* n:"BrtRRMove" */ },
19522 /*::[*/0x0198/*::]*/: { /* n:"BrtRREndMove" */ },
19523 /*::[*/0x0199/*::]*/: { /* n:"BrtRRChgCell" */ },
19524 /*::[*/0x019A/*::]*/: { /* n:"BrtRREndChgCell" */ },
19525 /*::[*/0x019B/*::]*/: { /* n:"BrtRRHeader" */ },
19526 /*::[*/0x019C/*::]*/: { /* n:"BrtRRUserView" */ },
19527 /*::[*/0x019D/*::]*/: { /* n:"BrtRRRenSheet" */ },
19528 /*::[*/0x019E/*::]*/: { /* n:"BrtRRInsertSh" */ },
19529 /*::[*/0x019F/*::]*/: { /* n:"BrtRRDefName" */ },
19530 /*::[*/0x01A0/*::]*/: { /* n:"BrtRRNote" */ },
19531 /*::[*/0x01A1/*::]*/: { /* n:"BrtRRConflict" */ },
19532 /*::[*/0x01A2/*::]*/: { /* n:"BrtRRTQSIF" */ },
19533 /*::[*/0x01A3/*::]*/: { /* n:"BrtRRFormat" */ },
19534 /*::[*/0x01A4/*::]*/: { /* n:"BrtRREndFormat" */ },
19535 /*::[*/0x01A5/*::]*/: { /* n:"BrtRRAutoFmt" */ },
19536 /*::[*/0x01A6/*::]*/: { /* n:"BrtBeginUserShViews", */ T:1 },
19537 /*::[*/0x01A7/*::]*/: { /* n:"BrtBeginUserShView", */ T:1 },
19538 /*::[*/0x01A8/*::]*/: { /* n:"BrtEndUserShView", */ T:-1 },
19539 /*::[*/0x01A9/*::]*/: { /* n:"BrtEndUserShViews", */ T:-1 },
19540 /*::[*/0x01AA/*::]*/: { /* n:"BrtArrFmla", */ f:parse_BrtArrFmla },
19541 /*::[*/0x01AB/*::]*/: { /* n:"BrtShrFmla", */ f:parse_BrtShrFmla },
19542 /*::[*/0x01AC/*::]*/: { /* n:"BrtTable" */ },
19543 /*::[*/0x01AD/*::]*/: { /* n:"BrtBeginExtConnections", */ T:1 },
19544 /*::[*/0x01AE/*::]*/: { /* n:"BrtEndExtConnections", */ T:-1 },
19545 /*::[*/0x01AF/*::]*/: { /* n:"BrtBeginPCDCalcMems", */ T:1 },
19546 /*::[*/0x01B0/*::]*/: { /* n:"BrtEndPCDCalcMems", */ T:-1 },
19547 /*::[*/0x01B1/*::]*/: { /* n:"BrtBeginPCDCalcMem", */ T:1 },
19548 /*::[*/0x01B2/*::]*/: { /* n:"BrtEndPCDCalcMem", */ T:-1 },
19549 /*::[*/0x01B3/*::]*/: { /* n:"BrtBeginPCDHGLevels", */ T:1 },
19550 /*::[*/0x01B4/*::]*/: { /* n:"BrtEndPCDHGLevels", */ T:-1 },
19551 /*::[*/0x01B5/*::]*/: { /* n:"BrtBeginPCDHGLevel", */ T:1 },
19552 /*::[*/0x01B6/*::]*/: { /* n:"BrtEndPCDHGLevel", */ T:-1 },
19553 /*::[*/0x01B7/*::]*/: { /* n:"BrtBeginPCDHGLGroups", */ T:1 },
19554 /*::[*/0x01B8/*::]*/: { /* n:"BrtEndPCDHGLGroups", */ T:-1 },
19555 /*::[*/0x01B9/*::]*/: { /* n:"BrtBeginPCDHGLGroup", */ T:1 },
19556 /*::[*/0x01BA/*::]*/: { /* n:"BrtEndPCDHGLGroup", */ T:-1 },
19557 /*::[*/0x01BB/*::]*/: { /* n:"BrtBeginPCDHGLGMembers", */ T:1 },
19558 /*::[*/0x01BC/*::]*/: { /* n:"BrtEndPCDHGLGMembers", */ T:-1 },
19559 /*::[*/0x01BD/*::]*/: { /* n:"BrtBeginPCDHGLGMember", */ T:1 },
19560 /*::[*/0x01BE/*::]*/: { /* n:"BrtEndPCDHGLGMember", */ T:-1 },
19561 /*::[*/0x01BF/*::]*/: { /* n:"BrtBeginQSI", */ T:1 },
19562 /*::[*/0x01C0/*::]*/: { /* n:"BrtEndQSI", */ T:-1 },
19563 /*::[*/0x01C1/*::]*/: { /* n:"BrtBeginQSIR", */ T:1 },
19564 /*::[*/0x01C2/*::]*/: { /* n:"BrtEndQSIR", */ T:-1 },
19565 /*::[*/0x01C3/*::]*/: { /* n:"BrtBeginDeletedNames", */ T:1 },
19566 /*::[*/0x01C4/*::]*/: { /* n:"BrtEndDeletedNames", */ T:-1 },
19567 /*::[*/0x01C5/*::]*/: { /* n:"BrtBeginDeletedName", */ T:1 },
19568 /*::[*/0x01C6/*::]*/: { /* n:"BrtEndDeletedName", */ T:-1 },
19569 /*::[*/0x01C7/*::]*/: { /* n:"BrtBeginQSIFs", */ T:1 },
19570 /*::[*/0x01C8/*::]*/: { /* n:"BrtEndQSIFs", */ T:-1 },
19571 /*::[*/0x01C9/*::]*/: { /* n:"BrtBeginQSIF", */ T:1 },
19572 /*::[*/0x01CA/*::]*/: { /* n:"BrtEndQSIF", */ T:-1 },
19573 /*::[*/0x01CB/*::]*/: { /* n:"BrtBeginAutoSortScope", */ T:1 },
19574 /*::[*/0x01CC/*::]*/: { /* n:"BrtEndAutoSortScope", */ T:-1 },
19575 /*::[*/0x01CD/*::]*/: { /* n:"BrtBeginConditionalFormatting", */ T:1 },
19576 /*::[*/0x01CE/*::]*/: { /* n:"BrtEndConditionalFormatting", */ T:-1 },
19577 /*::[*/0x01CF/*::]*/: { /* n:"BrtBeginCFRule", */ T:1 },
19578 /*::[*/0x01D0/*::]*/: { /* n:"BrtEndCFRule", */ T:-1 },
19579 /*::[*/0x01D1/*::]*/: { /* n:"BrtBeginIconSet", */ T:1 },
19580 /*::[*/0x01D2/*::]*/: { /* n:"BrtEndIconSet", */ T:-1 },
19581 /*::[*/0x01D3/*::]*/: { /* n:"BrtBeginDatabar", */ T:1 },
19582 /*::[*/0x01D4/*::]*/: { /* n:"BrtEndDatabar", */ T:-1 },
19583 /*::[*/0x01D5/*::]*/: { /* n:"BrtBeginColorScale", */ T:1 },
19584 /*::[*/0x01D6/*::]*/: { /* n:"BrtEndColorScale", */ T:-1 },
19585 /*::[*/0x01D7/*::]*/: { /* n:"BrtCFVO" */ },
19586 /*::[*/0x01D8/*::]*/: { /* n:"BrtExternValueMeta" */ },
19587 /*::[*/0x01D9/*::]*/: { /* n:"BrtBeginColorPalette", */ T:1 },
19588 /*::[*/0x01DA/*::]*/: { /* n:"BrtEndColorPalette", */ T:-1 },
19589 /*::[*/0x01DB/*::]*/: { /* n:"BrtIndexedColor" */ },
19590 /*::[*/0x01DC/*::]*/: { /* n:"BrtMargins", */ f:parse_BrtMargins },
19591 /*::[*/0x01DD/*::]*/: { /* n:"BrtPrintOptions" */ },
19592 /*::[*/0x01DE/*::]*/: { /* n:"BrtPageSetup" */ },
19593 /*::[*/0x01DF/*::]*/: { /* n:"BrtBeginHeaderFooter", */ T:1 },
19594 /*::[*/0x01E0/*::]*/: { /* n:"BrtEndHeaderFooter", */ T:-1 },
19595 /*::[*/0x01E1/*::]*/: { /* n:"BrtBeginSXCrtFormat", */ T:1 },
19596 /*::[*/0x01E2/*::]*/: { /* n:"BrtEndSXCrtFormat", */ T:-1 },
19597 /*::[*/0x01E3/*::]*/: { /* n:"BrtBeginSXCrtFormats", */ T:1 },
19598 /*::[*/0x01E4/*::]*/: { /* n:"BrtEndSXCrtFormats", */ T:-1 },
19599 /*::[*/0x01E5/*::]*/: { /* n:"BrtWsFmtInfo", */ f:parse_BrtWsFmtInfo },
19600 /*::[*/0x01E6/*::]*/: { /* n:"BrtBeginMgs", */ T:1 },
19601 /*::[*/0x01E7/*::]*/: { /* n:"BrtEndMGs", */ T:-1 },
19602 /*::[*/0x01E8/*::]*/: { /* n:"BrtBeginMGMaps", */ T:1 },
19603 /*::[*/0x01E9/*::]*/: { /* n:"BrtEndMGMaps", */ T:-1 },
19604 /*::[*/0x01EA/*::]*/: { /* n:"BrtBeginMG", */ T:1 },
19605 /*::[*/0x01EB/*::]*/: { /* n:"BrtEndMG", */ T:-1 },
19606 /*::[*/0x01EC/*::]*/: { /* n:"BrtBeginMap", */ T:1 },
19607 /*::[*/0x01ED/*::]*/: { /* n:"BrtEndMap", */ T:-1 },
19608 /*::[*/0x01EE/*::]*/: { /* n:"BrtHLink", */ f:parse_BrtHLink },
19609 /*::[*/0x01EF/*::]*/: { /* n:"BrtBeginDCon", */ T:1 },
19610 /*::[*/0x01F0/*::]*/: { /* n:"BrtEndDCon", */ T:-1 },
19611 /*::[*/0x01F1/*::]*/: { /* n:"BrtBeginDRefs", */ T:1 },
19612 /*::[*/0x01F2/*::]*/: { /* n:"BrtEndDRefs", */ T:-1 },
19613 /*::[*/0x01F3/*::]*/: { /* n:"BrtDRef" */ },
19614 /*::[*/0x01F4/*::]*/: { /* n:"BrtBeginScenMan", */ T:1 },
19615 /*::[*/0x01F5/*::]*/: { /* n:"BrtEndScenMan", */ T:-1 },
19616 /*::[*/0x01F6/*::]*/: { /* n:"BrtBeginSct", */ T:1 },
19617 /*::[*/0x01F7/*::]*/: { /* n:"BrtEndSct", */ T:-1 },
19618 /*::[*/0x01F8/*::]*/: { /* n:"BrtSlc" */ },
19619 /*::[*/0x01F9/*::]*/: { /* n:"BrtBeginDXFs", */ T:1 },
19620 /*::[*/0x01FA/*::]*/: { /* n:"BrtEndDXFs", */ T:-1 },
19621 /*::[*/0x01FB/*::]*/: { /* n:"BrtDXF" */ },
19622 /*::[*/0x01FC/*::]*/: { /* n:"BrtBeginTableStyles", */ T:1 },
19623 /*::[*/0x01FD/*::]*/: { /* n:"BrtEndTableStyles", */ T:-1 },
19624 /*::[*/0x01FE/*::]*/: { /* n:"BrtBeginTableStyle", */ T:1 },
19625 /*::[*/0x01FF/*::]*/: { /* n:"BrtEndTableStyle", */ T:-1 },
19626 /*::[*/0x0200/*::]*/: { /* n:"BrtTableStyleElement" */ },
19627 /*::[*/0x0201/*::]*/: { /* n:"BrtTableStyleClient" */ },
19628 /*::[*/0x0202/*::]*/: { /* n:"BrtBeginVolDeps", */ T:1 },
19629 /*::[*/0x0203/*::]*/: { /* n:"BrtEndVolDeps", */ T:-1 },
19630 /*::[*/0x0204/*::]*/: { /* n:"BrtBeginVolType", */ T:1 },
19631 /*::[*/0x0205/*::]*/: { /* n:"BrtEndVolType", */ T:-1 },
19632 /*::[*/0x0206/*::]*/: { /* n:"BrtBeginVolMain", */ T:1 },
19633 /*::[*/0x0207/*::]*/: { /* n:"BrtEndVolMain", */ T:-1 },
19634 /*::[*/0x0208/*::]*/: { /* n:"BrtBeginVolTopic", */ T:1 },
19635 /*::[*/0x0209/*::]*/: { /* n:"BrtEndVolTopic", */ T:-1 },
19636 /*::[*/0x020A/*::]*/: { /* n:"BrtVolSubtopic" */ },
19637 /*::[*/0x020B/*::]*/: { /* n:"BrtVolRef" */ },
19638 /*::[*/0x020C/*::]*/: { /* n:"BrtVolNum" */ },
19639 /*::[*/0x020D/*::]*/: { /* n:"BrtVolErr" */ },
19640 /*::[*/0x020E/*::]*/: { /* n:"BrtVolStr" */ },
19641 /*::[*/0x020F/*::]*/: { /* n:"BrtVolBool" */ },
19642 /*::[*/0x0210/*::]*/: { /* n:"BrtBeginCalcChain$", */ T:1 },
19643 /*::[*/0x0211/*::]*/: { /* n:"BrtEndCalcChain$", */ T:-1 },
19644 /*::[*/0x0212/*::]*/: { /* n:"BrtBeginSortState", */ T:1 },
19645 /*::[*/0x0213/*::]*/: { /* n:"BrtEndSortState", */ T:-1 },
19646 /*::[*/0x0214/*::]*/: { /* n:"BrtBeginSortCond", */ T:1 },
19647 /*::[*/0x0215/*::]*/: { /* n:"BrtEndSortCond", */ T:-1 },
19648 /*::[*/0x0216/*::]*/: { /* n:"BrtBookProtection" */ },
19649 /*::[*/0x0217/*::]*/: { /* n:"BrtSheetProtection" */ },
19650 /*::[*/0x0218/*::]*/: { /* n:"BrtRangeProtection" */ },
19651 /*::[*/0x0219/*::]*/: { /* n:"BrtPhoneticInfo" */ },
19652 /*::[*/0x021A/*::]*/: { /* n:"BrtBeginECTxtWiz", */ T:1 },
19653 /*::[*/0x021B/*::]*/: { /* n:"BrtEndECTxtWiz", */ T:-1 },
19654 /*::[*/0x021C/*::]*/: { /* n:"BrtBeginECTWFldInfoLst", */ T:1 },
19655 /*::[*/0x021D/*::]*/: { /* n:"BrtEndECTWFldInfoLst", */ T:-1 },
19656 /*::[*/0x021E/*::]*/: { /* n:"BrtBeginECTwFldInfo", */ T:1 },
19657 /*::[*/0x0224/*::]*/: { /* n:"BrtFileSharing" */ },
19658 /*::[*/0x0225/*::]*/: { /* n:"BrtOleSize" */ },
19659 /*::[*/0x0226/*::]*/: { /* n:"BrtDrawing", */ f:parse_RelID },
19660 /*::[*/0x0227/*::]*/: { /* n:"BrtLegacyDrawing" */ },
19661 /*::[*/0x0228/*::]*/: { /* n:"BrtLegacyDrawingHF" */ },
19662 /*::[*/0x0229/*::]*/: { /* n:"BrtWebOpt" */ },
19663 /*::[*/0x022A/*::]*/: { /* n:"BrtBeginWebPubItems", */ T:1 },
19664 /*::[*/0x022B/*::]*/: { /* n:"BrtEndWebPubItems", */ T:-1 },
19665 /*::[*/0x022C/*::]*/: { /* n:"BrtBeginWebPubItem", */ T:1 },
19666 /*::[*/0x022D/*::]*/: { /* n:"BrtEndWebPubItem", */ T:-1 },
19667 /*::[*/0x022E/*::]*/: { /* n:"BrtBeginSXCondFmt", */ T:1 },
19668 /*::[*/0x022F/*::]*/: { /* n:"BrtEndSXCondFmt", */ T:-1 },
19669 /*::[*/0x0230/*::]*/: { /* n:"BrtBeginSXCondFmts", */ T:1 },
19670 /*::[*/0x0231/*::]*/: { /* n:"BrtEndSXCondFmts", */ T:-1 },
19671 /*::[*/0x0232/*::]*/: { /* n:"BrtBkHim" */ },
19672 /*::[*/0x0234/*::]*/: { /* n:"BrtColor" */ },
19673 /*::[*/0x0235/*::]*/: { /* n:"BrtBeginIndexedColors", */ T:1 },
19674 /*::[*/0x0236/*::]*/: { /* n:"BrtEndIndexedColors", */ T:-1 },
19675 /*::[*/0x0239/*::]*/: { /* n:"BrtBeginMRUColors", */ T:1 },
19676 /*::[*/0x023A/*::]*/: { /* n:"BrtEndMRUColors", */ T:-1 },
19677 /*::[*/0x023C/*::]*/: { /* n:"BrtMRUColor" */ },
19678 /*::[*/0x023D/*::]*/: { /* n:"BrtBeginDVals", */ T:1 },
19679 /*::[*/0x023E/*::]*/: { /* n:"BrtEndDVals", */ T:-1 },
19680 /*::[*/0x0241/*::]*/: { /* n:"BrtSupNameStart" */ },
19681 /*::[*/0x0242/*::]*/: { /* n:"BrtSupNameValueStart" */ },
19682 /*::[*/0x0243/*::]*/: { /* n:"BrtSupNameValueEnd" */ },
19683 /*::[*/0x0244/*::]*/: { /* n:"BrtSupNameNum" */ },
19684 /*::[*/0x0245/*::]*/: { /* n:"BrtSupNameErr" */ },
19685 /*::[*/0x0246/*::]*/: { /* n:"BrtSupNameSt" */ },
19686 /*::[*/0x0247/*::]*/: { /* n:"BrtSupNameNil" */ },
19687 /*::[*/0x0248/*::]*/: { /* n:"BrtSupNameBool" */ },
19688 /*::[*/0x0249/*::]*/: { /* n:"BrtSupNameFmla" */ },
19689 /*::[*/0x024A/*::]*/: { /* n:"BrtSupNameBits" */ },
19690 /*::[*/0x024B/*::]*/: { /* n:"BrtSupNameEnd" */ },
19691 /*::[*/0x024C/*::]*/: { /* n:"BrtEndSupBook", */ T:-1 },
19692 /*::[*/0x024D/*::]*/: { /* n:"BrtCellSmartTagProperty" */ },
19693 /*::[*/0x024E/*::]*/: { /* n:"BrtBeginCellSmartTag", */ T:1 },
19694 /*::[*/0x024F/*::]*/: { /* n:"BrtEndCellSmartTag", */ T:-1 },
19695 /*::[*/0x0250/*::]*/: { /* n:"BrtBeginCellSmartTags", */ T:1 },
19696 /*::[*/0x0251/*::]*/: { /* n:"BrtEndCellSmartTags", */ T:-1 },
19697 /*::[*/0x0252/*::]*/: { /* n:"BrtBeginSmartTags", */ T:1 },
19698 /*::[*/0x0253/*::]*/: { /* n:"BrtEndSmartTags", */ T:-1 },
19699 /*::[*/0x0254/*::]*/: { /* n:"BrtSmartTagType" */ },
19700 /*::[*/0x0255/*::]*/: { /* n:"BrtBeginSmartTagTypes", */ T:1 },
19701 /*::[*/0x0256/*::]*/: { /* n:"BrtEndSmartTagTypes", */ T:-1 },
19702 /*::[*/0x0257/*::]*/: { /* n:"BrtBeginSXFilters", */ T:1 },
19703 /*::[*/0x0258/*::]*/: { /* n:"BrtEndSXFilters", */ T:-1 },
19704 /*::[*/0x0259/*::]*/: { /* n:"BrtBeginSXFILTER", */ T:1 },
19705 /*::[*/0x025A/*::]*/: { /* n:"BrtEndSXFilter", */ T:-1 },
19706 /*::[*/0x025B/*::]*/: { /* n:"BrtBeginFills", */ T:1 },
19707 /*::[*/0x025C/*::]*/: { /* n:"BrtEndFills", */ T:-1 },
19708 /*::[*/0x025D/*::]*/: { /* n:"BrtBeginCellWatches", */ T:1 },
19709 /*::[*/0x025E/*::]*/: { /* n:"BrtEndCellWatches", */ T:-1 },
19710 /*::[*/0x025F/*::]*/: { /* n:"BrtCellWatch" */ },
19711 /*::[*/0x0260/*::]*/: { /* n:"BrtBeginCRErrs", */ T:1 },
19712 /*::[*/0x0261/*::]*/: { /* n:"BrtEndCRErrs", */ T:-1 },
19713 /*::[*/0x0262/*::]*/: { /* n:"BrtCrashRecErr" */ },
19714 /*::[*/0x0263/*::]*/: { /* n:"BrtBeginFonts", */ T:1 },
19715 /*::[*/0x0264/*::]*/: { /* n:"BrtEndFonts", */ T:-1 },
19716 /*::[*/0x0265/*::]*/: { /* n:"BrtBeginBorders", */ T:1 },
19717 /*::[*/0x0266/*::]*/: { /* n:"BrtEndBorders", */ T:-1 },
19718 /*::[*/0x0267/*::]*/: { /* n:"BrtBeginFmts", */ T:1 },
19719 /*::[*/0x0268/*::]*/: { /* n:"BrtEndFmts", */ T:-1 },
19720 /*::[*/0x0269/*::]*/: { /* n:"BrtBeginCellXFs", */ T:1 },
19721 /*::[*/0x026A/*::]*/: { /* n:"BrtEndCellXFs", */ T:-1 },
19722 /*::[*/0x026B/*::]*/: { /* n:"BrtBeginStyles", */ T:1 },
19723 /*::[*/0x026C/*::]*/: { /* n:"BrtEndStyles", */ T:-1 },
19724 /*::[*/0x0271/*::]*/: { /* n:"BrtBigName" */ },
19725 /*::[*/0x0272/*::]*/: { /* n:"BrtBeginCellStyleXFs", */ T:1 },
19726 /*::[*/0x0273/*::]*/: { /* n:"BrtEndCellStyleXFs", */ T:-1 },
19727 /*::[*/0x0274/*::]*/: { /* n:"BrtBeginComments", */ T:1 },
19728 /*::[*/0x0275/*::]*/: { /* n:"BrtEndComments", */ T:-1 },
19729 /*::[*/0x0276/*::]*/: { /* n:"BrtBeginCommentAuthors", */ T:1 },
19730 /*::[*/0x0277/*::]*/: { /* n:"BrtEndCommentAuthors", */ T:-1 },
19731 /*::[*/0x0278/*::]*/: { /* n:"BrtCommentAuthor", */ f:parse_BrtCommentAuthor },
19732 /*::[*/0x0279/*::]*/: { /* n:"BrtBeginCommentList", */ T:1 },
19733 /*::[*/0x027A/*::]*/: { /* n:"BrtEndCommentList", */ T:-1 },
19734 /*::[*/0x027B/*::]*/: { /* n:"BrtBeginComment", */ T:1, f:parse_BrtBeginComment},
19735 /*::[*/0x027C/*::]*/: { /* n:"BrtEndComment", */ T:-1 },
19736 /*::[*/0x027D/*::]*/: { /* n:"BrtCommentText", */ f:parse_BrtCommentText },
19737 /*::[*/0x027E/*::]*/: { /* n:"BrtBeginOleObjects", */ T:1 },
19738 /*::[*/0x027F/*::]*/: { /* n:"BrtOleObject" */ },
19739 /*::[*/0x0280/*::]*/: { /* n:"BrtEndOleObjects", */ T:-1 },
19740 /*::[*/0x0281/*::]*/: { /* n:"BrtBeginSxrules", */ T:1 },
19741 /*::[*/0x0282/*::]*/: { /* n:"BrtEndSxRules", */ T:-1 },
19742 /*::[*/0x0283/*::]*/: { /* n:"BrtBeginActiveXControls", */ T:1 },
19743 /*::[*/0x0284/*::]*/: { /* n:"BrtActiveX" */ },
19744 /*::[*/0x0285/*::]*/: { /* n:"BrtEndActiveXControls", */ T:-1 },
19745 /*::[*/0x0286/*::]*/: { /* n:"BrtBeginPCDSDTCEMembersSortBy", */ T:1 },
19746 /*::[*/0x0288/*::]*/: { /* n:"BrtBeginCellIgnoreECs", */ T:1 },
19747 /*::[*/0x0289/*::]*/: { /* n:"BrtCellIgnoreEC" */ },
19748 /*::[*/0x028A/*::]*/: { /* n:"BrtEndCellIgnoreECs", */ T:-1 },
19749 /*::[*/0x028B/*::]*/: { /* n:"BrtCsProp", */ f:parse_BrtCsProp },
19750 /*::[*/0x028C/*::]*/: { /* n:"BrtCsPageSetup" */ },
19751 /*::[*/0x028D/*::]*/: { /* n:"BrtBeginUserCsViews", */ T:1 },
19752 /*::[*/0x028E/*::]*/: { /* n:"BrtEndUserCsViews", */ T:-1 },
19753 /*::[*/0x028F/*::]*/: { /* n:"BrtBeginUserCsView", */ T:1 },
19754 /*::[*/0x0290/*::]*/: { /* n:"BrtEndUserCsView", */ T:-1 },
19755 /*::[*/0x0291/*::]*/: { /* n:"BrtBeginPcdSFCIEntries", */ T:1 },
19756 /*::[*/0x0292/*::]*/: { /* n:"BrtEndPCDSFCIEntries", */ T:-1 },
19757 /*::[*/0x0293/*::]*/: { /* n:"BrtPCDSFCIEntry" */ },
19758 /*::[*/0x0294/*::]*/: { /* n:"BrtBeginListParts", */ T:1 },
19759 /*::[*/0x0295/*::]*/: { /* n:"BrtListPart" */ },
19760 /*::[*/0x0296/*::]*/: { /* n:"BrtEndListParts", */ T:-1 },
19761 /*::[*/0x0297/*::]*/: { /* n:"BrtSheetCalcProp" */ },
19762 /*::[*/0x0298/*::]*/: { /* n:"BrtBeginFnGroup", */ T:1 },
19763 /*::[*/0x0299/*::]*/: { /* n:"BrtFnGroup" */ },
19764 /*::[*/0x029A/*::]*/: { /* n:"BrtEndFnGroup", */ T:-1 },
19765 /*::[*/0x029B/*::]*/: { /* n:"BrtSupAddin" */ },
19766 /*::[*/0x029C/*::]*/: { /* n:"BrtSXTDMPOrder" */ },
19767 /*::[*/0x029D/*::]*/: { /* n:"BrtCsProtection" */ },
19768 /*::[*/0x029F/*::]*/: { /* n:"BrtBeginWsSortMap", */ T:1 },
19769 /*::[*/0x02A0/*::]*/: { /* n:"BrtEndWsSortMap", */ T:-1 },
19770 /*::[*/0x02A1/*::]*/: { /* n:"BrtBeginRRSort", */ T:1 },
19771 /*::[*/0x02A2/*::]*/: { /* n:"BrtEndRRSort", */ T:-1 },
19772 /*::[*/0x02A3/*::]*/: { /* n:"BrtRRSortItem" */ },
19773 /*::[*/0x02A4/*::]*/: { /* n:"BrtFileSharingIso" */ },
19774 /*::[*/0x02A5/*::]*/: { /* n:"BrtBookProtectionIso" */ },
19775 /*::[*/0x02A6/*::]*/: { /* n:"BrtSheetProtectionIso" */ },
19776 /*::[*/0x02A7/*::]*/: { /* n:"BrtCsProtectionIso" */ },
19777 /*::[*/0x02A8/*::]*/: { /* n:"BrtRangeProtectionIso" */ },
19778 /*::[*/0x02A9/*::]*/: { /* n:"BrtDValList" */ },
19779 /*::[*/0x0400/*::]*/: { /* n:"BrtRwDescent" */ },
19780 /*::[*/0x0401/*::]*/: { /* n:"BrtKnownFonts" */ },
19781 /*::[*/0x0402/*::]*/: { /* n:"BrtBeginSXTupleSet", */ T:1 },
19782 /*::[*/0x0403/*::]*/: { /* n:"BrtEndSXTupleSet", */ T:-1 },
19783 /*::[*/0x0404/*::]*/: { /* n:"BrtBeginSXTupleSetHeader", */ T:1 },
19784 /*::[*/0x0405/*::]*/: { /* n:"BrtEndSXTupleSetHeader", */ T:-1 },
19785 /*::[*/0x0406/*::]*/: { /* n:"BrtSXTupleSetHeaderItem" */ },
19786 /*::[*/0x0407/*::]*/: { /* n:"BrtBeginSXTupleSetData", */ T:1 },
19787 /*::[*/0x0408/*::]*/: { /* n:"BrtEndSXTupleSetData", */ T:-1 },
19788 /*::[*/0x0409/*::]*/: { /* n:"BrtBeginSXTupleSetRow", */ T:1 },
19789 /*::[*/0x040A/*::]*/: { /* n:"BrtEndSXTupleSetRow", */ T:-1 },
19790 /*::[*/0x040B/*::]*/: { /* n:"BrtSXTupleSetRowItem" */ },
19791 /*::[*/0x040C/*::]*/: { /* n:"BrtNameExt" */ },
19792 /*::[*/0x040D/*::]*/: { /* n:"BrtPCDH14" */ },
19793 /*::[*/0x040E/*::]*/: { /* n:"BrtBeginPCDCalcMem14", */ T:1 },
19794 /*::[*/0x040F/*::]*/: { /* n:"BrtEndPCDCalcMem14", */ T:-1 },
19795 /*::[*/0x0410/*::]*/: { /* n:"BrtSXTH14" */ },
19796 /*::[*/0x0411/*::]*/: { /* n:"BrtBeginSparklineGroup", */ T:1 },
19797 /*::[*/0x0412/*::]*/: { /* n:"BrtEndSparklineGroup", */ T:-1 },
19798 /*::[*/0x0413/*::]*/: { /* n:"BrtSparkline" */ },
19799 /*::[*/0x0414/*::]*/: { /* n:"BrtSXDI14" */ },
19800 /*::[*/0x0415/*::]*/: { /* n:"BrtWsFmtInfoEx14" */ },
19801 /*::[*/0x0416/*::]*/: { /* n:"BrtBeginConditionalFormatting14", */ T:1 },
19802 /*::[*/0x0417/*::]*/: { /* n:"BrtEndConditionalFormatting14", */ T:-1 },
19803 /*::[*/0x0418/*::]*/: { /* n:"BrtBeginCFRule14", */ T:1 },
19804 /*::[*/0x0419/*::]*/: { /* n:"BrtEndCFRule14", */ T:-1 },
19805 /*::[*/0x041A/*::]*/: { /* n:"BrtCFVO14" */ },
19806 /*::[*/0x041B/*::]*/: { /* n:"BrtBeginDatabar14", */ T:1 },
19807 /*::[*/0x041C/*::]*/: { /* n:"BrtBeginIconSet14", */ T:1 },
19808 /*::[*/0x041D/*::]*/: { /* n:"BrtDVal14", */ f: parse_BrtDVal14 },
19809 /*::[*/0x041E/*::]*/: { /* n:"BrtBeginDVals14", */ T:1 },
19810 /*::[*/0x041F/*::]*/: { /* n:"BrtColor14" */ },
19811 /*::[*/0x0420/*::]*/: { /* n:"BrtBeginSparklines", */ T:1 },
19812 /*::[*/0x0421/*::]*/: { /* n:"BrtEndSparklines", */ T:-1 },
19813 /*::[*/0x0422/*::]*/: { /* n:"BrtBeginSparklineGroups", */ T:1 },
19814 /*::[*/0x0423/*::]*/: { /* n:"BrtEndSparklineGroups", */ T:-1 },
19815 /*::[*/0x0425/*::]*/: { /* n:"BrtSXVD14" */ },
19816 /*::[*/0x0426/*::]*/: { /* n:"BrtBeginSXView14", */ T:1 },
19817 /*::[*/0x0427/*::]*/: { /* n:"BrtEndSXView14", */ T:-1 },
19818 /*::[*/0x0428/*::]*/: { /* n:"BrtBeginSXView16", */ T:1 },
19819 /*::[*/0x0429/*::]*/: { /* n:"BrtEndSXView16", */ T:-1 },
19820 /*::[*/0x042A/*::]*/: { /* n:"BrtBeginPCD14", */ T:1 },
19821 /*::[*/0x042B/*::]*/: { /* n:"BrtEndPCD14", */ T:-1 },
19822 /*::[*/0x042C/*::]*/: { /* n:"BrtBeginExtConn14", */ T:1 },
19823 /*::[*/0x042D/*::]*/: { /* n:"BrtEndExtConn14", */ T:-1 },
19824 /*::[*/0x042E/*::]*/: { /* n:"BrtBeginSlicerCacheIDs", */ T:1 },
19825 /*::[*/0x042F/*::]*/: { /* n:"BrtEndSlicerCacheIDs", */ T:-1 },
19826 /*::[*/0x0430/*::]*/: { /* n:"BrtBeginSlicerCacheID", */ T:1 },
19827 /*::[*/0x0431/*::]*/: { /* n:"BrtEndSlicerCacheID", */ T:-1 },
19828 /*::[*/0x0433/*::]*/: { /* n:"BrtBeginSlicerCache", */ T:1 },
19829 /*::[*/0x0434/*::]*/: { /* n:"BrtEndSlicerCache", */ T:-1 },
19830 /*::[*/0x0435/*::]*/: { /* n:"BrtBeginSlicerCacheDef", */ T:1 },
19831 /*::[*/0x0436/*::]*/: { /* n:"BrtEndSlicerCacheDef", */ T:-1 },
19832 /*::[*/0x0437/*::]*/: { /* n:"BrtBeginSlicersEx", */ T:1 },
19833 /*::[*/0x0438/*::]*/: { /* n:"BrtEndSlicersEx", */ T:-1 },
19834 /*::[*/0x0439/*::]*/: { /* n:"BrtBeginSlicerEx", */ T:1 },
19835 /*::[*/0x043A/*::]*/: { /* n:"BrtEndSlicerEx", */ T:-1 },
19836 /*::[*/0x043B/*::]*/: { /* n:"BrtBeginSlicer", */ T:1 },
19837 /*::[*/0x043C/*::]*/: { /* n:"BrtEndSlicer", */ T:-1 },
19838 /*::[*/0x043D/*::]*/: { /* n:"BrtSlicerCachePivotTables" */ },
19839 /*::[*/0x043E/*::]*/: { /* n:"BrtBeginSlicerCacheOlapImpl", */ T:1 },
19840 /*::[*/0x043F/*::]*/: { /* n:"BrtEndSlicerCacheOlapImpl", */ T:-1 },
19841 /*::[*/0x0440/*::]*/: { /* n:"BrtBeginSlicerCacheLevelsData", */ T:1 },
19842 /*::[*/0x0441/*::]*/: { /* n:"BrtEndSlicerCacheLevelsData", */ T:-1 },
19843 /*::[*/0x0442/*::]*/: { /* n:"BrtBeginSlicerCacheLevelData", */ T:1 },
19844 /*::[*/0x0443/*::]*/: { /* n:"BrtEndSlicerCacheLevelData", */ T:-1 },
19845 /*::[*/0x0444/*::]*/: { /* n:"BrtBeginSlicerCacheSiRanges", */ T:1 },
19846 /*::[*/0x0445/*::]*/: { /* n:"BrtEndSlicerCacheSiRanges", */ T:-1 },
19847 /*::[*/0x0446/*::]*/: { /* n:"BrtBeginSlicerCacheSiRange", */ T:1 },
19848 /*::[*/0x0447/*::]*/: { /* n:"BrtEndSlicerCacheSiRange", */ T:-1 },
19849 /*::[*/0x0448/*::]*/: { /* n:"BrtSlicerCacheOlapItem" */ },
19850 /*::[*/0x0449/*::]*/: { /* n:"BrtBeginSlicerCacheSelections", */ T:1 },
19851 /*::[*/0x044A/*::]*/: { /* n:"BrtSlicerCacheSelection" */ },
19852 /*::[*/0x044B/*::]*/: { /* n:"BrtEndSlicerCacheSelections", */ T:-1 },
19853 /*::[*/0x044C/*::]*/: { /* n:"BrtBeginSlicerCacheNative", */ T:1 },
19854 /*::[*/0x044D/*::]*/: { /* n:"BrtEndSlicerCacheNative", */ T:-1 },
19855 /*::[*/0x044E/*::]*/: { /* n:"BrtSlicerCacheNativeItem" */ },
19856 /*::[*/0x044F/*::]*/: { /* n:"BrtRangeProtection14" */ },
19857 /*::[*/0x0450/*::]*/: { /* n:"BrtRangeProtectionIso14" */ },
19858 /*::[*/0x0451/*::]*/: { /* n:"BrtCellIgnoreEC14" */ },
19859 /*::[*/0x0457/*::]*/: { /* n:"BrtList14" */ },
19860 /*::[*/0x0458/*::]*/: { /* n:"BrtCFIcon" */ },
19861 /*::[*/0x0459/*::]*/: { /* n:"BrtBeginSlicerCachesPivotCacheIDs", */ T:1 },
19862 /*::[*/0x045A/*::]*/: { /* n:"BrtEndSlicerCachesPivotCacheIDs", */ T:-1 },
19863 /*::[*/0x045B/*::]*/: { /* n:"BrtBeginSlicers", */ T:1 },
19864 /*::[*/0x045C/*::]*/: { /* n:"BrtEndSlicers", */ T:-1 },
19865 /*::[*/0x045D/*::]*/: { /* n:"BrtWbProp14" */ },
19866 /*::[*/0x045E/*::]*/: { /* n:"BrtBeginSXEdit", */ T:1 },
19867 /*::[*/0x045F/*::]*/: { /* n:"BrtEndSXEdit", */ T:-1 },
19868 /*::[*/0x0460/*::]*/: { /* n:"BrtBeginSXEdits", */ T:1 },
19869 /*::[*/0x0461/*::]*/: { /* n:"BrtEndSXEdits", */ T:-1 },
19870 /*::[*/0x0462/*::]*/: { /* n:"BrtBeginSXChange", */ T:1 },
19871 /*::[*/0x0463/*::]*/: { /* n:"BrtEndSXChange", */ T:-1 },
19872 /*::[*/0x0464/*::]*/: { /* n:"BrtBeginSXChanges", */ T:1 },
19873 /*::[*/0x0465/*::]*/: { /* n:"BrtEndSXChanges", */ T:-1 },
19874 /*::[*/0x0466/*::]*/: { /* n:"BrtSXTupleItems" */ },
19875 /*::[*/0x0468/*::]*/: { /* n:"BrtBeginSlicerStyle", */ T:1 },
19876 /*::[*/0x0469/*::]*/: { /* n:"BrtEndSlicerStyle", */ T:-1 },
19877 /*::[*/0x046A/*::]*/: { /* n:"BrtSlicerStyleElement" */ },
19878 /*::[*/0x046B/*::]*/: { /* n:"BrtBeginStyleSheetExt14", */ T:1 },
19879 /*::[*/0x046C/*::]*/: { /* n:"BrtEndStyleSheetExt14", */ T:-1 },
19880 /*::[*/0x046D/*::]*/: { /* n:"BrtBeginSlicerCachesPivotCacheID", */ T:1 },
19881 /*::[*/0x046E/*::]*/: { /* n:"BrtEndSlicerCachesPivotCacheID", */ T:-1 },
19882 /*::[*/0x046F/*::]*/: { /* n:"BrtBeginConditionalFormattings", */ T:1 },
19883 /*::[*/0x0470/*::]*/: { /* n:"BrtEndConditionalFormattings", */ T:-1 },
19884 /*::[*/0x0471/*::]*/: { /* n:"BrtBeginPCDCalcMemExt", */ T:1 },
19885 /*::[*/0x0472/*::]*/: { /* n:"BrtEndPCDCalcMemExt", */ T:-1 },
19886 /*::[*/0x0473/*::]*/: { /* n:"BrtBeginPCDCalcMemsExt", */ T:1 },
19887 /*::[*/0x0474/*::]*/: { /* n:"BrtEndPCDCalcMemsExt", */ T:-1 },
19888 /*::[*/0x0475/*::]*/: { /* n:"BrtPCDField14" */ },
19889 /*::[*/0x0476/*::]*/: { /* n:"BrtBeginSlicerStyles", */ T:1 },
19890 /*::[*/0x0477/*::]*/: { /* n:"BrtEndSlicerStyles", */ T:-1 },
19891 /*::[*/0x0478/*::]*/: { /* n:"BrtBeginSlicerStyleElements", */ T:1 },
19892 /*::[*/0x0479/*::]*/: { /* n:"BrtEndSlicerStyleElements", */ T:-1 },
19893 /*::[*/0x047A/*::]*/: { /* n:"BrtCFRuleExt" */ },
19894 /*::[*/0x047B/*::]*/: { /* n:"BrtBeginSXCondFmt14", */ T:1 },
19895 /*::[*/0x047C/*::]*/: { /* n:"BrtEndSXCondFmt14", */ T:-1 },
19896 /*::[*/0x047D/*::]*/: { /* n:"BrtBeginSXCondFmts14", */ T:1 },
19897 /*::[*/0x047E/*::]*/: { /* n:"BrtEndSXCondFmts14", */ T:-1 },
19898 /*::[*/0x0480/*::]*/: { /* n:"BrtBeginSortCond14", */ T:1 },
19899 /*::[*/0x0481/*::]*/: { /* n:"BrtEndSortCond14", */ T:-1 },
19900 /*::[*/0x0482/*::]*/: { /* n:"BrtEndDVals14", */ T:-1 },
19901 /*::[*/0x0483/*::]*/: { /* n:"BrtEndIconSet14", */ T:-1 },
19902 /*::[*/0x0484/*::]*/: { /* n:"BrtEndDatabar14", */ T:-1 },
19903 /*::[*/0x0485/*::]*/: { /* n:"BrtBeginColorScale14", */ T:1 },
19904 /*::[*/0x0486/*::]*/: { /* n:"BrtEndColorScale14", */ T:-1 },
19905 /*::[*/0x0487/*::]*/: { /* n:"BrtBeginSxrules14", */ T:1 },
19906 /*::[*/0x0488/*::]*/: { /* n:"BrtEndSxrules14", */ T:-1 },
19907 /*::[*/0x0489/*::]*/: { /* n:"BrtBeginPRule14", */ T:1 },
19908 /*::[*/0x048A/*::]*/: { /* n:"BrtEndPRule14", */ T:-1 },
19909 /*::[*/0x048B/*::]*/: { /* n:"BrtBeginPRFilters14", */ T:1 },
19910 /*::[*/0x048C/*::]*/: { /* n:"BrtEndPRFilters14", */ T:-1 },
19911 /*::[*/0x048D/*::]*/: { /* n:"BrtBeginPRFilter14", */ T:1 },
19912 /*::[*/0x048E/*::]*/: { /* n:"BrtEndPRFilter14", */ T:-1 },
19913 /*::[*/0x048F/*::]*/: { /* n:"BrtBeginPRFItem14", */ T:1 },
19914 /*::[*/0x0490/*::]*/: { /* n:"BrtEndPRFItem14", */ T:-1 },
19915 /*::[*/0x0491/*::]*/: { /* n:"BrtBeginCellIgnoreECs14", */ T:1 },
19916 /*::[*/0x0492/*::]*/: { /* n:"BrtEndCellIgnoreECs14", */ T:-1 },
19917 /*::[*/0x0493/*::]*/: { /* n:"BrtDxf14" */ },
19918 /*::[*/0x0494/*::]*/: { /* n:"BrtBeginDxF14s", */ T:1 },
19919 /*::[*/0x0495/*::]*/: { /* n:"BrtEndDxf14s", */ T:-1 },
19920 /*::[*/0x0499/*::]*/: { /* n:"BrtFilter14" */ },
19921 /*::[*/0x049A/*::]*/: { /* n:"BrtBeginCustomFilters14", */ T:1 },
19922 /*::[*/0x049C/*::]*/: { /* n:"BrtCustomFilter14" */ },
19923 /*::[*/0x049D/*::]*/: { /* n:"BrtIconFilter14" */ },
19924 /*::[*/0x049E/*::]*/: { /* n:"BrtPivotCacheConnectionName" */ },
19925 /*::[*/0x0800/*::]*/: { /* n:"BrtBeginDecoupledPivotCacheIDs", */ T:1 },
19926 /*::[*/0x0801/*::]*/: { /* n:"BrtEndDecoupledPivotCacheIDs", */ T:-1 },
19927 /*::[*/0x0802/*::]*/: { /* n:"BrtDecoupledPivotCacheID" */ },
19928 /*::[*/0x0803/*::]*/: { /* n:"BrtBeginPivotTableRefs", */ T:1 },
19929 /*::[*/0x0804/*::]*/: { /* n:"BrtEndPivotTableRefs", */ T:-1 },
19930 /*::[*/0x0805/*::]*/: { /* n:"BrtPivotTableRef" */ },
19931 /*::[*/0x0806/*::]*/: { /* n:"BrtSlicerCacheBookPivotTables" */ },
19932 /*::[*/0x0807/*::]*/: { /* n:"BrtBeginSxvcells", */ T:1 },
19933 /*::[*/0x0808/*::]*/: { /* n:"BrtEndSxvcells", */ T:-1 },
19934 /*::[*/0x0809/*::]*/: { /* n:"BrtBeginSxRow", */ T:1 },
19935 /*::[*/0x080A/*::]*/: { /* n:"BrtEndSxRow", */ T:-1 },
19936 /*::[*/0x080C/*::]*/: { /* n:"BrtPcdCalcMem15" */ },
19937 /*::[*/0x0813/*::]*/: { /* n:"BrtQsi15" */ },
19938 /*::[*/0x0814/*::]*/: { /* n:"BrtBeginWebExtensions", */ T:1 },
19939 /*::[*/0x0815/*::]*/: { /* n:"BrtEndWebExtensions", */ T:-1 },
19940 /*::[*/0x0816/*::]*/: { /* n:"BrtWebExtension" */ },
19941 /*::[*/0x0817/*::]*/: { /* n:"BrtAbsPath15" */ },
19942 /*::[*/0x0818/*::]*/: { /* n:"BrtBeginPivotTableUISettings", */ T:1 },
19943 /*::[*/0x0819/*::]*/: { /* n:"BrtEndPivotTableUISettings", */ T:-1 },
19944 /*::[*/0x081B/*::]*/: { /* n:"BrtTableSlicerCacheIDs" */ },
19945 /*::[*/0x081C/*::]*/: { /* n:"BrtTableSlicerCacheID" */ },
19946 /*::[*/0x081D/*::]*/: { /* n:"BrtBeginTableSlicerCache", */ T:1 },
19947 /*::[*/0x081E/*::]*/: { /* n:"BrtEndTableSlicerCache", */ T:-1 },
19948 /*::[*/0x081F/*::]*/: { /* n:"BrtSxFilter15" */ },
19949 /*::[*/0x0820/*::]*/: { /* n:"BrtBeginTimelineCachePivotCacheIDs", */ T:1 },
19950 /*::[*/0x0821/*::]*/: { /* n:"BrtEndTimelineCachePivotCacheIDs", */ T:-1 },
19951 /*::[*/0x0822/*::]*/: { /* n:"BrtTimelineCachePivotCacheID" */ },
19952 /*::[*/0x0823/*::]*/: { /* n:"BrtBeginTimelineCacheIDs", */ T:1 },
19953 /*::[*/0x0824/*::]*/: { /* n:"BrtEndTimelineCacheIDs", */ T:-1 },
19954 /*::[*/0x0825/*::]*/: { /* n:"BrtBeginTimelineCacheID", */ T:1 },
19955 /*::[*/0x0826/*::]*/: { /* n:"BrtEndTimelineCacheID", */ T:-1 },
19956 /*::[*/0x0827/*::]*/: { /* n:"BrtBeginTimelinesEx", */ T:1 },
19957 /*::[*/0x0828/*::]*/: { /* n:"BrtEndTimelinesEx", */ T:-1 },
19958 /*::[*/0x0829/*::]*/: { /* n:"BrtBeginTimelineEx", */ T:1 },
19959 /*::[*/0x082A/*::]*/: { /* n:"BrtEndTimelineEx", */ T:-1 },
19960 /*::[*/0x082B/*::]*/: { /* n:"BrtWorkBookPr15" */ },
19961 /*::[*/0x082C/*::]*/: { /* n:"BrtPCDH15" */ },
19962 /*::[*/0x082D/*::]*/: { /* n:"BrtBeginTimelineStyle", */ T:1 },
19963 /*::[*/0x082E/*::]*/: { /* n:"BrtEndTimelineStyle", */ T:-1 },
19964 /*::[*/0x082F/*::]*/: { /* n:"BrtTimelineStyleElement" */ },
19965 /*::[*/0x0830/*::]*/: { /* n:"BrtBeginTimelineStylesheetExt15", */ T:1 },
19966 /*::[*/0x0831/*::]*/: { /* n:"BrtEndTimelineStylesheetExt15", */ T:-1 },
19967 /*::[*/0x0832/*::]*/: { /* n:"BrtBeginTimelineStyles", */ T:1 },
19968 /*::[*/0x0833/*::]*/: { /* n:"BrtEndTimelineStyles", */ T:-1 },
19969 /*::[*/0x0834/*::]*/: { /* n:"BrtBeginTimelineStyleElements", */ T:1 },
19970 /*::[*/0x0835/*::]*/: { /* n:"BrtEndTimelineStyleElements", */ T:-1 },
19971 /*::[*/0x0836/*::]*/: { /* n:"BrtDxf15" */ },
19972 /*::[*/0x0837/*::]*/: { /* n:"BrtBeginDxfs15", */ T:1 },
19973 /*::[*/0x0838/*::]*/: { /* n:"BrtEndDxfs15", */ T:-1 },
19974 /*::[*/0x0839/*::]*/: { /* n:"BrtSlicerCacheHideItemsWithNoData" */ },
19975 /*::[*/0x083A/*::]*/: { /* n:"BrtBeginItemUniqueNames", */ T:1 },
19976 /*::[*/0x083B/*::]*/: { /* n:"BrtEndItemUniqueNames", */ T:-1 },
19977 /*::[*/0x083C/*::]*/: { /* n:"BrtItemUniqueName" */ },
19978 /*::[*/0x083D/*::]*/: { /* n:"BrtBeginExtConn15", */ T:1 },
19979 /*::[*/0x083E/*::]*/: { /* n:"BrtEndExtConn15", */ T:-1 },
19980 /*::[*/0x083F/*::]*/: { /* n:"BrtBeginOledbPr15", */ T:1 },
19981 /*::[*/0x0840/*::]*/: { /* n:"BrtEndOledbPr15", */ T:-1 },
19982 /*::[*/0x0841/*::]*/: { /* n:"BrtBeginDataFeedPr15", */ T:1 },
19983 /*::[*/0x0842/*::]*/: { /* n:"BrtEndDataFeedPr15", */ T:-1 },
19984 /*::[*/0x0843/*::]*/: { /* n:"BrtTextPr15" */ },
19985 /*::[*/0x0844/*::]*/: { /* n:"BrtRangePr15" */ },
19986 /*::[*/0x0845/*::]*/: { /* n:"BrtDbCommand15" */ },
19987 /*::[*/0x0846/*::]*/: { /* n:"BrtBeginDbTables15", */ T:1 },
19988 /*::[*/0x0847/*::]*/: { /* n:"BrtEndDbTables15", */ T:-1 },
19989 /*::[*/0x0848/*::]*/: { /* n:"BrtDbTable15" */ },
19990 /*::[*/0x0849/*::]*/: { /* n:"BrtBeginDataModel", */ T:1 },
19991 /*::[*/0x084A/*::]*/: { /* n:"BrtEndDataModel", */ T:-1 },
19992 /*::[*/0x084B/*::]*/: { /* n:"BrtBeginModelTables", */ T:1 },
19993 /*::[*/0x084C/*::]*/: { /* n:"BrtEndModelTables", */ T:-1 },
19994 /*::[*/0x084D/*::]*/: { /* n:"BrtModelTable" */ },
19995 /*::[*/0x084E/*::]*/: { /* n:"BrtBeginModelRelationships", */ T:1 },
19996 /*::[*/0x084F/*::]*/: { /* n:"BrtEndModelRelationships", */ T:-1 },
19997 /*::[*/0x0850/*::]*/: { /* n:"BrtModelRelationship" */ },
19998 /*::[*/0x0851/*::]*/: { /* n:"BrtBeginECTxtWiz15", */ T:1 },
19999 /*::[*/0x0852/*::]*/: { /* n:"BrtEndECTxtWiz15", */ T:-1 },
20000 /*::[*/0x0853/*::]*/: { /* n:"BrtBeginECTWFldInfoLst15", */ T:1 },
20001 /*::[*/0x0854/*::]*/: { /* n:"BrtEndECTWFldInfoLst15", */ T:-1 },
20002 /*::[*/0x0855/*::]*/: { /* n:"BrtBeginECTWFldInfo15", */ T:1 },
20003 /*::[*/0x0856/*::]*/: { /* n:"BrtFieldListActiveItem" */ },
20004 /*::[*/0x0857/*::]*/: { /* n:"BrtPivotCacheIdVersion" */ },
20005 /*::[*/0x0858/*::]*/: { /* n:"BrtSXDI15" */ },
20006 /*::[*/0x0859/*::]*/: { /* n:"BrtBeginModelTimeGroupings", */ T:1 },
20007 /*::[*/0x085A/*::]*/: { /* n:"BrtEndModelTimeGroupings", */ T:-1 },
20008 /*::[*/0x085B/*::]*/: { /* n:"BrtBeginModelTimeGrouping", */ T:1 },
20009 /*::[*/0x085C/*::]*/: { /* n:"BrtEndModelTimeGrouping", */ T:-1 },
20010 /*::[*/0x085D/*::]*/: { /* n:"BrtModelTimeGroupingCalcCol" */ },
20011 /*::[*/0x0C00/*::]*/: { /* n:"BrtUid" */ },
20012 /*::[*/0x0C01/*::]*/: { /* n:"BrtRevisionPtr" */ },
20013 /*::[*/0x1000/*::]*/: { /* n:"BrtBeginDynamicArrayPr", */ T:1 },
20014 /*::[*/0x1001/*::]*/: { /* n:"BrtEndDynamicArrayPr", */ T:-1 },
20015 /*::[*/0x138A/*::]*/: { /* n:"BrtBeginRichValueBlock", */ T:1 },
20016 /*::[*/0x138B/*::]*/: { /* n:"BrtEndRichValueBlock", */ T:-1 },
20017 /*::[*/0x13D9/*::]*/: { /* n:"BrtBeginRichFilters", */ T:1 },
20018 /*::[*/0x13DA/*::]*/: { /* n:"BrtEndRichFilters", */ T:-1 },
20019 /*::[*/0x13DB/*::]*/: { /* n:"BrtRichFilter" */ },
20020 /*::[*/0x13DC/*::]*/: { /* n:"BrtBeginRichFilterColumn", */ T:1 },
20021 /*::[*/0x13DD/*::]*/: { /* n:"BrtEndRichFilterColumn", */ T:-1 },
20022 /*::[*/0x13DE/*::]*/: { /* n:"BrtBeginCustomRichFilters", */ T:1 },
20023 /*::[*/0x13DF/*::]*/: { /* n:"BrtEndCustomRichFilters", */ T:-1 },
20024 /*::[*/0x13E0/*::]*/: { /* n:"BrtCustomRichFilter" */ },
20025 /*::[*/0x13E1/*::]*/: { /* n:"BrtTop10RichFilter" */ },
20026 /*::[*/0x13E2/*::]*/: { /* n:"BrtDynamicRichFilter" */ },
20027 /*::[*/0x13E4/*::]*/: { /* n:"BrtBeginRichSortCondition", */ T:1 },
20028 /*::[*/0x13E5/*::]*/: { /* n:"BrtEndRichSortCondition", */ T:-1 },
20029 /*::[*/0x13E6/*::]*/: { /* n:"BrtRichFilterDateGroupItem" */ },
20030 /*::[*/0x13E7/*::]*/: { /* n:"BrtBeginCalcFeatures", */ T:1 },
20031 /*::[*/0x13E8/*::]*/: { /* n:"BrtEndCalcFeatures", */ T:-1 },
20032 /*::[*/0x13E9/*::]*/: { /* n:"BrtCalcFeature" */ },
20033 /*::[*/0x13EB/*::]*/: { /* n:"BrtExternalLinksPr" */ },
20034 /*::[*/0xFFFF/*::]*/: { n:"" }
20035};
20036
20037/* [MS-XLS] 2.3 Record Enumeration (and other sources) */
20038var XLSRecordEnum = {
20039 /* [MS-XLS] 2.3 Record Enumeration 2021-08-17 */
20040 /*::[*/0x0006/*::]*/: { /* n:"Formula", */ f:parse_Formula },
20041 /*::[*/0x000a/*::]*/: { /* n:"EOF", */ f:parsenoop2 },
20042 /*::[*/0x000c/*::]*/: { /* n:"CalcCount", */ f:parseuint16 }, //
20043 /*::[*/0x000d/*::]*/: { /* n:"CalcMode", */ f:parseuint16 }, //
20044 /*::[*/0x000e/*::]*/: { /* n:"CalcPrecision", */ f:parsebool }, //
20045 /*::[*/0x000f/*::]*/: { /* n:"CalcRefMode", */ f:parsebool }, //
20046 /*::[*/0x0010/*::]*/: { /* n:"CalcDelta", */ f:parse_Xnum }, //
20047 /*::[*/0x0011/*::]*/: { /* n:"CalcIter", */ f:parsebool }, //
20048 /*::[*/0x0012/*::]*/: { /* n:"Protect", */ f:parsebool },
20049 /*::[*/0x0013/*::]*/: { /* n:"Password", */ f:parseuint16 },
20050 /*::[*/0x0014/*::]*/: { /* n:"Header", */ f:parse_XLHeaderFooter },
20051 /*::[*/0x0015/*::]*/: { /* n:"Footer", */ f:parse_XLHeaderFooter },
20052 /*::[*/0x0017/*::]*/: { /* n:"ExternSheet", */ f:parse_ExternSheet },
20053 /*::[*/0x0018/*::]*/: { /* n:"Lbl", */ f:parse_Lbl },
20054 /*::[*/0x0019/*::]*/: { /* n:"WinProtect", */ f:parsebool },
20055 /*::[*/0x001a/*::]*/: { /* n:"VerticalPageBreaks", */ },
20056 /*::[*/0x001b/*::]*/: { /* n:"HorizontalPageBreaks", */ },
20057 /*::[*/0x001c/*::]*/: { /* n:"Note", */ f:parse_Note },
20058 /*::[*/0x001d/*::]*/: { /* n:"Selection", */ },
20059 /*::[*/0x0022/*::]*/: { /* n:"Date1904", */ f:parsebool },
20060 /*::[*/0x0023/*::]*/: { /* n:"ExternName", */ f:parse_ExternName },
20061 /*::[*/0x0026/*::]*/: { /* n:"LeftMargin", */ f:parse_Xnum }, // *
20062 /*::[*/0x0027/*::]*/: { /* n:"RightMargin", */ f:parse_Xnum }, // *
20063 /*::[*/0x0028/*::]*/: { /* n:"TopMargin", */ f:parse_Xnum }, // *
20064 /*::[*/0x0029/*::]*/: { /* n:"BottomMargin", */ f:parse_Xnum }, // *
20065 /*::[*/0x002a/*::]*/: { /* n:"PrintRowCol", */ f:parsebool },
20066 /*::[*/0x002b/*::]*/: { /* n:"PrintGrid", */ f:parsebool },
20067 /*::[*/0x002f/*::]*/: { /* n:"FilePass", */ f:parse_FilePass },
20068 /*::[*/0x0031/*::]*/: { /* n:"Font", */ f:parse_Font },
20069 /*::[*/0x0033/*::]*/: { /* n:"PrintSize", */ f:parseuint16 },
20070 /*::[*/0x003c/*::]*/: { /* n:"Continue", */ },
20071 /*::[*/0x003d/*::]*/: { /* n:"Window1", */ f:parse_Window1 },
20072 /*::[*/0x0040/*::]*/: { /* n:"Backup", */ f:parsebool },
20073 /*::[*/0x0041/*::]*/: { /* n:"Pane", */ f:parse_Pane },
20074 /*::[*/0x0042/*::]*/: { /* n:"CodePage", */ f:parseuint16 },
20075 /*::[*/0x004d/*::]*/: { /* n:"Pls", */ },
20076 /*::[*/0x0050/*::]*/: { /* n:"DCon", */ },
20077 /*::[*/0x0051/*::]*/: { /* n:"DConRef", */ },
20078 /*::[*/0x0052/*::]*/: { /* n:"DConName", */ },
20079 /*::[*/0x0055/*::]*/: { /* n:"DefColWidth", */ f:parseuint16 },
20080 /*::[*/0x0059/*::]*/: { /* n:"XCT", */ },
20081 /*::[*/0x005a/*::]*/: { /* n:"CRN", */ },
20082 /*::[*/0x005b/*::]*/: { /* n:"FileSharing", */ },
20083 /*::[*/0x005c/*::]*/: { /* n:"WriteAccess", */ f:parse_WriteAccess },
20084 /*::[*/0x005d/*::]*/: { /* n:"Obj", */ f:parse_Obj },
20085 /*::[*/0x005e/*::]*/: { /* n:"Uncalced", */ },
20086 /*::[*/0x005f/*::]*/: { /* n:"CalcSaveRecalc", */ f:parsebool }, //
20087 /*::[*/0x0060/*::]*/: { /* n:"Template", */ },
20088 /*::[*/0x0061/*::]*/: { /* n:"Intl", */ },
20089 /*::[*/0x0063/*::]*/: { /* n:"ObjProtect", */ f:parsebool },
20090 /*::[*/0x007d/*::]*/: { /* n:"ColInfo", */ f:parse_ColInfo },
20091 /*::[*/0x0080/*::]*/: { /* n:"Guts", */ f:parse_Guts },
20092 /*::[*/0x0081/*::]*/: { /* n:"WsBool", */ f:parse_WsBool },
20093 /*::[*/0x0082/*::]*/: { /* n:"GridSet", */ f:parseuint16 },
20094 /*::[*/0x0083/*::]*/: { /* n:"HCenter", */ f:parsebool },
20095 /*::[*/0x0084/*::]*/: { /* n:"VCenter", */ f:parsebool },
20096 /*::[*/0x0085/*::]*/: { /* n:"BoundSheet8", */ f:parse_BoundSheet8 },
20097 /*::[*/0x0086/*::]*/: { /* n:"WriteProtect", */ },
20098 /*::[*/0x008c/*::]*/: { /* n:"Country", */ f:parse_Country },
20099 /*::[*/0x008d/*::]*/: { /* n:"HideObj", */ f:parseuint16 },
20100 /*::[*/0x0090/*::]*/: { /* n:"Sort", */ },
20101 /*::[*/0x0092/*::]*/: { /* n:"Palette", */ f:parse_Palette },
20102 /*::[*/0x0097/*::]*/: { /* n:"Sync", */ },
20103 /*::[*/0x0098/*::]*/: { /* n:"LPr", */ },
20104 /*::[*/0x0099/*::]*/: { /* n:"DxGCol", */ },
20105 /*::[*/0x009a/*::]*/: { /* n:"FnGroupName", */ },
20106 /*::[*/0x009b/*::]*/: { /* n:"FilterMode", */ },
20107 /*::[*/0x009c/*::]*/: { /* n:"BuiltInFnGroupCount", */ f:parseuint16 },
20108 /*::[*/0x009d/*::]*/: { /* n:"AutoFilterInfo", */ },
20109 /*::[*/0x009e/*::]*/: { /* n:"AutoFilter", */ },
20110 /*::[*/0x00a0/*::]*/: { /* n:"Scl", */ f:parse_Scl },
20111 /*::[*/0x00a1/*::]*/: { /* n:"Setup", */ f:parse_Setup },
20112 /*::[*/0x00ae/*::]*/: { /* n:"ScenMan", */ },
20113 /*::[*/0x00af/*::]*/: { /* n:"SCENARIO", */ },
20114 /*::[*/0x00b0/*::]*/: { /* n:"SxView", */ },
20115 /*::[*/0x00b1/*::]*/: { /* n:"Sxvd", */ },
20116 /*::[*/0x00b2/*::]*/: { /* n:"SXVI", */ },
20117 /*::[*/0x00b4/*::]*/: { /* n:"SxIvd", */ },
20118 /*::[*/0x00b5/*::]*/: { /* n:"SXLI", */ },
20119 /*::[*/0x00b6/*::]*/: { /* n:"SXPI", */ },
20120 /*::[*/0x00b8/*::]*/: { /* n:"DocRoute", */ },
20121 /*::[*/0x00b9/*::]*/: { /* n:"RecipName", */ },
20122 /*::[*/0x00bd/*::]*/: { /* n:"MulRk", */ f:parse_MulRk },
20123 /*::[*/0x00be/*::]*/: { /* n:"MulBlank", */ f:parse_MulBlank },
20124 /*::[*/0x00c1/*::]*/: { /* n:"Mms", */ f:parsenoop2 },
20125 /*::[*/0x00c5/*::]*/: { /* n:"SXDI", */ },
20126 /*::[*/0x00c6/*::]*/: { /* n:"SXDB", */ },
20127 /*::[*/0x00c7/*::]*/: { /* n:"SXFDB", */ },
20128 /*::[*/0x00c8/*::]*/: { /* n:"SXDBB", */ },
20129 /*::[*/0x00c9/*::]*/: { /* n:"SXNum", */ },
20130 /*::[*/0x00ca/*::]*/: { /* n:"SxBool", */ f:parsebool },
20131 /*::[*/0x00cb/*::]*/: { /* n:"SxErr", */ },
20132 /*::[*/0x00cc/*::]*/: { /* n:"SXInt", */ },
20133 /*::[*/0x00cd/*::]*/: { /* n:"SXString", */ },
20134 /*::[*/0x00ce/*::]*/: { /* n:"SXDtr", */ },
20135 /*::[*/0x00cf/*::]*/: { /* n:"SxNil", */ },
20136 /*::[*/0x00d0/*::]*/: { /* n:"SXTbl", */ },
20137 /*::[*/0x00d1/*::]*/: { /* n:"SXTBRGIITM", */ },
20138 /*::[*/0x00d2/*::]*/: { /* n:"SxTbpg", */ },
20139 /*::[*/0x00d3/*::]*/: { /* n:"ObProj", */ },
20140 /*::[*/0x00d5/*::]*/: { /* n:"SXStreamID", */ },
20141 /*::[*/0x00d7/*::]*/: { /* n:"DBCell", */ },
20142 /*::[*/0x00d8/*::]*/: { /* n:"SXRng", */ },
20143 /*::[*/0x00d9/*::]*/: { /* n:"SxIsxoper", */ },
20144 /*::[*/0x00da/*::]*/: { /* n:"BookBool", */ f:parseuint16 },
20145 /*::[*/0x00dc/*::]*/: { /* n:"DbOrParamQry", */ },
20146 /*::[*/0x00dd/*::]*/: { /* n:"ScenarioProtect", */ f:parsebool },
20147 /*::[*/0x00de/*::]*/: { /* n:"OleObjectSize", */ },
20148 /*::[*/0x00e0/*::]*/: { /* n:"XF", */ f:parse_XF },
20149 /*::[*/0x00e1/*::]*/: { /* n:"InterfaceHdr", */ f:parse_InterfaceHdr },
20150 /*::[*/0x00e2/*::]*/: { /* n:"InterfaceEnd", */ f:parsenoop2 },
20151 /*::[*/0x00e3/*::]*/: { /* n:"SXVS", */ },
20152 /*::[*/0x00e5/*::]*/: { /* n:"MergeCells", */ f:parse_MergeCells },
20153 /*::[*/0x00e9/*::]*/: { /* n:"BkHim", */ },
20154 /*::[*/0x00eb/*::]*/: { /* n:"MsoDrawingGroup", */ },
20155 /*::[*/0x00ec/*::]*/: { /* n:"MsoDrawing", */ },
20156 /*::[*/0x00ed/*::]*/: { /* n:"MsoDrawingSelection", */ },
20157 /*::[*/0x00ef/*::]*/: { /* n:"PhoneticInfo", */ },
20158 /*::[*/0x00f0/*::]*/: { /* n:"SxRule", */ },
20159 /*::[*/0x00f1/*::]*/: { /* n:"SXEx", */ },
20160 /*::[*/0x00f2/*::]*/: { /* n:"SxFilt", */ },
20161 /*::[*/0x00f4/*::]*/: { /* n:"SxDXF", */ },
20162 /*::[*/0x00f5/*::]*/: { /* n:"SxItm", */ },
20163 /*::[*/0x00f6/*::]*/: { /* n:"SxName", */ },
20164 /*::[*/0x00f7/*::]*/: { /* n:"SxSelect", */ },
20165 /*::[*/0x00f8/*::]*/: { /* n:"SXPair", */ },
20166 /*::[*/0x00f9/*::]*/: { /* n:"SxFmla", */ },
20167 /*::[*/0x00fb/*::]*/: { /* n:"SxFormat", */ },
20168 /*::[*/0x00fc/*::]*/: { /* n:"SST", */ f:parse_SST },
20169 /*::[*/0x00fd/*::]*/: { /* n:"LabelSst", */ f:parse_LabelSst },
20170 /*::[*/0x00ff/*::]*/: { /* n:"ExtSST", */ f:parse_ExtSST },
20171 /*::[*/0x0100/*::]*/: { /* n:"SXVDEx", */ },
20172 /*::[*/0x0103/*::]*/: { /* n:"SXFormula", */ },
20173 /*::[*/0x0122/*::]*/: { /* n:"SXDBEx", */ },
20174 /*::[*/0x0137/*::]*/: { /* n:"RRDInsDel", */ },
20175 /*::[*/0x0138/*::]*/: { /* n:"RRDHead", */ },
20176 /*::[*/0x013b/*::]*/: { /* n:"RRDChgCell", */ },
20177 /*::[*/0x013d/*::]*/: { /* n:"RRTabId", */ f:parseuint16a },
20178 /*::[*/0x013e/*::]*/: { /* n:"RRDRenSheet", */ },
20179 /*::[*/0x013f/*::]*/: { /* n:"RRSort", */ },
20180 /*::[*/0x0140/*::]*/: { /* n:"RRDMove", */ },
20181 /*::[*/0x014a/*::]*/: { /* n:"RRFormat", */ },
20182 /*::[*/0x014b/*::]*/: { /* n:"RRAutoFmt", */ },
20183 /*::[*/0x014d/*::]*/: { /* n:"RRInsertSh", */ },
20184 /*::[*/0x014e/*::]*/: { /* n:"RRDMoveBegin", */ },
20185 /*::[*/0x014f/*::]*/: { /* n:"RRDMoveEnd", */ },
20186 /*::[*/0x0150/*::]*/: { /* n:"RRDInsDelBegin", */ },
20187 /*::[*/0x0151/*::]*/: { /* n:"RRDInsDelEnd", */ },
20188 /*::[*/0x0152/*::]*/: { /* n:"RRDConflict", */ },
20189 /*::[*/0x0153/*::]*/: { /* n:"RRDDefName", */ },
20190 /*::[*/0x0154/*::]*/: { /* n:"RRDRstEtxp", */ },
20191 /*::[*/0x015f/*::]*/: { /* n:"LRng", */ },
20192 /*::[*/0x0160/*::]*/: { /* n:"UsesELFs", */ f:parsebool },
20193 /*::[*/0x0161/*::]*/: { /* n:"DSF", */ f:parsenoop2 },
20194 /*::[*/0x0191/*::]*/: { /* n:"CUsr", */ },
20195 /*::[*/0x0192/*::]*/: { /* n:"CbUsr", */ },
20196 /*::[*/0x0193/*::]*/: { /* n:"UsrInfo", */ },
20197 /*::[*/0x0194/*::]*/: { /* n:"UsrExcl", */ },
20198 /*::[*/0x0195/*::]*/: { /* n:"FileLock", */ },
20199 /*::[*/0x0196/*::]*/: { /* n:"RRDInfo", */ },
20200 /*::[*/0x0197/*::]*/: { /* n:"BCUsrs", */ },
20201 /*::[*/0x0198/*::]*/: { /* n:"UsrChk", */ },
20202 /*::[*/0x01a9/*::]*/: { /* n:"UserBView", */ },
20203 /*::[*/0x01aa/*::]*/: { /* n:"UserSViewBegin", */ },
20204 /*::[*/0x01ab/*::]*/: { /* n:"UserSViewEnd", */ },
20205 /*::[*/0x01ac/*::]*/: { /* n:"RRDUserView", */ },
20206 /*::[*/0x01ad/*::]*/: { /* n:"Qsi", */ },
20207 /*::[*/0x01ae/*::]*/: { /* n:"SupBook", */ f:parse_SupBook },
20208 /*::[*/0x01af/*::]*/: { /* n:"Prot4Rev", */ f:parsebool },
20209 /*::[*/0x01b0/*::]*/: { /* n:"CondFmt", */ },
20210 /*::[*/0x01b1/*::]*/: { /* n:"CF", */ },
20211 /*::[*/0x01b2/*::]*/: { /* n:"DVal", */ },
20212 /*::[*/0x01b5/*::]*/: { /* n:"DConBin", */ },
20213 /*::[*/0x01b6/*::]*/: { /* n:"TxO", */ f:parse_TxO },
20214 /*::[*/0x01b7/*::]*/: { /* n:"RefreshAll", */ f:parsebool }, //
20215 /*::[*/0x01b8/*::]*/: { /* n:"HLink", */ f:parse_HLink },
20216 /*::[*/0x01b9/*::]*/: { /* n:"Lel", */ },
20217 /*::[*/0x01ba/*::]*/: { /* n:"CodeName", */ f:parse_XLUnicodeString },
20218 /*::[*/0x01bb/*::]*/: { /* n:"SXFDBType", */ },
20219 /*::[*/0x01bc/*::]*/: { /* n:"Prot4RevPass", */ f:parseuint16 },
20220 /*::[*/0x01bd/*::]*/: { /* n:"ObNoMacros", */ },
20221 /*::[*/0x01be/*::]*/: { /* n:"Dv", */ },
20222 /*::[*/0x01c0/*::]*/: { /* n:"Excel9File", */ f:parsenoop2 },
20223 /*::[*/0x01c1/*::]*/: { /* n:"RecalcId", */ f:parse_RecalcId, r:2},
20224 /*::[*/0x01c2/*::]*/: { /* n:"EntExU2", */ f:parsenoop2 },
20225 /*::[*/0x0200/*::]*/: { /* n:"Dimensions", */ f:parse_Dimensions },
20226 /*::[*/0x0201/*::]*/: { /* n:"Blank", */ f:parse_Blank },
20227 /*::[*/0x0203/*::]*/: { /* n:"Number", */ f:parse_Number },
20228 /*::[*/0x0204/*::]*/: { /* n:"Label", */ f:parse_Label },
20229 /*::[*/0x0205/*::]*/: { /* n:"BoolErr", */ f:parse_BoolErr },
20230 /*::[*/0x0207/*::]*/: { /* n:"String", */ f:parse_String },
20231 /*::[*/0x0208/*::]*/: { /* n:"Row", */ f:parse_Row },
20232 /*::[*/0x020b/*::]*/: { /* n:"Index", */ },
20233 /*::[*/0x0221/*::]*/: { /* n:"Array", */ f:parse_Array },
20234 /*::[*/0x0225/*::]*/: { /* n:"DefaultRowHeight", */ f:parse_DefaultRowHeight },
20235 /*::[*/0x0236/*::]*/: { /* n:"Table", */ },
20236 /*::[*/0x023e/*::]*/: { /* n:"Window2", */ f:parse_Window2 },
20237 /*::[*/0x027e/*::]*/: { /* n:"RK", */ f:parse_RK },
20238 /*::[*/0x0293/*::]*/: { /* n:"Style", */ },
20239 /*::[*/0x0418/*::]*/: { /* n:"BigName", */ },
20240 /*::[*/0x041e/*::]*/: { /* n:"Format", */ f:parse_Format },
20241 /*::[*/0x043c/*::]*/: { /* n:"ContinueBigName", */ },
20242 /*::[*/0x04bc/*::]*/: { /* n:"ShrFmla", */ f:parse_ShrFmla },
20243 /*::[*/0x0800/*::]*/: { /* n:"HLinkTooltip", */ f:parse_HLinkTooltip },
20244 /*::[*/0x0801/*::]*/: { /* n:"WebPub", */ },
20245 /*::[*/0x0802/*::]*/: { /* n:"QsiSXTag", */ },
20246 /*::[*/0x0803/*::]*/: { /* n:"DBQueryExt", */ },
20247 /*::[*/0x0804/*::]*/: { /* n:"ExtString", */ },
20248 /*::[*/0x0805/*::]*/: { /* n:"TxtQry", */ },
20249 /*::[*/0x0806/*::]*/: { /* n:"Qsir", */ },
20250 /*::[*/0x0807/*::]*/: { /* n:"Qsif", */ },
20251 /*::[*/0x0808/*::]*/: { /* n:"RRDTQSIF", */ },
20252 /*::[*/0x0809/*::]*/: { /* n:"BOF", */ f:parse_BOF },
20253 /*::[*/0x080a/*::]*/: { /* n:"OleDbConn", */ },
20254 /*::[*/0x080b/*::]*/: { /* n:"WOpt", */ },
20255 /*::[*/0x080c/*::]*/: { /* n:"SXViewEx", */ },
20256 /*::[*/0x080d/*::]*/: { /* n:"SXTH", */ },
20257 /*::[*/0x080e/*::]*/: { /* n:"SXPIEx", */ },
20258 /*::[*/0x080f/*::]*/: { /* n:"SXVDTEx", */ },
20259 /*::[*/0x0810/*::]*/: { /* n:"SXViewEx9", */ },
20260 /*::[*/0x0812/*::]*/: { /* n:"ContinueFrt", */ },
20261 /*::[*/0x0813/*::]*/: { /* n:"RealTimeData", */ },
20262 /*::[*/0x0850/*::]*/: { /* n:"ChartFrtInfo", */ },
20263 /*::[*/0x0851/*::]*/: { /* n:"FrtWrapper", */ },
20264 /*::[*/0x0852/*::]*/: { /* n:"StartBlock", */ },
20265 /*::[*/0x0853/*::]*/: { /* n:"EndBlock", */ },
20266 /*::[*/0x0854/*::]*/: { /* n:"StartObject", */ },
20267 /*::[*/0x0855/*::]*/: { /* n:"EndObject", */ },
20268 /*::[*/0x0856/*::]*/: { /* n:"CatLab", */ },
20269 /*::[*/0x0857/*::]*/: { /* n:"YMult", */ },
20270 /*::[*/0x0858/*::]*/: { /* n:"SXViewLink", */ },
20271 /*::[*/0x0859/*::]*/: { /* n:"PivotChartBits", */ },
20272 /*::[*/0x085a/*::]*/: { /* n:"FrtFontList", */ },
20273 /*::[*/0x0862/*::]*/: { /* n:"SheetExt", */ },
20274 /*::[*/0x0863/*::]*/: { /* n:"BookExt", */ r:12},
20275 /*::[*/0x0864/*::]*/: { /* n:"SXAddl", */ },
20276 /*::[*/0x0865/*::]*/: { /* n:"CrErr", */ },
20277 /*::[*/0x0866/*::]*/: { /* n:"HFPicture", */ },
20278 /*::[*/0x0867/*::]*/: { /* n:"FeatHdr", */ f:parsenoop2 },
20279 /*::[*/0x0868/*::]*/: { /* n:"Feat", */ },
20280 /*::[*/0x086a/*::]*/: { /* n:"DataLabExt", */ },
20281 /*::[*/0x086b/*::]*/: { /* n:"DataLabExtContents", */ },
20282 /*::[*/0x086c/*::]*/: { /* n:"CellWatch", */ },
20283 /*::[*/0x0871/*::]*/: { /* n:"FeatHdr11", */ },
20284 /*::[*/0x0872/*::]*/: { /* n:"Feature11", */ },
20285 /*::[*/0x0874/*::]*/: { /* n:"DropDownObjIds", */ },
20286 /*::[*/0x0875/*::]*/: { /* n:"ContinueFrt11", */ },
20287 /*::[*/0x0876/*::]*/: { /* n:"DConn", */ },
20288 /*::[*/0x0877/*::]*/: { /* n:"List12", */ },
20289 /*::[*/0x0878/*::]*/: { /* n:"Feature12", */ },
20290 /*::[*/0x0879/*::]*/: { /* n:"CondFmt12", */ },
20291 /*::[*/0x087a/*::]*/: { /* n:"CF12", */ },
20292 /*::[*/0x087b/*::]*/: { /* n:"CFEx", */ },
20293 /*::[*/0x087c/*::]*/: { /* n:"XFCRC", */ f:parse_XFCRC, r:12 },
20294 /*::[*/0x087d/*::]*/: { /* n:"XFExt", */ f:parse_XFExt, r:12 },
20295 /*::[*/0x087e/*::]*/: { /* n:"AutoFilter12", */ },
20296 /*::[*/0x087f/*::]*/: { /* n:"ContinueFrt12", */ },
20297 /*::[*/0x0884/*::]*/: { /* n:"MDTInfo", */ },
20298 /*::[*/0x0885/*::]*/: { /* n:"MDXStr", */ },
20299 /*::[*/0x0886/*::]*/: { /* n:"MDXTuple", */ },
20300 /*::[*/0x0887/*::]*/: { /* n:"MDXSet", */ },
20301 /*::[*/0x0888/*::]*/: { /* n:"MDXProp", */ },
20302 /*::[*/0x0889/*::]*/: { /* n:"MDXKPI", */ },
20303 /*::[*/0x088a/*::]*/: { /* n:"MDB", */ },
20304 /*::[*/0x088b/*::]*/: { /* n:"PLV", */ },
20305 /*::[*/0x088c/*::]*/: { /* n:"Compat12", */ f:parsebool, r:12 },
20306 /*::[*/0x088d/*::]*/: { /* n:"DXF", */ },
20307 /*::[*/0x088e/*::]*/: { /* n:"TableStyles", */ r:12 },
20308 /*::[*/0x088f/*::]*/: { /* n:"TableStyle", */ },
20309 /*::[*/0x0890/*::]*/: { /* n:"TableStyleElement", */ },
20310 /*::[*/0x0892/*::]*/: { /* n:"StyleExt", */ },
20311 /*::[*/0x0893/*::]*/: { /* n:"NamePublish", */ },
20312 /*::[*/0x0894/*::]*/: { /* n:"NameCmt", */ f:parse_NameCmt, r:12 },
20313 /*::[*/0x0895/*::]*/: { /* n:"SortData", */ },
20314 /*::[*/0x0896/*::]*/: { /* n:"Theme", */ f:parse_Theme, r:12 },
20315 /*::[*/0x0897/*::]*/: { /* n:"GUIDTypeLib", */ },
20316 /*::[*/0x0898/*::]*/: { /* n:"FnGrp12", */ },
20317 /*::[*/0x0899/*::]*/: { /* n:"NameFnGrp12", */ },
20318 /*::[*/0x089a/*::]*/: { /* n:"MTRSettings", */ f:parse_MTRSettings, r:12 },
20319 /*::[*/0x089b/*::]*/: { /* n:"CompressPictures", */ f:parsenoop2 },
20320 /*::[*/0x089c/*::]*/: { /* n:"HeaderFooter", */ },
20321 /*::[*/0x089d/*::]*/: { /* n:"CrtLayout12", */ },
20322 /*::[*/0x089e/*::]*/: { /* n:"CrtMlFrt", */ },
20323 /*::[*/0x089f/*::]*/: { /* n:"CrtMlFrtContinue", */ },
20324 /*::[*/0x08a3/*::]*/: { /* n:"ForceFullCalculation", */ f:parse_ForceFullCalculation },
20325 /*::[*/0x08a4/*::]*/: { /* n:"ShapePropsStream", */ },
20326 /*::[*/0x08a5/*::]*/: { /* n:"TextPropsStream", */ },
20327 /*::[*/0x08a6/*::]*/: { /* n:"RichTextStream", */ },
20328 /*::[*/0x08a7/*::]*/: { /* n:"CrtLayout12A", */ },
20329 /*::[*/0x1001/*::]*/: { /* n:"Units", */ },
20330 /*::[*/0x1002/*::]*/: { /* n:"Chart", */ },
20331 /*::[*/0x1003/*::]*/: { /* n:"Series", */ },
20332 /*::[*/0x1006/*::]*/: { /* n:"DataFormat", */ },
20333 /*::[*/0x1007/*::]*/: { /* n:"LineFormat", */ },
20334 /*::[*/0x1009/*::]*/: { /* n:"MarkerFormat", */ },
20335 /*::[*/0x100a/*::]*/: { /* n:"AreaFormat", */ },
20336 /*::[*/0x100b/*::]*/: { /* n:"PieFormat", */ },
20337 /*::[*/0x100c/*::]*/: { /* n:"AttachedLabel", */ },
20338 /*::[*/0x100d/*::]*/: { /* n:"SeriesText", */ },
20339 /*::[*/0x1014/*::]*/: { /* n:"ChartFormat", */ },
20340 /*::[*/0x1015/*::]*/: { /* n:"Legend", */ },
20341 /*::[*/0x1016/*::]*/: { /* n:"SeriesList", */ },
20342 /*::[*/0x1017/*::]*/: { /* n:"Bar", */ },
20343 /*::[*/0x1018/*::]*/: { /* n:"Line", */ },
20344 /*::[*/0x1019/*::]*/: { /* n:"Pie", */ },
20345 /*::[*/0x101a/*::]*/: { /* n:"Area", */ },
20346 /*::[*/0x101b/*::]*/: { /* n:"Scatter", */ },
20347 /*::[*/0x101c/*::]*/: { /* n:"CrtLine", */ },
20348 /*::[*/0x101d/*::]*/: { /* n:"Axis", */ },
20349 /*::[*/0x101e/*::]*/: { /* n:"Tick", */ },
20350 /*::[*/0x101f/*::]*/: { /* n:"ValueRange", */ },
20351 /*::[*/0x1020/*::]*/: { /* n:"CatSerRange", */ },
20352 /*::[*/0x1021/*::]*/: { /* n:"AxisLine", */ },
20353 /*::[*/0x1022/*::]*/: { /* n:"CrtLink", */ },
20354 /*::[*/0x1024/*::]*/: { /* n:"DefaultText", */ },
20355 /*::[*/0x1025/*::]*/: { /* n:"Text", */ },
20356 /*::[*/0x1026/*::]*/: { /* n:"FontX", */ f:parseuint16 },
20357 /*::[*/0x1027/*::]*/: { /* n:"ObjectLink", */ },
20358 /*::[*/0x1032/*::]*/: { /* n:"Frame", */ },
20359 /*::[*/0x1033/*::]*/: { /* n:"Begin", */ },
20360 /*::[*/0x1034/*::]*/: { /* n:"End", */ },
20361 /*::[*/0x1035/*::]*/: { /* n:"PlotArea", */ },
20362 /*::[*/0x103a/*::]*/: { /* n:"Chart3d", */ },
20363 /*::[*/0x103c/*::]*/: { /* n:"PicF", */ },
20364 /*::[*/0x103d/*::]*/: { /* n:"DropBar", */ },
20365 /*::[*/0x103e/*::]*/: { /* n:"Radar", */ },
20366 /*::[*/0x103f/*::]*/: { /* n:"Surf", */ },
20367 /*::[*/0x1040/*::]*/: { /* n:"RadarArea", */ },
20368 /*::[*/0x1041/*::]*/: { /* n:"AxisParent", */ },
20369 /*::[*/0x1043/*::]*/: { /* n:"LegendException", */ },
20370 /*::[*/0x1044/*::]*/: { /* n:"ShtProps", */ f:parse_ShtProps },
20371 /*::[*/0x1045/*::]*/: { /* n:"SerToCrt", */ },
20372 /*::[*/0x1046/*::]*/: { /* n:"AxesUsed", */ },
20373 /*::[*/0x1048/*::]*/: { /* n:"SBaseRef", */ },
20374 /*::[*/0x104a/*::]*/: { /* n:"SerParent", */ },
20375 /*::[*/0x104b/*::]*/: { /* n:"SerAuxTrend", */ },
20376 /*::[*/0x104e/*::]*/: { /* n:"IFmtRecord", */ },
20377 /*::[*/0x104f/*::]*/: { /* n:"Pos", */ },
20378 /*::[*/0x1050/*::]*/: { /* n:"AlRuns", */ },
20379 /*::[*/0x1051/*::]*/: { /* n:"BRAI", */ },
20380 /*::[*/0x105b/*::]*/: { /* n:"SerAuxErrBar", */ },
20381 /*::[*/0x105c/*::]*/: { /* n:"ClrtClient", */ f:parse_ClrtClient },
20382 /*::[*/0x105d/*::]*/: { /* n:"SerFmt", */ },
20383 /*::[*/0x105f/*::]*/: { /* n:"Chart3DBarShape", */ },
20384 /*::[*/0x1060/*::]*/: { /* n:"Fbi", */ },
20385 /*::[*/0x1061/*::]*/: { /* n:"BopPop", */ },
20386 /*::[*/0x1062/*::]*/: { /* n:"AxcExt", */ },
20387 /*::[*/0x1063/*::]*/: { /* n:"Dat", */ },
20388 /*::[*/0x1064/*::]*/: { /* n:"PlotGrowth", */ },
20389 /*::[*/0x1065/*::]*/: { /* n:"SIIndex", */ },
20390 /*::[*/0x1066/*::]*/: { /* n:"GelFrame", */ },
20391 /*::[*/0x1067/*::]*/: { /* n:"BopPopCustom", */ },
20392 /*::[*/0x1068/*::]*/: { /* n:"Fbi2", */ },
20393
20394 /*::[*/0x0000/*::]*/: { /* n:"Dimensions", */ f:parse_Dimensions },
20395 /*::[*/0x0001/*::]*/: { /* n:"BIFF2BLANK", */ },
20396 /*::[*/0x0002/*::]*/: { /* n:"BIFF2INT", */ f:parse_BIFF2INT },
20397 /*::[*/0x0003/*::]*/: { /* n:"BIFF2NUM", */ f:parse_BIFF2NUM },
20398 /*::[*/0x0004/*::]*/: { /* n:"BIFF2STR", */ f:parse_BIFF2STR },
20399 /*::[*/0x0005/*::]*/: { /* n:"BoolErr", */ f:parse_BoolErr },
20400 /*::[*/0x0007/*::]*/: { /* n:"String", */ f:parse_BIFF2STRING },
20401 /*::[*/0x0008/*::]*/: { /* n:"BIFF2ROW", */ },
20402 /*::[*/0x0009/*::]*/: { /* n:"BOF", */ f:parse_BOF },
20403 /*::[*/0x000b/*::]*/: { /* n:"Index", */ },
20404 /*::[*/0x0016/*::]*/: { /* n:"ExternCount", */ f:parseuint16 },
20405 /*::[*/0x001e/*::]*/: { /* n:"BIFF2FORMAT", */ f:parse_BIFF2Format },
20406 /*::[*/0x001f/*::]*/: { /* n:"BIFF2FMTCNT", */ }, /* 16-bit cnt of BIFF2FORMAT records */
20407 /*::[*/0x0020/*::]*/: { /* n:"BIFF2COLINFO", */ },
20408 /*::[*/0x0021/*::]*/: { /* n:"Array", */ f:parse_Array },
20409 /*::[*/0x0024/*::]*/: { /* n:"COLWIDTH", */ },
20410 /*::[*/0x0025/*::]*/: { /* n:"DefaultRowHeight", */ f:parse_DefaultRowHeight },
20411 // 0x2c ??
20412 // 0x2d ??
20413 // 0x2e ??
20414 // 0x30 FONTCOUNT: number of fonts
20415 /*::[*/0x0032/*::]*/: { /* n:"BIFF2FONTXTRA", */ f:parse_BIFF2FONTXTRA },
20416 // 0x35: INFOOPTS
20417 // 0x36: TABLE (BIFF2 only)
20418 // 0x37: TABLE2 (BIFF2 only)
20419 // 0x38: WNDESK
20420 // 0x39 ??
20421 // 0x3a: BEGINPREF
20422 // 0x3b: ENDPREF
20423 /*::[*/0x003e/*::]*/: { /* n:"BIFF2WINDOW2", */ },
20424 // 0x3f ??
20425 // 0x46: SHOWSCROLL
20426 // 0x47: SHOWFORMULA
20427 // 0x48: STATUSBAR
20428 // 0x49: SHORTMENUS
20429 // 0x4A:
20430 // 0x4B:
20431 // 0x4C:
20432 // 0x4E:
20433 // 0x4F:
20434 // 0x58: TOOLBAR (BIFF3)
20435
20436 /* - - - */
20437 /*::[*/0x0034/*::]*/: { /* n:"DDEObjName", */ },
20438 /*::[*/0x0043/*::]*/: { /* n:"BIFF2XF", */ },
20439 /*::[*/0x0044/*::]*/: { /* n:"BIFF2XFINDEX", */ f:parseuint16 },
20440 /*::[*/0x0045/*::]*/: { /* n:"BIFF2FONTCLR", */ },
20441 /*::[*/0x0056/*::]*/: { /* n:"BIFF4FMTCNT", */ }, /* 16-bit cnt, similar to BIFF2 */
20442 /*::[*/0x007e/*::]*/: { /* n:"RK", */ }, /* Not necessarily same as 0x027e */
20443 /*::[*/0x007f/*::]*/: { /* n:"ImData", */ f:parse_ImData },
20444 /*::[*/0x0087/*::]*/: { /* n:"Addin", */ },
20445 /*::[*/0x0088/*::]*/: { /* n:"Edg", */ },
20446 /*::[*/0x0089/*::]*/: { /* n:"Pub", */ },
20447 // 0x8A
20448 // 0x8B LH: alternate menu key flag (BIFF3/4)
20449 // 0x8E
20450 // 0x8F
20451 /*::[*/0x0091/*::]*/: { /* n:"Sub", */ },
20452 // 0x93 STYLE
20453 /*::[*/0x0094/*::]*/: { /* n:"LHRecord", */ },
20454 /*::[*/0x0095/*::]*/: { /* n:"LHNGraph", */ },
20455 /*::[*/0x0096/*::]*/: { /* n:"Sound", */ },
20456 // 0xA2 FNPROTO: function prototypes (BIFF4)
20457 // 0xA3
20458 // 0xA8
20459 /*::[*/0x00a9/*::]*/: { /* n:"CoordList", */ },
20460 /*::[*/0x00ab/*::]*/: { /* n:"GCW", */ },
20461 /*::[*/0x00bc/*::]*/: { /* n:"ShrFmla", */ }, /* Not necessarily same as 0x04bc */
20462 /*::[*/0x00bf/*::]*/: { /* n:"ToolbarHdr", */ },
20463 /*::[*/0x00c0/*::]*/: { /* n:"ToolbarEnd", */ },
20464 /*::[*/0x00c2/*::]*/: { /* n:"AddMenu", */ },
20465 /*::[*/0x00c3/*::]*/: { /* n:"DelMenu", */ },
20466 /*::[*/0x00d6/*::]*/: { /* n:"RString", */ f:parse_RString },
20467 /*::[*/0x00df/*::]*/: { /* n:"UDDesc", */ },
20468 /*::[*/0x00ea/*::]*/: { /* n:"TabIdConf", */ },
20469 /*::[*/0x0162/*::]*/: { /* n:"XL5Modify", */ },
20470 /*::[*/0x01a5/*::]*/: { /* n:"FileSharing2", */ },
20471 /*::[*/0x0206/*::]*/: { /* n:"Formula", */ f:parse_Formula },
20472 /*::[*/0x0209/*::]*/: { /* n:"BOF", */ f:parse_BOF },
20473 /*::[*/0x0218/*::]*/: { /* n:"Lbl", */ f:parse_Lbl },
20474 /*::[*/0x0223/*::]*/: { /* n:"ExternName", */ f:parse_ExternName },
20475 /*::[*/0x0231/*::]*/: { /* n:"Font", */ },
20476 /*::[*/0x0243/*::]*/: { /* n:"BIFF3XF", */ },
20477 /*::[*/0x0406/*::]*/: { /* n:"Formula", */ f:parse_Formula },
20478 /*::[*/0x0409/*::]*/: { /* n:"BOF", */ f:parse_BOF },
20479 /*::[*/0x0443/*::]*/: { /* n:"BIFF4XF", */ },
20480 /*::[*/0x086d/*::]*/: { /* n:"FeatInfo", */ },
20481 /*::[*/0x0873/*::]*/: { /* n:"FeatInfo11", */ },
20482 /*::[*/0x0881/*::]*/: { /* n:"SXAddl12", */ },
20483 /*::[*/0x08c0/*::]*/: { /* n:"AutoWebPub", */ },
20484 /*::[*/0x08c1/*::]*/: { /* n:"ListObj", */ },
20485 /*::[*/0x08c2/*::]*/: { /* n:"ListField", */ },
20486 /*::[*/0x08c3/*::]*/: { /* n:"ListDV", */ },
20487 /*::[*/0x08c4/*::]*/: { /* n:"ListCondFmt", */ },
20488 /*::[*/0x08c5/*::]*/: { /* n:"ListCF", */ },
20489 /*::[*/0x08c6/*::]*/: { /* n:"FMQry", */ },
20490 /*::[*/0x08c7/*::]*/: { /* n:"FMSQry", */ },
20491 /*::[*/0x08c8/*::]*/: { /* n:"PLV", */ },
20492 /*::[*/0x08c9/*::]*/: { /* n:"LnExt", */ },
20493 /*::[*/0x08ca/*::]*/: { /* n:"MkrExt", */ },
20494 /*::[*/0x08cb/*::]*/: { /* n:"CrtCoopt", */ },
20495 /*::[*/0x08d6/*::]*/: { /* n:"FRTArchId$", */ r:12 },
20496
20497 /*::[*/0x7262/*::]*/: {}
20498};
20499
20500function write_biff_rec(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/)/*:void*/ {
20501 var t/*:number*/ = type;
20502 if(isNaN(t)) return;
20503 var len = length || (payload||[]).length || 0;
20504 var o = ba.next(4);
20505 o.write_shift(2, t);
20506 o.write_shift(2, len);
20507 if(/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload);
20508}
20509
20510function write_biff_continue(ba/*:BufArray*/, type/*:number*/, payload, length/*:?number*/)/*:void*/ {
20511 var len = length || (payload||[]).length || 0;
20512 if(len <= 8224) return write_biff_rec(ba, type, payload, len);
20513 var t = type;
20514 if(isNaN(t)) return;
20515 var parts = payload.parts || [], sidx = 0;
20516 var i = 0, w = 0;
20517 while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; }
20518 var o = ba.next(4);
20519 o.write_shift(2, t);
20520 o.write_shift(2, w);
20521 ba.push(payload.slice(i, i + w));
20522 i += w;
20523 while(i < len) {
20524 o = ba.next(4);
20525 o.write_shift(2, 0x3c); // TODO: figure out correct continue type
20526 w = 0;
20527 while(w + (parts[sidx] || 8224) <= 8224) { w+= (parts[sidx] || 8224); sidx++; }
20528 o.write_shift(2, w);
20529 ba.push(payload.slice(i, i+w)); i+= w;
20530 }
20531}
20532
20533function write_BIFF2Cell(out, r/*:number*/, c/*:number*/) {
20534 if(!out) out = new_buf(7);
20535 out.write_shift(2, r);
20536 out.write_shift(2, c);
20537 out.write_shift(2, 0);
20538 out.write_shift(1, 0);
20539 return out;
20540}
20541
20542function write_BIFF2BERR(r/*:number*/, c/*:number*/, val, t/*:?string*/) {
20543 var out = new_buf(9);
20544 write_BIFF2Cell(out, r, c);
20545 write_Bes(val, t || 'b', out);
20546 return out;
20547}
20548
20549/* TODO: codepage, large strings */
20550function write_BIFF2LABEL(r/*:number*/, c/*:number*/, val) {
20551 var out = new_buf(8 + 2*val.length);
20552 write_BIFF2Cell(out, r, c);
20553 out.write_shift(1, val.length);
20554 out.write_shift(val.length, val, 'sbcs');
20555 return out.l < out.length ? out.slice(0, out.l) : out;
20556}
20557
20558function write_ws_biff2_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*//*::, opts*/) {
20559 if(cell.v != null) switch(cell.t) {
20560 case 'd': case 'n':
20561 var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
20562 if((v == (v|0)) && (v >= 0) && (v < 65536))
20563 write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v));
20564 else
20565 write_biff_rec(ba, 0x0003, write_BIFF2NUM(R,C, v));
20566 return;
20567 case 'b': case 'e': write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t)); return;
20568 /* TODO: codepage, sst */
20569 case 's': case 'str':
20570 write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, (cell.v||"").slice(0,255)));
20571 return;
20572 }
20573 write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
20574}
20575
20576function write_ws_biff2(ba/*:BufArray*/, ws/*:Worksheet*/, idx/*:number*/, opts/*::, wb:Workbook*/) {
20577 var dense = Array.isArray(ws);
20578 var range = safe_decode_range(ws['!ref'] || "A1"), ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
20579 if(range.e.c > 0xFF || range.e.r > 0x3FFF) {
20580 if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
20581 range.e.c = Math.min(range.e.c, 0xFF);
20582 range.e.r = Math.min(range.e.c, 0x3FFF);
20583 ref = encode_range(range);
20584 }
20585 for(var R = range.s.r; R <= range.e.r; ++R) {
20586 rr = encode_row(R);
20587 for(var C = range.s.c; C <= range.e.c; ++C) {
20588 if(R === range.s.r) cols[C] = encode_col(C);
20589 ref = cols[C] + rr;
20590 var cell = dense ? (ws[R]||[])[C] : ws[ref];
20591 if(!cell) continue;
20592 /* write cell */
20593 write_ws_biff2_cell(ba, cell, R, C, opts);
20594 }
20595 }
20596}
20597
20598/* Based on test files */
20599function write_biff2_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
20600 var o = opts || {};
20601 if(DENSE != null && o.dense == null) o.dense = DENSE;
20602 var ba = buf_array();
20603 var idx = 0;
20604 for(var i=0;i<wb.SheetNames.length;++i) if(wb.SheetNames[i] == o.sheet) idx=i;
20605 if(idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
20606 write_biff_rec(ba, (o.biff == 4 ? 0x0409 : (o.biff == 3 ? 0x0209 : 0x0009)), write_BOF(wb, 0x10, o));
20607 /* ... */
20608 write_ws_biff2(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
20609 /* ... */
20610 write_biff_rec(ba, 0x000A);
20611 return ba.end();
20612}
20613
20614function write_FONTS_biff8(ba, data, opts) {
20615 write_biff_rec(ba, 0x0031 /* Font */, write_Font({
20616 sz:12,
20617 color: {theme:1},
20618 name: "Arial",
20619 family: 2,
20620 scheme: "minor"
20621 }, opts));
20622}
20623
20624
20625function write_FMTS_biff8(ba, NF/*:?SSFTable*/, opts) {
20626 if(!NF) return;
20627 [[5,8],[23,26],[41,44],[/*63*/50,/*66],[164,*/392]].forEach(function(r) {
20628 /*:: if(!NF) return; */
20629 for(var i = r[0]; i <= r[1]; ++i) if(NF[i] != null) write_biff_rec(ba, 0x041E /* Format */, write_Format(i, NF[i], opts));
20630 });
20631}
20632
20633function write_FEAT(ba, ws) {
20634 /* [MS-XLS] 2.4.112 */
20635 var o = new_buf(19);
20636 o.write_shift(4, 0x867); o.write_shift(4, 0); o.write_shift(4, 0);
20637 o.write_shift(2, 3); o.write_shift(1, 1); o.write_shift(4, 0);
20638 write_biff_rec(ba, 0x0867 /* FeatHdr */, o);
20639 /* [MS-XLS] 2.4.111 */
20640 o = new_buf(39);
20641 o.write_shift(4, 0x868); o.write_shift(4, 0); o.write_shift(4, 0);
20642 o.write_shift(2, 3); o.write_shift(1, 0); o.write_shift(4, 0);
20643 o.write_shift(2, 1); o.write_shift(4, 4); o.write_shift(2, 0);
20644 write_Ref8U(safe_decode_range(ws['!ref']||"A1"), o);
20645 o.write_shift(4, 4);
20646 write_biff_rec(ba, 0x0868 /* Feat */, o);
20647}
20648
20649function write_CELLXFS_biff8(ba, opts) {
20650 for(var i = 0; i < 16; ++i) write_biff_rec(ba, 0x00e0 /* XF */, write_XF({numFmtId:0, style:true}, 0, opts));
20651 opts.cellXfs.forEach(function(c) {
20652 write_biff_rec(ba, 0x00e0 /* XF */, write_XF(c, 0, opts));
20653 });
20654}
20655
20656function write_ws_biff8_hlinks(ba/*:BufArray*/, ws) {
20657 for(var R=0; R<ws['!links'].length; ++R) {
20658 var HL = ws['!links'][R];
20659 write_biff_rec(ba, 0x01b8 /* HLink */, write_HLink(HL));
20660 if(HL[1].Tooltip) write_biff_rec(ba, 0x0800 /* HLinkTooltip */, write_HLinkTooltip(HL));
20661 }
20662 delete ws['!links'];
20663}
20664
20665function write_ws_cols_biff8(ba, cols) {
20666 if(!cols) return;
20667 var cnt = 0;
20668 cols.forEach(function(col, idx) {
20669 if(++cnt <= 256 && col) {
20670 write_biff_rec(ba, 0x007d /* ColInfo */, write_ColInfo(col_obj_w(idx, col), idx));
20671 }
20672 });
20673}
20674
20675function write_ws_biff8_cell(ba/*:BufArray*/, cell/*:Cell*/, R/*:number*/, C/*:number*/, opts) {
20676 var os = 16 + get_cell_style(opts.cellXfs, cell, opts);
20677 if(cell.v == null && !cell.bf) {
20678 write_biff_rec(ba, 0x0201 /* Blank */, write_XLSCell(R, C, os));
20679 return;
20680 }
20681 if(cell.bf) write_biff_rec(ba, 0x0006 /* Formula */, write_Formula(cell, R, C, opts, os));
20682 else switch(cell.t) {
20683 case 'd': case 'n':
20684 var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
20685 /* TODO: emit RK as appropriate */
20686 write_biff_rec(ba, 0x0203 /* Number */, write_Number(R, C, v, os, opts));
20687 break;
20688 case 'b': case 'e':
20689 write_biff_rec(ba, 0x0205 /* BoolErr */, write_BoolErr(R, C, cell.v, os, opts, cell.t));
20690 break;
20691 /* TODO: codepage, sst */
20692 case 's': case 'str':
20693 if(opts.bookSST) {
20694 var isst = get_sst_id(opts.Strings, cell.v, opts.revStrings);
20695 write_biff_rec(ba, 0x00fd /* LabelSst */, write_LabelSst(R, C, isst, os, opts));
20696 } else write_biff_rec(ba, 0x0204 /* Label */, write_Label(R, C, (cell.v||"").slice(0,255), os, opts));
20697 break;
20698 default:
20699 write_biff_rec(ba, 0x0201 /* Blank */, write_XLSCell(R, C, os));
20700 }
20701}
20702
20703/* [MS-XLS] 2.1.7.20.5 */
20704function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) {
20705 var ba = buf_array();
20706 var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
20707 var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/);
20708 var _sheet/*:WBWSProp*/ = ((_WB.Sheets||[])[idx]||{}/*:any*/);
20709 var dense = Array.isArray(ws);
20710 var b8 = opts.biff == 8;
20711 var ref/*:string*/, rr = "", cols/*:Array<string>*/ = [];
20712 var range = safe_decode_range(ws['!ref'] || "A1");
20713 var MAX_ROWS = b8 ? 65536 : 16384;
20714 if(range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
20715 if(opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
20716 range.e.c = Math.min(range.e.c, 0xFF);
20717 range.e.r = Math.min(range.e.c, MAX_ROWS-1);
20718 }
20719
20720 write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
20721 /* [Uncalced] Index */
20722 write_biff_rec(ba, 0x000d /* CalcMode */, writeuint16(1));
20723 write_biff_rec(ba, 0x000c /* CalcCount */, writeuint16(100));
20724 write_biff_rec(ba, 0x000f /* CalcRefMode */, writebool(true));
20725 write_biff_rec(ba, 0x0011 /* CalcIter */, writebool(false));
20726 write_biff_rec(ba, 0x0010 /* CalcDelta */, write_Xnum(0.001));
20727 write_biff_rec(ba, 0x005f /* CalcSaveRecalc */, writebool(true));
20728 write_biff_rec(ba, 0x002a /* PrintRowCol */, writebool(false));
20729 write_biff_rec(ba, 0x002b /* PrintGrid */, writebool(false));
20730 write_biff_rec(ba, 0x0082 /* GridSet */, writeuint16(1));
20731 write_biff_rec(ba, 0x0080 /* Guts */, write_Guts([0,0]));
20732 /* DefaultRowHeight WsBool [Sync] [LPr] [HorizontalPageBreaks] [VerticalPageBreaks] */
20733 /* Header (string) */
20734 /* Footer (string) */
20735 write_biff_rec(ba, 0x0083 /* HCenter */, writebool(false));
20736 write_biff_rec(ba, 0x0084 /* VCenter */, writebool(false));
20737 /* ... */
20738 if(b8) write_ws_cols_biff8(ba, ws["!cols"]);
20739 /* ... */
20740 write_biff_rec(ba, 0x200, write_Dimensions(range, opts));
20741 /* ... */
20742
20743 if(b8) ws['!links'] = [];
20744 for(var R = range.s.r; R <= range.e.r; ++R) {
20745 rr = encode_row(R);
20746 for(var C = range.s.c; C <= range.e.c; ++C) {
20747 if(R === range.s.r) cols[C] = encode_col(C);
20748 ref = cols[C] + rr;
20749 var cell = dense ? (ws[R]||[])[C] : ws[ref];
20750 if(!cell) continue;
20751 /* write cell */
20752 write_ws_biff8_cell(ba, cell, R, C, opts);
20753 if(b8 && cell.l) ws['!links'].push([ref, cell.l]);
20754 }
20755 }
20756 var cname/*:string*/ = _sheet.CodeName || _sheet.name || s;
20757 /* ... */
20758 if(b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views||[])[0]));
20759 /* ... */
20760 if(b8 && (ws['!merges']||[]).length) write_biff_rec(ba, 0x00e5 /* MergeCells */, write_MergeCells(ws['!merges']));
20761 /* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
20762 if(b8) write_ws_biff8_hlinks(ba, ws);
20763 /* [DVAL] */
20764 write_biff_rec(ba, 0x01ba /* CodeName */, write_XLUnicodeString(cname, opts));
20765 /* *WebPub *CellWatch [SheetExt] */
20766 if(b8) write_FEAT(ba, ws);
20767 /* *FEAT11 *RECORD12 */
20768 write_biff_rec(ba, 0x000a /* EOF */);
20769 return ba.end();
20770}
20771
20772/* [MS-XLS] 2.1.7.20.3 */
20773function write_biff8_global(wb/*:Workbook*/, bufs, opts/*:WriteOpts*/) {
20774 var A = buf_array();
20775 var _WB/*:WBWBProps*/ = ((wb||{}).Workbook||{}/*:any*/);
20776 var _sheets/*:Array<WBWSProp>*/ = (_WB.Sheets||[]);
20777 var _wb/*:WBProps*/ = /*::((*/_WB.WBProps||{/*::CodeName:"ThisWorkbook"*/}/*:: ):any)*/;
20778 var b8 = opts.biff == 8, b5 = opts.biff == 5;
20779 write_biff_rec(A, 0x0809, write_BOF(wb, 0x05, opts));
20780 if(opts.bookType == "xla") write_biff_rec(A, 0x0087 /* Addin */);
20781 write_biff_rec(A, 0x00e1 /* InterfaceHdr */, b8 ? writeuint16(0x04b0) : null);
20782 write_biff_rec(A, 0x00c1 /* Mms */, writezeroes(2));
20783 if(b5) write_biff_rec(A, 0x00bf /* ToolbarHdr */);
20784 if(b5) write_biff_rec(A, 0x00c0 /* ToolbarEnd */);
20785 write_biff_rec(A, 0x00e2 /* InterfaceEnd */);
20786 write_biff_rec(A, 0x005c /* WriteAccess */, write_WriteAccess("SheetJS", opts));
20787 /* [FileSharing] */
20788 write_biff_rec(A, 0x0042 /* CodePage */, writeuint16(b8 ? 0x04b0 : 0x04E4));
20789 /* *2047 Lel */
20790 if(b8) write_biff_rec(A, 0x0161 /* DSF */, writeuint16(0));
20791 if(b8) write_biff_rec(A, 0x01c0 /* Excel9File */);
20792 write_biff_rec(A, 0x013d /* RRTabId */, write_RRTabId(wb.SheetNames.length));
20793 if(b8 && wb.vbaraw) write_biff_rec(A, 0x00d3 /* ObProj */);
20794 /* [ObNoMacros] */
20795 if(b8 && wb.vbaraw) {
20796 var cname/*:string*/ = _wb.CodeName || "ThisWorkbook";
20797 write_biff_rec(A, 0x01ba /* CodeName */, write_XLUnicodeString(cname, opts));
20798 }
20799 write_biff_rec(A, 0x009c /* BuiltInFnGroupCount */, writeuint16(0x11));
20800 /* *FnGroupName *FnGrp12 */
20801 /* *Lbl */
20802 /* [OleObjectSize] */
20803 write_biff_rec(A, 0x0019 /* WinProtect */, writebool(false));
20804 write_biff_rec(A, 0x0012 /* Protect */, writebool(false));
20805 write_biff_rec(A, 0x0013 /* Password */, writeuint16(0));
20806 if(b8) write_biff_rec(A, 0x01af /* Prot4Rev */, writebool(false));
20807 if(b8) write_biff_rec(A, 0x01bc /* Prot4RevPass */, writeuint16(0));
20808 write_biff_rec(A, 0x003d /* Window1 */, write_Window1(opts));
20809 write_biff_rec(A, 0x0040 /* Backup */, writebool(false));
20810 write_biff_rec(A, 0x008d /* HideObj */, writeuint16(0));
20811 write_biff_rec(A, 0x0022 /* Date1904 */, writebool(safe1904(wb)=="true"));
20812 write_biff_rec(A, 0x000e /* CalcPrecision */, writebool(true));
20813 if(b8) write_biff_rec(A, 0x01b7 /* RefreshAll */, writebool(false));
20814 write_biff_rec(A, 0x00DA /* BookBool */, writeuint16(0));
20815 /* ... */
20816 write_FONTS_biff8(A, wb, opts);
20817 write_FMTS_biff8(A, wb.SSF, opts);
20818 write_CELLXFS_biff8(A, opts);
20819 /* ... */
20820 if(b8) write_biff_rec(A, 0x0160 /* UsesELFs */, writebool(false));
20821 var a = A.end();
20822
20823 var C = buf_array();
20824 /* METADATA [MTRSettings] [ForceFullCalculation] */
20825 if(b8) write_biff_rec(C, 0x008C, write_Country());
20826 /* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */
20827
20828 /* BIFF8: [SST *Continue] ExtSST */
20829 if(b8 && opts.Strings) write_biff_continue(C, 0x00FC, write_SST(opts.Strings, opts));
20830
20831 /* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */
20832 write_biff_rec(C, 0x000A /* EOF */);
20833 var c = C.end();
20834
20835 var B = buf_array();
20836 var blen = 0, j = 0;
20837 for(j = 0; j < wb.SheetNames.length; ++j) blen += (b8 ? 12 : 11) + (b8 ? 2 : 1) * wb.SheetNames[j].length;
20838 var start = a.length + blen + c.length;
20839 for(j = 0; j < wb.SheetNames.length; ++j) {
20840 var _sheet/*:WBWSProp*/ = _sheets[j] || ({}/*:any*/);
20841 write_biff_rec(B, 0x0085 /* BoundSheet8 */, write_BoundSheet8({pos:start, hs:_sheet.Hidden||0, dt:0, name:wb.SheetNames[j]}, opts));
20842 start += bufs[j].length;
20843 }
20844 /* 1*BoundSheet8 */
20845 var b = B.end();
20846 if(blen != b.length) throw new Error("BS8 " + blen + " != " + b.length);
20847
20848 var out = [];
20849 if(a.length) out.push(a);
20850 if(b.length) out.push(b);
20851 if(c.length) out.push(c);
20852 return bconcat(out);
20853}
20854
20855/* [MS-XLS] 2.1.7.20 Workbook Stream */
20856function write_biff8_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
20857 var o = opts || {};
20858 var bufs = [];
20859
20860 if(wb && !wb.SSF) {
20861 wb.SSF = dup(table_fmt);
20862 }
20863 if(wb && wb.SSF) {
20864 make_ssf(); SSF_load_table(wb.SSF);
20865 // $FlowIgnore
20866 o.revssf = evert_num(wb.SSF); o.revssf[wb.SSF[65535]] = 0;
20867 o.ssf = wb.SSF;
20868 }
20869
20870 o.Strings = /*::((*/[]/*:: :any):SST)*/; o.Strings.Count = 0; o.Strings.Unique = 0;
20871 fix_write_opts(o);
20872
20873 o.cellXfs = [];
20874 get_cell_style(o.cellXfs, {}, {revssf:{"General":0}});
20875
20876 if(!wb.Props) wb.Props = {};
20877
20878 for(var i = 0; i < wb.SheetNames.length; ++i) bufs[bufs.length] = write_ws_biff8(i, o, wb);
20879 bufs.unshift(write_biff8_global(wb, bufs, o));
20880 return bconcat(bufs);
20881}
20882
20883function write_biff_buf(wb/*:Workbook*/, opts/*:WriteOpts*/) {
20884 for(var i = 0; i <= wb.SheetNames.length; ++i) {
20885 var ws = wb.Sheets[wb.SheetNames[i]];
20886 if(!ws || !ws["!ref"]) continue;
20887 var range = decode_range(ws["!ref"]);
20888 if(range.e.c > 255) { // note: 255 is IV
20889 if(typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255). Data may be lost.");
20890 }
20891 }
20892
20893 var o = opts || {};
20894 switch(o.biff || 2) {
20895 case 8: case 5: return write_biff8_buf(wb, opts);
20896 case 4: case 3: case 2: return write_biff2_buf(wb, opts);
20897 }
20898 throw new Error("invalid type " + o.bookType + " for BIFF");
20899}
20900/* note: browser DOM element cannot see mso- style attrs, must parse */
20901function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
20902 var opts = _opts || {};
20903 if(DENSE != null && opts.dense == null) opts.dense = DENSE;
20904 var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
20905 str = str.replace(/<!--.*?-->/g, "");
20906 var mtch/*:any*/ = str.match(/<table/i);
20907 if(!mtch) throw new Error("Invalid HTML: could not find <table>");
20908 var mtch2/*:any*/ = str.match(/<\/table/i);
20909 var i/*:number*/ = mtch.index, j/*:number*/ = mtch2 && mtch2.index || str.length;
20910 var rows = split_regex(str.slice(i, j), /(:?<tr[^>]*>)/i, "<tr>");
20911 var R = -1, C = 0, RS = 0, CS = 0;
20912 var range/*:Range*/ = {s:{r:10000000, c:10000000},e:{r:0,c:0}};
20913 var merges/*:Array<Range>*/ = [];
20914 for(i = 0; i < rows.length; ++i) {
20915 var row = rows[i].trim();
20916 var hd = row.slice(0,3).toLowerCase();
20917 if(hd == "<tr") { ++R; if(opts.sheetRows && opts.sheetRows <= R) { --R; break; } C = 0; continue; }
20918 if(hd != "<td" && hd != "<th") continue;
20919 var cells = row.split(/<\/t[dh]>/i);
20920 for(j = 0; j < cells.length; ++j) {
20921 var cell = cells[j].trim();
20922 if(!cell.match(/<t[dh]/i)) continue;
20923 var m = cell, cc = 0;
20924 /* TODO: parse styles etc */
20925 while(m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc+1);
20926 for(var midx = 0; midx < merges.length; ++midx) {
20927 var _merge/*:Range*/ = merges[midx];
20928 if(_merge.s.c == C && _merge.s.r < R && R <= _merge.e.r) { C = _merge.e.c + 1; midx = -1; }
20929 }
20930 var tag = parsexmltag(cell.slice(0, cell.indexOf(">")));
20931 CS = tag.colspan ? +tag.colspan : 1;
20932 if((RS = +tag.rowspan)>1 || CS>1) merges.push({s:{r:R,c:C},e:{r:R + (RS||1) - 1, c:C + CS - 1}});
20933 var _t/*:string*/ = tag.t || tag["data-t"] || "";
20934 /* TODO: generate stub cells */
20935 if(!m.length) { C += CS; continue; }
20936 m = htmldecode(m);
20937 if(range.s.r > R) range.s.r = R; if(range.e.r < R) range.e.r = R;
20938 if(range.s.c > C) range.s.c = C; if(range.e.c < C) range.e.c = C;
20939 if(!m.length) { C += CS; continue; }
20940 var o/*:Cell*/ = {t:'s', v:m};
20941 if(opts.raw || !m.trim().length || _t == 's'){}
20942 else if(m === 'TRUE') o = {t:'b', v:true};
20943 else if(m === 'FALSE') o = {t:'b', v:false};
20944 else if(!isNaN(fuzzynum(m))) o = {t:'n', v:fuzzynum(m)};
20945 else if(!isNaN(fuzzydate(m).getDate())) {
20946 o = ({t:'d', v:parseDate(m)}/*:any*/);
20947 if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
20948 o.z = opts.dateNF || table_fmt[14];
20949 }
20950 if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = o; }
20951 else ws[encode_cell({r:R, c:C})] = o;
20952 C += CS;
20953 }
20954 }
20955 ws['!ref'] = encode_range(range);
20956 if(merges.length) ws["!merges"] = merges;
20957 return ws;
20958}
20959function make_html_row(ws/*:Worksheet*/, r/*:Range*/, R/*:number*/, o/*:Sheet2HTMLOpts*/)/*:string*/ {
20960 var M/*:Array<Range>*/ = (ws['!merges'] ||[]);
20961 var oo/*:Array<string>*/ = [];
20962 for(var C = r.s.c; C <= r.e.c; ++C) {
20963 var RS = 0, CS = 0;
20964 for(var j = 0; j < M.length; ++j) {
20965 if(M[j].s.r > R || M[j].s.c > C) continue;
20966 if(M[j].e.r < R || M[j].e.c < C) continue;
20967 if(M[j].s.r < R || M[j].s.c < C) { RS = -1; break; }
20968 RS = M[j].e.r - M[j].s.r + 1; CS = M[j].e.c - M[j].s.c + 1; break;
20969 }
20970 if(RS < 0) continue;
20971 var coord = encode_cell({r:R,c:C});
20972 var cell = o.dense ? (ws[R]||[])[C] : ws[coord];
20973 /* TODO: html entities */
20974 var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
20975 var sp = ({}/*:any*/);
20976 if(RS > 1) sp.rowspan = RS;
20977 if(CS > 1) sp.colspan = CS;
20978 if(o.editable) w = '<span contenteditable="true">' + w + '</span>';
20979 else if(cell) {
20980 sp["data-t"] = cell && cell.t || 'z';
20981 if(cell.v != null) sp["data-v"] = cell.v;
20982 if(cell.z != null) sp["data-z"] = cell.z;
20983 if(cell.l && (cell.l.Target || "#").charAt(0) != "#") w = '<a href="' + cell.l.Target +'">' + w + '</a>';
20984 }
20985 sp.id = (o.id || "sjs") + "-" + coord;
20986 oo.push(writextag('td', w, sp));
20987 }
20988 var preamble = "<tr>";
20989 return preamble + oo.join("") + "</tr>";
20990}
20991
20992var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
20993var HTML_END = '</body></html>';
20994
20995function html_to_workbook(str/*:string*/, opts)/*:Workbook*/ {
20996 var mtch = str.match(/<table[\s\S]*?>[\s\S]*?<\/table>/gi);
20997 if(!mtch || mtch.length == 0) throw new Error("Invalid HTML: could not find <table>");
20998 if(mtch.length == 1) return sheet_to_workbook(html_to_sheet(mtch[0], opts), opts);
20999 var wb = book_new();
21000 mtch.forEach(function(s, idx) { book_append_sheet(wb, html_to_sheet(s, opts), "Sheet" + (idx+1)); });
21001 return wb;
21002}
21003
21004function make_html_preamble(ws/*:Worksheet*/, R/*:Range*/, o/*:Sheet2HTMLOpts*/)/*:string*/ {
21005 var out/*:Array<string>*/ = [];
21006 return out.join("") + '<table' + (o && o.id ? ' id="' + o.id + '"' : "") + '>';
21007}
21008
21009function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*//*, wb:?Workbook*/)/*:string*/ {
21010 var o = opts || {};
21011 var header = o.header != null ? o.header : HTML_BEGIN;
21012 var footer = o.footer != null ? o.footer : HTML_END;
21013 var out/*:Array<string>*/ = [header];
21014 var r = decode_range(ws['!ref']);
21015 o.dense = Array.isArray(ws);
21016 out.push(make_html_preamble(ws, r, o));
21017 for(var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
21018 out.push("</table>" + footer);
21019 return out.join("");
21020}
21021
21022function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
21023 var opts = _opts || {};
21024 if(DENSE != null) opts.dense = DENSE;
21025 var or_R = 0, or_C = 0;
21026 if(opts.origin != null) {
21027 if(typeof opts.origin == 'number') or_R = opts.origin;
21028 else {
21029 var _origin/*:CellAddress*/ = typeof opts.origin == "string" ? decode_cell(opts.origin) : opts.origin;
21030 or_R = _origin.r; or_C = _origin.c;
21031 }
21032 }
21033
21034 var rows/*:HTMLCollection<HTMLTableRowElement>*/ = table.getElementsByTagName('tr');
21035 var sheetRows = Math.min(opts.sheetRows||10000000, rows.length);
21036 var range/*:Range*/ = {s:{r:0,c:0},e:{r:or_R,c:or_C}};
21037 if(ws["!ref"]) {
21038 var _range/*:Range*/ = decode_range(ws["!ref"]);
21039 range.s.r = Math.min(range.s.r, _range.s.r);
21040 range.s.c = Math.min(range.s.c, _range.s.c);
21041 range.e.r = Math.max(range.e.r, _range.e.r);
21042 range.e.c = Math.max(range.e.c, _range.e.c);
21043 if(or_R == -1) range.e.r = or_R = _range.e.r + 1;
21044 }
21045 var merges/*:Array<Range>*/ = [], midx = 0;
21046 var rowinfo/*:Array<RowInfo>*/ = ws["!rows"] || (ws["!rows"] = []);
21047 var _R = 0, R = 0, _C = 0, C = 0, RS = 0, CS = 0;
21048 if(!ws["!cols"]) ws['!cols'] = [];
21049 for(; _R < rows.length && R < sheetRows; ++_R) {
21050 var row/*:HTMLTableRowElement*/ = rows[_R];
21051 if (is_dom_element_hidden(row)) {
21052 if (opts.display) continue;
21053 rowinfo[R] = {hidden: true};
21054 }
21055 var elts/*:HTMLCollection<HTMLTableCellElement>*/ = (row.children/*:any*/);
21056 for(_C = C = 0; _C < elts.length; ++_C) {
21057 var elt/*:HTMLTableCellElement*/ = elts[_C];
21058 if (opts.display && is_dom_element_hidden(elt)) continue;
21059 var v/*:?string*/ = elt.hasAttribute('data-v') ? elt.getAttribute('data-v') : elt.hasAttribute('v') ? elt.getAttribute('v') : htmldecode(elt.innerHTML);
21060 var z/*:?string*/ = elt.getAttribute('data-z') || elt.getAttribute('z');
21061 for(midx = 0; midx < merges.length; ++midx) {
21062 var m/*:Range*/ = merges[midx];
21063 if(m.s.c == C + or_C && m.s.r < R + or_R && R + or_R <= m.e.r) { C = m.e.c+1 - or_C; midx = -1; }
21064 }
21065 /* TODO: figure out how to extract nonstandard mso- style */
21066 CS = +elt.getAttribute("colspan") || 1;
21067 if( ((RS = (+elt.getAttribute("rowspan") || 1)))>1 || CS>1) merges.push({s:{r:R + or_R,c:C + or_C},e:{r:R + or_R + (RS||1) - 1, c:C + or_C + (CS||1) - 1}});
21068 var o/*:Cell*/ = {t:'s', v:v};
21069 var _t/*:string*/ = elt.getAttribute("data-t") || elt.getAttribute("t") || "";
21070 if(v != null) {
21071 if(v.length == 0) o.t = _t || 'z';
21072 else if(opts.raw || v.trim().length == 0 || _t == "s"){}
21073 else if(v === 'TRUE') o = {t:'b', v:true};
21074 else if(v === 'FALSE') o = {t:'b', v:false};
21075 else if(!isNaN(fuzzynum(v))) o = {t:'n', v:fuzzynum(v)};
21076 else if(!isNaN(fuzzydate(v).getDate())) {
21077 o = ({t:'d', v:parseDate(v)}/*:any*/);
21078 if(!opts.cellDates) o = ({t:'n', v:datenum(o.v)}/*:any*/);
21079 o.z = opts.dateNF || table_fmt[14];
21080 }
21081 }
21082 if(o.z === undefined && z != null) o.z = z;
21083 /* The first link is used. Links are assumed to be fully specified.
21084 * TODO: The right way to process relative links is to make a new <a> */
21085 var l = "", Aelts = elt.getElementsByTagName("A");
21086 if(Aelts && Aelts.length) for(var Aelti = 0; Aelti < Aelts.length; ++Aelti) if(Aelts[Aelti].hasAttribute("href")) {
21087 l = Aelts[Aelti].getAttribute("href"); if(l.charAt(0) != "#") break;
21088 }
21089 if(l && l.charAt(0) != "#") o.l = ({ Target: l });
21090 if(opts.dense) { if(!ws[R + or_R]) ws[R + or_R] = []; ws[R + or_R][C + or_C] = o; }
21091 else ws[encode_cell({c:C + or_C, r:R + or_R})] = o;
21092 if(range.e.c < C + or_C) range.e.c = C + or_C;
21093 C += CS;
21094 }
21095 ++R;
21096 }
21097 if(merges.length) ws['!merges'] = (ws["!merges"] || []).concat(merges);
21098 range.e.r = Math.max(range.e.r, R - 1 + or_R);
21099 ws['!ref'] = encode_range(range);
21100 if(R >= sheetRows) ws['!fullref'] = encode_range((range.e.r = rows.length-_R+R-1 + or_R,range)); // We can count the real number of rows to parse but we don't to improve the performance
21101 return ws;
21102}
21103
21104function parse_dom_table(table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ {
21105 var opts = _opts || {};
21106 var ws/*:Worksheet*/ = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
21107 return sheet_add_dom(ws, table, _opts);
21108}
21109
21110function table_to_book(table/*:HTMLElement*/, opts/*:?any*/)/*:Workbook*/ {
21111 return sheet_to_workbook(parse_dom_table(table, opts), opts);
21112}
21113
21114function is_dom_element_hidden(element/*:HTMLElement*/)/*:boolean*/ {
21115 var display/*:string*/ = '';
21116 var get_computed_style/*:?function*/ = get_get_computed_style_function(element);
21117 if(get_computed_style) display = get_computed_style(element).getPropertyValue('display');
21118 if(!display) display = element.style && element.style.display;
21119 return display === 'none';
21120}
21121
21122/* global getComputedStyle */
21123function get_get_computed_style_function(element/*:HTMLElement*/)/*:?function*/ {
21124 // The proper getComputedStyle implementation is the one defined in the element window
21125 if(element.ownerDocument.defaultView && typeof element.ownerDocument.defaultView.getComputedStyle === 'function') return element.ownerDocument.defaultView.getComputedStyle;
21126 // If it is not available, try to get one from the global namespace
21127 if(typeof getComputedStyle === 'function') return getComputedStyle;
21128 return null;
21129}
21130/* OpenDocument */
21131function parse_text_p(text/*:string*//*::, tag*/)/*:Array<any>*/ {
21132 /* 6.1.2 White Space Characters */
21133 var fixed = text
21134 .replace(/[\t\r\n]/g, " ").trim().replace(/ +/g, " ")
21135 .replace(/<text:s\/>/g," ")
21136 .replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
21137 .replace(/<text:tab[^>]*\/>/g,"\t")
21138 .replace(/<text:line-break\/>/g,"\n");
21139 var v = unescapexml(fixed.replace(/<[^>]*>/g,""));
21140
21141 return [v];
21142}
21143
21144var number_formats_ods = {
21145 /* ods name: [short ssf fmt, long ssf fmt] */
21146 day: ["d", "dd"],
21147 month: ["m", "mm"],
21148 year: ["y", "yy"],
21149 hours: ["h", "hh"],
21150 minutes: ["m", "mm"],
21151 seconds: ["s", "ss"],
21152 "am-pm": ["A/P", "AM/PM"],
21153 "day-of-week": ["ddd", "dddd"],
21154 era: ["e", "ee"],
21155 /* there is no native representation of LO "Q" format */
21156 quarter: ["\\Qm", "m\\\"th quarter\""]
21157};
21158
21159
21160function parse_content_xml(d/*:string*/, _opts)/*:Workbook*/ {
21161 var opts = _opts || {};
21162 if(DENSE != null && opts.dense == null) opts.dense = DENSE;
21163 var str = xlml_normalize(d);
21164 var state/*:Array<any>*/ = [], tmp;
21165 var tag/*:: = {}*/;
21166 var NFtag = {name:""}, NF = "", pidx = 0;
21167 var sheetag/*:: = {name:"", '名称':""}*/;
21168 var rowtag/*:: = {'行号':""}*/;
21169 var Sheets = {}, SheetNames/*:Array<string>*/ = [];
21170 var ws = opts.dense ? ([]/*:any*/) : ({}/*:any*/);
21171 var Rn, q/*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
21172 var ctag = ({value:""}/*:any*/);
21173 var textp = "", textpidx = 0, textptag/*:: = {}*/;
21174 var textR = [];
21175 var R = -1, C = -1, range = {s: {r:1000000,c:10000000}, e: {r:0, c:0}};
21176 var row_ol = 0;
21177 var number_format_map = {};
21178 var merges/*:Array<Range>*/ = [], mrange = {}, mR = 0, mC = 0;
21179 var rowinfo/*:Array<RowInfo>*/ = [], rowpeat = 1, colpeat = 1;
21180 var arrayf/*:Array<[Range, string]>*/ = [];
21181 var WB = {Names:[]};
21182 var atag = ({}/*:any*/);
21183 var _Ref/*:[string, string]*/ = ["", ""];
21184 var comments/*:Array<Comment>*/ = [], comment/*:Comment*/ = ({}/*:any*/);
21185 var creator = "", creatoridx = 0;
21186 var isstub = false, intable = false;
21187 var i = 0;
21188 xlmlregex.lastIndex = 0;
21189 str = str.replace(/<!--([\s\S]*?)-->/mg,"").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
21190 while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
21191
21192 case 'table': case '工作表': // 9.1.2 <table:table>
21193 if(Rn[1]==='/') {
21194 if(range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = encode_range(range);
21195 else ws['!ref'] = "A1:A1";
21196 if(opts.sheetRows > 0 && opts.sheetRows <= range.e.r) {
21197 ws['!fullref'] = ws['!ref'];
21198 range.e.r = opts.sheetRows - 1;
21199 ws['!ref'] = encode_range(range);
21200 }
21201 if(merges.length) ws['!merges'] = merges;
21202 if(rowinfo.length) ws["!rows"] = rowinfo;
21203 sheetag.name = sheetag['名称'] || sheetag.name;
21204 if(typeof JSON !== 'undefined') JSON.stringify(sheetag);
21205 SheetNames.push(sheetag.name);
21206 Sheets[sheetag.name] = ws;
21207 intable = false;
21208 }
21209 else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
21210 sheetag = parsexmltag(Rn[0], false);
21211 R = C = -1;
21212 range.s.r = range.s.c = 10000000; range.e.r = range.e.c = 0;
21213 ws = opts.dense ? ([]/*:any*/) : ({}/*:any*/); merges = [];
21214 rowinfo = [];
21215 intable = true;
21216 }
21217 break;
21218
21219 case 'table-row-group': // 9.1.9 <table:table-row-group>
21220 if(Rn[1] === "/") --row_ol; else ++row_ol;
21221 break;
21222 case 'table-row': case '行': // 9.1.3 <table:table-row>
21223 if(Rn[1] === '/') { R+=rowpeat; rowpeat = 1; break; }
21224 rowtag = parsexmltag(Rn[0], false);
21225 if(rowtag['行号']) R = rowtag['行号'] - 1; else if(R == -1) R = 0;
21226 rowpeat = +rowtag['number-rows-repeated'] || 1;
21227 /* TODO: remove magic */
21228 if(rowpeat < 10) for(i = 0; i < rowpeat; ++i) if(row_ol > 0) rowinfo[R + i] = {level: row_ol};
21229 C = -1; break;
21230 case 'covered-table-cell': // 9.1.5 <table:covered-table-cell>
21231 if(Rn[1] !== '/') ++C;
21232 if(opts.sheetStubs) {
21233 if(opts.dense) { if(!ws[R]) ws[R] = []; ws[R][C] = {t:'z'}; }
21234 else ws[encode_cell({r:R,c:C})] = {t:'z'};
21235 }
21236 textp = ""; textR = [];
21237 break; /* stub */
21238 case 'table-cell': case '数据':
21239 if(Rn[0].charAt(Rn[0].length-2) === '/') {
21240 ++C;
21241 ctag = parsexmltag(Rn[0], false);
21242 colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
21243 q = ({t:'z', v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
21244 if(ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
21245 if((ctag['数据类型'] || ctag['value-type']) == "string") {
21246 q.t = "s"; q.v = unescapexml(ctag['string-value'] || "");
21247 if(opts.dense) {
21248 if(!ws[R]) ws[R] = [];
21249 ws[R][C] = q;
21250 } else {
21251 ws[encode_cell({r:R,c:C})] = q;
21252 }
21253 }
21254 C+= colpeat-1;
21255 } else if(Rn[1]!=='/') {
21256 ++C;
21257 textp = ""; textpidx = 0; textR = [];
21258 colpeat = 1;
21259 var rptR = rowpeat ? R + rowpeat - 1 : R;
21260 if(C > range.e.c) range.e.c = C;
21261 if(C < range.s.c) range.s.c = C;
21262 if(R < range.s.r) range.s.r = R;
21263 if(rptR > range.e.r) range.e.r = rptR;
21264 ctag = parsexmltag(Rn[0], false);
21265 comments = []; comment = ({}/*:any*/);
21266 q = ({t:ctag['数据类型'] || ctag['value-type'], v:null/*:: , z:null, w:"",c:[]*/}/*:any*/);
21267 if(opts.cellFormula) {
21268 if(ctag.formula) ctag.formula = unescapexml(ctag.formula);
21269 if(ctag['number-matrix-columns-spanned'] && ctag['number-matrix-rows-spanned']) {
21270 mR = parseInt(ctag['number-matrix-rows-spanned'],10) || 0;
21271 mC = parseInt(ctag['number-matrix-columns-spanned'],10) || 0;
21272 mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
21273 q.F = encode_range(mrange);
21274 arrayf.push([mrange, q.F]);
21275 }
21276 if(ctag.formula) q.f = ods_to_csf_formula(ctag.formula);
21277 else for(i = 0; i < arrayf.length; ++i)
21278 if(R >= arrayf[i][0].s.r && R <= arrayf[i][0].e.r)
21279 if(C >= arrayf[i][0].s.c && C <= arrayf[i][0].e.c)
21280 q.F = arrayf[i][1];
21281 }
21282 if(ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
21283 mR = parseInt(ctag['number-rows-spanned'],10) || 0;
21284 mC = parseInt(ctag['number-columns-spanned'],10) || 0;
21285 mrange = {s: {r:R,c:C}, e:{r:R + mR-1,c:C + mC-1}};
21286 merges.push(mrange);
21287 }
21288
21289 /* 19.675.2 table:number-columns-repeated */
21290 if(ctag['number-columns-repeated']) colpeat = parseInt(ctag['number-columns-repeated'], 10);
21291
21292 /* 19.385 office:value-type */
21293 switch(q.t) {
21294 case 'boolean': q.t = 'b'; q.v = parsexmlbool(ctag['boolean-value']); break;
21295 case 'float': q.t = 'n'; q.v = parseFloat(ctag.value); break;
21296 case 'percentage': q.t = 'n'; q.v = parseFloat(ctag.value); break;
21297 case 'currency': q.t = 'n'; q.v = parseFloat(ctag.value); break;
21298 case 'date': q.t = 'd'; q.v = parseDate(ctag['date-value']);
21299 if(!opts.cellDates) { q.t = 'n'; q.v = datenum(q.v); }
21300 q.z = 'm/d/yy'; break;
21301 case 'time': q.t = 'n'; q.v = parse_isodur(ctag['time-value'])/86400;
21302 if(opts.cellDates) { q.t = 'd'; q.v = numdate(q.v); }
21303 q.z = 'HH:MM:SS'; break;
21304 case 'number': q.t = 'n'; q.v = parseFloat(ctag['数据数值']); break;
21305 default:
21306 if(q.t === 'string' || q.t === 'text' || !q.t) {
21307 q.t = 's';
21308 if(ctag['string-value'] != null) { textp = unescapexml(ctag['string-value']); textR = []; }
21309 } else throw new Error('Unsupported value type ' + q.t);
21310 }
21311 } else {
21312 isstub = false;
21313 if(q.t === 's') {
21314 q.v = textp || '';
21315 if(textR.length) q.R = textR;
21316 isstub = textpidx == 0;
21317 }
21318 if(atag.Target) q.l = atag;
21319 if(comments.length > 0) { q.c = comments; comments = []; }
21320 if(textp && opts.cellText !== false) q.w = textp;
21321 if(isstub) { q.t = "z"; delete q.v; }
21322 if(!isstub || opts.sheetStubs) {
21323 if(!(opts.sheetRows && opts.sheetRows <= R)) {
21324 for(var rpt = 0; rpt < rowpeat; ++rpt) {
21325 colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
21326 if(opts.dense) {
21327 if(!ws[R + rpt]) ws[R + rpt] = [];
21328 ws[R + rpt][C] = rpt == 0 ? q : dup(q);
21329 while(--colpeat > 0) ws[R + rpt][C + colpeat] = dup(q);
21330 } else {
21331 ws[encode_cell({r:R + rpt,c:C})] = q;
21332 while(--colpeat > 0) ws[encode_cell({r:R + rpt,c:C + colpeat})] = dup(q);
21333 }
21334 if(range.e.c <= C) range.e.c = C;
21335 }
21336 }
21337 }
21338 colpeat = parseInt(ctag['number-columns-repeated']||"1", 10);
21339 C += colpeat-1; colpeat = 0;
21340 q = {/*:: t:"", v:null, z:null, w:"",c:[]*/};
21341 textp = ""; textR = [];
21342 }
21343 atag = ({}/*:any*/);
21344 break; // 9.1.4 <table:table-cell>
21345
21346 /* pure state */
21347 case 'document': // TODO: <office:document> is the root for FODS
21348 case 'document-content': case '电子表格文档': // 3.1.3.2 <office:document-content>
21349 case 'spreadsheet': case '主体': // 3.7 <office:spreadsheet>
21350 case 'scripts': // 3.12 <office:scripts>
21351 case 'styles': // TODO <office:styles>
21352 case 'font-face-decls': // 3.14 <office:font-face-decls>
21353 case 'master-styles': // 3.15.4 <office:master-styles> -- relevant for FODS
21354 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
21355 else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], true]);
21356 break;
21357
21358 case 'annotation': // 14.1 <office:annotation>
21359 if(Rn[1]==='/'){
21360 if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
21361 comment.t = textp;
21362 if(textR.length) /*::(*/comment/*:: :any)*/.R = textR;
21363 comment.a = creator;
21364 comments.push(comment);
21365 }
21366 else if(Rn[0].charAt(Rn[0].length-2) !== '/') {state.push([Rn[3], false]);}
21367 creator = ""; creatoridx = 0;
21368 textp = ""; textpidx = 0; textR = [];
21369 break;
21370
21371 case 'creator': // 4.3.2.7 <dc:creator>
21372 if(Rn[1]==='/') { creator = str.slice(creatoridx,Rn.index); }
21373 else creatoridx = Rn.index + Rn[0].length;
21374 break;
21375
21376 /* ignore state */
21377 case 'meta': case '元数据': // TODO: <office:meta> <uof:元数据> FODS/UOF
21378 case 'settings': // TODO: <office:settings>
21379 case 'config-item-set': // TODO: <office:config-item-set>
21380 case 'config-item-map-indexed': // TODO: <office:config-item-map-indexed>
21381 case 'config-item-map-entry': // TODO: <office:config-item-map-entry>
21382 case 'config-item-map-named': // TODO: <office:config-item-map-entry>
21383 case 'shapes': // 9.2.8 <table:shapes>
21384 case 'frame': // 10.4.2 <draw:frame>
21385 case 'text-box': // 10.4.3 <draw:text-box>
21386 case 'image': // 10.4.4 <draw:image>
21387 case 'data-pilot-tables': // 9.6.2 <table:data-pilot-tables>
21388 case 'list-style': // 16.30 <text:list-style>
21389 case 'form': // 13.13 <form:form>
21390 case 'dde-links': // 9.8 <table:dde-links>
21391 case 'event-listeners': // TODO
21392 case 'chart': // TODO
21393 if(Rn[1]==='/'){if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;}
21394 else if(Rn[0].charAt(Rn[0].length-2) !== '/') state.push([Rn[3], false]);
21395 textp = ""; textpidx = 0; textR = [];
21396 break;
21397
21398 case 'scientific-number': // TODO: <number:scientific-number>
21399 break;
21400 case 'currency-symbol': // TODO: <number:currency-symbol>
21401 break;
21402 case 'currency-style': // TODO: <number:currency-style>
21403 break;
21404 case 'number-style': // 16.27.2 <number:number-style>
21405 case 'percentage-style': // 16.27.9 <number:percentage-style>
21406 case 'date-style': // 16.27.10 <number:date-style>
21407 case 'time-style': // 16.27.18 <number:time-style>
21408 if(Rn[1]==='/'){
21409 number_format_map[NFtag.name] = NF;
21410 if((tmp=state.pop())[0]!==Rn[3]) throw "Bad state: "+tmp;
21411 } else if(Rn[0].charAt(Rn[0].length-2) !== '/') {
21412 NF = "";
21413 NFtag = parsexmltag(Rn[0], false);
21414 state.push([Rn[3], true]);
21415 } break;
21416
21417 case 'script': break; // 3.13 <office:script>
21418 case 'libraries': break; // TODO: <ooo:libraries>
21419 case 'automatic-styles': break; // 3.15.3 <office:automatic-styles>
21420
21421 case 'default-style': // TODO: <style:default-style>
21422 case 'page-layout': break; // TODO: <style:page-layout>
21423 case 'style': // 16.2 <style:style>
21424 break;
21425 case 'map': break; // 16.3 <style:map>
21426 case 'font-face': break; // 16.21 <style:font-face>
21427
21428 case 'paragraph-properties': break; // 17.6 <style:paragraph-properties>
21429 case 'table-properties': break; // 17.15 <style:table-properties>
21430 case 'table-column-properties': break; // 17.16 <style:table-column-properties>
21431 case 'table-row-properties': break; // 17.17 <style:table-row-properties>
21432 case 'table-cell-properties': break; // 17.18 <style:table-cell-properties>
21433
21434 case 'number': // 16.27.3 <number:number>
21435 switch(state[state.length-1][0]) {
21436 case 'time-style':
21437 case 'date-style':
21438 tag = parsexmltag(Rn[0], false);
21439 NF += number_formats_ods[Rn[3]][tag.style==='long'?1:0]; break;
21440 } break;
21441
21442 case 'fraction': break; // TODO 16.27.6 <number:fraction>
21443
21444 case 'day': // 16.27.11 <number:day>
21445 case 'month': // 16.27.12 <number:month>
21446 case 'year': // 16.27.13 <number:year>
21447 case 'era': // 16.27.14 <number:era>
21448 case 'day-of-week': // 16.27.15 <number:day-of-week>
21449 case 'week-of-year': // 16.27.16 <number:week-of-year>
21450 case 'quarter': // 16.27.17 <number:quarter>
21451 case 'hours': // 16.27.19 <number:hours>
21452 case 'minutes': // 16.27.20 <number:minutes>
21453 case 'seconds': // 16.27.21 <number:seconds>
21454 case 'am-pm': // 16.27.22 <number:am-pm>
21455 switch(state[state.length-1][0]) {
21456 case 'time-style':
21457 case 'date-style':
21458 tag = parsexmltag(Rn[0], false);
21459 NF += number_formats_ods[Rn[3]][tag.style==='long'?1:0]; break;
21460 } break;
21461
21462 case 'boolean-style': break; // 16.27.23 <number:boolean-style>
21463 case 'boolean': break; // 16.27.24 <number:boolean>
21464 case 'text-style': break; // 16.27.25 <number:text-style>
21465 case 'text': // 16.27.26 <number:text>
21466 if(Rn[0].slice(-2) === "/>") break;
21467 else if(Rn[1]==="/") switch(state[state.length-1][0]) {
21468 case 'number-style':
21469 case 'date-style':
21470 case 'time-style':
21471 NF += str.slice(pidx, Rn.index);
21472 break;
21473 }
21474 else pidx = Rn.index + Rn[0].length;
21475 break;
21476
21477 case 'named-range': // 9.4.12 <table:named-range>
21478 tag = parsexmltag(Rn[0], false);
21479 _Ref = ods_to_csf_3D(tag['cell-range-address']);
21480 var nrange = ({Name:tag.name, Ref:_Ref[0] + '!' + _Ref[1]}/*:any*/);
21481 if(intable) nrange.Sheet = SheetNames.length;
21482 WB.Names.push(nrange);
21483 break;
21484
21485 case 'text-content': break; // 16.27.27 <number:text-content>
21486 case 'text-properties': break; // 16.27.27 <style:text-properties>
21487 case 'embedded-text': break; // 16.27.4 <number:embedded-text>
21488
21489 case 'body': case '电子表格': break; // 3.3 16.9.6 19.726.3
21490
21491 case 'forms': break; // 12.25.2 13.2
21492 case 'table-column': break; // 9.1.6 <table:table-column>
21493 case 'table-header-rows': break; // 9.1.7 <table:table-header-rows>
21494 case 'table-rows': break; // 9.1.12 <table:table-rows>
21495 /* TODO: outline levels */
21496 case 'table-column-group': break; // 9.1.10 <table:table-column-group>
21497 case 'table-header-columns': break; // 9.1.11 <table:table-header-columns>
21498 case 'table-columns': break; // 9.1.12 <table:table-columns>
21499
21500 case 'null-date': break; // 9.4.2 <table:null-date> TODO: date1904
21501
21502 case 'graphic-properties': break; // 17.21 <style:graphic-properties>
21503 case 'calculation-settings': break; // 9.4.1 <table:calculation-settings>
21504 case 'named-expressions': break; // 9.4.11 <table:named-expressions>
21505 case 'label-range': break; // 9.4.9 <table:label-range>
21506 case 'label-ranges': break; // 9.4.10 <table:label-ranges>
21507 case 'named-expression': break; // 9.4.13 <table:named-expression>
21508 case 'sort': break; // 9.4.19 <table:sort>
21509 case 'sort-by': break; // 9.4.20 <table:sort-by>
21510 case 'sort-groups': break; // 9.4.22 <table:sort-groups>
21511
21512 case 'tab': break; // 6.1.4 <text:tab>
21513 case 'line-break': break; // 6.1.5 <text:line-break>
21514 case 'span': break; // 6.1.7 <text:span>
21515 case 'p': case '文本串': // 5.1.3 <text:p>
21516 if(['master-styles'].indexOf(state[state.length-1][0]) > -1) break;
21517 if(Rn[1]==='/' && (!ctag || !ctag['string-value'])) {
21518 var ptp = parse_text_p(str.slice(textpidx,Rn.index), textptag);
21519 textp = (textp.length > 0 ? textp + "\n" : "") + ptp[0];
21520 } else { textptag = parsexmltag(Rn[0], false); textpidx = Rn.index + Rn[0].length; }
21521 break; // <text:p>
21522 case 's': break; // <text:s>
21523
21524 case 'database-range': // 9.4.15 <table:database-range>
21525 if(Rn[1]==='/') break;
21526 try {
21527 _Ref = ods_to_csf_3D(parsexmltag(Rn[0])['target-range-address']);
21528 Sheets[_Ref[0]]['!autofilter'] = { ref:_Ref[1] };
21529 } catch(e) {/* empty */}
21530 break;
21531
21532 case 'date': break; // <*:date>
21533
21534 case 'object': break; // 10.4.6.2 <draw:object>
21535 case 'title': case '标题': break; // <*:title> OR <uof:标题>
21536 case 'desc': break; // <*:desc>
21537 case 'binary-data': break; // 10.4.5 TODO: b64 blob
21538
21539 /* 9.2 Advanced Tables */
21540 case 'table-source': break; // 9.2.6
21541 case 'scenario': break; // 9.2.6
21542
21543 case 'iteration': break; // 9.4.3 <table:iteration>
21544 case 'content-validations': break; // 9.4.4 <table:
21545 case 'content-validation': break; // 9.4.5 <table:
21546 case 'help-message': break; // 9.4.6 <table:
21547 case 'error-message': break; // 9.4.7 <table:
21548 case 'database-ranges': break; // 9.4.14 <table:database-ranges>
21549 case 'filter': break; // 9.5.2 <table:filter>
21550 case 'filter-and': break; // 9.5.3 <table:filter-and>
21551 case 'filter-or': break; // 9.5.4 <table:filter-or>
21552 case 'filter-condition': break; // 9.5.5 <table:filter-condition>
21553
21554 case 'list-level-style-bullet': break; // 16.31 <text:
21555 case 'list-level-style-number': break; // 16.32 <text:
21556 case 'list-level-properties': break; // 17.19 <style:
21557
21558 /* 7.3 Document Fields */
21559 case 'sender-firstname': // 7.3.6.2
21560 case 'sender-lastname': // 7.3.6.3
21561 case 'sender-initials': // 7.3.6.4
21562 case 'sender-title': // 7.3.6.5
21563 case 'sender-position': // 7.3.6.6
21564 case 'sender-email': // 7.3.6.7
21565 case 'sender-phone-private': // 7.3.6.8
21566 case 'sender-fax': // 7.3.6.9
21567 case 'sender-company': // 7.3.6.10
21568 case 'sender-phone-work': // 7.3.6.11
21569 case 'sender-street': // 7.3.6.12
21570 case 'sender-city': // 7.3.6.13
21571 case 'sender-postal-code': // 7.3.6.14
21572 case 'sender-country': // 7.3.6.15
21573 case 'sender-state-or-province': // 7.3.6.16
21574 case 'author-name': // 7.3.7.1
21575 case 'author-initials': // 7.3.7.2
21576 case 'chapter': // 7.3.8
21577 case 'file-name': // 7.3.9
21578 case 'template-name': // 7.3.9
21579 case 'sheet-name': // 7.3.9
21580 break;
21581
21582 case 'event-listener':
21583 break;
21584 /* TODO: FODS Properties */
21585 case 'initial-creator':
21586 case 'creation-date':
21587 case 'print-date':
21588 case 'generator':
21589 case 'document-statistic':
21590 case 'user-defined':
21591 case 'editing-duration':
21592 case 'editing-cycles':
21593 break;
21594
21595 /* TODO: FODS Config */
21596 case 'config-item':
21597 break;
21598
21599 /* TODO: style tokens */
21600 case 'page-number': break; // TODO <text:page-number>
21601 case 'page-count': break; // TODO <text:page-count>
21602 case 'time': break; // TODO <text:time>
21603
21604 /* 9.3 Advanced Table Cells */
21605 case 'cell-range-source': break; // 9.3.1 <table:
21606 case 'detective': break; // 9.3.2 <table:
21607 case 'operation': break; // 9.3.3 <table:
21608 case 'highlighted-range': break; // 9.3.4 <table:
21609
21610 /* 9.6 Data Pilot Tables <table: */
21611 case 'data-pilot-table': // 9.6.3
21612 case 'source-cell-range': // 9.6.5
21613 case 'source-service': // 9.6.6
21614 case 'data-pilot-field': // 9.6.7
21615 case 'data-pilot-level': // 9.6.8
21616 case 'data-pilot-subtotals': // 9.6.9
21617 case 'data-pilot-subtotal': // 9.6.10
21618 case 'data-pilot-members': // 9.6.11
21619 case 'data-pilot-member': // 9.6.12
21620 case 'data-pilot-display-info': // 9.6.13
21621 case 'data-pilot-sort-info': // 9.6.14
21622 case 'data-pilot-layout-info': // 9.6.15
21623 case 'data-pilot-field-reference': // 9.6.16
21624 case 'data-pilot-groups': // 9.6.17
21625 case 'data-pilot-group': // 9.6.18
21626 case 'data-pilot-group-member': // 9.6.19
21627 break;
21628
21629 /* 10.3 Drawing Shapes */
21630 case 'rect': // 10.3.2
21631 break;
21632
21633 /* 14.6 DDE Connections */
21634 case 'dde-connection-decls': // 14.6.2 <text:
21635 case 'dde-connection-decl': // 14.6.3 <text:
21636 case 'dde-link': // 14.6.4 <table:
21637 case 'dde-source': // 14.6.5 <office:
21638 break;
21639
21640 case 'properties': break; // 13.7 <form:properties>
21641 case 'property': break; // 13.8 <form:property>
21642
21643 case 'a': // 6.1.8 hyperlink
21644 if(Rn[1]!== '/') {
21645 atag = parsexmltag(Rn[0], false);
21646 if(!atag.href) break;
21647 atag.Target = unescapexml(atag.href); delete atag.href;
21648 if(atag.Target.charAt(0) == "#" && atag.Target.indexOf(".") > -1) {
21649 _Ref = ods_to_csf_3D(atag.Target.slice(1));
21650 atag.Target = "#" + _Ref[0] + "!" + _Ref[1];
21651 } else if(atag.Target.match(/^\.\.[\\\/]/)) atag.Target = atag.Target.slice(3);
21652 }
21653 break;
21654
21655 /* non-standard */
21656 case 'table-protection': break;
21657 case 'data-pilot-grand-total': break; // <table:
21658 case 'office-document-common-attrs': break; // bare
21659 default: switch(Rn[2]) {
21660 case 'dc:': // TODO: properties
21661 case 'calcext:': // ignore undocumented extensions
21662 case 'loext:': // ignore undocumented extensions
21663 case 'ooo:': // ignore undocumented extensions
21664 case 'chartooo:': // ignore undocumented extensions
21665 case 'draw:': // TODO: drawing
21666 case 'style:': // TODO: styles
21667 case 'chart:': // TODO: charts
21668 case 'form:': // TODO: forms
21669 case 'uof:': // TODO: uof
21670 case '表:': // TODO: uof
21671 case '字:': // TODO: uof
21672 break;
21673 default: if(opts.WTF) throw new Error(Rn);
21674 }
21675 }
21676 var out/*:Workbook*/ = ({
21677 Sheets: Sheets,
21678 SheetNames: SheetNames,
21679 Workbook: WB
21680 }/*:any*/);
21681 if(opts.bookSheets) delete /*::(*/out/*:: :any)*/.Sheets;
21682 return out;
21683}
21684
21685function parse_ods(zip/*:ZIPFile*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
21686 opts = opts || ({}/*:any*/);
21687 if(safegetzipfile(zip, 'META-INF/manifest.xml')) parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
21688 var content = getzipstr(zip, 'content.xml');
21689 if(!content) throw new Error("Missing content.xml in ODS / UOF file");
21690 var wb = parse_content_xml(utf8read(content), opts);
21691 if(safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
21692 return wb;
21693}
21694function parse_fods(data/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
21695 return parse_content_xml(data, opts);
21696}
21697
21698/* OpenDocument */
21699var write_styles_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
21700 var master_styles = [
21701 '<office:master-styles>',
21702 '<style:master-page style:name="mp1" style:page-layout-name="mp1">',
21703 '<style:header/>',
21704 '<style:header-left style:display="false"/>',
21705 '<style:footer/>',
21706 '<style:footer-left style:display="false"/>',
21707 '</style:master-page>',
21708 '</office:master-styles>'
21709 ].join("");
21710
21711 var payload = '<office:document-styles ' + wxt_helper({
21712 'xmlns:office': "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
21713 'xmlns:table': "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
21714 'xmlns:style': "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
21715 'xmlns:text': "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
21716 'xmlns:draw': "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
21717 'xmlns:fo': "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
21718 'xmlns:xlink': "http://www.w3.org/1999/xlink",
21719 'xmlns:dc': "http://purl.org/dc/elements/1.1/",
21720 'xmlns:number': "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
21721 'xmlns:svg': "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
21722 'xmlns:of': "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
21723 'office:version': "1.2"
21724 }) + '>' + master_styles + '</office:document-styles>';
21725
21726 return function wso(/*::wb, opts*/) {
21727 return XML_HEADER + payload;
21728 };
21729})();
21730var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function() {
21731 /* 6.1.2 White Space Characters */
21732 var write_text_p = function(text/*:string*/)/*:string*/ {
21733 return escapexml(text)
21734 .replace(/ +/g, function($$){return '<text:s text:c="'+$$.length+'"/>';})
21735 .replace(/\t/g, "<text:tab/>")
21736 .replace(/\n/g, "</text:p><text:p>")
21737 .replace(/^ /, "<text:s/>").replace(/ $/, "<text:s/>");
21738 };
21739
21740 var null_cell_xml = ' <table:table-cell />\n';
21741 var covered_cell_xml = ' <table:covered-table-cell/>\n';
21742 var write_ws = function(ws, wb/*:Workbook*/, i/*:number*//*::, opts*/)/*:string*/ {
21743 /* Section 9 Tables */
21744 var o/*:Array<string>*/ = [];
21745 o.push(' <table:table table:name="' + escapexml(wb.SheetNames[i]) + '" table:style-name="ta1">\n');
21746 var R=0,C=0, range = decode_range(ws['!ref']||"A1");
21747 var marr/*:Array<Range>*/ = ws['!merges'] || [], mi = 0;
21748 var dense = Array.isArray(ws);
21749 if(ws["!cols"]) {
21750 for(C = 0; C <= range.e.c; ++C) o.push(' <table:table-column' + (ws["!cols"][C] ? ' table:style-name="co' + ws["!cols"][C].ods + '"' : '') + '></table:table-column>\n');
21751 }
21752 var H = "", ROWS = ws["!rows"]||[];
21753 for(R = 0; R < range.s.r; ++R) {
21754 H = ROWS[R] ? ' table:style-name="ro' + ROWS[R].ods + '"' : "";
21755 o.push(' <table:table-row' + H + '></table:table-row>\n');
21756 }
21757 for(; R <= range.e.r; ++R) {
21758 H = ROWS[R] ? ' table:style-name="ro' + ROWS[R].ods + '"' : "";
21759 o.push(' <table:table-row' + H + '>\n');
21760 for(C=0; C < range.s.c; ++C) o.push(null_cell_xml);
21761 for(; C <= range.e.c; ++C) {
21762 var skip = false, ct = {}, textp = "";
21763 for(mi = 0; mi != marr.length; ++mi) {
21764 if(marr[mi].s.c > C) continue;
21765 if(marr[mi].s.r > R) continue;
21766 if(marr[mi].e.c < C) continue;
21767 if(marr[mi].e.r < R) continue;
21768 if(marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
21769 ct['table:number-columns-spanned'] = (marr[mi].e.c - marr[mi].s.c + 1);
21770 ct['table:number-rows-spanned'] = (marr[mi].e.r - marr[mi].s.r + 1);
21771 break;
21772 }
21773 if(skip) { o.push(covered_cell_xml); continue; }
21774 var ref = encode_cell({r:R, c:C}), cell = dense ? (ws[R]||[])[C]: ws[ref];
21775 if(cell && cell.f) {
21776 ct['table:formula'] = escapexml(csf_to_ods_formula(cell.f));
21777 if(cell.F) {
21778 if(cell.F.slice(0, ref.length) == ref) {
21779 var _Fref = decode_range(cell.F);
21780 ct['table:number-matrix-columns-spanned'] = (_Fref.e.c - _Fref.s.c + 1);
21781 ct['table:number-matrix-rows-spanned'] = (_Fref.e.r - _Fref.s.r + 1);
21782 }
21783 }
21784 }
21785 if(!cell) { o.push(null_cell_xml); continue; }
21786 switch(cell.t) {
21787 case 'b':
21788 textp = (cell.v ? 'TRUE' : 'FALSE');
21789 ct['office:value-type'] = "boolean";
21790 ct['office:boolean-value'] = (cell.v ? 'true' : 'false');
21791 break;
21792 case 'n':
21793 textp = (cell.w||String(cell.v||0));
21794 ct['office:value-type'] = "float";
21795 ct['office:value'] = (cell.v||0);
21796 break;
21797 case 's': case 'str':
21798 textp = cell.v == null ? "" : cell.v;
21799 ct['office:value-type'] = "string";
21800 break;
21801 case 'd':
21802 textp = (cell.w||(parseDate(cell.v).toISOString()));
21803 ct['office:value-type'] = "date";
21804 ct['office:date-value'] = (parseDate(cell.v).toISOString());
21805 ct['table:style-name'] = "ce1";
21806 break;
21807 //case 'e':
21808 default: o.push(null_cell_xml); continue;
21809 }
21810 var text_p = write_text_p(textp);
21811 if(cell.l && cell.l.Target) {
21812 var _tgt = cell.l.Target;
21813 _tgt = _tgt.charAt(0) == "#" ? "#" + csf_to_ods_3D(_tgt.slice(1)) : _tgt;
21814 // TODO: choose correct parent path format based on link delimiters
21815 if(_tgt.charAt(0) != "#" && !_tgt.match(/^\w+:/)) _tgt = '../' + _tgt;
21816 text_p = writextag('text:a', text_p, {'xlink:href': _tgt.replace(/&/g, "&amp;")});
21817 }
21818 o.push(' ' + writextag('table:table-cell', writextag('text:p', text_p, {}), ct) + '\n');
21819 }
21820 o.push(' </table:table-row>\n');
21821 }
21822 o.push(' </table:table>\n');
21823 return o.join("");
21824 };
21825
21826 var write_automatic_styles_ods = function(o/*:Array<string>*/, wb) {
21827 o.push(' <office:automatic-styles>\n');
21828
21829 o.push(' <number:date-style style:name="N37" number:automatic-order="true">\n');
21830 o.push(' <number:month number:style="long"/>\n');
21831 o.push(' <number:text>/</number:text>\n');
21832 o.push(' <number:day number:style="long"/>\n');
21833 o.push(' <number:text>/</number:text>\n');
21834 o.push(' <number:year/>\n');
21835 o.push(' </number:date-style>\n');
21836
21837 /* column styles */
21838 var cidx = 0;
21839 wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
21840 if(!ws) return;
21841 if(ws["!cols"]) {
21842 for(var C = 0; C < ws["!cols"].length; ++C) if(ws["!cols"][C]) {
21843 var colobj = ws["!cols"][C];
21844 if(colobj.width == null && colobj.wpx == null && colobj.wch == null) continue;
21845 process_col(colobj);
21846 colobj.ods = cidx;
21847 var w = ws["!cols"][C].wpx + "px";
21848 o.push(' <style:style style:name="co' + cidx + '" style:family="table-column">\n');
21849 o.push(' <style:table-column-properties fo:break-before="auto" style:column-width="' + w + '"/>\n');
21850 o.push(' </style:style>\n');
21851 ++cidx;
21852 }
21853 }
21854 });
21855
21856 /* row styles */
21857 var ridx = 0;
21858 wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
21859 if(!ws) return;
21860 if(ws["!rows"]) {
21861 for(var R = 0; R < ws["!rows"].length; ++R) if(ws["!rows"][R]) {
21862 ws["!rows"][R].ods = ridx;
21863 var h = ws["!rows"][R].hpx + "px";
21864 o.push(' <style:style style:name="ro' + ridx + '" style:family="table-row">\n');
21865 o.push(' <style:table-row-properties fo:break-before="auto" style:row-height="' + h + '"/>\n');
21866 o.push(' </style:style>\n');
21867 ++ridx;
21868 }
21869 }
21870 });
21871
21872 /* table */
21873 o.push(' <style:style style:name="ta1" style:family="table" style:master-page-name="mp1">\n');
21874 o.push(' <style:table-properties table:display="true" style:writing-mode="lr-tb"/>\n');
21875 o.push(' </style:style>\n');
21876
21877 /* table cells, text */
21878 o.push(' <style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N37"/>\n');
21879
21880 /* page-layout */
21881
21882 o.push(' </office:automatic-styles>\n');
21883 };
21884
21885 return function wcx(wb, opts) {
21886 var o = [XML_HEADER];
21887 /* 3.1.3.2 */
21888 var attr = wxt_helper({
21889 'xmlns:office': "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
21890 'xmlns:table': "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
21891 'xmlns:style': "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
21892 'xmlns:text': "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
21893 'xmlns:draw': "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
21894 'xmlns:fo': "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
21895 'xmlns:xlink': "http://www.w3.org/1999/xlink",
21896 'xmlns:dc': "http://purl.org/dc/elements/1.1/",
21897 'xmlns:meta': "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
21898 'xmlns:number': "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
21899 'xmlns:presentation': "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",
21900 'xmlns:svg': "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
21901 'xmlns:chart': "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
21902 'xmlns:dr3d': "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
21903 'xmlns:math': "http://www.w3.org/1998/Math/MathML",
21904 'xmlns:form': "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
21905 'xmlns:script': "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
21906 'xmlns:ooo': "http://openoffice.org/2004/office",
21907 'xmlns:ooow': "http://openoffice.org/2004/writer",
21908 'xmlns:oooc': "http://openoffice.org/2004/calc",
21909 'xmlns:dom': "http://www.w3.org/2001/xml-events",
21910 'xmlns:xforms': "http://www.w3.org/2002/xforms",
21911 'xmlns:xsd': "http://www.w3.org/2001/XMLSchema",
21912 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance",
21913 'xmlns:sheet': "urn:oasis:names:tc:opendocument:sh33tjs:1.0",
21914 'xmlns:rpt': "http://openoffice.org/2005/report",
21915 'xmlns:of': "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
21916 'xmlns:xhtml': "http://www.w3.org/1999/xhtml",
21917 'xmlns:grddl': "http://www.w3.org/2003/g/data-view#",
21918 'xmlns:tableooo': "http://openoffice.org/2009/table",
21919 'xmlns:drawooo': "http://openoffice.org/2010/draw",
21920 'xmlns:calcext': "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0",
21921 'xmlns:loext': "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0",
21922 'xmlns:field': "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0",
21923 'xmlns:formx': "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0",
21924 'xmlns:css3t': "http://www.w3.org/TR/css3-text/",
21925 'office:version': "1.2"
21926 });
21927
21928 var fods = wxt_helper({
21929 'xmlns:config': "urn:oasis:names:tc:opendocument:xmlns:config:1.0",
21930 'office:mimetype': "application/vnd.oasis.opendocument.spreadsheet"
21931 });
21932
21933 if(opts.bookType == "fods") {
21934 o.push('<office:document' + attr + fods + '>\n');
21935 o.push(write_meta_ods().replace(/office:document-meta/g, "office:meta"));
21936 // TODO: settings (equiv of settings.xml for ODS)
21937 } else o.push('<office:document-content' + attr + '>\n');
21938 // o.push(' <office:scripts/>\n');
21939 write_automatic_styles_ods(o, wb);
21940 o.push(' <office:body>\n');
21941 o.push(' <office:spreadsheet>\n');
21942 for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
21943 o.push(' </office:spreadsheet>\n');
21944 o.push(' </office:body>\n');
21945 if(opts.bookType == "fods") o.push('</office:document>');
21946 else o.push('</office:document-content>');
21947 return o.join("");
21948 };
21949})();
21950
21951function write_ods(wb/*:any*/, opts/*:any*/) {
21952 if(opts.bookType == "fods") return write_content_ods(wb, opts);
21953
21954 var zip = zip_new();
21955 var f = "";
21956
21957 var manifest/*:Array<Array<string> >*/ = [];
21958 var rdf/*:Array<[string, string]>*/ = [];
21959
21960 /* Part 3 Section 3.3 MIME Media Type */
21961 f = "mimetype";
21962 zip_add_file(zip, f, "application/vnd.oasis.opendocument.spreadsheet");
21963
21964 /* Part 1 Section 2.2 Documents */
21965 f = "content.xml";
21966 zip_add_file(zip, f, write_content_ods(wb, opts));
21967 manifest.push([f, "text/xml"]);
21968 rdf.push([f, "ContentFile"]);
21969
21970 /* TODO: these are hard-coded styles to satiate excel */
21971 f = "styles.xml";
21972 zip_add_file(zip, f, write_styles_ods(wb, opts));
21973 manifest.push([f, "text/xml"]);
21974 rdf.push([f, "StylesFile"]);
21975
21976 /* TODO: this is hard-coded to satiate excel */
21977 f = "meta.xml";
21978 zip_add_file(zip, f, XML_HEADER + write_meta_ods(/*::wb, opts*/));
21979 manifest.push([f, "text/xml"]);
21980 rdf.push([f, "MetadataFile"]);
21981
21982 /* Part 3 Section 6 Metadata Manifest File */
21983 f = "manifest.rdf";
21984 zip_add_file(zip, f, write_rdf(rdf/*, opts*/));
21985 manifest.push([f, "application/rdf+xml"]);
21986
21987 /* Part 3 Section 4 Manifest File */
21988 f = "META-INF/manifest.xml";
21989 zip_add_file(zip, f, write_manifest(manifest/*, opts*/));
21990
21991 return zip;
21992}
21993
21994/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
21995function u8_to_dataview(array) {
21996 return new DataView(array.buffer, array.byteOffset, array.byteLength);
21997}
21998function u8str(u8) {
21999 return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
22000}
22001function stru8(str) {
22002 return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
22003}
22004function u8contains(body, search) {
22005 outer:
22006 for (var L = 0; L <= body.length - search.length; ++L) {
22007 for (var j = 0; j < search.length; ++j)
22008 if (body[L + j] != search[j])
22009 continue outer;
22010 return true;
22011 }
22012 return false;
22013}
22014function u8concat(u8a) {
22015 var len = u8a.reduce(function(acc, x) {
22016 return acc + x.length;
22017 }, 0);
22018 var out = new Uint8Array(len);
22019 var off = 0;
22020 u8a.forEach(function(u8) {
22021 out.set(u8, off);
22022 off += u8.length;
22023 });
22024 return out;
22025}
22026function popcnt(x) {
22027 x -= x >> 1 & 1431655765;
22028 x = (x & 858993459) + (x >> 2 & 858993459);
22029 return (x + (x >> 4) & 252645135) * 16843009 >>> 24;
22030}
22031function readDecimal128LE(buf, offset) {
22032 var exp = (buf[offset + 15] & 127) << 7 | buf[offset + 14] >> 1;
22033 var mantissa = buf[offset + 14] & 1;
22034 for (var j = offset + 13; j >= offset; --j)
22035 mantissa = mantissa * 256 + buf[j];
22036 return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
22037}
22038function writeDecimal128LE(buf, offset, value) {
22039 var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
22040 var mantissa = value / Math.pow(10, exp - 6176);
22041 buf[offset + 15] |= exp >> 7;
22042 buf[offset + 14] |= (exp & 127) << 1;
22043 for (var i = 0; mantissa >= 1; ++i, mantissa /= 256)
22044 buf[offset + i] = mantissa & 255;
22045 buf[offset + 15] |= value >= 0 ? 0 : 128;
22046}
22047function parse_varint49(buf, ptr) {
22048 var l = ptr ? ptr[0] : 0;
22049 var usz = buf[l] & 127;
22050 varint:
22051 if (buf[l++] >= 128) {
22052 usz |= (buf[l] & 127) << 7;
22053 if (buf[l++] < 128)
22054 break varint;
22055 usz |= (buf[l] & 127) << 14;
22056 if (buf[l++] < 128)
22057 break varint;
22058 usz |= (buf[l] & 127) << 21;
22059 if (buf[l++] < 128)
22060 break varint;
22061 usz += (buf[l] & 127) * Math.pow(2, 28);
22062 ++l;
22063 if (buf[l++] < 128)
22064 break varint;
22065 usz += (buf[l] & 127) * Math.pow(2, 35);
22066 ++l;
22067 if (buf[l++] < 128)
22068 break varint;
22069 usz += (buf[l] & 127) * Math.pow(2, 42);
22070 ++l;
22071 if (buf[l++] < 128)
22072 break varint;
22073 }
22074 if (ptr)
22075 ptr[0] = l;
22076 return usz;
22077}
22078function write_varint49(v) {
22079 var usz = new Uint8Array(7);
22080 usz[0] = v & 127;
22081 var L = 1;
22082 sz:
22083 if (v > 127) {
22084 usz[L - 1] |= 128;
22085 usz[L] = v >> 7 & 127;
22086 ++L;
22087 if (v <= 16383)
22088 break sz;
22089 usz[L - 1] |= 128;
22090 usz[L] = v >> 14 & 127;
22091 ++L;
22092 if (v <= 2097151)
22093 break sz;
22094 usz[L - 1] |= 128;
22095 usz[L] = v >> 21 & 127;
22096 ++L;
22097 if (v <= 268435455)
22098 break sz;
22099 usz[L - 1] |= 128;
22100 usz[L] = v / 256 >>> 21 & 127;
22101 ++L;
22102 if (v <= 34359738367)
22103 break sz;
22104 usz[L - 1] |= 128;
22105 usz[L] = v / 65536 >>> 21 & 127;
22106 ++L;
22107 if (v <= 4398046511103)
22108 break sz;
22109 usz[L - 1] |= 128;
22110 usz[L] = v / 16777216 >>> 21 & 127;
22111 ++L;
22112 }
22113 return usz.slice(0, L);
22114}
22115function varint_to_i32(buf) {
22116 var l = 0, i32 = buf[l] & 127;
22117 varint:
22118 if (buf[l++] >= 128) {
22119 i32 |= (buf[l] & 127) << 7;
22120 if (buf[l++] < 128)
22121 break varint;
22122 i32 |= (buf[l] & 127) << 14;
22123 if (buf[l++] < 128)
22124 break varint;
22125 i32 |= (buf[l] & 127) << 21;
22126 if (buf[l++] < 128)
22127 break varint;
22128 i32 |= (buf[l] & 127) << 28;
22129 }
22130 return i32;
22131}
22132function parse_shallow(buf) {
22133 var out = [], ptr = [0];
22134 while (ptr[0] < buf.length) {
22135 var off = ptr[0];
22136 var num = parse_varint49(buf, ptr);
22137 var type = num & 7;
22138 num = Math.floor(num / 8);
22139 var len = 0;
22140 var res;
22141 if (num == 0)
22142 break;
22143 switch (type) {
22144 case 0:
22145 {
22146 var l = ptr[0];
22147 while (buf[ptr[0]++] >= 128)
22148 ;
22149 res = buf.slice(l, ptr[0]);
22150 }
22151 break;
22152 case 5:
22153 len = 4;
22154 res = buf.slice(ptr[0], ptr[0] + len);
22155 ptr[0] += len;
22156 break;
22157 case 1:
22158 len = 8;
22159 res = buf.slice(ptr[0], ptr[0] + len);
22160 ptr[0] += len;
22161 break;
22162 case 2:
22163 len = parse_varint49(buf, ptr);
22164 res = buf.slice(ptr[0], ptr[0] + len);
22165 ptr[0] += len;
22166 break;
22167 case 3:
22168 case 4:
22169 default:
22170 throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
22171 }
22172 var v = { data: res, type: type };
22173 if (out[num] == null)
22174 out[num] = [v];
22175 else
22176 out[num].push(v);
22177 }
22178 return out;
22179}
22180function write_shallow(proto) {
22181 var out = [];
22182 proto.forEach(function(field, idx) {
22183 field.forEach(function(item) {
22184 if (!item.data)
22185 return;
22186 out.push(write_varint49(idx * 8 + item.type));
22187 if (item.type == 2)
22188 out.push(write_varint49(item.data.length));
22189 out.push(item.data);
22190 });
22191 });
22192 return u8concat(out);
22193}
22194function mappa(data, cb) {
22195 return (data == null ? void 0 : data.map(function(d) {
22196 return cb(d.data);
22197 })) || [];
22198}
22199function parse_iwa_file(buf) {
22200 var _a;
22201 var out = [], ptr = [0];
22202 while (ptr[0] < buf.length) {
22203 var len = parse_varint49(buf, ptr);
22204 var ai = parse_shallow(buf.slice(ptr[0], ptr[0] + len));
22205 ptr[0] += len;
22206 var res = {
22207 id: varint_to_i32(ai[1][0].data),
22208 messages: []
22209 };
22210 ai[2].forEach(function(b) {
22211 var mi = parse_shallow(b.data);
22212 var fl = varint_to_i32(mi[3][0].data);
22213 res.messages.push({
22214 meta: mi,
22215 data: buf.slice(ptr[0], ptr[0] + fl)
22216 });
22217 ptr[0] += fl;
22218 });
22219 if ((_a = ai[3]) == null ? void 0 : _a[0])
22220 res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
22221 out.push(res);
22222 }
22223 return out;
22224}
22225function write_iwa_file(ias) {
22226 var bufs = [];
22227 ias.forEach(function(ia) {
22228 var ai = [];
22229 ai[1] = [{ data: write_varint49(ia.id), type: 0 }];
22230 ai[2] = [];
22231 if (ia.merge != null)
22232 ai[3] = [{ data: write_varint49(+!!ia.merge), type: 0 }];
22233 var midata = [];
22234 ia.messages.forEach(function(mi) {
22235 midata.push(mi.data);
22236 mi.meta[3] = [{ type: 0, data: write_varint49(mi.data.length) }];
22237 ai[2].push({ data: write_shallow(mi.meta), type: 2 });
22238 });
22239 var aipayload = write_shallow(ai);
22240 bufs.push(write_varint49(aipayload.length));
22241 bufs.push(aipayload);
22242 midata.forEach(function(mid) {
22243 return bufs.push(mid);
22244 });
22245 });
22246 return u8concat(bufs);
22247}
22248function parse_snappy_chunk(type, buf) {
22249 if (type != 0)
22250 throw new Error("Unexpected Snappy chunk type ".concat(type));
22251 var ptr = [0];
22252 var usz = parse_varint49(buf, ptr);
22253 var chunks = [];
22254 while (ptr[0] < buf.length) {
22255 var tag = buf[ptr[0]] & 3;
22256 if (tag == 0) {
22257 var len = buf[ptr[0]++] >> 2;
22258 if (len < 60)
22259 ++len;
22260 else {
22261 var c = len - 59;
22262 len = buf[ptr[0]];
22263 if (c > 1)
22264 len |= buf[ptr[0] + 1] << 8;
22265 if (c > 2)
22266 len |= buf[ptr[0] + 2] << 16;
22267 if (c > 3)
22268 len |= buf[ptr[0] + 3] << 24;
22269 len >>>= 0;
22270 len++;
22271 ptr[0] += c;
22272 }
22273 chunks.push(buf.slice(ptr[0], ptr[0] + len));
22274 ptr[0] += len;
22275 continue;
22276 } else {
22277 var offset = 0, length = 0;
22278 if (tag == 1) {
22279 length = (buf[ptr[0]] >> 2 & 7) + 4;
22280 offset = (buf[ptr[0]++] & 224) << 3;
22281 offset |= buf[ptr[0]++];
22282 } else {
22283 length = (buf[ptr[0]++] >> 2) + 1;
22284 if (tag == 2) {
22285 offset = buf[ptr[0]] | buf[ptr[0] + 1] << 8;
22286 ptr[0] += 2;
22287 } else {
22288 offset = (buf[ptr[0]] | buf[ptr[0] + 1] << 8 | buf[ptr[0] + 2] << 16 | buf[ptr[0] + 3] << 24) >>> 0;
22289 ptr[0] += 4;
22290 }
22291 }
22292 chunks = [u8concat(chunks)];
22293 if (offset == 0)
22294 throw new Error("Invalid offset 0");
22295 if (offset > chunks[0].length)
22296 throw new Error("Invalid offset beyond length");
22297 if (length >= offset) {
22298 chunks.push(chunks[0].slice(-offset));
22299 length -= offset;
22300 while (length >= chunks[chunks.length - 1].length) {
22301 chunks.push(chunks[chunks.length - 1]);
22302 length -= chunks[chunks.length - 1].length;
22303 }
22304 }
22305 chunks.push(chunks[0].slice(-offset, -offset + length));
22306 }
22307 }
22308 var o = u8concat(chunks);
22309 if (o.length != usz)
22310 throw new Error("Unexpected length: ".concat(o.length, " != ").concat(usz));
22311 return o;
22312}
22313function decompress_iwa_file(buf) {
22314 var out = [];
22315 var l = 0;
22316 while (l < buf.length) {
22317 var t = buf[l++];
22318 var len = buf[l] | buf[l + 1] << 8 | buf[l + 2] << 16;
22319 l += 3;
22320 out.push(parse_snappy_chunk(t, buf.slice(l, l + len)));
22321 l += len;
22322 }
22323 if (l !== buf.length)
22324 throw new Error("data is not a valid framed stream!");
22325 return u8concat(out);
22326}
22327function compress_iwa_file(buf) {
22328 var out = [];
22329 var l = 0;
22330 while (l < buf.length) {
22331 var c = Math.min(buf.length - l, 268435455);
22332 var frame = new Uint8Array(4);
22333 out.push(frame);
22334 var usz = write_varint49(c);
22335 var L = usz.length;
22336 out.push(usz);
22337 if (c <= 60) {
22338 L++;
22339 out.push(new Uint8Array([c - 1 << 2]));
22340 } else if (c <= 256) {
22341 L += 2;
22342 out.push(new Uint8Array([240, c - 1 & 255]));
22343 } else if (c <= 65536) {
22344 L += 3;
22345 out.push(new Uint8Array([244, c - 1 & 255, c - 1 >> 8 & 255]));
22346 } else if (c <= 16777216) {
22347 L += 4;
22348 out.push(new Uint8Array([248, c - 1 & 255, c - 1 >> 8 & 255, c - 1 >> 16 & 255]));
22349 } else if (c <= 4294967296) {
22350 L += 5;
22351 out.push(new Uint8Array([252, c - 1 & 255, c - 1 >> 8 & 255, c - 1 >> 16 & 255, c - 1 >>> 24 & 255]));
22352 }
22353 out.push(buf.slice(l, l + c));
22354 L += c;
22355 frame[0] = 0;
22356 frame[1] = L & 255;
22357 frame[2] = L >> 8 & 255;
22358 frame[3] = L >> 16 & 255;
22359 l += c;
22360 }
22361 return u8concat(out);
22362}
22363function parse_old_storage(buf, sst, rsst, v) {
22364 var dv = u8_to_dataview(buf);
22365 var flags = dv.getUint32(4, true);
22366 var data_offset = (v > 1 ? 12 : 8) + popcnt(flags & (v > 1 ? 3470 : 398)) * 4;
22367 var ridx = -1, sidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
22368 if (flags & 512) {
22369 ridx = dv.getUint32(data_offset, true);
22370 data_offset += 4;
22371 }
22372 data_offset += popcnt(flags & (v > 1 ? 12288 : 4096)) * 4;
22373 if (flags & 16) {
22374 sidx = dv.getUint32(data_offset, true);
22375 data_offset += 4;
22376 }
22377 if (flags & 32) {
22378 ieee = dv.getFloat64(data_offset, true);
22379 data_offset += 8;
22380 }
22381 if (flags & 64) {
22382 dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
22383 data_offset += 8;
22384 }
22385 var ret;
22386 switch (buf[2]) {
22387 case 0:
22388 break;
22389 case 2:
22390 ret = { t: "n", v: ieee };
22391 break;
22392 case 3:
22393 ret = { t: "s", v: sst[sidx] };
22394 break;
22395 case 5:
22396 ret = { t: "d", v: dt };
22397 break;
22398 case 6:
22399 ret = { t: "b", v: ieee > 0 };
22400 break;
22401 case 7:
22402 ret = { t: "n", v: ieee / 86400 };
22403 break;
22404 case 8:
22405 ret = { t: "e", v: 0 };
22406 break;
22407 case 9:
22408 {
22409 if (ridx > -1)
22410 ret = { t: "s", v: rsst[ridx] };
22411 else if (sidx > -1)
22412 ret = { t: "s", v: sst[sidx] };
22413 else if (!isNaN(ieee))
22414 ret = { t: "n", v: ieee };
22415 else
22416 throw new Error("Unsupported cell type ".concat(buf.slice(0, 4)));
22417 }
22418 break;
22419 default:
22420 throw new Error("Unsupported cell type ".concat(buf.slice(0, 4)));
22421 }
22422 return ret;
22423}
22424function parse_new_storage(buf, sst, rsst) {
22425 var dv = u8_to_dataview(buf);
22426 var flags = dv.getUint32(8, true);
22427 var data_offset = 12;
22428 var ridx = -1, sidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
22429 if (flags & 1) {
22430 d128 = readDecimal128LE(buf, data_offset);
22431 data_offset += 16;
22432 }
22433 if (flags & 2) {
22434 ieee = dv.getFloat64(data_offset, true);
22435 data_offset += 8;
22436 }
22437 if (flags & 4) {
22438 dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
22439 data_offset += 8;
22440 }
22441 if (flags & 8) {
22442 sidx = dv.getUint32(data_offset, true);
22443 data_offset += 4;
22444 }
22445 if (flags & 16) {
22446 ridx = dv.getUint32(data_offset, true);
22447 data_offset += 4;
22448 }
22449 var ret;
22450 switch (buf[1]) {
22451 case 0:
22452 break;
22453 case 2:
22454 ret = { t: "n", v: d128 };
22455 break;
22456 case 3:
22457 ret = { t: "s", v: sst[sidx] };
22458 break;
22459 case 5:
22460 ret = { t: "d", v: dt };
22461 break;
22462 case 6:
22463 ret = { t: "b", v: ieee > 0 };
22464 break;
22465 case 7:
22466 ret = { t: "n", v: ieee / 86400 };
22467 break;
22468 case 8:
22469 ret = { t: "e", v: 0 };
22470 break;
22471 case 9:
22472 {
22473 if (ridx > -1)
22474 ret = { t: "s", v: rsst[ridx] };
22475 else
22476 throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf.slice(0, 4)));
22477 }
22478 break;
22479 case 10:
22480 ret = { t: "n", v: d128 };
22481 break;
22482 default:
22483 throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf.slice(0, 4)));
22484 }
22485 return ret;
22486}
22487function write_new_storage(cell, sst) {
22488 var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
22489 out[0] = 5;
22490 switch (cell.t) {
22491 case "n":
22492 out[1] = 2;
22493 writeDecimal128LE(out, l, cell.v);
22494 flags |= 1;
22495 l += 16;
22496 break;
22497 case "b":
22498 out[1] = 6;
22499 dv.setFloat64(l, cell.v ? 1 : 0, true);
22500 flags |= 2;
22501 l += 8;
22502 break;
22503 case "s":
22504 if (sst.indexOf(cell.v) == -1)
22505 throw new Error("Value ".concat(cell.v, " missing from SST!"));
22506 out[1] = 3;
22507 dv.setUint32(l, sst.indexOf(cell.v), true);
22508 flags |= 8;
22509 l += 4;
22510 break;
22511 default:
22512 throw "unsupported cell type " + cell.t;
22513 }
22514 dv.setUint32(8, flags, true);
22515 return out.slice(0, l);
22516}
22517function write_old_storage(cell, sst) {
22518 var out = new Uint8Array(32), dv = u8_to_dataview(out), l = 12, flags = 0;
22519 out[0] = 3;
22520 switch (cell.t) {
22521 case "n":
22522 out[2] = 2;
22523 dv.setFloat64(l, cell.v, true);
22524 flags |= 32;
22525 l += 8;
22526 break;
22527 case "b":
22528 out[2] = 6;
22529 dv.setFloat64(l, cell.v ? 1 : 0, true);
22530 flags |= 32;
22531 l += 8;
22532 break;
22533 case "s":
22534 if (sst.indexOf(cell.v) == -1)
22535 throw new Error("Value ".concat(cell.v, " missing from SST!"));
22536 out[2] = 3;
22537 dv.setUint32(l, sst.indexOf(cell.v), true);
22538 flags |= 16;
22539 l += 4;
22540 break;
22541 default:
22542 throw "unsupported cell type " + cell.t;
22543 }
22544 dv.setUint32(4, flags, true);
22545 return out.slice(0, l);
22546}
22547function parse_cell_storage(buf, sst, rsst) {
22548 switch (buf[0]) {
22549 case 0:
22550 case 1:
22551 case 2:
22552 case 3:
22553 return parse_old_storage(buf, sst, rsst, buf[0]);
22554 case 5:
22555 return parse_new_storage(buf, sst, rsst);
22556 default:
22557 throw new Error("Unsupported payload version ".concat(buf[0]));
22558 }
22559}
22560function parse_TSP_Reference(buf) {
22561 var pb = parse_shallow(buf);
22562 return parse_varint49(pb[1][0].data);
22563}
22564function write_TSP_Reference(idx) {
22565 var out = [];
22566 out[1] = [{ type: 0, data: write_varint49(idx) }];
22567 return write_shallow(out);
22568}
22569function parse_TST_TableDataList(M, root) {
22570 var pb = parse_shallow(root.data);
22571 var type = varint_to_i32(pb[1][0].data);
22572 var entries = pb[3];
22573 var data = [];
22574 (entries || []).forEach(function(entry) {
22575 var le = parse_shallow(entry.data);
22576 var key = varint_to_i32(le[1][0].data) >>> 0;
22577 switch (type) {
22578 case 1:
22579 data[key] = u8str(le[3][0].data);
22580 break;
22581 case 8:
22582 {
22583 var rt = M[parse_TSP_Reference(le[9][0].data)][0];
22584 var rtp = parse_shallow(rt.data);
22585 var rtpref = M[parse_TSP_Reference(rtp[1][0].data)][0];
22586 var mtype = varint_to_i32(rtpref.meta[1][0].data);
22587 if (mtype != 2001)
22588 throw new Error("2000 unexpected reference to ".concat(mtype));
22589 var tswpsa = parse_shallow(rtpref.data);
22590 data[key] = tswpsa[3].map(function(x) {
22591 return u8str(x.data);
22592 }).join("");
22593 }
22594 break;
22595 }
22596 });
22597 return data;
22598}
22599function parse_TST_TileRowInfo(u8, type) {
22600 var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
22601 var pb = parse_shallow(u8);
22602 var R = varint_to_i32(pb[1][0].data) >>> 0;
22603 var cnt = varint_to_i32(pb[2][0].data) >>> 0;
22604 var wide_offsets = ((_b = (_a = pb[8]) == null ? void 0 : _a[0]) == null ? void 0 : _b.data) && varint_to_i32(pb[8][0].data) > 0 || false;
22605 var used_storage_u8, used_storage;
22606 if (((_d = (_c = pb[7]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && type != 0) {
22607 used_storage_u8 = (_f = (_e = pb[7]) == null ? void 0 : _e[0]) == null ? void 0 : _f.data;
22608 used_storage = (_h = (_g = pb[6]) == null ? void 0 : _g[0]) == null ? void 0 : _h.data;
22609 } else if (((_j = (_i = pb[4]) == null ? void 0 : _i[0]) == null ? void 0 : _j.data) && type != 1) {
22610 used_storage_u8 = (_l = (_k = pb[4]) == null ? void 0 : _k[0]) == null ? void 0 : _l.data;
22611 used_storage = (_n = (_m = pb[3]) == null ? void 0 : _m[0]) == null ? void 0 : _n.data;
22612 } else
22613 throw "NUMBERS Tile missing ".concat(type, " cell storage");
22614 var width = wide_offsets ? 4 : 1;
22615 var used_storage_offsets = u8_to_dataview(used_storage_u8);
22616 var offsets = [];
22617 for (var C = 0; C < used_storage_u8.length / 2; ++C) {
22618 var off = used_storage_offsets.getUint16(C * 2, true);
22619 if (off < 65535)
22620 offsets.push([C, off]);
22621 }
22622 if (offsets.length != cnt)
22623 throw "Expected ".concat(cnt, " cells, found ").concat(offsets.length);
22624 var cells = [];
22625 for (C = 0; C < offsets.length - 1; ++C)
22626 cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
22627 if (offsets.length >= 1)
22628 cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
22629 return { R: R, cells: cells };
22630}
22631function parse_TST_Tile(M, root) {
22632 var _a;
22633 var pb = parse_shallow(root.data);
22634 var storage = ((_a = pb == null ? void 0 : pb[7]) == null ? void 0 : _a[0]) ? varint_to_i32(pb[7][0].data) >>> 0 > 0 ? 1 : 0 : -1;
22635 var ri = mappa(pb[5], function(u8) {
22636 return parse_TST_TileRowInfo(u8, storage);
22637 });
22638 return {
22639 nrows: varint_to_i32(pb[4][0].data) >>> 0,
22640 data: ri.reduce(function(acc, x) {
22641 if (!acc[x.R])
22642 acc[x.R] = [];
22643 x.cells.forEach(function(cell, C) {
22644 if (acc[x.R][C])
22645 throw new Error("Duplicate cell r=".concat(x.R, " c=").concat(C));
22646 acc[x.R][C] = cell;
22647 });
22648 return acc;
22649 }, [])
22650 };
22651}
22652function parse_TST_TableModelArchive(M, root, ws) {
22653 var _a;
22654 var pb = parse_shallow(root.data);
22655 var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
22656 range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
22657 if (range.e.r < 0)
22658 throw new Error("Invalid row varint ".concat(pb[6][0].data));
22659 range.e.c = (varint_to_i32(pb[7][0].data) >>> 0) - 1;
22660 if (range.e.c < 0)
22661 throw new Error("Invalid col varint ".concat(pb[7][0].data));
22662 ws["!ref"] = encode_range(range);
22663 var store = parse_shallow(pb[4][0].data);
22664 var sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
22665 var rsst = ((_a = store[17]) == null ? void 0 : _a[0]) ? parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]) : [];
22666 var tile = parse_shallow(store[3][0].data);
22667 var _R = 0;
22668 tile[1].forEach(function(t) {
22669 var tl = parse_shallow(t.data);
22670 var ref = M[parse_TSP_Reference(tl[2][0].data)][0];
22671 var mtype = varint_to_i32(ref.meta[1][0].data);
22672 if (mtype != 6002)
22673 throw new Error("6001 unexpected reference to ".concat(mtype));
22674 var _tile = parse_TST_Tile(M, ref);
22675 _tile.data.forEach(function(row, R) {
22676 row.forEach(function(buf, C) {
22677 var addr = encode_cell({ r: _R + R, c: C });
22678 var res = parse_cell_storage(buf, sst, rsst);
22679 if (res)
22680 ws[addr] = res;
22681 });
22682 });
22683 _R += _tile.nrows;
22684 });
22685}
22686function parse_TST_TableInfoArchive(M, root) {
22687 var pb = parse_shallow(root.data);
22688 var out = { "!ref": "A1" };
22689 var tableref = M[parse_TSP_Reference(pb[2][0].data)];
22690 var mtype = varint_to_i32(tableref[0].meta[1][0].data);
22691 if (mtype != 6001)
22692 throw new Error("6000 unexpected reference to ".concat(mtype));
22693 parse_TST_TableModelArchive(M, tableref[0], out);
22694 return out;
22695}
22696function parse_TN_SheetArchive(M, root) {
22697 var _a;
22698 var pb = parse_shallow(root.data);
22699 var out = {
22700 name: ((_a = pb[1]) == null ? void 0 : _a[0]) ? u8str(pb[1][0].data) : "",
22701 sheets: []
22702 };
22703 var shapeoffs = mappa(pb[2], parse_TSP_Reference);
22704 shapeoffs.forEach(function(off) {
22705 M[off].forEach(function(m) {
22706 var mtype = varint_to_i32(m.meta[1][0].data);
22707 if (mtype == 6e3)
22708 out.sheets.push(parse_TST_TableInfoArchive(M, m));
22709 });
22710 });
22711 return out;
22712}
22713function parse_TN_DocumentArchive(M, root) {
22714 var out = book_new();
22715 var pb = parse_shallow(root.data);
22716 var sheetoffs = mappa(pb[1], parse_TSP_Reference);
22717 sheetoffs.forEach(function(off) {
22718 M[off].forEach(function(m) {
22719 var mtype = varint_to_i32(m.meta[1][0].data);
22720 if (mtype == 2) {
22721 var root2 = parse_TN_SheetArchive(M, m);
22722 root2.sheets.forEach(function(sheet, idx) {
22723 book_append_sheet(out, sheet, idx == 0 ? root2.name : root2.name + "_" + idx, true);
22724 });
22725 }
22726 });
22727 });
22728 if (out.SheetNames.length == 0)
22729 throw new Error("Empty NUMBERS file");
22730 return out;
22731}
22732function parse_numbers_iwa(cfb) {
22733 var _a, _b, _c, _d;
22734 var M = {}, indices = [];
22735 cfb.FullPaths.forEach(function(p) {
22736 if (p.match(/\.iwpv2/))
22737 throw new Error("Unsupported password protection");
22738 });
22739 cfb.FileIndex.forEach(function(s) {
22740 if (!s.name.match(/\.iwa$/))
22741 return;
22742 var o;
22743 try {
22744 o = decompress_iwa_file(s.content);
22745 } catch (e) {
22746 return console.log("?? " + s.content.length + " " + (e.message || e));
22747 }
22748 var packets;
22749 try {
22750 packets = parse_iwa_file(o);
22751 } catch (e) {
22752 return console.log("## " + (e.message || e));
22753 }
22754 packets.forEach(function(packet) {
22755 M[packet.id] = packet.messages;
22756 indices.push(packet.id);
22757 });
22758 });
22759 if (!indices.length)
22760 throw new Error("File has no messages");
22761 var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
22762 if (!docroot)
22763 indices.forEach(function(idx) {
22764 M[idx].forEach(function(iwam) {
22765 var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
22766 if (mtype == 1) {
22767 if (!docroot)
22768 docroot = iwam;
22769 else
22770 throw new Error("Document has multiple roots");
22771 }
22772 });
22773 });
22774 if (!docroot)
22775 throw new Error("Cannot find Document root");
22776 return parse_TN_DocumentArchive(M, docroot);
22777}
22778function write_tile_row(tri, data, SST) {
22779 var _a, _b, _c, _d;
22780 if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0]))
22781 throw "Mutation only works on post-BNC storages!";
22782 var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
22783 if (wide_offsets)
22784 throw "Math only works with normal offsets";
22785 var cnt = 0;
22786 var dv = u8_to_dataview(tri[7][0].data), last_offset = 0, cell_storage = [];
22787 var _dv = u8_to_dataview(tri[4][0].data), _last_offset = 0, _cell_storage = [];
22788 for (var C = 0; C < data.length; ++C) {
22789 if (data[C] == null) {
22790 dv.setUint16(C * 2, 65535, true);
22791 _dv.setUint16(C * 2, 65535);
22792 continue;
22793 }
22794 dv.setUint16(C * 2, last_offset, true);
22795 _dv.setUint16(C * 2, _last_offset, true);
22796 var celload, _celload;
22797 switch (typeof data[C]) {
22798 case "string":
22799 celload = write_new_storage({ t: "s", v: data[C] }, SST);
22800 _celload = write_old_storage({ t: "s", v: data[C] }, SST);
22801 break;
22802 case "number":
22803 celload = write_new_storage({ t: "n", v: data[C] }, SST);
22804 _celload = write_old_storage({ t: "n", v: data[C] }, SST);
22805 break;
22806 case "boolean":
22807 celload = write_new_storage({ t: "b", v: data[C] }, SST);
22808 _celload = write_old_storage({ t: "b", v: data[C] }, SST);
22809 break;
22810 default:
22811 throw new Error("Unsupported value " + data[C]);
22812 }
22813 cell_storage.push(celload);
22814 last_offset += celload.length;
22815 _cell_storage.push(_celload);
22816 _last_offset += _celload.length;
22817 ++cnt;
22818 }
22819 tri[2][0].data = write_varint49(cnt);
22820 for (; C < tri[7][0].data.length / 2; ++C) {
22821 dv.setUint16(C * 2, 65535, true);
22822 _dv.setUint16(C * 2, 65535, true);
22823 }
22824 tri[6][0].data = u8concat(cell_storage);
22825 tri[3][0].data = u8concat(_cell_storage);
22826 return cnt;
22827}
22828function write_numbers_iwa(wb, opts) {
22829 if (!opts || !opts.numbers)
22830 throw new Error("Must pass a `numbers` option -- check the README");
22831 var ws = wb.Sheets[wb.SheetNames[0]];
22832 if (wb.SheetNames.length > 1)
22833 console.error("The Numbers writer currently writes only the first table");
22834 var range = decode_range(ws["!ref"]);
22835 range.s.r = range.s.c = 0;
22836 var trunc = false;
22837 if (range.e.c > 9) {
22838 trunc = true;
22839 range.e.c = 9;
22840 }
22841 if (range.e.r > 49) {
22842 trunc = true;
22843 range.e.r = 49;
22844 }
22845 if (trunc)
22846 console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
22847 var data = sheet_to_json(ws, { range: range, header: 1 });
22848 var SST = ["~Sh33tJ5~"];
22849 data.forEach(function(row) {
22850 return row.forEach(function(cell) {
22851 if (typeof cell == "string")
22852 SST.push(cell);
22853 });
22854 });
22855 var dependents = {};
22856 var indices = [];
22857 var cfb = CFB.read(opts.numbers, { type: "base64" });
22858 cfb.FileIndex.map(function(fi, idx) {
22859 return [fi, cfb.FullPaths[idx]];
22860 }).forEach(function(row) {
22861 var fi = row[0], fp = row[1];
22862 if (fi.type != 2)
22863 return;
22864 if (!fi.name.match(/\.iwa/))
22865 return;
22866 var old_content = fi.content;
22867 var raw1 = decompress_iwa_file(old_content);
22868 var x2 = parse_iwa_file(raw1);
22869 x2.forEach(function(packet2) {
22870 indices.push(packet2.id);
22871 dependents[packet2.id] = { deps: [], location: fp, type: varint_to_i32(packet2.messages[0].meta[1][0].data) };
22872 });
22873 });
22874 indices.sort(function(x2, y2) {
22875 return x2 - y2;
22876 });
22877 var indices_varint = indices.filter(function(x2) {
22878 return x2 > 1;
22879 }).map(function(x2) {
22880 return [x2, write_varint49(x2)];
22881 });
22882 cfb.FileIndex.map(function(fi, idx) {
22883 return [fi, cfb.FullPaths[idx]];
22884 }).forEach(function(row) {
22885 var fi = row[0], fp = row[1];
22886 if (!fi.name.match(/\.iwa/))
22887 return;
22888 var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
22889 x2.forEach(function(ia) {
22890 ia.messages.forEach(function(m) {
22891 indices_varint.forEach(function(ivi) {
22892 if (ia.messages.some(function(mess) {
22893 return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
22894 })) {
22895 dependents[ivi[0]].deps.push(ia.id);
22896 }
22897 });
22898 });
22899 });
22900 });
22901 function get_unique_msgid() {
22902 for (var i = 927262; i < 2e6; ++i)
22903 if (!dependents[i])
22904 return i;
22905 throw new Error("Too many messages");
22906 }
22907 var entry = CFB.find(cfb, dependents[1].location);
22908 var x = parse_iwa_file(decompress_iwa_file(entry.content));
22909 var docroot;
22910 for (var xi = 0; xi < x.length; ++xi) {
22911 var packet = x[xi];
22912 if (packet.id == 1)
22913 docroot = packet;
22914 }
22915 var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
22916 entry = CFB.find(cfb, dependents[sheetrootref].location);
22917 x = parse_iwa_file(decompress_iwa_file(entry.content));
22918 for (xi = 0; xi < x.length; ++xi) {
22919 packet = x[xi];
22920 if (packet.id == sheetrootref)
22921 docroot = packet;
22922 }
22923 sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
22924 entry = CFB.find(cfb, dependents[sheetrootref].location);
22925 x = parse_iwa_file(decompress_iwa_file(entry.content));
22926 for (xi = 0; xi < x.length; ++xi) {
22927 packet = x[xi];
22928 if (packet.id == sheetrootref)
22929 docroot = packet;
22930 }
22931 sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
22932 entry = CFB.find(cfb, dependents[sheetrootref].location);
22933 x = parse_iwa_file(decompress_iwa_file(entry.content));
22934 for (xi = 0; xi < x.length; ++xi) {
22935 packet = x[xi];
22936 if (packet.id == sheetrootref)
22937 docroot = packet;
22938 }
22939 var pb = parse_shallow(docroot.messages[0].data);
22940 {
22941 pb[6][0].data = write_varint49(range.e.r + 1);
22942 pb[7][0].data = write_varint49(range.e.c + 1);
22943 var cruidsref = parse_TSP_Reference(pb[46][0].data);
22944 var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
22945 var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
22946 {
22947 for (var j = 0; j < _x.length; ++j) {
22948 if (_x[j].id == cruidsref)
22949 break;
22950 }
22951 if (_x[j].id != cruidsref)
22952 throw "Bad ColumnRowUIDMapArchive";
22953 var cruids = parse_shallow(_x[j].messages[0].data);
22954 cruids[1] = [];
22955 cruids[2] = [], cruids[3] = [];
22956 for (var C = 0; C <= range.e.c; ++C) {
22957 var uuid = [];
22958 uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(C + 420690) }];
22959 cruids[1].push({ type: 2, data: write_shallow(uuid) });
22960 cruids[2].push({ type: 0, data: write_varint49(C) });
22961 cruids[3].push({ type: 0, data: write_varint49(C) });
22962 }
22963 cruids[4] = [];
22964 cruids[5] = [], cruids[6] = [];
22965 for (var R = 0; R <= range.e.r; ++R) {
22966 uuid = [];
22967 uuid[1] = uuid[2] = [{ type: 0, data: write_varint49(R + 726270) }];
22968 cruids[4].push({ type: 2, data: write_shallow(uuid) });
22969 cruids[5].push({ type: 0, data: write_varint49(R) });
22970 cruids[6].push({ type: 0, data: write_varint49(R) });
22971 }
22972 _x[j].messages[0].data = write_shallow(cruids);
22973 }
22974 oldbucket.content = compress_iwa_file(write_iwa_file(_x));
22975 oldbucket.size = oldbucket.content.length;
22976 delete pb[46];
22977 var store = parse_shallow(pb[4][0].data);
22978 {
22979 store[7][0].data = write_varint49(range.e.r + 1);
22980 var row_headers = parse_shallow(store[1][0].data);
22981 var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
22982 oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
22983 _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
22984 {
22985 if (_x[0].id != row_header_ref)
22986 throw "Bad HeaderStorageBucket";
22987 var base_bucket = parse_shallow(_x[0].messages[0].data);
22988 for (R = 0; R < data.length; ++R) {
22989 var _bucket = parse_shallow(base_bucket[2][0].data);
22990 _bucket[1][0].data = write_varint49(R);
22991 _bucket[4][0].data = write_varint49(data[R].length);
22992 base_bucket[2][R] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
22993 }
22994 _x[0].messages[0].data = write_shallow(base_bucket);
22995 }
22996 oldbucket.content = compress_iwa_file(write_iwa_file(_x));
22997 oldbucket.size = oldbucket.content.length;
22998 var col_header_ref = parse_TSP_Reference(store[2][0].data);
22999 oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
23000 _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
23001 {
23002 if (_x[0].id != col_header_ref)
23003 throw "Bad HeaderStorageBucket";
23004 base_bucket = parse_shallow(_x[0].messages[0].data);
23005 for (C = 0; C <= range.e.c; ++C) {
23006 _bucket = parse_shallow(base_bucket[2][0].data);
23007 _bucket[1][0].data = write_varint49(C);
23008 _bucket[4][0].data = write_varint49(range.e.r + 1);
23009 base_bucket[2][C] = { type: base_bucket[2][0].type, data: write_shallow(_bucket) };
23010 }
23011 _x[0].messages[0].data = write_shallow(base_bucket);
23012 }
23013 oldbucket.content = compress_iwa_file(write_iwa_file(_x));
23014 oldbucket.size = oldbucket.content.length;
23015 var sstref = parse_TSP_Reference(store[4][0].data);
23016 (function() {
23017 var sentry = CFB.find(cfb, dependents[sstref].location);
23018 var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
23019 var sstroot;
23020 for (var sxi = 0; sxi < sx.length; ++sxi) {
23021 var packet2 = sx[sxi];
23022 if (packet2.id == sstref)
23023 sstroot = packet2;
23024 }
23025 var sstdata = parse_shallow(sstroot.messages[0].data);
23026 {
23027 sstdata[3] = [];
23028 var newsst = [];
23029 SST.forEach(function(str, i) {
23030 newsst[1] = [{ type: 0, data: write_varint49(i) }];
23031 newsst[2] = [{ type: 0, data: write_varint49(1) }];
23032 newsst[3] = [{ type: 2, data: stru8(str) }];
23033 sstdata[3].push({ type: 2, data: write_shallow(newsst) });
23034 });
23035 }
23036 sstroot.messages[0].data = write_shallow(sstdata);
23037 var sy = write_iwa_file(sx);
23038 var raw32 = compress_iwa_file(sy);
23039 sentry.content = raw32;
23040 sentry.size = sentry.content.length;
23041 })();
23042 var tile = parse_shallow(store[3][0].data);
23043 {
23044 var t = tile[1][0];
23045 delete tile[2];
23046 var tl = parse_shallow(t.data);
23047 {
23048 var tileref = parse_TSP_Reference(tl[2][0].data);
23049 (function() {
23050 var tentry = CFB.find(cfb, dependents[tileref].location);
23051 var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
23052 var tileroot;
23053 for (var sxi = 0; sxi < tx.length; ++sxi) {
23054 var packet2 = tx[sxi];
23055 if (packet2.id == tileref)
23056 tileroot = packet2;
23057 }
23058 var tiledata = parse_shallow(tileroot.messages[0].data);
23059 {
23060 delete tiledata[6];
23061 delete tile[7];
23062 var rowload = new Uint8Array(tiledata[5][0].data);
23063 tiledata[5] = [];
23064 var cnt = 0;
23065 for (var R2 = 0; R2 <= range.e.r; ++R2) {
23066 var tilerow = parse_shallow(rowload);
23067 cnt += write_tile_row(tilerow, data[R2], SST);
23068 tilerow[1][0].data = write_varint49(R2);
23069 tiledata[5].push({ data: write_shallow(tilerow), type: 2 });
23070 }
23071 tiledata[1] = [{ type: 0, data: write_varint49(range.e.c + 1) }];
23072 tiledata[2] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
23073 tiledata[3] = [{ type: 0, data: write_varint49(cnt) }];
23074 tiledata[4] = [{ type: 0, data: write_varint49(range.e.r + 1) }];
23075 }
23076 tileroot.messages[0].data = write_shallow(tiledata);
23077 var ty = write_iwa_file(tx);
23078 var raw32 = compress_iwa_file(ty);
23079 tentry.content = raw32;
23080 tentry.size = tentry.content.length;
23081 })();
23082 }
23083 t.data = write_shallow(tl);
23084 }
23085 store[3][0].data = write_shallow(tile);
23086 }
23087 pb[4][0].data = write_shallow(store);
23088 }
23089 docroot.messages[0].data = write_shallow(pb);
23090 var y = write_iwa_file(x);
23091 var raw3 = compress_iwa_file(y);
23092 entry.content = raw3;
23093 entry.size = entry.content.length;
23094 return cfb;
23095}
23096function fix_opts_func(defaults/*:Array<Array<any> >*/)/*:{(o:any):void}*/ {
23097 return function fix_opts(opts) {
23098 for(var i = 0; i != defaults.length; ++i) {
23099 var d = defaults[i];
23100 if(opts[d[0]] === undefined) opts[d[0]] = d[1];
23101 if(d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
23102 }
23103 };
23104}
23105
23106function fix_read_opts(opts) {
23107fix_opts_func([
23108 ['cellNF', false], /* emit cell number format string as .z */
23109 ['cellHTML', true], /* emit html string as .h */
23110 ['cellFormula', true], /* emit formulae as .f */
23111 ['cellStyles', false], /* emits style/theme as .s */
23112 ['cellText', true], /* emit formatted text as .w */
23113 ['cellDates', false], /* emit date cells with type `d` */
23114
23115 ['sheetStubs', false], /* emit empty cells */
23116 ['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */
23117
23118 ['bookDeps', false], /* parse calculation chains */
23119 ['bookSheets', false], /* only try to get sheet names (no Sheets) */
23120 ['bookProps', false], /* only try to get properties (no Sheets) */
23121 ['bookFiles', false], /* include raw file structure (keys, files, cfb) */
23122 ['bookVBA', false], /* include vba raw data (vbaraw) */
23123
23124 ['password',''], /* password */
23125 ['WTF', false] /* WTF mode (throws errors) */
23126])(opts);
23127}
23128
23129function fix_write_opts(opts) {
23130fix_opts_func([
23131 ['cellDates', false], /* write date cells with type `d` */
23132
23133 ['bookSST', false], /* Generate Shared String Table */
23134
23135 ['bookType', 'xlsx'], /* Type of workbook (xlsx/m/b) */
23136
23137 ['compression', false], /* Use file compression */
23138
23139 ['WTF', false] /* WTF mode (throws errors) */
23140])(opts);
23141}
23142function get_sheet_type(n/*:string*/)/*:string*/ {
23143 if(RELS.WS.indexOf(n) > -1) return "sheet";
23144 if(RELS.CS && n == RELS.CS) return "chart";
23145 if(RELS.DS && n == RELS.DS) return "dialog";
23146 if(RELS.MS && n == RELS.MS) return "macro";
23147 return (n && n.length) ? n : "sheet";
23148}
23149function safe_parse_wbrels(wbrels, sheets) {
23150 if(!wbrels) return 0;
23151 try {
23152 wbrels = sheets.map(function pwbr(w) { if(!w.id) w.id = w.strRelID; return [w.name, wbrels['!id'][w.id].Target, get_sheet_type(wbrels['!id'][w.id].Type)]; });
23153 } catch(e) { return null; }
23154 return !wbrels || wbrels.length === 0 ? null : wbrels;
23155}
23156
23157function safe_parse_sheet(zip, path/*:string*/, relsPath/*:string*/, sheet, idx/*:number*/, sheetRels, sheets, stype/*:string*/, opts, wb, themes, styles) {
23158 try {
23159 sheetRels[sheet]=parse_rels(getzipstr(zip, relsPath, true), path);
23160 var data = getzipdata(zip, path);
23161 var _ws;
23162 switch(stype) {
23163 case 'sheet': _ws = parse_ws(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
23164 case 'chart': _ws = parse_cs(data, path, idx, opts, sheetRels[sheet], wb, themes, styles);
23165 if(!_ws || !_ws['!drawel']) break;
23166 var dfile = resolve_path(_ws['!drawel'].Target, path);
23167 var drelsp = get_rels_path(dfile);
23168 var draw = parse_drawing(getzipstr(zip, dfile, true), parse_rels(getzipstr(zip, drelsp, true), dfile));
23169 var chartp = resolve_path(draw, dfile);
23170 var crelsp = get_rels_path(chartp);
23171 _ws = parse_chart(getzipstr(zip, chartp, true), chartp, opts, parse_rels(getzipstr(zip, crelsp, true), chartp), wb, _ws);
23172 break;
23173 case 'macro': _ws = parse_ms(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
23174 case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
23175 default: throw new Error("Unrecognized sheet type " + stype);
23176 }
23177 sheets[sheet] = _ws;
23178
23179 /* scan rels for comments and threaded comments */
23180 var tcomments = [];
23181 if(sheetRels && sheetRels[sheet]) keys(sheetRels[sheet]).forEach(function(n) {
23182 var dfile = "";
23183 if(sheetRels[sheet][n].Type == RELS.CMNT) {
23184 dfile = resolve_path(sheetRels[sheet][n].Target, path);
23185 var comments = parse_cmnt(getzipdata(zip, dfile, true), dfile, opts);
23186 if(!comments || !comments.length) return;
23187 sheet_insert_comments(_ws, comments, false);
23188 }
23189 if(sheetRels[sheet][n].Type == RELS.TCMNT) {
23190 dfile = resolve_path(sheetRels[sheet][n].Target, path);
23191 tcomments = tcomments.concat(parse_tcmnt_xml(getzipdata(zip, dfile, true), opts));
23192 }
23193 });
23194 if(tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
23195 } catch(e) { if(opts.WTF) throw e; }
23196}
23197
23198function strip_front_slash(x/*:string*/)/*:string*/ { return x.charAt(0) == '/' ? x.slice(1) : x; }
23199
23200function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
23201 make_ssf();
23202 opts = opts || {};
23203 fix_read_opts(opts);
23204
23205 /* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
23206 if(safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
23207 /* UOC */
23208 if(safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
23209 /* Numbers */
23210 if(safegetzipfile(zip, 'Index/Document.iwa')) {
23211 if(typeof Uint8Array == "undefined") throw new Error('NUMBERS file parsing requires Uint8Array support');
23212 if(typeof parse_numbers_iwa != "undefined") {
23213 if(zip.FileIndex) return parse_numbers_iwa(zip);
23214 var _zip = CFB.utils.cfb_new();
23215 zipentries(zip).forEach(function(e) { zip_add_file(_zip, e, getzipbin(zip, e)); });
23216 return parse_numbers_iwa(_zip);
23217 }
23218 throw new Error('Unsupported NUMBERS file');
23219 }
23220 if(!safegetzipfile(zip, '[Content_Types].xml')) {
23221 if(safegetzipfile(zip, 'index.xml.gz')) throw new Error('Unsupported NUMBERS 08 file');
23222 if(safegetzipfile(zip, 'index.xml')) throw new Error('Unsupported NUMBERS 09 file');
23223 throw new Error('Unsupported ZIP file');
23224 }
23225
23226 var entries = zipentries(zip);
23227 var dir = parse_ct((getzipstr(zip, '[Content_Types].xml')/*:?any*/));
23228 var xlsb = false;
23229 var sheets, binname;
23230 if(dir.workbooks.length === 0) {
23231 binname = "xl/workbook.xml";
23232 if(getzipdata(zip,binname, true)) dir.workbooks.push(binname);
23233 }
23234 if(dir.workbooks.length === 0) {
23235 binname = "xl/workbook.bin";
23236 if(!getzipdata(zip,binname,true)) throw new Error("Could not find workbook");
23237 dir.workbooks.push(binname);
23238 xlsb = true;
23239 }
23240 if(dir.workbooks[0].slice(-3) == "bin") xlsb = true;
23241
23242 var themes = ({}/*:any*/);
23243 var styles = ({}/*:any*/);
23244 if(!opts.bookSheets && !opts.bookProps) {
23245 strs = [];
23246 if(dir.sst) try { strs=parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts); } catch(e) { if(opts.WTF) throw e; }
23247
23248 if(opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//,''), true)||"",dir.themes[0], opts);
23249
23250 if(dir.style) styles = parse_sty(getzipdata(zip, strip_front_slash(dir.style)), dir.style, themes, opts);
23251 }
23252
23253 /*var externbooks = */dir.links.map(function(link) {
23254 try {
23255 var rels = parse_rels(getzipstr(zip, get_rels_path(strip_front_slash(link))), link);
23256 return parse_xlink(getzipdata(zip, strip_front_slash(link)), rels, link, opts);
23257 } catch(e) {}
23258 });
23259
23260 var wb = parse_wb(getzipdata(zip, strip_front_slash(dir.workbooks[0])), dir.workbooks[0], opts);
23261
23262 var props = {}, propdata = "";
23263
23264 if(dir.coreprops.length) {
23265 propdata = getzipdata(zip, strip_front_slash(dir.coreprops[0]), true);
23266 if(propdata) props = parse_core_props(propdata);
23267 if(dir.extprops.length !== 0) {
23268 propdata = getzipdata(zip, strip_front_slash(dir.extprops[0]), true);
23269 if(propdata) parse_ext_props(propdata, props, opts);
23270 }
23271 }
23272
23273 var custprops = {};
23274 if(!opts.bookSheets || opts.bookProps) {
23275 if (dir.custprops.length !== 0) {
23276 propdata = getzipstr(zip, strip_front_slash(dir.custprops[0]), true);
23277 if(propdata) custprops = parse_cust_props(propdata, opts);
23278 }
23279 }
23280
23281 var out = ({}/*:any*/);
23282 if(opts.bookSheets || opts.bookProps) {
23283 if(wb.Sheets) sheets = wb.Sheets.map(function pluck(x){ return x.name; });
23284 else if(props.Worksheets && props.SheetNames.length > 0) sheets=props.SheetNames;
23285 if(opts.bookProps) { out.Props = props; out.Custprops = custprops; }
23286 if(opts.bookSheets && typeof sheets !== 'undefined') out.SheetNames = sheets;
23287 if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
23288 }
23289 sheets = {};
23290
23291 var deps = {};
23292 if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, strip_front_slash(dir.calcchain)),dir.calcchain,opts);
23293
23294 var i=0;
23295 var sheetRels = ({}/*:any*/);
23296 var path, relsPath;
23297
23298 {
23299 var wbsheets = wb.Sheets;
23300 props.Worksheets = wbsheets.length;
23301 props.SheetNames = [];
23302 for(var j = 0; j != wbsheets.length; ++j) {
23303 props.SheetNames[j] = wbsheets[j].name;
23304 }
23305 }
23306
23307 var wbext = xlsb ? "bin" : "xml";
23308 var wbrelsi = dir.workbooks[0].lastIndexOf("/");
23309 var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi+1) + "_rels/" + dir.workbooks[0].slice(wbrelsi+1) + ".rels").replace(/^\//,"");
23310 if(!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
23311 var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
23312
23313 if((dir.metadata || []).length >= 1) {
23314 /* TODO: MDX and other types of metadata */
23315 opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])),dir.metadata[0],opts);
23316 }
23317
23318 if((dir.people || []).length >= 1) {
23319 opts.people = parse_people_xml(getzipdata(zip, strip_front_slash(dir.people[0])),opts);
23320 }
23321
23322 if(wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);
23323
23324 /* Numbers iOS hack */
23325 var nmode = (getzipdata(zip,"xl/worksheets/sheet.xml",true))?1:0;
23326 wsloop: for(i = 0; i != props.Worksheets; ++i) {
23327 var stype = "sheet";
23328 if(wbrels && wbrels[i]) {
23329 path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
23330 if(!safegetzipfile(zip, path)) path = wbrels[i][1];
23331 if(!safegetzipfile(zip, path)) path = wbrelsfile.replace(/_rels\/.*$/,"") + wbrels[i][1];
23332 stype = wbrels[i][2];
23333 } else {
23334 path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext;
23335 path = path.replace(/sheet0\./,"sheet.");
23336 }
23337 relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
23338 if(opts && opts.sheets != null) switch(typeof opts.sheets) {
23339 case "number": if(i != opts.sheets) continue wsloop; break;
23340 case "string": if(props.SheetNames[i].toLowerCase() != opts.sheets.toLowerCase()) continue wsloop; break;
23341 default: if(Array.isArray && Array.isArray(opts.sheets)) {
23342 var snjseen = false;
23343 for(var snj = 0; snj != opts.sheets.length; ++snj) {
23344 if(typeof opts.sheets[snj] == "number" && opts.sheets[snj] == i) snjseen=1;
23345 if(typeof opts.sheets[snj] == "string" && opts.sheets[snj].toLowerCase() == props.SheetNames[i].toLowerCase()) snjseen = 1;
23346 }
23347 if(!snjseen) continue wsloop;
23348 }
23349 }
23350 safe_parse_sheet(zip, path, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles);
23351 }
23352
23353 out = ({
23354 Directory: dir,
23355 Workbook: wb,
23356 Props: props,
23357 Custprops: custprops,
23358 Deps: deps,
23359 Sheets: sheets,
23360 SheetNames: props.SheetNames,
23361 Strings: strs,
23362 Styles: styles,
23363 Themes: themes,
23364 SSF: dup(table_fmt)
23365 }/*:any*/);
23366 if(opts && opts.bookFiles) {
23367 if(zip.files) {
23368 out.keys = entries;
23369 out.files = zip.files;
23370 } else {
23371 out.keys = [];
23372 out.files = {};
23373 zip.FullPaths.forEach(function(p, idx) {
23374 p = p.replace(/^Root Entry[\/]/, "");
23375 out.keys.push(p);
23376 out.files[p] = zip.FileIndex[idx];
23377 });
23378 }
23379 }
23380 if(opts && opts.bookVBA) {
23381 if(dir.vba.length > 0) out.vbaraw = getzipdata(zip,strip_front_slash(dir.vba[0]),true);
23382 else if(dir.defaults && dir.defaults.bin === CT_VBA) out.vbaraw = getzipdata(zip, 'xl/vbaProject.bin',true);
23383 }
23384 return out;
23385}
23386
23387/* [MS-OFFCRYPTO] 2.1.1 */
23388function parse_xlsxcfb(cfb, _opts/*:?ParseOpts*/)/*:Workbook*/ {
23389 var opts = _opts || {};
23390 var f = 'Workbook', data = CFB.find(cfb, f);
23391 try {
23392 f = '/!DataSpaces/Version';
23393 data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
23394 /*var version = */parse_DataSpaceVersionInfo(data.content);
23395
23396 /* 2.3.4.1 */
23397 f = '/!DataSpaces/DataSpaceMap';
23398 data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
23399 var dsm = parse_DataSpaceMap(data.content);
23400 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")
23401 throw new Error("ECMA-376 Encrypted file bad " + f);
23402
23403 /* 2.3.4.2 */
23404 f = '/!DataSpaces/DataSpaceInfo/StrongEncryptionDataSpace';
23405 data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
23406 var seds = parse_DataSpaceDefinition(data.content);
23407 if(seds.length != 1 || seds[0] != "StrongEncryptionTransform")
23408 throw new Error("ECMA-376 Encrypted file bad " + f);
23409
23410 /* 2.3.4.3 */
23411 f = '/!DataSpaces/TransformInfo/StrongEncryptionTransform/!Primary';
23412 data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
23413 /*var hdr = */parse_Primary(data.content);
23414 } catch(e) {}
23415
23416 f = '/EncryptionInfo';
23417 data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
23418 var einfo = parse_EncryptionInfo(data.content);
23419
23420 /* 2.3.4.4 */
23421 f = '/EncryptedPackage';
23422 data = CFB.find(cfb, f); if(!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
23423
23424/*global decrypt_agile */
23425/*:: declare var decrypt_agile:any; */
23426 if(einfo[0] == 0x04 && typeof decrypt_agile !== 'undefined') return decrypt_agile(einfo[1], data.content, opts.password || "", opts);
23427/*global decrypt_std76 */
23428/*:: declare var decrypt_std76:any; */
23429 if(einfo[0] == 0x02 && typeof decrypt_std76 !== 'undefined') return decrypt_std76(einfo[1], data.content, opts.password || "", opts);
23430 throw new Error("File is password-protected");
23431}
23432
23433function write_zip(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
23434 if(opts.bookType == "ods") return write_ods(wb, opts);
23435 if(opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
23436 if(opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
23437 return write_zip_xlsx(wb, opts);
23438}
23439
23440/* XLSX and XLSB writing are very similar. Originally they were unified in one
23441 export function. This is horrible for tree shaking in the common case (most
23442 applications need to export files in one format) so this function supports
23443 both formats while write_zip_xlsx only handles XLSX */
23444function write_zip_xlsxb(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
23445 _shapeid = 1024;
23446 if(wb && !wb.SSF) {
23447 wb.SSF = dup(table_fmt);
23448 }
23449 if(wb && wb.SSF) {
23450 make_ssf(); SSF_load_table(wb.SSF);
23451 // $FlowIgnore
23452 opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
23453 opts.ssf = wb.SSF;
23454 }
23455 opts.rels = {}; opts.wbrels = {};
23456 opts.Strings = /*::((*/[]/*:: :any):SST)*/; opts.Strings.Count = 0; opts.Strings.Unique = 0;
23457 if(browser_has_Map) opts.revStrings = new Map();
23458 else { opts.revStrings = {}; opts.revStrings.foo = []; delete opts.revStrings.foo; }
23459 var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
23460 var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
23461 var ct = new_ct();
23462 fix_write_opts(opts = opts || {});
23463 var zip = zip_new();
23464 var f = "", rId = 0;
23465
23466 opts.cellXfs = [];
23467 get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
23468
23469 if(!wb.Props) wb.Props = {};
23470
23471 f = "docProps/core.xml";
23472 zip_add_file(zip, f, write_core_props(wb.Props, opts));
23473 ct.coreprops.push(f);
23474 add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
23475
23476 /*::if(!wb.Props) throw "unreachable"; */
23477 f = "docProps/app.xml";
23478 if(wb.Props && wb.Props.SheetNames){/* empty */}
23479 else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
23480 else {
23481 var _sn = [];
23482 for(var _i = 0; _i < wb.SheetNames.length; ++_i)
23483 if((wb.Workbook.Sheets[_i]||{}).Hidden != 2) _sn.push(wb.SheetNames[_i]);
23484 wb.Props.SheetNames = _sn;
23485 }
23486 wb.Props.Worksheets = wb.Props.SheetNames.length;
23487 zip_add_file(zip, f, write_ext_props(wb.Props, opts));
23488 ct.extprops.push(f);
23489 add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
23490
23491 if(wb.Custprops !== wb.Props && keys(wb.Custprops||{}).length > 0) {
23492 f = "docProps/custom.xml";
23493 zip_add_file(zip, f, write_cust_props(wb.Custprops, opts));
23494 ct.custprops.push(f);
23495 add_rels(opts.rels, 4, f, RELS.CUST_PROPS);
23496 }
23497
23498 for(rId=1;rId <= wb.SheetNames.length; ++rId) {
23499 var wsrels = {'!id':{}};
23500 var ws = wb.Sheets[wb.SheetNames[rId-1]];
23501 var _type = (ws || {})["!type"] || "sheet";
23502 switch(_type) {
23503 case "chart":
23504 /* falls through */
23505 default:
23506 f = "xl/worksheets/sheet" + rId + "." + wbext;
23507 zip_add_file(zip, f, write_ws(rId-1, f, opts, wb, wsrels));
23508 ct.sheets.push(f);
23509 add_rels(opts.wbrels, -1, "worksheets/sheet" + rId + "." + wbext, RELS.WS[0]);
23510 }
23511
23512 if(ws) {
23513 var comments = ws['!comments'];
23514 var need_vml = false;
23515 var cf = "";
23516 if(comments && comments.length > 0) {
23517 cf = "xl/comments" + rId + "." + wbext;
23518 zip_add_file(zip, cf, write_cmnt(comments, cf, opts));
23519 ct.comments.push(cf);
23520 add_rels(wsrels, -1, "../comments" + rId + "." + wbext, RELS.CMNT);
23521 need_vml = true;
23522 }
23523 if(ws['!legacy']) {
23524 if(need_vml) zip_add_file(zip, "xl/drawings/vmlDrawing" + (rId) + ".vml", write_comments_vml(rId, ws['!comments']));
23525 }
23526 delete ws['!comments'];
23527 delete ws['!legacy'];
23528 }
23529
23530 if(wsrels['!id'].rId1) zip_add_file(zip, get_rels_path(f), write_rels(wsrels));
23531 }
23532
23533 if(opts.Strings != null && opts.Strings.length > 0) {
23534 f = "xl/sharedStrings." + wbext;
23535 zip_add_file(zip, f, write_sst(opts.Strings, f, opts));
23536 ct.strs.push(f);
23537 add_rels(opts.wbrels, -1, "sharedStrings." + wbext, RELS.SST);
23538 }
23539
23540 f = "xl/workbook." + wbext;
23541 zip_add_file(zip, f, write_wb(wb, f, opts));
23542 ct.workbooks.push(f);
23543 add_rels(opts.rels, 1, f, RELS.WB);
23544
23545 /* TODO: something more intelligent with themes */
23546
23547 f = "xl/theme/theme1.xml";
23548 zip_add_file(zip, f, write_theme(wb.Themes, opts));
23549 ct.themes.push(f);
23550 add_rels(opts.wbrels, -1, "theme/theme1.xml", RELS.THEME);
23551
23552 /* TODO: something more intelligent with styles */
23553
23554 f = "xl/styles." + wbext;
23555 zip_add_file(zip, f, write_sty(wb, f, opts));
23556 ct.styles.push(f);
23557 add_rels(opts.wbrels, -1, "styles." + wbext, RELS.STY);
23558
23559 if(wb.vbaraw && vbafmt) {
23560 f = "xl/vbaProject.bin";
23561 zip_add_file(zip, f, wb.vbaraw);
23562 ct.vba.push(f);
23563 add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
23564 }
23565
23566 f = "xl/metadata." + wbext;
23567 zip_add_file(zip, f, write_xlmeta(f));
23568 ct.metadata.push(f);
23569 add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
23570
23571 zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
23572 zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
23573 zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
23574
23575 delete opts.revssf; delete opts.ssf;
23576 return zip;
23577}
23578
23579function write_zip_xlsx(wb/*:Workbook*/, opts/*:WriteOpts*/)/*:ZIP*/ {
23580 _shapeid = 1024;
23581 if(wb && !wb.SSF) {
23582 wb.SSF = dup(table_fmt);
23583 }
23584 if(wb && wb.SSF) {
23585 make_ssf(); SSF_load_table(wb.SSF);
23586 // $FlowIgnore
23587 opts.revssf = evert_num(wb.SSF); opts.revssf[wb.SSF[65535]] = 0;
23588 opts.ssf = wb.SSF;
23589 }
23590 opts.rels = {}; opts.wbrels = {};
23591 opts.Strings = /*::((*/[]/*:: :any):SST)*/; opts.Strings.Count = 0; opts.Strings.Unique = 0;
23592 if(browser_has_Map) opts.revStrings = new Map();
23593 else { opts.revStrings = {}; opts.revStrings.foo = []; delete opts.revStrings.foo; }
23594 var wbext = "xml";
23595 var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
23596 var ct = new_ct();
23597 fix_write_opts(opts = opts || {});
23598 var zip = zip_new();
23599 var f = "", rId = 0;
23600
23601 opts.cellXfs = [];
23602 get_cell_style(opts.cellXfs, {}, {revssf:{"General":0}});
23603
23604 if(!wb.Props) wb.Props = {};
23605
23606 f = "docProps/core.xml";
23607 zip_add_file(zip, f, write_core_props(wb.Props, opts));
23608 ct.coreprops.push(f);
23609 add_rels(opts.rels, 2, f, RELS.CORE_PROPS);
23610
23611 /*::if(!wb.Props) throw "unreachable"; */
23612 f = "docProps/app.xml";
23613 if(wb.Props && wb.Props.SheetNames){/* empty */}
23614 else if(!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;
23615 else {
23616 var _sn = [];
23617 for(var _i = 0; _i < wb.SheetNames.length; ++_i)
23618 if((wb.Workbook.Sheets[_i]||{}).Hidden != 2) _sn.push(wb.SheetNames[_i]);
23619 wb.Props.SheetNames = _sn;
23620 }
23621 wb.Props.Worksheets = wb.Props.SheetNames.length;
23622 zip_add_file(zip, f, write_ext_props(wb.Props, opts));
23623 ct.extprops.push(f);
23624 add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
23625
23626 if(wb.Custprops !== wb.Props && keys(wb.Custprops||{}).length > 0) {
23627 f = "docProps/custom.xml";
23628 zip_add_file(zip, f, write_cust_props(wb.Custprops, opts));
23629 ct.custprops.push(f);
23630 add_rels(opts.rels, 4, f, RELS.CUST_PROPS);
23631 }
23632
23633 var people = ["SheetJ5"];
23634 opts.tcid = 0;
23635
23636 for(rId=1;rId <= wb.SheetNames.length; ++rId) {
23637 var wsrels = {'!id':{}};
23638 var ws = wb.Sheets[wb.SheetNames[rId-1]];
23639 var _type = (ws || {})["!type"] || "sheet";
23640 switch(_type) {
23641 case "chart":
23642 /* falls through */
23643 default:
23644 f = "xl/worksheets/sheet" + rId + "." + wbext;
23645 zip_add_file(zip, f, write_ws_xml(rId-1, opts, wb, wsrels));
23646 ct.sheets.push(f);
23647 add_rels(opts.wbrels, -1, "worksheets/sheet" + rId + "." + wbext, RELS.WS[0]);
23648 }
23649
23650 if(ws) {
23651 var comments = ws['!comments'];
23652 var need_vml = false;
23653 var cf = "";
23654 if(comments && comments.length > 0) {
23655 var needtc = false;
23656 comments.forEach(function(carr) {
23657 carr[1].forEach(function(c) { if(c.T == true) needtc = true; });
23658 });
23659 if(needtc) {
23660 cf = "xl/threadedComments/threadedComment" + rId + "." + wbext;
23661 zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
23662 ct.threadedcomments.push(cf);
23663 add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + "." + wbext, RELS.TCMNT);
23664 }
23665
23666 cf = "xl/comments" + rId + "." + wbext;
23667 zip_add_file(zip, cf, write_comments_xml(comments, opts));
23668 ct.comments.push(cf);
23669 add_rels(wsrels, -1, "../comments" + rId + "." + wbext, RELS.CMNT);
23670 need_vml = true;
23671 }
23672 if(ws['!legacy']) {
23673 if(need_vml) zip_add_file(zip, "xl/drawings/vmlDrawing" + (rId) + ".vml", write_comments_vml(rId, ws['!comments']));
23674 }
23675 delete ws['!comments'];
23676 delete ws['!legacy'];
23677 }
23678
23679 if(wsrels['!id'].rId1) zip_add_file(zip, get_rels_path(f), write_rels(wsrels));
23680 }
23681
23682 if(opts.Strings != null && opts.Strings.length > 0) {
23683 f = "xl/sharedStrings." + wbext;
23684 zip_add_file(zip, f, write_sst_xml(opts.Strings, opts));
23685 ct.strs.push(f);
23686 add_rels(opts.wbrels, -1, "sharedStrings." + wbext, RELS.SST);
23687 }
23688
23689 f = "xl/workbook." + wbext;
23690 zip_add_file(zip, f, write_wb_xml(wb, opts));
23691 ct.workbooks.push(f);
23692 add_rels(opts.rels, 1, f, RELS.WB);
23693
23694 /* TODO: something more intelligent with themes */
23695
23696 f = "xl/theme/theme1.xml";
23697 zip_add_file(zip, f, write_theme(wb.Themes, opts));
23698 ct.themes.push(f);
23699 add_rels(opts.wbrels, -1, "theme/theme1.xml", RELS.THEME);
23700
23701 /* TODO: something more intelligent with styles */
23702
23703 f = "xl/styles." + wbext;
23704 zip_add_file(zip, f, write_sty_xml(wb, opts));
23705 ct.styles.push(f);
23706 add_rels(opts.wbrels, -1, "styles." + wbext, RELS.STY);
23707
23708 if(wb.vbaraw && vbafmt) {
23709 f = "xl/vbaProject.bin";
23710 zip_add_file(zip, f, wb.vbaraw);
23711 ct.vba.push(f);
23712 add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
23713 }
23714
23715 f = "xl/metadata." + wbext;
23716 zip_add_file(zip, f, write_xlmeta_xml());
23717 ct.metadata.push(f);
23718 add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
23719
23720 if(people.length > 1) {
23721 f = "xl/persons/person.xml";
23722 zip_add_file(zip, f, write_people_xml(people, opts));
23723 ct.people.push(f);
23724 add_rels(opts.wbrels, -1, "persons/person.xml", RELS.PEOPLE);
23725 }
23726
23727 zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
23728 zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
23729 zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
23730
23731 delete opts.revssf; delete opts.ssf;
23732 return zip;
23733}
23734
23735function firstbyte(f/*:RawData*/,o/*:?TypeOpts*/)/*:Array<number>*/ {
23736 var x = "";
23737 switch((o||{}).type || "base64") {
23738 case 'buffer': return [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]];
23739 case 'base64': x = Base64_decode(f.slice(0,12)); break;
23740 case 'binary': x = f; break;
23741 case 'array': return [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]];
23742 default: throw new Error("Unrecognized type " + (o && o.type || "undefined"));
23743 }
23744 return [x.charCodeAt(0), x.charCodeAt(1), x.charCodeAt(2), x.charCodeAt(3), x.charCodeAt(4), x.charCodeAt(5), x.charCodeAt(6), x.charCodeAt(7)];
23745}
23746
23747function read_cfb(cfb/*:CFBContainer*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
23748 if(CFB.find(cfb, "EncryptedPackage")) return parse_xlsxcfb(cfb, opts);
23749 return parse_xlscfb(cfb, opts);
23750}
23751
23752function read_zip(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
23753 var zip, d = data;
23754 var o = opts||{};
23755 if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
23756 zip = zip_read(d, o);
23757 return parse_zip(zip, o);
23758}
23759
23760function read_plaintext(data/*:string*/, o/*:ParseOpts*/)/*:Workbook*/ {
23761 var i = 0;
23762 main: while(i < data.length) switch(data.charCodeAt(i)) {
23763 case 0x0A: case 0x0D: case 0x20: ++i; break;
23764 case 0x3C: return parse_xlml(data.slice(i),o);
23765 default: break main;
23766 }
23767 return PRN.to_workbook(data, o);
23768}
23769
23770function read_plaintext_raw(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ {
23771 var str = "", bytes = firstbyte(data, o);
23772 switch(o.type) {
23773 case 'base64': str = Base64_decode(data); break;
23774 case 'binary': str = data; break;
23775 case 'buffer': str = data.toString('binary'); break;
23776 case 'array': str = cc2str(data); break;
23777 default: throw new Error("Unrecognized type " + o.type);
23778 }
23779 if(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
23780 o.type = "binary";
23781 return read_plaintext(str, o);
23782}
23783
23784function read_utf16(data/*:RawData*/, o/*:ParseOpts*/)/*:Workbook*/ {
23785 var d = data;
23786 if(o.type == 'base64') d = Base64_decode(d);
23787 d = $cptable.utils.decode(1200, d.slice(2), 'str');
23788 o.type = "binary";
23789 return read_plaintext(d, o);
23790}
23791
23792function bstrify(data/*:string*/)/*:string*/ {
23793 return !data.match(/[^\x00-\x7F]/) ? data : utf8write(data);
23794}
23795
23796function read_prn(data, d, o, str) {
23797 if(str) { o.type = "string"; return PRN.to_workbook(data, o); }
23798 return PRN.to_workbook(d, o);
23799}
23800
23801function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
23802 reset_cp();
23803 var o = opts||{};
23804 if(typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
23805 if(typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && !o.type) o.type = typeof Deno !== "undefined" ? "buffer" : "array";
23806 var d = data, n = [0,0,0,0], str = false;
23807 if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
23808 _ssfopts = {};
23809 if(o.dateNF) _ssfopts.dateNF = o.dateNF;
23810 if(!o.type) o.type = (has_buf && Buffer.isBuffer(data)) ? "buffer" : "base64";
23811 if(o.type == "file") { o.type = has_buf ? "buffer" : "binary"; d = read_binary(data); if(typeof Uint8Array !== 'undefined' && !has_buf) o.type = "array"; }
23812 if(o.type == "string") { str = true; o.type = "binary"; o.codepage = 65001; d = bstrify(data); }
23813 if(o.type == 'array' && typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && typeof ArrayBuffer !== 'undefined') {
23814 // $FlowIgnore
23815 var ab=new ArrayBuffer(3), vu=new Uint8Array(ab); vu.foo="bar";
23816 // $FlowIgnore
23817 if(!vu.foo) {o=dup(o); o.type='array'; return readSync(ab2a(d), o);}
23818 }
23819 switch((n = firstbyte(d, o))[0]) {
23820 case 0xD0: if(n[1] === 0xCF && n[2] === 0x11 && n[3] === 0xE0 && n[4] === 0xA1 && n[5] === 0xB1 && n[6] === 0x1A && n[7] === 0xE1) return read_cfb(CFB.read(d, o), o); break;
23821 case 0x09: if(n[1] <= 0x08) return parse_xlscfb(d, o); break;
23822 case 0x3C: return parse_xlml(d, o);
23823 case 0x49:
23824 if(n[1] === 0x49 && n[2] === 0x2a && n[3] === 0x00) throw new Error("TIFF Image File is not a spreadsheet");
23825 if(n[1] === 0x44) return read_wb_ID(d, o);
23826 break;
23827 case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break;
23828 case 0x50: return (n[1] === 0x4B && n[2] < 0x09 && n[3] < 0x09) ? read_zip(d, o) : read_prn(data, d, o, str);
23829 case 0xEF: return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
23830 case 0xFF:
23831 if(n[1] === 0xFE) { return read_utf16(d, o); }
23832 else if(n[1] === 0x00 && n[2] === 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o);
23833 break;
23834 case 0x00:
23835 if(n[1] === 0x00) {
23836 if(n[2] >= 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o);
23837 if(n[2] === 0x00 && (n[3] === 0x08 || n[3] === 0x09)) return WK_.to_workbook(d, o);
23838 }
23839 break;
23840 case 0x03: case 0x83: case 0x8B: case 0x8C: return DBF.to_workbook(d, o);
23841 case 0x7B: if(n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o); break;
23842 case 0x0A: case 0x0D: case 0x20: return read_plaintext_raw(d, o);
23843 case 0x89: if(n[1] === 0x50 && n[2] === 0x4E && n[3] === 0x47) throw new Error("PNG Image File is not a spreadsheet"); break;
23844 }
23845 if(DBF_SUPPORTED_VERSIONS.indexOf(n[0]) > -1 && n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
23846 return read_prn(data, d, o, str);
23847}
23848
23849function readFileSync(filename/*:string*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
23850 var o = opts||{}; o.type = 'file';
23851 return readSync(filename, o);
23852}
23853function write_cfb_ctr(cfb/*:CFBContainer*/, o/*:WriteOpts*/)/*:any*/ {
23854 switch(o.type) {
23855 case "base64": case "binary": break;
23856 case "buffer": case "array": o.type = ""; break;
23857 case "file": return write_dl(o.file, CFB.write(cfb, {type:has_buf ? 'buffer' : ""}));
23858 case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
23859 default: throw new Error("Unrecognized type " + o.type);
23860 }
23861 return CFB.write(cfb, o);
23862}
23863
23864/*:: declare var encrypt_agile:any; */
23865function write_zip_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
23866 var o = dup(opts||{});
23867 var z = write_zip(wb, o);
23868 return write_zip_denouement(z, o);
23869}
23870function write_zip_typeXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
23871 var o = dup(opts||{});
23872 var z = write_zip_xlsx(wb, o);
23873 return write_zip_denouement(z, o);
23874}
23875function write_zip_denouement(z/*:any*/, o/*:?WriteOpts*/)/*:any*/ {
23876 var oopts = {};
23877 var ftype = has_buf ? "nodebuffer" : (typeof Uint8Array !== "undefined" ? "array" : "string");
23878 if(o.compression) oopts.compression = 'DEFLATE';
23879 if(o.password) oopts.type = ftype;
23880 else switch(o.type) {
23881 case "base64": oopts.type = "base64"; break;
23882 case "binary": oopts.type = "string"; break;
23883 case "string": throw new Error("'string' output type invalid for '" + o.bookType + "' files");
23884 case "buffer":
23885 case "file": oopts.type = ftype; break;
23886 default: throw new Error("Unrecognized type " + o.type);
23887 }
23888 var out = z.FullPaths ? CFB.write(z, {fileType:"zip", type: /*::(*/{"nodebuffer": "buffer", "string": "binary"}/*:: :any)*/[oopts.type] || oopts.type, compression: !!o.compression}) : z.generate(oopts);
23889 if(typeof Deno !== "undefined") {
23890 if(typeof out == "string") {
23891 if(o.type == "binary" || o.type == "base64") return out;
23892 out = new Uint8Array(s2ab(out));
23893 }
23894 }
23895/*jshint -W083 */
23896 if(o.password && typeof encrypt_agile !== 'undefined') return write_cfb_ctr(encrypt_agile(out, o.password), o); // eslint-disable-line no-undef
23897/*jshint +W083 */
23898 if(o.type === "file") return write_dl(o.file, out);
23899 return o.type == "string" ? utf8read(/*::(*/out/*:: :any)*/) : out;
23900}
23901
23902function write_cfb_type(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:any*/ {
23903 var o = opts||{};
23904 var cfb/*:CFBContainer*/ = write_xlscfb(wb, o);
23905 return write_cfb_ctr(cfb, o);
23906}
23907
23908function write_string_type(out/*:string*/, opts/*:WriteOpts*/, bom/*:?string*/)/*:any*/ {
23909 if(!bom) bom = "";
23910 var o = bom + out;
23911 switch(opts.type) {
23912 case "base64": return Base64_encode(utf8write(o));
23913 case "binary": return utf8write(o);
23914 case "string": return out;
23915 case "file": return write_dl(opts.file, o, 'utf8');
23916 case "buffer": {
23917 if(has_buf) return Buffer_from(o, 'utf8');
23918 else if(typeof TextEncoder !== "undefined") return new TextEncoder().encode(o);
23919 else return write_string_type(o, {type:'binary'}).split("").map(function(c) { return c.charCodeAt(0); });
23920 }
23921 }
23922 throw new Error("Unrecognized type " + opts.type);
23923}
23924
23925function write_stxt_type(out/*:string*/, opts/*:WriteOpts*/)/*:any*/ {
23926 switch(opts.type) {
23927 case "base64": return Base64_encode(out);
23928 case "binary": return out;
23929 case "string": return out; /* override in sheet_to_txt */
23930 case "file": return write_dl(opts.file, out, 'binary');
23931 case "buffer": {
23932 if(has_buf) return Buffer_from(out, 'binary');
23933 else return out.split("").map(function(c) { return c.charCodeAt(0); });
23934 }
23935 }
23936 throw new Error("Unrecognized type " + opts.type);
23937}
23938
23939/* TODO: test consistency */
23940function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ {
23941 switch(opts.type) {
23942 case "string":
23943 case "base64":
23944 case "binary":
23945 var bstr = "";
23946 // $FlowIgnore
23947 for(var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
23948 return opts.type == 'base64' ? Base64_encode(bstr) : opts.type == 'string' ? utf8read(bstr) : bstr;
23949 case "file": return write_dl(opts.file, out);
23950 case "buffer": return out;
23951 default: throw new Error("Unrecognized type " + opts.type);
23952 }
23953}
23954
23955function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
23956 reset_cp();
23957 check_wb(wb);
23958 var o = dup(opts||{});
23959 if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
23960 if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSyncXLSX(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
23961 return write_zip_typeXLSX(wb, o);
23962}
23963
23964function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) {
23965 reset_cp();
23966 check_wb(wb);
23967 var o = dup(opts||{});
23968 if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; }
23969 if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSync(wb, o)/*:any*/); o.type = "array"; return s2ab(out); }
23970 var idx = 0;
23971 if(o.sheet) {
23972 if(typeof o.sheet == "number") idx = o.sheet;
23973 else idx = wb.SheetNames.indexOf(o.sheet);
23974 if(!wb.SheetNames[idx]) throw new Error("Sheet not found: " + o.sheet + " : " + (typeof o.sheet));
23975 }
23976 switch(o.bookType || 'xlsb') {
23977 case 'xml':
23978 case 'xlml': return write_string_type(write_xlml(wb, o), o);
23979 case 'slk':
23980 case 'sylk': return write_string_type(SYLK.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
23981 case 'htm':
23982 case 'html': return write_string_type(sheet_to_html(wb.Sheets[wb.SheetNames[idx]], o), o);
23983 case 'txt': return write_stxt_type(sheet_to_txt(wb.Sheets[wb.SheetNames[idx]], o), o);
23984 case 'csv': return write_string_type(sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o), o, "\ufeff");
23985 case 'dif': return write_string_type(DIF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
23986 case 'dbf': return write_binary_type(DBF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
23987 case 'prn': return write_string_type(PRN.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
23988 case 'rtf': return write_string_type(RTF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
23989 case 'eth': return write_string_type(ETH.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
23990 case 'fods': return write_string_type(write_ods(wb, o), o);
23991 case 'wk1': return write_binary_type(WK_.sheet_to_wk1(wb.Sheets[wb.SheetNames[idx]], o), o);
23992 case 'wk3': return write_binary_type(WK_.book_to_wk3(wb, o), o);
23993 case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
23994 case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
23995 case 'biff4': if(!o.biff) o.biff = 4; return write_binary_type(write_biff_buf(wb, o), o);
23996 case 'biff5': if(!o.biff) o.biff = 5; /* falls through */
23997 case 'biff8':
23998 case 'xla':
23999 case 'xls': if(!o.biff) o.biff = 8; return write_cfb_type(wb, o);
24000 case 'xlsx':
24001 case 'xlsm':
24002 case 'xlam':
24003 case 'xlsb':
24004 case 'numbers':
24005 case 'ods': return write_zip_type(wb, o);
24006 default: throw new Error ("Unrecognized bookType |" + o.bookType + "|");
24007 }
24008}
24009
24010function resolve_book_type(o/*:WriteFileOpts*/) {
24011 if(o.bookType) return;
24012 var _BT = {
24013 "xls": "biff8",
24014 "htm": "html",
24015 "slk": "sylk",
24016 "socialcalc": "eth",
24017 "Sh33tJS": "WTF"
24018 };
24019 var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();
24020 if(ext.match(/^\.[a-z]+$/)) o.bookType = ext.slice(1);
24021 o.bookType = _BT[o.bookType] || o.bookType;
24022}
24023
24024function writeFileSync(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOpts*/) {
24025 var o = opts||{}; o.type = 'file';
24026 o.file = filename;
24027 resolve_book_type(o);
24028 return writeSync(wb, o);
24029}
24030
24031function writeFileSyncXLSX(wb/*:Workbook*/, filename/*:string*/, opts/*:?WriteFileOpts*/) {
24032 var o = opts||{}; o.type = 'file';
24033 o.file = filename;
24034 resolve_book_type(o);
24035 return writeSyncXLSX(wb, o);
24036}
24037
24038
24039function writeFileAsync(filename/*:string*/, wb/*:Workbook*/, opts/*:?WriteFileOpts*/, cb/*:?(e?:ErrnoError)=>void*/) {
24040 var o = opts||{}; o.type = 'file';
24041 o.file = filename;
24042 resolve_book_type(o);
24043 o.type = 'buffer';
24044 var _cb = cb; if(!(_cb instanceof Function)) _cb = (opts/*:any*/);
24045 return _fs.writeFile(filename, writeSync(wb, o), _cb);
24046}
24047/*::
24048type MJRObject = {
24049 row: any;
24050 isempty: boolean;
24051};
24052*/
24053function make_json_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, header/*:number*/, hdr/*:Array<any>*/, dense/*:boolean*/, o/*:Sheet2JSONOpts*/)/*:MJRObject*/ {
24054 var rr = encode_row(R);
24055 var defval = o.defval, raw = o.raw || !Object.prototype.hasOwnProperty.call(o, "raw");
24056 var isempty = true;
24057 var row/*:any*/ = (header === 1) ? [] : {};
24058 if(header !== 1) {
24059 if(Object.defineProperty) try { Object.defineProperty(row, '__rowNum__', {value:R, enumerable:false}); } catch(e) { row.__rowNum__ = R; }
24060 else row.__rowNum__ = R;
24061 }
24062 if(!dense || sheet[R]) for (var C = r.s.c; C <= r.e.c; ++C) {
24063 var val = dense ? sheet[R][C] : sheet[cols[C] + rr];
24064 if(val === undefined || val.t === undefined) {
24065 if(defval === undefined) continue;
24066 if(hdr[C] != null) { row[hdr[C]] = defval; }
24067 continue;
24068 }
24069 var v = val.v;
24070 switch(val.t){
24071 case 'z': if(v == null) break; continue;
24072 case 'e': v = (v == 0 ? null : void 0); break;
24073 case 's': case 'd': case 'b': case 'n': break;
24074 default: throw new Error('unrecognized type ' + val.t);
24075 }
24076 if(hdr[C] != null) {
24077 if(v == null) {
24078 if(val.t == "e" && v === null) row[hdr[C]] = null;
24079 else if(defval !== undefined) row[hdr[C]] = defval;
24080 else if(raw && v === null) row[hdr[C]] = null;
24081 else continue;
24082 } else {
24083 row[hdr[C]] = raw && (val.t !== "n" || (val.t === "n" && o.rawNumbers !== false)) ? v : format_cell(val,v,o);
24084 }
24085 if(v != null) isempty = false;
24086 }
24087 }
24088 return { row: row, isempty: isempty };
24089}
24090
24091
24092function sheet_to_json(sheet/*:Worksheet*/, opts/*:?Sheet2JSONOpts*/) {
24093 if(sheet == null || sheet["!ref"] == null) return [];
24094 var val = {t:'n',v:0}, header = 0, offset = 1, hdr/*:Array<any>*/ = [], v=0, vv="";
24095 var r = {s:{r:0,c:0},e:{r:0,c:0}};
24096 var o = opts || {};
24097 var range = o.range != null ? o.range : sheet["!ref"];
24098 if(o.header === 1) header = 1;
24099 else if(o.header === "A") header = 2;
24100 else if(Array.isArray(o.header)) header = 3;
24101 else if(o.header == null) header = 0;
24102 switch(typeof range) {
24103 case 'string': r = safe_decode_range(range); break;
24104 case 'number': r = safe_decode_range(sheet["!ref"]); r.s.r = range; break;
24105 default: r = range;
24106 }
24107 if(header > 0) offset = 0;
24108 var rr = encode_row(r.s.r);
24109 var cols/*:Array<string>*/ = [];
24110 var out/*:Array<any>*/ = [];
24111 var outi = 0, counter = 0;
24112 var dense = Array.isArray(sheet);
24113 var R = r.s.r, C = 0;
24114 var header_cnt = {};
24115 if(dense && !sheet[R]) sheet[R] = [];
24116 var colinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
24117 var rowinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!rows"] || [];
24118 for(C = r.s.c; C <= r.e.c; ++C) {
24119 if(((colinfo[C]||{}).hidden)) continue;
24120 cols[C] = encode_col(C);
24121 val = dense ? sheet[R][C] : sheet[cols[C] + rr];
24122 switch(header) {
24123 case 1: hdr[C] = C - r.s.c; break;
24124 case 2: hdr[C] = cols[C]; break;
24125 case 3: hdr[C] = o.header[C - r.s.c]; break;
24126 default:
24127 if(val == null) val = {w: "__EMPTY", t: "s"};
24128 vv = v = format_cell(val, null, o);
24129 counter = header_cnt[v] || 0;
24130 if(!counter) header_cnt[v] = 1;
24131 else {
24132 do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter;
24133 header_cnt[vv] = 1;
24134 }
24135 hdr[C] = vv;
24136 }
24137 }
24138 for (R = r.s.r + offset; R <= r.e.r; ++R) {
24139 if ((rowinfo[R]||{}).hidden) continue;
24140 var row = make_json_row(sheet, r, R, cols, header, hdr, dense, o);
24141 if((row.isempty === false) || (header === 1 ? o.blankrows !== false : !!o.blankrows)) out[outi++] = row.row;
24142 }
24143 out.length = outi;
24144 return out;
24145}
24146
24147var qreg = /"/g;
24148function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Array<string>*/, fs/*:number*/, rs/*:number*/, FS/*:string*/, o/*:Sheet2CSVOpts*/)/*:?string*/ {
24149 var isempty = true;
24150 var row/*:Array<string>*/ = [], txt = "", rr = encode_row(R);
24151 for(var C = r.s.c; C <= r.e.c; ++C) {
24152 if (!cols[C]) continue;
24153 var val = o.dense ? (sheet[R]||[])[C]: sheet[cols[C] + rr];
24154 if(val == null) txt = "";
24155 else if(val.v != null) {
24156 isempty = false;
24157 txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
24158 for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; }
24159 if(txt == "ID") txt = '"ID"';
24160 } else if(val.f != null && !val.F) {
24161 isempty = false;
24162 txt = '=' + val.f; if(txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
24163 } else txt = "";
24164 /* NOTE: Excel CSV does not support array formulae */
24165 row.push(txt);
24166 }
24167 if(o.blankrows === false && isempty) return null;
24168 return row.join(FS);
24169}
24170
24171function sheet_to_csv(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/)/*:string*/ {
24172 var out/*:Array<string>*/ = [];
24173 var o = opts == null ? {} : opts;
24174 if(sheet == null || sheet["!ref"] == null) return "";
24175 var r = safe_decode_range(sheet["!ref"]);
24176 var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0);
24177 var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0);
24178 var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
24179 var row = "", cols/*:Array<string>*/ = [];
24180 o.dense = Array.isArray(sheet);
24181 var colinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
24182 var rowinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!rows"] || [];
24183 for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
24184 var w = 0;
24185 for(var R = r.s.r; R <= r.e.r; ++R) {
24186 if ((rowinfo[R]||{}).hidden) continue;
24187 row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
24188 if(row == null) { continue; }
24189 if(o.strip) row = row.replace(endregex,"");
24190 if(row || (o.blankrows !== false)) out.push((w++ ? RS : "") + row);
24191 }
24192 delete o.dense;
24193 return out.join("");
24194}
24195
24196function sheet_to_txt(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
24197 if(!opts) opts = {}; opts.FS = "\t"; opts.RS = "\n";
24198 var s = sheet_to_csv(sheet, opts);
24199 if(typeof $cptable == 'undefined' || opts.type == 'string') return s;
24200 var o = $cptable.utils.encode(1200, s, 'str');
24201 return String.fromCharCode(255) + String.fromCharCode(254) + o;
24202}
24203
24204function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
24205 var y = "", x, val="";
24206 if(sheet == null || sheet["!ref"] == null) return [];
24207 var r = safe_decode_range(sheet['!ref']), rr = "", cols/*:Array<string>*/ = [], C;
24208 var cmds/*:Array<string>*/ = [];
24209 var dense = Array.isArray(sheet);
24210 for(C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
24211 for(var R = r.s.r; R <= r.e.r; ++R) {
24212 rr = encode_row(R);
24213 for(C = r.s.c; C <= r.e.c; ++C) {
24214 y = cols[C] + rr;
24215 x = dense ? (sheet[R]||[])[C] : sheet[y];
24216 val = "";
24217 if(x === undefined) continue;
24218 else if(x.F != null) {
24219 y = x.F;
24220 if(!x.f) continue;
24221 val = x.f;
24222 if(y.indexOf(":") == -1) y = y + ":" + y;
24223 }
24224 if(x.f != null) val = x.f;
24225 else if(x.t == 'z') continue;
24226 else if(x.t == 'n' && x.v != null) val = "" + x.v;
24227 else if(x.t == 'b') val = x.v ? "TRUE" : "FALSE";
24228 else if(x.w !== undefined) val = "'" + x.w;
24229 else if(x.v === undefined) continue;
24230 else if(x.t == 's') val = "'" + x.v;
24231 else val = ""+x.v;
24232 cmds[cmds.length] = y + "=" + val;
24233 }
24234 }
24235 return cmds;
24236}
24237
24238function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet*/ {
24239 var o = opts || {};
24240 var offset = +!o.skipHeader;
24241 var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
24242 var _R = 0, _C = 0;
24243 if(ws && o.origin != null) {
24244 if(typeof o.origin == 'number') _R = o.origin;
24245 else {
24246 var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
24247 _R = _origin.r; _C = _origin.c;
24248 }
24249 }
24250 var cell/*:Cell*/;
24251 var range/*:Range*/ = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}}/*:any*/);
24252 if(ws['!ref']) {
24253 var _range = safe_decode_range(ws['!ref']);
24254 range.e.c = Math.max(range.e.c, _range.e.c);
24255 range.e.r = Math.max(range.e.r, _range.e.r);
24256 if(_R == -1) { _R = _range.e.r + 1; range.e.r = _R + js.length - 1 + offset; }
24257 } else {
24258 if(_R == -1) { _R = 0; range.e.r = js.length - 1 + offset; }
24259 }
24260 var hdr/*:Array<string>*/ = o.header || [], C = 0;
24261
24262 js.forEach(function (JS, R/*:number*/) {
24263 keys(JS).forEach(function(k) {
24264 if((C=hdr.indexOf(k)) == -1) hdr[C=hdr.length] = k;
24265 var v = JS[k];
24266 var t = 'z';
24267 var z = "";
24268 var ref = encode_cell({c:_C + C,r:_R + R + offset});
24269 cell = ws_get_cell_stub(ws, ref);
24270 if(v && typeof v === 'object' && !(v instanceof Date)){
24271 ws[ref] = v;
24272 } else {
24273 if(typeof v == 'number') t = 'n';
24274 else if(typeof v == 'boolean') t = 'b';
24275 else if(typeof v == 'string') t = 's';
24276 else if(v instanceof Date) {
24277 t = 'd';
24278 if(!o.cellDates) { t = 'n'; v = datenum(v); }
24279 z = (o.dateNF || table_fmt[14]);
24280 }
24281 else if(v === null && o.nullError) { t = 'e'; v = 0; }
24282 if(!cell) ws[ref] = cell = ({t:t, v:v}/*:any*/);
24283 else {
24284 cell.t = t; cell.v = v;
24285 delete cell.w; delete cell.R;
24286 if(z) cell.z = z;
24287 }
24288 if(z) cell.z = z;
24289 }
24290 });
24291 });
24292 range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
24293 var __R = encode_row(_R);
24294 if(offset) for(C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
24295 ws['!ref'] = encode_range(range);
24296 return ws;
24297}
24298function json_to_sheet(js/*:Array<any>*/, opts)/*:Worksheet*/ { return sheet_add_json(null, js, opts); }
24299
24300/* get cell, creating a stub if necessary */
24301function ws_get_cell_stub(ws/*:Worksheet*/, R, C/*:?number*/)/*:Cell*/ {
24302 /* A1 cell address */
24303 if(typeof R == "string") {
24304 /* dense */
24305 if(Array.isArray(ws)) {
24306 var RC = decode_cell(R);
24307 if(!ws[RC.r]) ws[RC.r] = [];
24308 return ws[RC.r][RC.c] || (ws[RC.r][RC.c] = {t:'z'});
24309 }
24310 return ws[R] || (ws[R] = {t:'z'});
24311 }
24312 /* cell address object */
24313 if(typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
24314 /* R and C are 0-based indices */
24315 return ws_get_cell_stub(ws, encode_cell({r:R,c:C||0}));
24316}
24317
24318/* find sheet index for given name / validate index */
24319function wb_sheet_idx(wb/*:Workbook*/, sh/*:number|string*/) {
24320 if(typeof sh == "number") {
24321 if(sh >= 0 && wb.SheetNames.length > sh) return sh;
24322 throw new Error("Cannot find sheet # " + sh);
24323 } else if(typeof sh == "string") {
24324 var idx = wb.SheetNames.indexOf(sh);
24325 if(idx > -1) return idx;
24326 throw new Error("Cannot find sheet name |" + sh + "|");
24327 } else throw new Error("Cannot find sheet |" + sh + "|");
24328}
24329
24330/* simple blank workbook object */
24331function book_new()/*:Workbook*/ {
24332 return { SheetNames: [], Sheets: {} };
24333}
24334
24335/* add a worksheet to the end of a given workbook */
24336function book_append_sheet(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/, roll/*:?boolean*/)/*:string*/ {
24337 var i = 1;
24338 if(!name) for(; i <= 0xFFFF; ++i, name = undefined) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break;
24339 if(!name || wb.SheetNames.length >= 0xFFFF) throw new Error("Too many worksheets");
24340 if(roll && wb.SheetNames.indexOf(name) >= 0) {
24341 var m = name.match(/(^.*?)(\d+)$/);
24342 i = m && +m[2] || 0;
24343 var root = m && m[1] || name;
24344 for(++i; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = root + i) == -1) break;
24345 }
24346 check_ws_name(name);
24347 if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
24348
24349 wb.SheetNames.push(name);
24350 wb.Sheets[name] = ws;
24351 return name;
24352}
24353
24354/* set sheet visibility (visible/hidden/very hidden) */
24355function book_set_sheet_visibility(wb/*:Workbook*/, sh/*:number|string*/, vis/*:number*/) {
24356 if(!wb.Workbook) wb.Workbook = {};
24357 if(!wb.Workbook.Sheets) wb.Workbook.Sheets = [];
24358
24359 var idx = wb_sheet_idx(wb, sh);
24360 // $FlowIgnore
24361 if(!wb.Workbook.Sheets[idx]) wb.Workbook.Sheets[idx] = {};
24362
24363 switch(vis) {
24364 case 0: case 1: case 2: break;
24365 default: throw new Error("Bad sheet visibility setting " + vis);
24366 }
24367 // $FlowIgnore
24368 wb.Workbook.Sheets[idx].Hidden = vis;
24369}
24370
24371/* set number format */
24372function cell_set_number_format(cell/*:Cell*/, fmt/*:string|number*/) {
24373 cell.z = fmt;
24374 return cell;
24375}
24376
24377/* set cell hyperlink */
24378function cell_set_hyperlink(cell/*:Cell*/, target/*:string*/, tooltip/*:?string*/) {
24379 if(!target) {
24380 delete cell.l;
24381 } else {
24382 cell.l = ({ Target: target }/*:Hyperlink*/);
24383 if(tooltip) cell.l.Tooltip = tooltip;
24384 }
24385 return cell;
24386}
24387function cell_set_internal_link(cell/*:Cell*/, range/*:string*/, tooltip/*:?string*/) { return cell_set_hyperlink(cell, "#" + range, tooltip); }
24388
24389/* add to cell comments */
24390function cell_add_comment(cell/*:Cell*/, text/*:string*/, author/*:?string*/) {
24391 if(!cell.c) cell.c = [];
24392 cell.c.push({t:text, a:author||"SheetJS"});
24393}
24394
24395/* set array formula and flush related cells */
24396function sheet_set_array_formula(ws/*:Worksheet*/, range, formula/*:string*/, dynamic/*:boolean*/) {
24397 var rng = typeof range != "string" ? range : safe_decode_range(range);
24398 var rngstr = typeof range == "string" ? range : encode_range(range);
24399 for(var R = rng.s.r; R <= rng.e.r; ++R) for(var C = rng.s.c; C <= rng.e.c; ++C) {
24400 var cell = ws_get_cell_stub(ws, R, C);
24401 cell.t = 'n';
24402 cell.F = rngstr;
24403 delete cell.v;
24404 if(R == rng.s.r && C == rng.s.c) {
24405 cell.f = formula;
24406 if(dynamic) cell.D = true;
24407 }
24408 }
24409 return ws;
24410}
24411
24412var utils/*:any*/ = {
24413 encode_col: encode_col,
24414 encode_row: encode_row,
24415 encode_cell: encode_cell,
24416 encode_range: encode_range,
24417 decode_col: decode_col,
24418 decode_row: decode_row,
24419 split_cell: split_cell,
24420 decode_cell: decode_cell,
24421 decode_range: decode_range,
24422 format_cell: format_cell,
24423 sheet_add_aoa: sheet_add_aoa,
24424 sheet_add_json: sheet_add_json,
24425 sheet_add_dom: sheet_add_dom,
24426 aoa_to_sheet: aoa_to_sheet,
24427 json_to_sheet: json_to_sheet,
24428 table_to_sheet: parse_dom_table,
24429 table_to_book: table_to_book,
24430 sheet_to_csv: sheet_to_csv,
24431 sheet_to_txt: sheet_to_txt,
24432 sheet_to_json: sheet_to_json,
24433 sheet_to_html: sheet_to_html,
24434 sheet_to_formulae: sheet_to_formulae,
24435 sheet_to_row_object_array: sheet_to_json,
24436 sheet_get_cell: ws_get_cell_stub,
24437 book_new: book_new,
24438 book_append_sheet: book_append_sheet,
24439 book_set_sheet_visibility: book_set_sheet_visibility,
24440 cell_set_number_format: cell_set_number_format,
24441 cell_set_hyperlink: cell_set_hyperlink,
24442 cell_set_internal_link: cell_set_internal_link,
24443 cell_add_comment: cell_add_comment,
24444 sheet_set_array_formula: sheet_set_array_formula,
24445 consts: {
24446 SHEET_VISIBLE: 0,
24447 SHEET_HIDDEN: 1,
24448 SHEET_VERY_HIDDEN: 2
24449 }
24450};
24451
24452var _Readable;
24453function set_readable(R) { _Readable = R; }
24454
24455function write_csv_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
24456 var stream = _Readable();
24457 var o = opts == null ? {} : opts;
24458 if(sheet == null || sheet["!ref"] == null) { stream.push(null); return stream; }
24459 var r = safe_decode_range(sheet["!ref"]);
24460 var FS = o.FS !== undefined ? o.FS : ",", fs = FS.charCodeAt(0);
24461 var RS = o.RS !== undefined ? o.RS : "\n", rs = RS.charCodeAt(0);
24462 var endregex = new RegExp((FS=="|" ? "\\|" : FS)+"+$");
24463 var row/*:?string*/ = "", cols/*:Array<string>*/ = [];
24464 o.dense = Array.isArray(sheet);
24465 var colinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
24466 var rowinfo/*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
24467 for(var C = r.s.c; C <= r.e.c; ++C) if (!((colinfo[C]||{}).hidden)) cols[C] = encode_col(C);
24468 var R = r.s.r;
24469 var BOM = false, w = 0;
24470 stream._read = function() {
24471 if(!BOM) { BOM = true; return stream.push("\uFEFF"); }
24472 while(R <= r.e.r) {
24473 ++R;
24474 if ((rowinfo[R-1]||{}).hidden) continue;
24475 row = make_csv_row(sheet, r, R-1, cols, fs, rs, FS, o);
24476 if(row != null) {
24477 if(o.strip) row = row.replace(endregex,"");
24478 if(row || (o.blankrows !== false)) return stream.push((w++ ? RS : "") + row);
24479 }
24480 }
24481 return stream.push(null);
24482 };
24483 return stream;
24484}
24485
24486function write_html_stream(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*/) {
24487 var stream = _Readable();
24488
24489 var o = opts || {};
24490 var header = o.header != null ? o.header : HTML_BEGIN;
24491 var footer = o.footer != null ? o.footer : HTML_END;
24492 stream.push(header);
24493 var r = decode_range(ws['!ref']);
24494 o.dense = Array.isArray(ws);
24495 stream.push(make_html_preamble(ws, r, o));
24496 var R = r.s.r;
24497 var end = false;
24498 stream._read = function() {
24499 if(R > r.e.r) {
24500 if(!end) { end = true; stream.push("</table>" + footer); }
24501 return stream.push(null);
24502 }
24503 while(R <= r.e.r) {
24504 stream.push(make_html_row(ws, r, R, o));
24505 ++R;
24506 break;
24507 }
24508 };
24509 return stream;
24510}
24511
24512function write_json_stream(sheet/*:Worksheet*/, opts/*:?Sheet2CSVOpts*/) {
24513 var stream = _Readable({objectMode:true});
24514
24515 if(sheet == null || sheet["!ref"] == null) { stream.push(null); return stream; }
24516 var val = {t:'n',v:0}, header = 0, offset = 1, hdr/*:Array<any>*/ = [], v=0, vv="";
24517 var r = {s:{r:0,c:0},e:{r:0,c:0}};
24518 var o = opts || {};
24519 var range = o.range != null ? o.range : sheet["!ref"];
24520 if(o.header === 1) header = 1;
24521 else if(o.header === "A") header = 2;
24522 else if(Array.isArray(o.header)) header = 3;
24523 switch(typeof range) {
24524 case 'string': r = safe_decode_range(range); break;
24525 case 'number': r = safe_decode_range(sheet["!ref"]); r.s.r = range; break;
24526 default: r = range;
24527 }
24528 if(header > 0) offset = 0;
24529 var rr = encode_row(r.s.r);
24530 var cols/*:Array<string>*/ = [];
24531 var counter = 0;
24532 var dense = Array.isArray(sheet);
24533 var R = r.s.r, C = 0;
24534 var header_cnt = {};
24535 if(dense && !sheet[R]) sheet[R] = [];
24536 var colinfo/*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
24537 var rowinfo/*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
24538 for(C = r.s.c; C <= r.e.c; ++C) {
24539 if(((colinfo[C]||{}).hidden)) continue;
24540 cols[C] = encode_col(C);
24541 val = dense ? sheet[R][C] : sheet[cols[C] + rr];
24542 switch(header) {
24543 case 1: hdr[C] = C - r.s.c; break;
24544 case 2: hdr[C] = cols[C]; break;
24545 case 3: hdr[C] = o.header[C - r.s.c]; break;
24546 default:
24547 if(val == null) val = {w: "__EMPTY", t: "s"};
24548 vv = v = format_cell(val, null, o);
24549 counter = header_cnt[v] || 0;
24550 if(!counter) header_cnt[v] = 1;
24551 else {
24552 do { vv = v + "_" + (counter++); } while(header_cnt[vv]); header_cnt[v] = counter;
24553 header_cnt[vv] = 1;
24554 }
24555 hdr[C] = vv;
24556 }
24557 }
24558 R = r.s.r + offset;
24559 stream._read = function() {
24560 while(R <= r.e.r) {
24561 if ((rowinfo[R-1]||{}).hidden) continue;
24562 var row = make_json_row(sheet, r, R, cols, header, hdr, dense, o);
24563 ++R;
24564 if((row.isempty === false) || (header === 1 ? o.blankrows !== false : !!o.blankrows)) {
24565 stream.push(row.row);
24566 return;
24567 }
24568 }
24569 return stream.push(null);
24570 };
24571 return stream;
24572}
24573
24574var __stream = {
24575 to_json: write_json_stream,
24576 to_html: write_html_stream,
24577 to_csv: write_csv_stream,
24578 set_readable: set_readable
24579};
24580export const version = XLSX.version;
24581export {
24582 parse_xlscfb,
24583 parse_zip,
24584 readSync as read,
24585 readFileSync as readFile,
24586 readFileSync,
24587 writeSync as write,
24588 writeFileSync as writeFile,
24589 writeFileSync,
24590 writeFileAsync,
24591 writeSyncXLSX as writeXLSX,
24592 writeFileSyncXLSX as writeFileXLSX,
24593 utils,
24594 __stream as stream,
24595 SSF,
24596 CFB
24597};