Repository URL to install this package:
|
Version:
1.2.14 ▾
|
"use strict";
/**
* @author Pieroxy <pieroxy@pieroxy.net>
* @see http://pieroxy.net/blog/pages/lz-string/testing.html
* @name LZ-based compression algorithm
* @version 1.3.3
*
* @see https://www.html5rocks.com/en/tutorials/speed/txt-compression/
*
* @file essentially we can compress our strings into numbers and it's much smaller
* to avoid local storage maximum issues
*
* @todo https://github.com/kawanet/msgpack-lite
*/
var LZString = {
// * private property
_keyStr: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
_f: String.fromCharCode,
compressToBase64(input) {
if (input == null) {
return '';
}
let output = '';
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
let i = 0;
input = LZString.compress(input);
while (i < input.length * 2) {
if (i % 2 == 0) {
chr1 = input.charCodeAt(i / 2) >> 8;
chr2 = input.charCodeAt(i / 2) & 255;
if (i / 2 + 1 < input.length) {
chr3 = input.charCodeAt(i / 2 + 1) >> 8;
} else {
chr3 = NaN;
}
} else {
chr1 = input.charCodeAt((i - 1) / 2) & 255;
if ((i + 1) / 2 < input.length) {
chr2 = input.charCodeAt((i + 1) / 2) >> 8;
chr3 = input.charCodeAt((i + 1) / 2) & 255;
} else {
chr2 = chr3 = NaN;
}
}
i += 3;
enc1 = chr1 >> 2;
enc2 = (chr1 & 3) << 4 | chr2 >> 4;
enc3 = (chr2 & 15) << 2 | chr3 >> 6;
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + LZString._keyStr.charAt(enc1) + LZString._keyStr.charAt(enc2) + LZString._keyStr.charAt(enc3) + LZString._keyStr.charAt(enc4);
}
return output;
},
decompressFromBase64(input) {
if (input == null) {
return '';
}
let output = '',
ol = 0,
output_,
chr1,
chr2,
chr3,
enc1,
enc2,
enc3,
enc4,
i = 0,
f = LZString._f;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (i < input.length) {
enc1 = LZString._keyStr.indexOf(input.charAt(i++));
enc2 = LZString._keyStr.indexOf(input.charAt(i++));
enc3 = LZString._keyStr.indexOf(input.charAt(i++));
enc4 = LZString._keyStr.indexOf(input.charAt(i++));
chr1 = enc1 << 2 | enc2 >> 4;
chr2 = (enc2 & 15) << 4 | enc3 >> 2;
chr3 = (enc3 & 3) << 6 | enc4;
if (ol % 2 == 0) {
output_ = chr1 << 8;
if (enc3 != 64) {
output += f(output_ | chr2);
}
if (enc4 != 64) {
output_ = chr3 << 8;
}
} else {
output = output + f(output_ | chr1);
if (enc3 != 64) {
output_ = chr2 << 8;
}
if (enc4 != 64) {
output += f(output_ | chr3);
}
}
ol += 3;
}
return LZString.decompress(output);
},
compressToUTF16(input) {
if (input == null) {
return '';
}
let output = '',
i,
c,
current,
status = 0,
f = LZString._f;
input = LZString.compress(input);
for (i = 0; i < input.length; i++) {
c = input.charCodeAt(i);
switch (status++) {
case 0:
output += f((c >> 1) + 32);
current = (c & 1) << 14;
break;
case 1:
output += f(current + (c >> 2) + 32);
current = (c & 3) << 13;
break;
case 2:
output += f(current + (c >> 3) + 32);
current = (c & 7) << 12;
break;
case 3:
output += f(current + (c >> 4) + 32);
current = (c & 15) << 11;
break;
case 4:
output += f(current + (c >> 5) + 32);
current = (c & 31) << 10;
break;
case 5:
output += f(current + (c >> 6) + 32);
current = (c & 63) << 9;
break;
case 6:
output += f(current + (c >> 7) + 32);
current = (c & 127) << 8;
break;
case 7:
output += f(current + (c >> 8) + 32);
current = (c & 255) << 7;
break;
case 8:
output += f(current + (c >> 9) + 32);
current = (c & 511) << 6;
break;
case 9:
output += f(current + (c >> 10) + 32);
current = (c & 1023) << 5;
break;
case 10:
output += f(current + (c >> 11) + 32);
current = (c & 2047) << 4;
break;
case 11:
output += f(current + (c >> 12) + 32);
current = (c & 4095) << 3;
break;
case 12:
output += f(current + (c >> 13) + 32);
current = (c & 8191) << 2;
break;
case 13:
output += f(current + (c >> 14) + 32);
current = (c & 16383) << 1;
break;
case 14:
output += f(current + (c >> 15) + 32, (c & 32767) + 32);
status = 0;
break;
}
}
return output + f(current + 32);
},
decompressFromUTF16(input) {
if (input == null) {
return '';
}
let output = '',
current,
c,
status = 0,
i = 0,
f = LZString._f;
while (i < input.length) {
c = input.charCodeAt(i) - 32;
switch (status++) {
case 0:
current = c << 1;
break;
case 1:
output += f(current | c >> 14);
current = (c & 16383) << 2;
break;
case 2:
output += f(current | c >> 13);
current = (c & 8191) << 3;
break;
case 3:
output += f(current | c >> 12);
current = (c & 4095) << 4;
break;
case 4:
output += f(current | c >> 11);
current = (c & 2047) << 5;
break;
case 5:
output += f(current | c >> 10);
current = (c & 1023) << 6;
break;
case 6:
output += f(current | c >> 9);
current = (c & 511) << 7;
break;
case 7:
output += f(current | c >> 8);
current = (c & 255) << 8;
break;
case 8:
output += f(current | c >> 7);
current = (c & 127) << 9;
break;
case 9:
output += f(current | c >> 6);
current = (c & 63) << 10;
break;
case 10:
output += f(current | c >> 5);
current = (c & 31) << 11;
break;
case 11:
output += f(current | c >> 4);
current = (c & 15) << 12;
break;
case 12:
output += f(current | c >> 3);
current = (c & 7) << 13;
break;
case 13:
output += f(current | c >> 2);
current = (c & 3) << 14;
break;
case 14:
output += f(current | c >> 1);
current = (c & 1) << 15;
break;
case 15:
output += f(current | c);
status = 0;
break;
}
i++;
}
return LZString.decompress(output); // return output;
},
compress(uncompressed) {
if (uncompressed == null) {
return '';
}
let i,
value,
context_dictionary = {},
context_dictionaryToCreate = {},
context_c = '',
context_wc = '',
context_w = '',
context_enlargeIn = 2,
// Compensate for the first entry which should not count
context_dictSize = 3,
context_numBits = 2,
context_data_string = '',
context_data_val = 0,
context_data_position = 0,
ii,
f = LZString._f;
for (ii = 0; ii < uncompressed.length; ii += 1) {
context_c = uncompressed.charAt(ii);
if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
context_dictionary[context_c] = context_dictSize++;
context_dictionaryToCreate[context_c] = true;
}
context_wc = context_w + context_c;
if (Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)) {
context_w = context_wc;
} else {
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
if (context_w.charCodeAt(0) < 256) {
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
}
value = context_w.charCodeAt(0);
for (i = 0; i < 8; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
} else {
value = 1;
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1 | value;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = 0;
}
value = context_w.charCodeAt(0);
for (i = 0; i < 16; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
delete context_dictionaryToCreate[context_w];
} else {
value = context_dictionary[context_w];
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
} // Add wc to the dictionary.
context_dictionary[context_wc] = context_dictSize++;
context_w = String(context_c);
}
} // Output the code for w.
if (context_w !== '') {
if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate, context_w)) {
if (context_w.charCodeAt(0) < 256) {
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
}
value = context_w.charCodeAt(0);
for (i = 0; i < 8; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
} else {
value = 1;
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1 | value;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = 0;
}
value = context_w.charCodeAt(0);
for (i = 0; i < 16; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
delete context_dictionaryToCreate[context_w];
} else {
value = context_dictionary[context_w];
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
}
}
context_enlargeIn--;
if (context_enlargeIn == 0) {
context_enlargeIn = Math.pow(2, context_numBits);
context_numBits++;
}
} // Mark the end of the stream
value = 2;
for (i = 0; i < context_numBits; i++) {
context_data_val = context_data_val << 1 | value & 1;
if (context_data_position == 15) {
context_data_position = 0;
context_data_string += f(context_data_val);
context_data_val = 0;
} else {
context_data_position++;
}
value = value >> 1;
} // Flush the last char
while (true) {
context_data_val = context_data_val << 1;
if (context_data_position == 15) {
context_data_string += f(context_data_val);
break;
} else {
context_data_position++;
}
}
return context_data_string;
},
decompress(compressed) {
if (compressed == null) {
return '';
}
if (compressed == '') {
return null;
}
let dictionary = [],
next,
enlargeIn = 4,
dictSize = 4,
numBits = 3,
entry = '',
result = '',
i,
w,
bits,
resb,
maxpower,
power,
c,
f = LZString._f,
data = {
string: compressed,
val: compressed.charCodeAt(0),
position: 32768,
index: 1
};
for (i = 0; i < 3; i += 1) {
dictionary[i] = i;
}
bits = 0;
maxpower = Math.pow(2, 2);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = 32768;
data.val = data.string.charCodeAt(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
switch (next = bits) {
case 0:
bits = 0;
maxpower = Math.pow(2, 8);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = 32768;
data.val = data.string.charCodeAt(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
c = f(bits);
break;
case 1:
bits = 0;
maxpower = Math.pow(2, 16);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = 32768;
data.val = data.string.charCodeAt(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
c = f(bits);
break;
case 2:
return '';
}
dictionary[3] = c;
w = result = c;
while (true) {
if (data.index > data.string.length) {
return '';
}
bits = 0;
maxpower = Math.pow(2, numBits);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = 32768;
data.val = data.string.charCodeAt(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
switch (c = bits) {
case 0:
bits = 0;
maxpower = Math.pow(2, 8);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = 32768;
data.val = data.string.charCodeAt(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
dictionary[dictSize++] = f(bits);
c = dictSize - 1;
enlargeIn--;
break;
case 1:
bits = 0;
maxpower = Math.pow(2, 16);
power = 1;
while (power != maxpower) {
resb = data.val & data.position;
data.position >>= 1;
if (data.position == 0) {
data.position = 32768;
data.val = data.string.charCodeAt(data.index++);
}
bits |= (resb > 0 ? 1 : 0) * power;
power <<= 1;
}
dictionary[dictSize++] = f(bits);
c = dictSize - 1;
enlargeIn--;
break;
case 2:
return result;
}
if (enlargeIn == 0) {
enlargeIn = Math.pow(2, numBits);
numBits++;
}
if (dictionary[c]) {
entry = dictionary[c];
} else if (c === dictSize) {
entry = w + w.charAt(0);
} else {
return null;
}
result += entry; // Add w+entry[0] to the dictionary.
dictionary[dictSize++] = w + entry.charAt(0);
enlargeIn--;
w = entry;
if (enlargeIn == 0) {
enlargeIn = Math.pow(2, numBits);
numBits++;
}
}
}
};
if (typeof module !== 'undefined' && module != null) {
module.exports = LZString;
}
/**
* @example
*/
function onReady() {
let jsonobj = {
'sample': 'This is supposed to be ling string',
'score': 'another long string which is going to be compressed'
};
let string = JSON.stringify(jsonobj);
alert('Size of sample is: ' + string.length);
let compressed = LZString.compress(string);
localStorage.setItem('mystring', compressed);
alert('Size of compressed sample is: ' + localStorage.getItem('mystring').length);
alert('Compressed localstorage item is: ' + localStorage.getItem('mystring'));
string = LZString.decompress(localStorage.getItem('mystring'));
alert('Decompressed sample is: ' + string);
}