NUMBERS duration cell number format

This commit is contained in:
SheetJS 2022-09-04 17:51:49 -04:00
parent 6c9010f9d1
commit df0e7b5f25
4 changed files with 545 additions and 123 deletions

@ -411,37 +411,168 @@ function compress_iwa_file(buf) {
}
return u8concat(out);
}
function parse_old_storage(buf, sst, rsst, v) {
var numbers_lut_new = function() {
return { sst: [], rsst: [], ofmt: [], nfmt: [] };
};
function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
var _a, _b, _c, _d;
var ctype = t & 255, ver = t >> 8;
var fmt = ver >= 5 ? nfmt : ofmt;
dur:
if (flags & (ver > 4 ? 8 : 4) && cell.t == "n" && ctype == 7) {
var dstyle = ((_a = fmt[7]) == null ? void 0 : _a[0]) ? parse_varint49(fmt[7][0].data) : -1;
var dmin = ((_b = fmt[15]) == null ? void 0 : _b[0]) ? parse_varint49(fmt[15][0].data) : -1;
var dmax = ((_c = fmt[16]) == null ? void 0 : _c[0]) ? parse_varint49(fmt[16][0].data) : -1;
var auto = ((_d = fmt[40]) == null ? void 0 : _d[0]) ? parse_varint49(fmt[40][0].data) : -1;
if (dstyle == -1)
break dur;
var d = cell.v, dd = d;
autodur:
if (auto) {
if (d == 0) {
dmin = dmax = 2;
break autodur;
}
if (d >= 604800)
dmin = 1;
else if (d >= 86400)
dmin = 2;
else if (d >= 3600)
dmin = 4;
else if (d >= 60)
dmin = 8;
else if (d >= 1)
dmin = 16;
else
dmin = 32;
if (Math.floor(d) != d)
dmax = 32;
else if (d % 60)
dmax = 16;
else if (d % 3600)
dmax = 8;
else if (d % 86400)
dmax = 4;
else if (d % 604800)
dmax = 2;
if (dmax < dmin)
dmax = dmin;
}
if (dmin == -1 || dmax == -1)
break dur;
var dstr = [], zstr = [];
if (dmin == 1) {
dd = d / 604800;
if (dmax == 1) {
zstr.push('d"d"');
} else {
dd |= 0;
d -= 604800 * dd;
}
dstr.push(dd + (dstyle == 2 ? " week" + (dd == 1 ? "" : "s") : dstyle == 1 ? "w" : ""));
}
if (dmin <= 2 && dmax >= 2) {
dd = d / 86400;
if (dmax > 2) {
dd |= 0;
d -= 86400 * dd;
}
zstr.push('d"d"');
dstr.push(dd + (dstyle == 2 ? " day" + (dd == 1 ? "" : "s") : dstyle == 1 ? "d" : ""));
}
if (dmin <= 4 && dmax >= 4) {
dd = d / 3600;
if (dmax > 4) {
dd |= 0;
d -= 3600 * dd;
}
zstr.push((dmin >= 4 ? "[h]" : "h") + '"h"');
dstr.push(dd + (dstyle == 2 ? " hour" + (dd == 1 ? "" : "s") : dstyle == 1 ? "h" : ""));
}
if (dmin <= 8 && dmax >= 8) {
dd = d / 60;
if (dmax > 8) {
dd |= 0;
d -= 60 * dd;
}
zstr.push((dmin >= 8 ? "[m]" : "m") + '"m"');
if (dstyle == 0)
dstr.push((dmin == 8 && dmax == 8 || dd >= 10 ? "" : "0") + dd);
else
dstr.push(dd + (dstyle == 2 ? " minute" + (dd == 1 ? "" : "s") : dstyle == 1 ? "m" : ""));
}
if (dmin <= 16 && dmax >= 16) {
dd = d;
if (dmax > 16) {
dd |= 0;
d -= dd;
}
zstr.push((dmin >= 16 ? "[s]" : "s") + '"s"');
if (dstyle == 0)
dstr.push((dmax == 16 && dmin == 16 || dd >= 10 ? "" : "0") + dd);
else
dstr.push(dd + (dstyle == 2 ? " second" + (dd == 1 ? "" : "s") : dstyle == 1 ? "s" : ""));
}
if (dmax >= 32) {
dd = Math.round(1e3 * d);
if (dmin < 32)
zstr.push('.000"ms"');
if (dstyle == 0)
dstr.push((dd >= 100 ? "" : dd >= 10 ? "0" : "00") + dd);
else
dstr.push(dd + (dstyle == 2 ? " millisecond" + (dd == 1 ? "" : "s") : dstyle == 1 ? "ms" : ""));
}
cell.w = dstr.join(dstyle == 0 ? ":" : " ");
cell.z = zstr.join(dstyle == 0 ? '":"' : " ");
if (dstyle == 0)
cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
}
}
function parse_old_storage(buf, lut, v) {
var dv = u8_to_dataview(buf);
var flags = dv.getUint32(4, true);
var data_offset = (v > 1 ? 12 : 8) + popcnt(flags & (v > 1 ? 3470 : 398)) * 4;
var ridx = -1, sidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
if (flags & 512) {
ridx = dv.getUint32(data_offset, true);
data_offset += 4;
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
var doff = v > 1 ? 12 : 8;
if (flags & 2) {
zidx = dv.getUint32(doff, true);
doff += 4;
}
data_offset += popcnt(flags & (v > 1 ? 12288 : 4096)) * 4;
doff += popcnt(flags & (v > 1 ? 3468 : 396)) * 4;
if (flags & 512) {
ridx = dv.getUint32(doff, true);
doff += 4;
}
doff += popcnt(flags & (v > 1 ? 12288 : 4096)) * 4;
if (flags & 16) {
sidx = dv.getUint32(data_offset, true);
data_offset += 4;
sidx = dv.getUint32(doff, true);
doff += 4;
}
if (flags & 32) {
ieee = dv.getFloat64(data_offset, true);
data_offset += 8;
ieee = dv.getFloat64(doff, true);
doff += 8;
}
if (flags & 64) {
dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
data_offset += 8;
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
doff += 8;
}
if (v > 1) {
flags = dv.getUint32(8, true) >>> 16;
if (flags & 255) {
if (zidx == -1)
zidx = dv.getUint32(doff, true);
doff += 4;
}
}
var ret;
switch (buf[2]) {
var t = buf[v >= 4 ? 1 : 2];
switch (t) {
case 0:
return void 0;
case 2:
ret = { t: "n", v: ieee };
break;
case 3:
ret = { t: "s", v: sst[sidx] };
ret = { t: "s", v: lut.sst[sidx] };
break;
case 5:
ret = { t: "d", v: dt };
@ -450,7 +581,7 @@ function parse_old_storage(buf, sst, rsst, v) {
ret = { t: "b", v: ieee > 0 };
break;
case 7:
ret = { t: "n", v: ieee / 86400 };
ret = { t: "n", v: ieee };
break;
case 8:
ret = { t: "e", v: 0 };
@ -458,7 +589,7 @@ function parse_old_storage(buf, sst, rsst, v) {
case 9:
{
if (ridx > -1)
ret = { t: "s", v: rsst[ridx] };
ret = { t: "s", v: lut.rsst[ridx] };
else
throw new Error("Unsupported cell type ".concat(buf[subarray](0, 4)));
}
@ -466,42 +597,53 @@ function parse_old_storage(buf, sst, rsst, v) {
default:
throw new Error("Unsupported cell type ".concat(buf[subarray](0, 4)));
}
if (zidx > -1)
numbers_format_cell(ret, t | v << 8, flags, lut.ofmt[zidx], lut.nfmt[zidx]);
if (t == 7)
ret.v /= 86400;
return ret;
}
function parse_new_storage(buf, sst, rsst) {
function parse_new_storage(buf, lut) {
var dv = u8_to_dataview(buf);
var flags = dv.getUint32(8, true);
var data_offset = 12;
var ridx = -1, sidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
var doff = 12;
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
if (flags & 1) {
d128 = readDecimal128LE(buf, data_offset);
data_offset += 16;
d128 = readDecimal128LE(buf, doff);
doff += 16;
}
if (flags & 2) {
ieee = dv.getFloat64(data_offset, true);
data_offset += 8;
ieee = dv.getFloat64(doff, true);
doff += 8;
}
if (flags & 4) {
dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
data_offset += 8;
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
doff += 8;
}
if (flags & 8) {
sidx = dv.getUint32(data_offset, true);
data_offset += 4;
sidx = dv.getUint32(doff, true);
doff += 4;
}
if (flags & 16) {
ridx = dv.getUint32(data_offset, true);
data_offset += 4;
ridx = dv.getUint32(doff, true);
doff += 4;
}
doff += popcnt(flags & 8160) * 4;
if (flags & 516096) {
if (zidx == -1)
zidx = dv.getUint32(doff, true);
doff += 4;
}
var ret;
switch (buf[1]) {
var t = buf[1];
switch (t) {
case 0:
return void 0;
case 2:
ret = { t: "n", v: d128 };
break;
case 3:
ret = { t: "s", v: sst[sidx] };
ret = { t: "s", v: lut.sst[sidx] };
break;
case 5:
ret = { t: "d", v: dt };
@ -510,7 +652,7 @@ function parse_new_storage(buf, sst, rsst) {
ret = { t: "b", v: ieee > 0 };
break;
case 7:
ret = { t: "n", v: ieee / 86400 };
ret = { t: "n", v: ieee };
break;
case 8:
ret = { t: "e", v: 0 };
@ -518,7 +660,7 @@ function parse_new_storage(buf, sst, rsst) {
case 9:
{
if (ridx > -1)
ret = { t: "s", v: rsst[ridx] };
ret = { t: "s", v: lut.rsst[ridx] };
else
throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf[subarray](0, 4)));
}
@ -529,6 +671,10 @@ function parse_new_storage(buf, sst, rsst) {
default:
throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf[subarray](0, 4)));
}
if (zidx > -1)
numbers_format_cell(ret, t | 5 << 8, flags >> 13, lut.ofmt[zidx], lut.nfmt[zidx]);
if (t == 7)
ret.v /= 86400;
return ret;
}
function write_new_storage(cell, sst) {
@ -591,15 +737,16 @@ function write_old_storage(cell, sst) {
dv.setUint32(4, flags, true);
return out[subarray](0, l);
}
function parse_cell_storage(buf, sst, rsst) {
function parse_cell_storage(buf, lut) {
switch (buf[0]) {
case 0:
case 1:
case 2:
case 3:
return parse_old_storage(buf, sst, rsst, buf[0]);
case 4:
return parse_old_storage(buf, lut, buf[0]);
case 5:
return parse_new_storage(buf, sst, rsst);
return parse_new_storage(buf, lut);
default:
throw new Error("Unsupported payload version ".concat(buf[0]));
}
@ -640,6 +787,11 @@ function parse_TST_TableDataList(M, root) {
}).join("");
}
break;
case 2:
data[key] = parse_shallow(le[6][0].data);
break;
default:
throw type;
}
});
return data;
@ -704,7 +856,7 @@ function parse_TST_Tile(M, root) {
};
}
function parse_TST_TableModelArchive(M, root, ws) {
var _a, _b, _c;
var _a, _b, _c, _d, _e, _f;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -716,8 +868,15 @@ function parse_TST_TableModelArchive(M, root, ws) {
ws["!ref"] = encode_range(range);
var dense = Array.isArray(ws);
var store = parse_shallow(pb[4][0].data);
var sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
var rsst = ((_a = store[17]) == null ? void 0 : _a[0]) ? parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]) : [];
var lut = numbers_lut_new();
if ((_a = store[4]) == null ? void 0 : _a[0])
lut.sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
if ((_b = store[11]) == null ? void 0 : _b[0])
lut.ofmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[11][0].data)][0]);
if ((_c = store[17]) == null ? void 0 : _c[0])
lut.rsst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]);
if ((_d = store[22]) == null ? void 0 : _d[0])
lut.nfmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[22][0].data)][0]);
var tile = parse_shallow(store[3][0].data);
var _R = 0;
tile[1].forEach(function(t) {
@ -729,7 +888,7 @@ function parse_TST_TableModelArchive(M, root, ws) {
var _tile = parse_TST_Tile(M, ref2);
_tile.data.forEach(function(row, R) {
row.forEach(function(buf, C) {
var res = parse_cell_storage(buf, sst, rsst);
var res = parse_cell_storage(buf, lut);
if (res) {
if (dense) {
if (!ws[_R + R])
@ -744,12 +903,12 @@ function parse_TST_TableModelArchive(M, root, ws) {
});
_R += _tile.nrows;
});
if ((_b = store[13]) == null ? void 0 : _b[0]) {
if ((_e = store[13]) == null ? void 0 : _e[0]) {
var ref = M[parse_TSP_Reference(store[13][0].data)][0];
var mtype = varint_to_i32(ref.meta[1][0].data);
if (mtype != 6144)
throw new Error("Expected merge type 6144, found ".concat(mtype));
ws["!merges"] = (_c = parse_shallow(ref.data)) == null ? void 0 : _c[1].map(function(pi) {
ws["!merges"] = (_f = parse_shallow(ref.data)) == null ? void 0 : _f[1].map(function(pi) {
var merge = parse_shallow(pi.data);
var origin = u8_to_dataview(parse_shallow(merge[1][0].data)[1][0].data), size = u8_to_dataview(parse_shallow(merge[2][0].data)[1][0].data);
return {

@ -411,37 +411,168 @@ function compress_iwa_file(buf) {
}
return u8concat(out);
}
function parse_old_storage(buf, sst, rsst, v) {
var numbers_lut_new = function() {
return { sst: [], rsst: [], ofmt: [], nfmt: [] };
};
function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
var _a, _b, _c, _d;
var ctype = t & 255, ver = t >> 8;
var fmt = ver >= 5 ? nfmt : ofmt;
dur:
if (flags & (ver > 4 ? 8 : 4) && cell.t == "n" && ctype == 7) {
var dstyle = ((_a = fmt[7]) == null ? void 0 : _a[0]) ? parse_varint49(fmt[7][0].data) : -1;
var dmin = ((_b = fmt[15]) == null ? void 0 : _b[0]) ? parse_varint49(fmt[15][0].data) : -1;
var dmax = ((_c = fmt[16]) == null ? void 0 : _c[0]) ? parse_varint49(fmt[16][0].data) : -1;
var auto = ((_d = fmt[40]) == null ? void 0 : _d[0]) ? parse_varint49(fmt[40][0].data) : -1;
if (dstyle == -1)
break dur;
var d = cell.v, dd = d;
autodur:
if (auto) {
if (d == 0) {
dmin = dmax = 2;
break autodur;
}
if (d >= 604800)
dmin = 1;
else if (d >= 86400)
dmin = 2;
else if (d >= 3600)
dmin = 4;
else if (d >= 60)
dmin = 8;
else if (d >= 1)
dmin = 16;
else
dmin = 32;
if (Math.floor(d) != d)
dmax = 32;
else if (d % 60)
dmax = 16;
else if (d % 3600)
dmax = 8;
else if (d % 86400)
dmax = 4;
else if (d % 604800)
dmax = 2;
if (dmax < dmin)
dmax = dmin;
}
if (dmin == -1 || dmax == -1)
break dur;
var dstr = [], zstr = [];
if (dmin == 1) {
dd = d / 604800;
if (dmax == 1) {
zstr.push('d"d"');
} else {
dd |= 0;
d -= 604800 * dd;
}
dstr.push(dd + (dstyle == 2 ? " week" + (dd == 1 ? "" : "s") : dstyle == 1 ? "w" : ""));
}
if (dmin <= 2 && dmax >= 2) {
dd = d / 86400;
if (dmax > 2) {
dd |= 0;
d -= 86400 * dd;
}
zstr.push('d"d"');
dstr.push(dd + (dstyle == 2 ? " day" + (dd == 1 ? "" : "s") : dstyle == 1 ? "d" : ""));
}
if (dmin <= 4 && dmax >= 4) {
dd = d / 3600;
if (dmax > 4) {
dd |= 0;
d -= 3600 * dd;
}
zstr.push((dmin >= 4 ? "[h]" : "h") + '"h"');
dstr.push(dd + (dstyle == 2 ? " hour" + (dd == 1 ? "" : "s") : dstyle == 1 ? "h" : ""));
}
if (dmin <= 8 && dmax >= 8) {
dd = d / 60;
if (dmax > 8) {
dd |= 0;
d -= 60 * dd;
}
zstr.push((dmin >= 8 ? "[m]" : "m") + '"m"');
if (dstyle == 0)
dstr.push((dmin == 8 && dmax == 8 || dd >= 10 ? "" : "0") + dd);
else
dstr.push(dd + (dstyle == 2 ? " minute" + (dd == 1 ? "" : "s") : dstyle == 1 ? "m" : ""));
}
if (dmin <= 16 && dmax >= 16) {
dd = d;
if (dmax > 16) {
dd |= 0;
d -= dd;
}
zstr.push((dmin >= 16 ? "[s]" : "s") + '"s"');
if (dstyle == 0)
dstr.push((dmax == 16 && dmin == 16 || dd >= 10 ? "" : "0") + dd);
else
dstr.push(dd + (dstyle == 2 ? " second" + (dd == 1 ? "" : "s") : dstyle == 1 ? "s" : ""));
}
if (dmax >= 32) {
dd = Math.round(1e3 * d);
if (dmin < 32)
zstr.push('.000"ms"');
if (dstyle == 0)
dstr.push((dd >= 100 ? "" : dd >= 10 ? "0" : "00") + dd);
else
dstr.push(dd + (dstyle == 2 ? " millisecond" + (dd == 1 ? "" : "s") : dstyle == 1 ? "ms" : ""));
}
cell.w = dstr.join(dstyle == 0 ? ":" : " ");
cell.z = zstr.join(dstyle == 0 ? '":"' : " ");
if (dstyle == 0)
cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
}
}
function parse_old_storage(buf, lut, v) {
var dv = u8_to_dataview(buf);
var flags = dv.getUint32(4, true);
var data_offset = (v > 1 ? 12 : 8) + popcnt(flags & (v > 1 ? 3470 : 398)) * 4;
var ridx = -1, sidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
if (flags & 512) {
ridx = dv.getUint32(data_offset, true);
data_offset += 4;
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
var doff = v > 1 ? 12 : 8;
if (flags & 2) {
zidx = dv.getUint32(doff, true);
doff += 4;
}
data_offset += popcnt(flags & (v > 1 ? 12288 : 4096)) * 4;
doff += popcnt(flags & (v > 1 ? 3468 : 396)) * 4;
if (flags & 512) {
ridx = dv.getUint32(doff, true);
doff += 4;
}
doff += popcnt(flags & (v > 1 ? 12288 : 4096)) * 4;
if (flags & 16) {
sidx = dv.getUint32(data_offset, true);
data_offset += 4;
sidx = dv.getUint32(doff, true);
doff += 4;
}
if (flags & 32) {
ieee = dv.getFloat64(data_offset, true);
data_offset += 8;
ieee = dv.getFloat64(doff, true);
doff += 8;
}
if (flags & 64) {
dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
data_offset += 8;
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
doff += 8;
}
if (v > 1) {
flags = dv.getUint32(8, true) >>> 16;
if (flags & 255) {
if (zidx == -1)
zidx = dv.getUint32(doff, true);
doff += 4;
}
}
var ret;
switch (buf[2]) {
var t = buf[v >= 4 ? 1 : 2];
switch (t) {
case 0:
return void 0;
case 2:
ret = { t: "n", v: ieee };
break;
case 3:
ret = { t: "s", v: sst[sidx] };
ret = { t: "s", v: lut.sst[sidx] };
break;
case 5:
ret = { t: "d", v: dt };
@ -450,7 +581,7 @@ function parse_old_storage(buf, sst, rsst, v) {
ret = { t: "b", v: ieee > 0 };
break;
case 7:
ret = { t: "n", v: ieee / 86400 };
ret = { t: "n", v: ieee };
break;
case 8:
ret = { t: "e", v: 0 };
@ -458,7 +589,7 @@ function parse_old_storage(buf, sst, rsst, v) {
case 9:
{
if (ridx > -1)
ret = { t: "s", v: rsst[ridx] };
ret = { t: "s", v: lut.rsst[ridx] };
else
throw new Error("Unsupported cell type ".concat(buf[subarray](0, 4)));
}
@ -466,42 +597,53 @@ function parse_old_storage(buf, sst, rsst, v) {
default:
throw new Error("Unsupported cell type ".concat(buf[subarray](0, 4)));
}
if (zidx > -1)
numbers_format_cell(ret, t | v << 8, flags, lut.ofmt[zidx], lut.nfmt[zidx]);
if (t == 7)
ret.v /= 86400;
return ret;
}
function parse_new_storage(buf, sst, rsst) {
function parse_new_storage(buf, lut) {
var dv = u8_to_dataview(buf);
var flags = dv.getUint32(8, true);
var data_offset = 12;
var ridx = -1, sidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
var doff = 12;
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
if (flags & 1) {
d128 = readDecimal128LE(buf, data_offset);
data_offset += 16;
d128 = readDecimal128LE(buf, doff);
doff += 16;
}
if (flags & 2) {
ieee = dv.getFloat64(data_offset, true);
data_offset += 8;
ieee = dv.getFloat64(doff, true);
doff += 8;
}
if (flags & 4) {
dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
data_offset += 8;
dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1e3);
doff += 8;
}
if (flags & 8) {
sidx = dv.getUint32(data_offset, true);
data_offset += 4;
sidx = dv.getUint32(doff, true);
doff += 4;
}
if (flags & 16) {
ridx = dv.getUint32(data_offset, true);
data_offset += 4;
ridx = dv.getUint32(doff, true);
doff += 4;
}
doff += popcnt(flags & 8160) * 4;
if (flags & 516096) {
if (zidx == -1)
zidx = dv.getUint32(doff, true);
doff += 4;
}
var ret;
switch (buf[1]) {
var t = buf[1];
switch (t) {
case 0:
return void 0;
case 2:
ret = { t: "n", v: d128 };
break;
case 3:
ret = { t: "s", v: sst[sidx] };
ret = { t: "s", v: lut.sst[sidx] };
break;
case 5:
ret = { t: "d", v: dt };
@ -510,7 +652,7 @@ function parse_new_storage(buf, sst, rsst) {
ret = { t: "b", v: ieee > 0 };
break;
case 7:
ret = { t: "n", v: ieee / 86400 };
ret = { t: "n", v: ieee };
break;
case 8:
ret = { t: "e", v: 0 };
@ -518,7 +660,7 @@ function parse_new_storage(buf, sst, rsst) {
case 9:
{
if (ridx > -1)
ret = { t: "s", v: rsst[ridx] };
ret = { t: "s", v: lut.rsst[ridx] };
else
throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf[subarray](0, 4)));
}
@ -529,6 +671,10 @@ function parse_new_storage(buf, sst, rsst) {
default:
throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf[subarray](0, 4)));
}
if (zidx > -1)
numbers_format_cell(ret, t | 5 << 8, flags >> 13, lut.ofmt[zidx], lut.nfmt[zidx]);
if (t == 7)
ret.v /= 86400;
return ret;
}
function write_new_storage(cell, sst) {
@ -591,15 +737,16 @@ function write_old_storage(cell, sst) {
dv.setUint32(4, flags, true);
return out[subarray](0, l);
}
function parse_cell_storage(buf, sst, rsst) {
function parse_cell_storage(buf, lut) {
switch (buf[0]) {
case 0:
case 1:
case 2:
case 3:
return parse_old_storage(buf, sst, rsst, buf[0]);
case 4:
return parse_old_storage(buf, lut, buf[0]);
case 5:
return parse_new_storage(buf, sst, rsst);
return parse_new_storage(buf, lut);
default:
throw new Error("Unsupported payload version ".concat(buf[0]));
}
@ -640,6 +787,11 @@ function parse_TST_TableDataList(M, root) {
}).join("");
}
break;
case 2:
data[key] = parse_shallow(le[6][0].data);
break;
default:
throw type;
}
});
return data;
@ -704,7 +856,7 @@ function parse_TST_Tile(M, root) {
};
}
function parse_TST_TableModelArchive(M, root, ws) {
var _a, _b, _c;
var _a, _b, _c, _d, _e, _f;
var pb = parse_shallow(root.data);
var range = { s: { r: 0, c: 0 }, e: { r: 0, c: 0 } };
range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
@ -716,8 +868,15 @@ function parse_TST_TableModelArchive(M, root, ws) {
ws["!ref"] = encode_range(range);
var dense = Array.isArray(ws);
var store = parse_shallow(pb[4][0].data);
var sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
var rsst = ((_a = store[17]) == null ? void 0 : _a[0]) ? parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]) : [];
var lut = numbers_lut_new();
if ((_a = store[4]) == null ? void 0 : _a[0])
lut.sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
if ((_b = store[11]) == null ? void 0 : _b[0])
lut.ofmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[11][0].data)][0]);
if ((_c = store[17]) == null ? void 0 : _c[0])
lut.rsst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]);
if ((_d = store[22]) == null ? void 0 : _d[0])
lut.nfmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[22][0].data)][0]);
var tile = parse_shallow(store[3][0].data);
var _R = 0;
tile[1].forEach(function(t) {
@ -729,7 +888,7 @@ function parse_TST_TableModelArchive(M, root, ws) {
var _tile = parse_TST_Tile(M, ref2);
_tile.data.forEach(function(row, R) {
row.forEach(function(buf, C) {
var res = parse_cell_storage(buf, sst, rsst);
var res = parse_cell_storage(buf, lut);
if (res) {
if (dense) {
if (!ws[_R + R])
@ -744,12 +903,12 @@ function parse_TST_TableModelArchive(M, root, ws) {
});
_R += _tile.nrows;
});
if ((_b = store[13]) == null ? void 0 : _b[0]) {
if ((_e = store[13]) == null ? void 0 : _e[0]) {
var ref = M[parse_TSP_Reference(store[13][0].data)][0];
var mtype = varint_to_i32(ref.meta[1][0].data);
if (mtype != 6144)
throw new Error("Expected merge type 6144, found ".concat(mtype));
ws["!merges"] = (_c = parse_shallow(ref.data)) == null ? void 0 : _c[1].map(function(pi) {
ws["!merges"] = (_f = parse_shallow(ref.data)) == null ? void 0 : _f[1].map(function(pi) {
var merge = parse_shallow(pi.data);
var origin = u8_to_dataview(parse_shallow(merge[1][0].data)[1][0].data), size = u8_to_dataview(parse_shallow(merge[2][0].data)[1][0].data);
return {

@ -356,75 +356,174 @@ function compress_iwa_file(buf: Uint8Array): Uint8Array {
}
//<<export { decompress_iwa_file, compress_iwa_file };
/** Parse "old storage" (version 0..3) */
function parse_old_storage(buf: Uint8Array, sst: string[], rsst: string[], v: 0|1|2|3): CellObject | void {
/** .TST.DataStore */
interface DataLUT {
/** shared string table */
sst: string[];
/** rich string table table */
rsst: string[];
/** old format table */
ofmt: ProtoMessage[];
/** new format table */
nfmt: ProtoMessage[];
}
var numbers_lut_new = (): DataLUT => ({ sst: [], rsst: [], ofmt: [], nfmt: [] });
function numbers_format_cell(cell: CellObject, t: number, flags: number, ofmt: ProtoMessage, nfmt: ProtoMessage): void {
var ctype = t & 0xFF, ver = t >> 8;
var fmt = ver >= 5 ? nfmt : ofmt;
dur: if((flags & (ver > 4 ? 8: 4)) && cell.t == "n" && ctype == 7) {
var dstyle = (fmt[7]?.[0]) ? parse_varint49(fmt[7][0].data) : -1;
if(dstyle == -1) break dur;
var dmin = (fmt[15]?.[0]) ? parse_varint49(fmt[15][0].data) : -1;
var dmax = (fmt[16]?.[0]) ? parse_varint49(fmt[16][0].data) : -1;
var auto = (fmt[40]?.[0]) ? parse_varint49(fmt[40][0].data) : -1;
var d: number = cell.v as number, dd = d;
autodur: if(auto) { // TODO: check if numbers reformats on load
if(d == 0) { dmin = dmax = 2; break autodur; }
if(d >= 604800) dmin = 1;
else if(d >= 86400) dmin = 2;
else if(d >= 3600) dmin = 4;
else if(d >= 60) dmin = 8;
else if(d >= 1) dmin = 16;
else dmin = 32;
if(Math.floor(d) != d) dmax = 32;
else if(d % 60) dmax = 16;
else if(d % 3600) dmax = 8;
else if(d % 86400) dmax = 4;
else if(d % 604800) dmax = 2;
if(dmax < dmin) dmax = dmin;
}
if(dmin == -1 || dmax == -1) break dur;
var dstr: string[] = [], zstr: string[] = [];
/* TODO: plurality, SSF equivalents */
if(dmin == 1) {
dd = d / 604800;
if(dmax == 1) { zstr.push('d"d"'); } else { dd |= 0; d -= 604800 * dd; }
dstr.push(dd + (dstyle == 2 ? " week" + (dd == 1 ? "" : "s") : dstyle == 1 ? "w": ""));
}
if(dmin <= 2 && dmax >= 2) {
dd = d / 86400;
if(dmax > 2) { dd |= 0; d -= 86400 * dd; }
zstr.push("d" + '"d"');
dstr.push(dd + (dstyle == 2 ? " day" + (dd == 1 ? "" : "s") : dstyle == 1 ? "d" : ""));
}
if(dmin <= 4 && dmax >= 4) {
dd = d / 3600;
if(dmax > 4) { dd |= 0; d -= 3600 * dd; }
zstr.push((dmin >= 4 ? "[h]" : "h") + '"h"');
dstr.push(dd + (dstyle == 2 ? " hour" + (dd == 1 ? "" : "s") : dstyle == 1 ? "h" : ""));
}
if(dmin <= 8 && dmax >= 8) {
dd = d / 60;
if(dmax > 8) { dd |= 0; d -= 60 * dd; }
zstr.push((dmin >= 8 ? "[m]" : "m") + '"m"');
if(dstyle == 0) dstr.push(((dmin == 8 && dmax == 8 || dd >= 10) ? "" : "0") + dd)
else dstr.push(dd + (dstyle == 2 ? " minute" + (dd == 1 ? "" : "s") : dstyle == 1 ? "m" : ""));
}
if(dmin <= 16 && dmax >= 16) {
dd = d;
if(dmax > 16) { dd |= 0; d -= dd; }
zstr.push((dmin >= 16 ? "[s]" : "s") + '"s"');
if(dstyle == 0) dstr.push((dmax == 16 && dmin == 16 || dd >= 10 ? "" : "0") + dd)
else dstr.push(dd + (dstyle == 2 ? " second" + (dd == 1 ? "" : "s") : dstyle == 1 ? "s" : ""));
}
if(dmax >= 32) {
dd = Math.round(1000 * d);
if(dmin < 32) zstr.push(".000" + '"ms"');
if(dstyle == 0) dstr.push((dd >= 100 ? "" : dd >= 10 ? "0" : "00") + dd)
else dstr.push(dd + (dstyle == 2 ? " millisecond" + (dd == 1 ? "" : "s") : dstyle == 1 ? "ms" : ""));
}
cell.w = dstr.join(dstyle == 0 ? ":" : " "); cell.z = zstr.join(dstyle == 0 ? '":"': " ");
if(dstyle == 0) cell.w = cell.w.replace(/:(\d\d\d)$/, ".$1");
}
}
/** Parse "old storage" (version 0..4) */
function parse_old_storage(buf: Uint8Array, lut: DataLUT, v: 0|1|2|3|4): CellObject | void {
var dv = u8_to_dataview(buf);
var flags = dv.getUint32(4, true);
/* TODO: find the correct field position of number formats, formulae, etc */
var data_offset = (v > 1 ? 12 : 8) + popcnt(flags & (v > 1 ? 0x0D8E : 0x018E)) * 4;
var ridx = -1, sidx = -1, zidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
var doff = (v > 1 ? 12 : 8);
if(flags & 0x0002) { zidx = dv.getUint32(doff, true); doff += 4;}
doff += popcnt(flags & (v > 1 ? 0x0D8C : 0x018C)) * 4;
var ridx = -1, sidx = -1, ieee = NaN, dt = new Date(2001, 0, 1);
if(flags & 0x0200) { ridx = dv.getUint32(data_offset, true); data_offset += 4; }
data_offset += popcnt(flags & (v > 1 ? 0x3000 : 0x1000)) * 4;
if(flags & 0x0010) { sidx = dv.getUint32(data_offset, true); data_offset += 4; }
if(flags & 0x0020) { ieee = dv.getFloat64(data_offset, true); data_offset += 8; }
if(flags & 0x0040) { dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1000); data_offset += 8; }
if(flags & 0x0200) { ridx = dv.getUint32(doff, true); doff += 4; }
doff += popcnt(flags & (v > 1 ? 0x3000 : 0x1000)) * 4;
if(flags & 0x0010) { sidx = dv.getUint32(doff, true); doff += 4; }
if(flags & 0x0020) { ieee = dv.getFloat64(doff, true); doff += 8; }
if(flags & 0x0040) { dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1000); doff += 8; }
if(v > 1) {
flags = dv.getUint32(8, true) >>> 16;
/* TODO: stress test if a cell can have multiple sub-type formats */
if(flags & 0xFF) { if(zidx == -1) zidx = dv.getUint32(doff, true); doff += 4; }
}
var ret: CellObject;
switch(buf[2]) {
var t = buf[v >= 4 ? 1 : 2];
switch(t) {
case 0: return void 0; // return { t: "z" }; // blank?
case 2: ret = { t: "n", v: ieee }; break; // number
case 3: ret = { t: "s", v: sst[sidx] }; break; // string
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
case 5: ret = { t: "d", v: dt }; break; // date-time
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
case 7: ret = { t: "n", v: ieee / 86400 }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
case 7: ret = { t: "n", v: ieee }; break; // duration in seconds
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
case 9: { // "rich text"
if(ridx > -1) ret = { t: "s", v: rsst[ridx] };
if(ridx > -1) ret = { t: "s", v: lut.rsst[ridx] };
else throw new Error(`Unsupported cell type ${buf[subarray](0,4)}`);
} break;
default: throw new Error(`Unsupported cell type ${buf[subarray](0,4)}`);
}
/* TODO: Some fields appear after the cell data */
if(zidx > -1) numbers_format_cell(ret, t | (v<<8), flags, lut.ofmt[zidx], lut.nfmt[zidx]);
if(t == 7) (ret.v as number) /= 86400;
return ret;
}
/** Parse "new storage" (version 5) */
function parse_new_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObject | void {
function parse_new_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
var dv = u8_to_dataview(buf);
var flags = dv.getUint32(8, true);
/* TODO: find the correct field position of number formats, formulae, etc */
var data_offset = 12;
var doff = 12;
var ridx = -1, sidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
var ridx = -1, sidx = -1, zidx = -1, d128 = NaN, ieee = NaN, dt = new Date(2001, 0, 1);
if(flags & 0x0001) { d128 = readDecimal128LE(buf, data_offset); data_offset += 16; }
if(flags & 0x0002) { ieee = dv.getFloat64(data_offset, true); data_offset += 8; }
if(flags & 0x0004) { dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1000); data_offset += 8; }
if(flags & 0x0008) { sidx = dv.getUint32(data_offset, true); data_offset += 4; }
if(flags & 0x0010) { ridx = dv.getUint32(data_offset, true); data_offset += 4; }
if(flags & 0x0001) { d128 = readDecimal128LE(buf, doff); doff += 16; }
if(flags & 0x0002) { ieee = dv.getFloat64(doff, true); doff += 8; }
if(flags & 0x0004) { dt.setTime(dt.getTime() + dv.getFloat64(doff, true) * 1000); doff += 8; }
if(flags & 0x0008) { sidx = dv.getUint32(doff, true); doff += 4; }
if(flags & 0x0010) { ridx = dv.getUint32(doff, true); doff += 4; }
doff += popcnt(flags & 0x1FE0) * 4;
/* TODO: stress test if a cell can have multiple sub-type formats */
if(flags & 0x7E000) { if(zidx == -1) zidx = dv.getUint32(doff, true); doff += 4; }
var ret: CellObject;
switch(buf[1]) {
var t = buf[1];
switch(t) {
case 0: return void 0; // return { t: "z" }; // blank?
case 2: ret = { t: "n", v: d128 }; break; // number
case 3: ret = { t: "s", v: sst[sidx] }; break; // string
case 3: ret = { t: "s", v: lut.sst[sidx] }; break; // string
case 5: ret = { t: "d", v: dt }; break; // date-time
case 6: ret = { t: "b", v: ieee > 0 }; break; // boolean
case 7: ret = { t: "n", v: ieee / 86400 }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
case 7: ret = { t: "n", v: ieee }; break; // duration in seconds TODO: emit [hh]:[mm] style format with adjusted value
case 8: ret = { t: "e", v: 0}; break; // "formula error" TODO: enumerate and map errors to csf equivalents
case 9: { // "rich text"
if(ridx > -1) ret = { t: "s", v: rsst[ridx] };
if(ridx > -1) ret = { t: "s", v: lut.rsst[ridx] };
else throw new Error(`Unsupported cell type ${buf[1]} : ${flags & 0x1F} : ${buf[subarray](0,4)}`);
} break;
case 10: ret = { t: "n", v: d128 }; break; // currency
default: throw new Error(`Unsupported cell type ${buf[1]} : ${flags & 0x1F} : ${buf[subarray](0,4)}`);
}
/* TODO: All styling fields appear after the cell data */
if(zidx > -1) numbers_format_cell(ret, t | (5<<8), flags >> 13, lut.ofmt[zidx], lut.nfmt[zidx] );
if(t == 7) (ret.v as number) /= 86400;
return ret;
}
@ -459,11 +558,11 @@ function write_old_storage(cell: CellObject, sst: string[]): Uint8Array {
return out[subarray](0, l);
}
//<<export { write_new_storage, write_old_storage };
function parse_cell_storage(buf: Uint8Array, sst: string[], rsst: string[]): CellObject | void {
function parse_cell_storage(buf: Uint8Array, lut: DataLUT): CellObject | void {
switch(buf[0]) {
case 0: case 1:
case 2: case 3: return parse_old_storage(buf, sst, rsst, buf[0]);
case 5: return parse_new_storage(buf, sst, rsst);
case 2: case 3: case 4: return parse_old_storage(buf, lut, buf[0]);
case 5: return parse_new_storage(buf, lut);
default: throw new Error(`Unsupported payload version ${buf[0]}`);
}
}
@ -490,13 +589,13 @@ function write_TSP_Reference(idx: number): Uint8Array {
type MessageSpace = {[id: number]: IWAMessage[]};
/** Parse .TST.TableDataList */
function parse_TST_TableDataList(M: MessageSpace, root: IWAMessage): string[] {
function parse_TST_TableDataList(M: MessageSpace, root: IWAMessage): any[] {
var pb = parse_shallow(root.data);
// .TST.TableDataList.ListType
var type = varint_to_i32(pb[1][0].data);
var entries = pb[3];
var data: Array<string> = [];
var data: any[] = [];
(entries||[]).forEach(entry => {
// .TST.TableDataList.ListEntry
var le = parse_shallow(entry.data);
@ -516,6 +615,8 @@ function parse_TST_TableDataList(M: MessageSpace, root: IWAMessage): string[] {
data[key] = tswpsa[3].map(x => u8str(x.data)).join("");
} break;
case 2: data[key] = parse_shallow(le[6][0].data); break;
default: throw type;
}
});
return data;
@ -595,8 +696,11 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
var dense = Array.isArray(ws);
// .TST.DataStore
var store = parse_shallow(pb[4][0].data);
var sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
var rsst: string[] = store[17]?.[0] ? parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]) : [];
var lut: DataLUT = numbers_lut_new();
if(store[4]?.[0]) lut.sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
if(store[11]?.[0]) lut.ofmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[11][0].data)][0]);
if(store[17]?.[0]) lut.rsst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]);
if(store[22]?.[0]) lut.nfmt = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[22][0].data)][0]);
// .TST.TileStorage
var tile = parse_shallow(store[3][0].data);
@ -611,7 +715,7 @@ function parse_TST_TableModelArchive(M: MessageSpace, root: IWAMessage, ws: Work
var _tile = parse_TST_Tile(M, ref);
_tile.data.forEach((row, R) => {
row.forEach((buf, C) => {
var res = parse_cell_storage(buf, sst, rsst);
var res = parse_cell_storage(buf, lut);
if(res) {
if(dense) {
if(!ws[_R + R]) ws[_R + R] = [];

@ -1 +1 @@
Subproject commit f91c73f99ccb7919b7992e720f9ba7a730071770
Subproject commit 787cc72932acf77ac58018d60d934b65847b16a3