PronounsPage/shared/compressor.ts

63 lines
1.8 KiB
TypeScript

export default class Compressor {
static compress(data: string[], base: string[]): string[] {
const dataFirst = data[0];
const dataRest = data.slice(1);
const baseFirst = base[0];
const baseRest = base.slice(1);
if (dataFirst !== baseFirst || dataRest.length !== baseRest.length) {
throw 'Cannot compress data, format does not match the base';
}
const compressed = [];
let stack = [];
for (const i in dataRest) {
if (dataRest[i] === baseRest[i]) {
stack.push(dataRest[i]);
continue;
}
if (stack.length) {
compressed.push(`!${stack.length}`);
}
stack = [];
compressed.push(dataRest[i]);
}
if (stack.length) {
compressed.push(`!${stack.length}`);
}
return [dataFirst, ...compressed];
}
static uncompress(data: (string | null)[], base: (string | null)[] | null, locale: string): (string | null)[] {
if (!base) {
return data;
}
const uncompressed = [];
let i = 0;
for (const piece of data) {
const m = piece?.match(/^!(\d+)$/);
if (!m) {
uncompressed.push(piece);
i++;
continue;
}
let skipped = parseInt(m[1]);
while (skipped--) {
uncompressed.push(base[i]);
i++;
}
}
// i know, i know…
if (locale === 'pl' && uncompressed.length === 24 && base.length === 25) {
return Compressor.uncompress(data, [...base.slice(0, 2), ...base.slice(3)], locale);
}
return uncompressed;
}
}