lz-worker.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. // Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
  2. // This work is free. You can redistribute it and/or modify it
  3. // under the terms of the WTFPL, Version 2
  4. // For more information see LICENSE.txt or http://www.wtfpl.net/
  5. //
  6. // For more information, the home page:
  7. // http://pieroxy.net/blog/pages/lz-string/testing.html
  8. //
  9. // LZ-based compression algorithm, version 1.4.4
  10. var LZString = (function () {
  11. // private property
  12. var f = String.fromCharCode;
  13. var keyStrBase64 =
  14. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  15. var keyStrUriSafe =
  16. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
  17. var baseReverseDic = {};
  18. function getBaseValue(alphabet, character) {
  19. if (!baseReverseDic[alphabet]) {
  20. baseReverseDic[alphabet] = {};
  21. for (var i = 0; i < alphabet.length; i++) {
  22. baseReverseDic[alphabet][alphabet.charAt(i)] = i;
  23. }
  24. }
  25. return baseReverseDic[alphabet][character];
  26. }
  27. var LZString = {
  28. compressToBase64: function (input) {
  29. if (input == null) return "";
  30. var res = LZString._compress(input, 6, function (a) {
  31. return keyStrBase64.charAt(a);
  32. });
  33. switch (
  34. res.length % 4 // To produce valid Base64
  35. ) {
  36. default: // When could this happen ?
  37. case 0:
  38. return res;
  39. case 1:
  40. return res + "===";
  41. case 2:
  42. return res + "==";
  43. case 3:
  44. return res + "=";
  45. }
  46. },
  47. decompressFromBase64: function (input) {
  48. if (input == null) return "";
  49. if (input == "") return null;
  50. return LZString._decompress(input.length, 32, function (index) {
  51. return getBaseValue(keyStrBase64, input.charAt(index));
  52. });
  53. },
  54. compressToUTF16: function (input) {
  55. if (input == null) return "";
  56. return (
  57. LZString._compress(input, 15, function (a) {
  58. return f(a + 32);
  59. }) + " "
  60. );
  61. },
  62. decompressFromUTF16: function (compressed) {
  63. if (compressed == null) return "";
  64. if (compressed == "") return null;
  65. return LZString._decompress(
  66. compressed.length,
  67. 16384,
  68. function (index) {
  69. return compressed.charCodeAt(index) - 32;
  70. },
  71. );
  72. },
  73. //compress into uint8array (UCS-2 big endian format)
  74. compressToUint8Array: function (uncompressed) {
  75. var compressed = LZString.compress(uncompressed);
  76. var buf = new Uint8Array(compressed.length * 2); // 2 bytes per character
  77. for (var i = 0, TotalLen = compressed.length; i < TotalLen; i++) {
  78. var current_value = compressed.charCodeAt(i);
  79. buf[i * 2] = current_value >>> 8;
  80. buf[i * 2 + 1] = current_value % 256;
  81. }
  82. return buf;
  83. },
  84. //decompress from uint8array (UCS-2 big endian format)
  85. decompressFromUint8Array: function (compressed) {
  86. if (compressed === null || compressed === undefined) {
  87. return LZString.decompress(compressed);
  88. } else {
  89. var buf = new Array(compressed.length / 2); // 2 bytes per character
  90. for (var i = 0, TotalLen = buf.length; i < TotalLen; i++) {
  91. buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1];
  92. }
  93. var result = [];
  94. buf.forEach(function (c) {
  95. result.push(f(c));
  96. });
  97. return LZString.decompress(result.join(""));
  98. }
  99. },
  100. //compress into a string that is already URI encoded
  101. compressToEncodedURIComponent: function (input) {
  102. if (input == null) return "";
  103. return LZString._compress(input, 6, function (a) {
  104. return keyStrUriSafe.charAt(a);
  105. });
  106. },
  107. //decompress from an output of compressToEncodedURIComponent
  108. decompressFromEncodedURIComponent: function (input) {
  109. if (input == null) return "";
  110. if (input == "") return null;
  111. input = input.replace(/ /g, "+");
  112. return LZString._decompress(input.length, 32, function (index) {
  113. return getBaseValue(keyStrUriSafe, input.charAt(index));
  114. });
  115. },
  116. compress: function (uncompressed) {
  117. return LZString._compress(uncompressed, 16, function (a) {
  118. return f(a);
  119. });
  120. },
  121. _compress: function (uncompressed, bitsPerChar, getCharFromInt) {
  122. if (uncompressed == null) return "";
  123. var i,
  124. value,
  125. context_dictionary = {},
  126. context_dictionaryToCreate = {},
  127. context_c = "",
  128. context_wc = "",
  129. context_w = "",
  130. context_enlargeIn = 2, // Compensate for the first entry which should not count
  131. context_dictSize = 3,
  132. context_numBits = 2,
  133. context_data = [],
  134. context_data_val = 0,
  135. context_data_position = 0,
  136. ii;
  137. for (ii = 0; ii < uncompressed.length; ii += 1) {
  138. context_c = uncompressed.charAt(ii);
  139. if (
  140. !Object.prototype.hasOwnProperty.call(
  141. context_dictionary,
  142. context_c,
  143. )
  144. ) {
  145. context_dictionary[context_c] = context_dictSize++;
  146. context_dictionaryToCreate[context_c] = true;
  147. }
  148. context_wc = context_w + context_c;
  149. if (
  150. Object.prototype.hasOwnProperty.call(
  151. context_dictionary,
  152. context_wc,
  153. )
  154. ) {
  155. context_w = context_wc;
  156. } else {
  157. if (
  158. Object.prototype.hasOwnProperty.call(
  159. context_dictionaryToCreate,
  160. context_w,
  161. )
  162. ) {
  163. if (context_w.charCodeAt(0) < 256) {
  164. for (i = 0; i < context_numBits; i++) {
  165. context_data_val = context_data_val << 1;
  166. if (context_data_position == bitsPerChar - 1) {
  167. context_data_position = 0;
  168. context_data.push(
  169. getCharFromInt(context_data_val),
  170. );
  171. context_data_val = 0;
  172. } else {
  173. context_data_position++;
  174. }
  175. }
  176. value = context_w.charCodeAt(0);
  177. for (i = 0; i < 8; i++) {
  178. context_data_val =
  179. (context_data_val << 1) | (value & 1);
  180. if (context_data_position == bitsPerChar - 1) {
  181. context_data_position = 0;
  182. context_data.push(
  183. getCharFromInt(context_data_val),
  184. );
  185. context_data_val = 0;
  186. } else {
  187. context_data_position++;
  188. }
  189. value = value >> 1;
  190. }
  191. } else {
  192. value = 1;
  193. for (i = 0; i < context_numBits; i++) {
  194. context_data_val =
  195. (context_data_val << 1) | value;
  196. if (context_data_position == bitsPerChar - 1) {
  197. context_data_position = 0;
  198. context_data.push(
  199. getCharFromInt(context_data_val),
  200. );
  201. context_data_val = 0;
  202. } else {
  203. context_data_position++;
  204. }
  205. value = 0;
  206. }
  207. value = context_w.charCodeAt(0);
  208. for (i = 0; i < 16; i++) {
  209. context_data_val =
  210. (context_data_val << 1) | (value & 1);
  211. if (context_data_position == bitsPerChar - 1) {
  212. context_data_position = 0;
  213. context_data.push(
  214. getCharFromInt(context_data_val),
  215. );
  216. context_data_val = 0;
  217. } else {
  218. context_data_position++;
  219. }
  220. value = value >> 1;
  221. }
  222. }
  223. context_enlargeIn--;
  224. if (context_enlargeIn == 0) {
  225. context_enlargeIn = Math.pow(2, context_numBits);
  226. context_numBits++;
  227. }
  228. delete context_dictionaryToCreate[context_w];
  229. } else {
  230. value = context_dictionary[context_w];
  231. for (i = 0; i < context_numBits; i++) {
  232. context_data_val =
  233. (context_data_val << 1) | (value & 1);
  234. if (context_data_position == bitsPerChar - 1) {
  235. context_data_position = 0;
  236. context_data.push(
  237. getCharFromInt(context_data_val),
  238. );
  239. context_data_val = 0;
  240. } else {
  241. context_data_position++;
  242. }
  243. value = value >> 1;
  244. }
  245. }
  246. context_enlargeIn--;
  247. if (context_enlargeIn == 0) {
  248. context_enlargeIn = Math.pow(2, context_numBits);
  249. context_numBits++;
  250. }
  251. // Add wc to the dictionary.
  252. context_dictionary[context_wc] = context_dictSize++;
  253. context_w = String(context_c);
  254. }
  255. }
  256. // Output the code for w.
  257. if (context_w !== "") {
  258. if (
  259. Object.prototype.hasOwnProperty.call(
  260. context_dictionaryToCreate,
  261. context_w,
  262. )
  263. ) {
  264. if (context_w.charCodeAt(0) < 256) {
  265. for (i = 0; i < context_numBits; i++) {
  266. context_data_val = context_data_val << 1;
  267. if (context_data_position == bitsPerChar - 1) {
  268. context_data_position = 0;
  269. context_data.push(
  270. getCharFromInt(context_data_val),
  271. );
  272. context_data_val = 0;
  273. } else {
  274. context_data_position++;
  275. }
  276. }
  277. value = context_w.charCodeAt(0);
  278. for (i = 0; i < 8; i++) {
  279. context_data_val =
  280. (context_data_val << 1) | (value & 1);
  281. if (context_data_position == bitsPerChar - 1) {
  282. context_data_position = 0;
  283. context_data.push(
  284. getCharFromInt(context_data_val),
  285. );
  286. context_data_val = 0;
  287. } else {
  288. context_data_position++;
  289. }
  290. value = value >> 1;
  291. }
  292. } else {
  293. value = 1;
  294. for (i = 0; i < context_numBits; i++) {
  295. context_data_val = (context_data_val << 1) | value;
  296. if (context_data_position == bitsPerChar - 1) {
  297. context_data_position = 0;
  298. context_data.push(
  299. getCharFromInt(context_data_val),
  300. );
  301. context_data_val = 0;
  302. } else {
  303. context_data_position++;
  304. }
  305. value = 0;
  306. }
  307. value = context_w.charCodeAt(0);
  308. for (i = 0; i < 16; i++) {
  309. context_data_val =
  310. (context_data_val << 1) | (value & 1);
  311. if (context_data_position == bitsPerChar - 1) {
  312. context_data_position = 0;
  313. context_data.push(
  314. getCharFromInt(context_data_val),
  315. );
  316. context_data_val = 0;
  317. } else {
  318. context_data_position++;
  319. }
  320. value = value >> 1;
  321. }
  322. }
  323. context_enlargeIn--;
  324. if (context_enlargeIn == 0) {
  325. context_enlargeIn = Math.pow(2, context_numBits);
  326. context_numBits++;
  327. }
  328. delete context_dictionaryToCreate[context_w];
  329. } else {
  330. value = context_dictionary[context_w];
  331. for (i = 0; i < context_numBits; i++) {
  332. context_data_val =
  333. (context_data_val << 1) | (value & 1);
  334. if (context_data_position == bitsPerChar - 1) {
  335. context_data_position = 0;
  336. context_data.push(getCharFromInt(context_data_val));
  337. context_data_val = 0;
  338. } else {
  339. context_data_position++;
  340. }
  341. value = value >> 1;
  342. }
  343. }
  344. context_enlargeIn--;
  345. if (context_enlargeIn == 0) {
  346. context_enlargeIn = Math.pow(2, context_numBits);
  347. context_numBits++;
  348. }
  349. }
  350. // Mark the end of the stream
  351. value = 2;
  352. for (i = 0; i < context_numBits; i++) {
  353. context_data_val = (context_data_val << 1) | (value & 1);
  354. if (context_data_position == bitsPerChar - 1) {
  355. context_data_position = 0;
  356. context_data.push(getCharFromInt(context_data_val));
  357. context_data_val = 0;
  358. } else {
  359. context_data_position++;
  360. }
  361. value = value >> 1;
  362. }
  363. // Flush the last char
  364. while (true) {
  365. context_data_val = context_data_val << 1;
  366. if (context_data_position == bitsPerChar - 1) {
  367. context_data.push(getCharFromInt(context_data_val));
  368. break;
  369. } else context_data_position++;
  370. }
  371. return context_data.join("");
  372. },
  373. decompress: function (compressed) {
  374. if (compressed == null) return "";
  375. if (compressed == "") return null;
  376. return LZString._decompress(
  377. compressed.length,
  378. 32768,
  379. function (index) {
  380. return compressed.charCodeAt(index);
  381. },
  382. );
  383. },
  384. _decompress: function (length, resetValue, getNextValue) {
  385. var dictionary = [],
  386. next,
  387. enlargeIn = 4,
  388. dictSize = 4,
  389. numBits = 3,
  390. entry = "",
  391. result = [],
  392. i,
  393. w,
  394. bits,
  395. resb,
  396. maxpower,
  397. power,
  398. c,
  399. data = { val: getNextValue(0), position: resetValue, index: 1 };
  400. for (i = 0; i < 3; i += 1) {
  401. dictionary[i] = i;
  402. }
  403. bits = 0;
  404. maxpower = Math.pow(2, 2);
  405. power = 1;
  406. while (power != maxpower) {
  407. resb = data.val & data.position;
  408. data.position >>= 1;
  409. if (data.position == 0) {
  410. data.position = resetValue;
  411. data.val = getNextValue(data.index++);
  412. }
  413. bits |= (resb > 0 ? 1 : 0) * power;
  414. power <<= 1;
  415. }
  416. switch ((next = bits)) {
  417. case 0:
  418. bits = 0;
  419. maxpower = Math.pow(2, 8);
  420. power = 1;
  421. while (power != maxpower) {
  422. resb = data.val & data.position;
  423. data.position >>= 1;
  424. if (data.position == 0) {
  425. data.position = resetValue;
  426. data.val = getNextValue(data.index++);
  427. }
  428. bits |= (resb > 0 ? 1 : 0) * power;
  429. power <<= 1;
  430. }
  431. c = f(bits);
  432. break;
  433. case 1:
  434. bits = 0;
  435. maxpower = Math.pow(2, 16);
  436. power = 1;
  437. while (power != maxpower) {
  438. resb = data.val & data.position;
  439. data.position >>= 1;
  440. if (data.position == 0) {
  441. data.position = resetValue;
  442. data.val = getNextValue(data.index++);
  443. }
  444. bits |= (resb > 0 ? 1 : 0) * power;
  445. power <<= 1;
  446. }
  447. c = f(bits);
  448. break;
  449. case 2:
  450. return "";
  451. }
  452. dictionary[3] = c;
  453. w = c;
  454. result.push(c);
  455. while (true) {
  456. if (data.index > length) {
  457. return "";
  458. }
  459. bits = 0;
  460. maxpower = Math.pow(2, numBits);
  461. power = 1;
  462. while (power != maxpower) {
  463. resb = data.val & data.position;
  464. data.position >>= 1;
  465. if (data.position == 0) {
  466. data.position = resetValue;
  467. data.val = getNextValue(data.index++);
  468. }
  469. bits |= (resb > 0 ? 1 : 0) * power;
  470. power <<= 1;
  471. }
  472. switch ((c = bits)) {
  473. case 0:
  474. bits = 0;
  475. maxpower = Math.pow(2, 8);
  476. power = 1;
  477. while (power != maxpower) {
  478. resb = data.val & data.position;
  479. data.position >>= 1;
  480. if (data.position == 0) {
  481. data.position = resetValue;
  482. data.val = getNextValue(data.index++);
  483. }
  484. bits |= (resb > 0 ? 1 : 0) * power;
  485. power <<= 1;
  486. }
  487. dictionary[dictSize++] = f(bits);
  488. c = dictSize - 1;
  489. enlargeIn--;
  490. break;
  491. case 1:
  492. bits = 0;
  493. maxpower = Math.pow(2, 16);
  494. power = 1;
  495. while (power != maxpower) {
  496. resb = data.val & data.position;
  497. data.position >>= 1;
  498. if (data.position == 0) {
  499. data.position = resetValue;
  500. data.val = getNextValue(data.index++);
  501. }
  502. bits |= (resb > 0 ? 1 : 0) * power;
  503. power <<= 1;
  504. }
  505. dictionary[dictSize++] = f(bits);
  506. c = dictSize - 1;
  507. enlargeIn--;
  508. break;
  509. case 2:
  510. return result.join("");
  511. }
  512. if (enlargeIn == 0) {
  513. enlargeIn = Math.pow(2, numBits);
  514. numBits++;
  515. }
  516. if (dictionary[c]) {
  517. entry = dictionary[c];
  518. } else {
  519. if (c === dictSize) {
  520. entry = w + w.charAt(0);
  521. } else {
  522. return null;
  523. }
  524. }
  525. result.push(entry);
  526. // Add w+entry[0] to the dictionary.
  527. dictionary[dictSize++] = w + entry.charAt(0);
  528. enlargeIn--;
  529. w = entry;
  530. if (enlargeIn == 0) {
  531. enlargeIn = Math.pow(2, numBits);
  532. numBits++;
  533. }
  534. }
  535. },
  536. };
  537. return LZString;
  538. })();
  539. // receive data from a JavaScript file
  540. onmessage = ({ data }) => {
  541. const { code } = data ?? {};
  542. if (code) {
  543. const compressed = LZString.compressToEncodedURIComponent(code);
  544. postMessage({ compressed });
  545. }
  546. };