zip.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. var zip = zip || {};
  2. var zlib = zlib || {};
  3. zip.Archive = class {
  4. static open(data) {
  5. const stream = data instanceof Uint8Array ? new zip.BinaryReader(data) : data;
  6. if (stream.length > 2) {
  7. const buffer = stream.peek(2);
  8. if (buffer[0] === 0x78) { // zlib
  9. const check = (buffer[0] << 8) + buffer[1];
  10. if (check % 31 === 0) {
  11. return new zlib.Archive(stream);
  12. }
  13. }
  14. const signature = buffer[0] === 0x50 && buffer[1] === 0x4B;
  15. const position = stream.position;
  16. const seek = (content) => {
  17. let position = stream.length;
  18. do {
  19. position = Math.max(0, position - 66000);
  20. stream.seek(position);
  21. const length = Math.min(stream.length - position, 66000 + 4);
  22. const buffer = stream.read(length);
  23. for (let i = buffer.length - 4; i >= 0; i--) {
  24. if (content[0] === buffer[i] && content[1] === buffer[i + 1] && content[2] === buffer[i + 2] && content[3] === buffer[i + 3]) {
  25. stream.seek(position + i + 4);
  26. return true;
  27. }
  28. }
  29. if (!signature) {
  30. break;
  31. }
  32. }
  33. while (position > 0);
  34. return false;
  35. };
  36. if (!seek([ 0x50, 0x4B, 0x05, 0x06 ])) {
  37. stream.seek(position);
  38. if (!signature) {
  39. return null;
  40. }
  41. throw new zip.Error('End of Zip central directory not found.');
  42. }
  43. const reader = new zip.BinaryReader(stream.read(16));
  44. reader.skip(12);
  45. let offset = reader.uint32(); // central directory offset
  46. if (offset > stream.length) {
  47. if (!seek([ 0x50, 0x4B, 0x06, 0x06 ])) {
  48. stream.seek(position);
  49. throw new zip.Error('End of Zip64 central directory not found.');
  50. }
  51. const reader = new zip.BinaryReader(stream.read(52));
  52. reader.skip(44);
  53. offset = reader.uint32();
  54. if (reader.uint32() !== 0) {
  55. stream.seek(position);
  56. throw new zip.Error('Zip 64-bit central directory offset not supported.');
  57. }
  58. }
  59. if (offset > stream.length) {
  60. stream.seek(position);
  61. throw new zip.Error('Invalid Zip central directory offset.');
  62. }
  63. stream.seek(offset);
  64. const archive = new zip.Archive(stream);
  65. stream.seek(position);
  66. return archive;
  67. }
  68. return null;
  69. }
  70. constructor(stream) {
  71. this._entries = new Map();
  72. const headers = [];
  73. const signature = [ 0x50, 0x4B, 0x01, 0x02 ];
  74. while (stream.position + 4 < stream.length && stream.read(4).every((value, index) => value === signature[index])) {
  75. const header = {};
  76. const reader = new zip.BinaryReader(stream.read(42));
  77. reader.uint16(); // version made by
  78. reader.skip(2); // version needed to extract
  79. const flags = reader.uint16();
  80. if ((flags & 1) == 1) {
  81. throw new zip.Error('Encrypted Zip entries not supported.');
  82. }
  83. header.encoding = flags & 0x800 ? 'utf-8' : 'ascii';
  84. header.compressionMethod = reader.uint16();
  85. reader.uint32(); // date
  86. reader.uint32(); // crc32
  87. header.compressedSize = reader.uint32();
  88. header.size = reader.uint32();
  89. header.nameLength = reader.uint16(); // file name length
  90. const extraDataLength = reader.uint16();
  91. const commentLength = reader.uint16();
  92. header.disk = reader.uint16(); // disk number start
  93. reader.uint16(); // internal file attributes
  94. reader.uint32(); // external file attributes
  95. header.localHeaderOffset = reader.uint32();
  96. const nameBuffer = stream.read(header.nameLength);
  97. const decoder = new TextDecoder(header.encoding);
  98. header.name = decoder.decode(nameBuffer);
  99. const extraData = stream.read(extraDataLength);
  100. if (extraData.length > 0) {
  101. const reader = new zip.BinaryReader(extraData);
  102. while (reader.position < reader.length) {
  103. const type = reader.uint16();
  104. const length = reader.uint16();
  105. switch (type) {
  106. case 0x0001:
  107. if (header.size === 0xffffffff) {
  108. header.size = reader.uint32();
  109. if (reader.uint32() !== 0) {
  110. throw new zip.Error('Zip 64-bit offset not supported.');
  111. }
  112. }
  113. if (header.compressedSize === 0xffffffff) {
  114. header.compressedSize = reader.uint32();
  115. if (reader.uint32() !== 0) {
  116. throw new zip.Error('Zip 64-bit offset not supported.');
  117. }
  118. }
  119. if (header.localHeaderOffset === 0xffffffff) {
  120. header.localHeaderOffset = reader.uint32();
  121. if (reader.uint32() !== 0) {
  122. throw new zip.Error('Zip 64-bit offset not supported.');
  123. }
  124. }
  125. if (header.disk === 0xffff) {
  126. header.disk = reader.uint32();
  127. }
  128. break;
  129. default:
  130. reader.skip(length);
  131. break;
  132. }
  133. }
  134. }
  135. stream.read(commentLength); // comment
  136. headers.push(header);
  137. }
  138. for (const header of headers) {
  139. if (header.size === 0 && header.name.endsWith('/')) {
  140. continue;
  141. }
  142. const entry = new zip.Entry(stream, header);
  143. this._entries.set(entry.name, entry.stream);
  144. }
  145. }
  146. get entries() {
  147. return this._entries;
  148. }
  149. };
  150. zip.Entry = class {
  151. constructor(stream, header) {
  152. stream.seek(header.localHeaderOffset);
  153. const signature = [ 0x50, 0x4B, 0x03, 0x04 ];
  154. if (stream.position + 4 > stream.length || !stream.read(4).every((value, index) => value === signature[index])) {
  155. throw new zip.Error('Invalid Zip local file header signature.');
  156. }
  157. const reader = new zip.BinaryReader(stream.read(26));
  158. reader.skip(22);
  159. header.nameLength = reader.uint16();
  160. const extraDataLength = reader.uint16();
  161. header.nameBuffer = stream.read(header.nameLength);
  162. stream.skip(extraDataLength);
  163. const decoder = new TextDecoder(header.encoding);
  164. this._name = decoder.decode(header.nameBuffer);
  165. this._stream = stream.stream(header.compressedSize);
  166. switch (header.compressionMethod) {
  167. case 0: { // stored
  168. if (header.size !== header.compressedSize) {
  169. throw new zip.Error('Invalid compression size.');
  170. }
  171. break;
  172. }
  173. case 8: { // deflate
  174. this._stream = new zip.InflaterStream(this._stream, header.size);
  175. break;
  176. }
  177. default:
  178. throw new zip.Error('Invalid compression method.');
  179. }
  180. }
  181. get name() {
  182. return this._name;
  183. }
  184. get stream() {
  185. return this._stream;
  186. }
  187. };
  188. zip.Inflater = class {
  189. inflateRaw(data, length) {
  190. let buffer = null;
  191. if (typeof process === 'object' && typeof process.versions == 'object' && typeof process.versions.node !== 'undefined') {
  192. buffer = require('zlib').inflateRawSync(data);
  193. }
  194. else {
  195. const reader = new zip.BitReader(data);
  196. const writer = length === undefined ? new zip.BlockWriter() : new zip.BufferWriter(length);
  197. if (!zip.Inflater._staticLengthTree) {
  198. zip.Inflater._codeLengths = new Uint8Array(19);
  199. zip.Inflater._codeOrder = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
  200. zip.Inflater._lengthBase = [ 24, 32, 40, 48, 56, 64, 72, 80, 89, 105, 121, 137, 154, 186, 218, 250, 283, 347, 411, 475, 540, 668, 796, 924, 1053, 1309, 1565, 1821, 2064, 7992, 7992, 7992 ];
  201. zip.Inflater._distanceBase = [ 16, 32, 48, 64, 81, 113, 146, 210, 275, 403, 532, 788, 1045, 1557, 2070, 3094, 4119, 6167, 8216, 12312, 16409, 24601, 32794, 49178, 65563, 98331, 131100, 196636, 262173, 393245, 1048560, 1048560 ];
  202. }
  203. let type;
  204. do {
  205. type = reader.bits(3);
  206. switch (type >>> 1) {
  207. case 0: { // uncompressed block
  208. this._copyUncompressedBlock(reader, writer);
  209. break;
  210. }
  211. case 1: { // block with fixed huffman trees
  212. if (!zip.Inflater._staticLengthTree) {
  213. zip.Inflater._staticLengthTree = zip.HuffmanTree.create(new Uint8Array([].concat.apply([], [[144, 8], [112, 9], [24, 7], [8, 8]].map((x) => [...Array(x[0])].map(() => x[1])))));
  214. zip.Inflater._staticDistanceTree = zip.HuffmanTree.create(new Uint8Array([...Array(32)].map(() => 5)));
  215. }
  216. this._lengthTree = zip.Inflater._staticLengthTree;
  217. this._distanceTree = zip.Inflater._staticDistanceTree;
  218. this._inflateBlock(reader, writer);
  219. break;
  220. }
  221. case 2: { // block with dynamic huffman trees
  222. this._decodeTrees(reader);
  223. this._inflateBlock(reader, writer);
  224. break;
  225. }
  226. default: {
  227. throw new zip.Error('Unsupported block type.');
  228. }
  229. }
  230. } while ((type & 1) == 0);
  231. if (length !== undefined && length !== writer.length) {
  232. throw new zip.Error('Invalid uncompressed size.');
  233. }
  234. buffer = writer.toBuffer();
  235. }
  236. if (length !== undefined && length !== buffer.length) {
  237. throw new zip.Error('Invalid uncompressed size.');
  238. }
  239. return buffer;
  240. }
  241. _copyUncompressedBlock(reader, writer) {
  242. const length = reader.uint16();
  243. const inverseLength = reader.uint16();
  244. if (length !== (~inverseLength & 0xffff)) {
  245. throw new zip.Error('Invalid uncompressed block length.');
  246. }
  247. writer.write(reader.read(length));
  248. }
  249. _decodeTrees(reader) {
  250. const hlit = reader.bits(5) + 257;
  251. const hdist = reader.bits(5) + 1;
  252. const hclen = reader.bits(4) + 4;
  253. const codeLengths = zip.Inflater._codeLengths;
  254. for (let i = 0; i < codeLengths.length; i++) {
  255. codeLengths[i] = 0;
  256. }
  257. const codeOrder = zip.Inflater._codeOrder;
  258. for (let i = 0; i < hclen; i++) {
  259. codeLengths[codeOrder[i]] = reader.bits(3);
  260. }
  261. const codeTree = zip.HuffmanTree.create(codeLengths);
  262. const codeMask = codeTree.length - 1;
  263. const lengths = new Uint8Array(hlit + hdist);
  264. let value = 0;
  265. let length = 0;
  266. for (let i = 0; i < hlit + hdist;) {
  267. const code = codeTree[reader.bits16() & codeMask];
  268. reader.position += code & 0x0f;
  269. const literal = code >>> 4;
  270. switch (literal) {
  271. case 16: length = reader.bits(2) + 3; break;
  272. case 17: length = reader.bits(3) + 3; value = 0; break;
  273. case 18: length = reader.bits(7) + 11; value = 0; break;
  274. default: length = 1; value = literal; break;
  275. }
  276. for (; length > 0; length--) {
  277. lengths[i++] = value;
  278. }
  279. }
  280. this._lengthTree = zip.HuffmanTree.create(lengths.subarray(0, hlit));
  281. this._distanceTree = zip.HuffmanTree.create(lengths.subarray(hlit, hlit + hdist));
  282. }
  283. _inflateBlock(reader, writer) {
  284. const lengthTree = this._lengthTree;
  285. const distanceTree = this._distanceTree;
  286. const lengthMask = lengthTree.length - 1;
  287. const distanceMask = distanceTree.length - 1;
  288. const buffer = writer.buffer;
  289. const threshold = writer.threshold !== undefined ? writer.threshold : writer.length;
  290. let position = writer.position;
  291. for (;;) {
  292. if (position > threshold) {
  293. position = writer.push(position);
  294. }
  295. const code = lengthTree[reader.bits16() & lengthMask];
  296. reader.position += code & 0x0f;
  297. const literal = code >>> 4;
  298. if (literal < 256) {
  299. buffer[position++] = literal;
  300. }
  301. else if (literal === 256) {
  302. writer.push(position);
  303. return;
  304. }
  305. else {
  306. let length = literal - 254;
  307. if (literal > 264) {
  308. const lengthBase = zip.Inflater._lengthBase[literal - 257];
  309. length = (lengthBase >>> 3) + reader.bits(lengthBase & 0x07);
  310. }
  311. const code = distanceTree[reader.bits16() & distanceMask];
  312. reader.position += code & 0x0f;
  313. const distanceBase = zip.Inflater._distanceBase[code >>> 4];
  314. const bits = distanceBase & 0x0f;
  315. const distance = (distanceBase >>> 4) + (reader.bits16() & ((1 << bits) - 1));
  316. reader.position += bits;
  317. let offset = position - distance;
  318. for (let i = 0; i < length; i++) {
  319. buffer[position++] = buffer[offset++];
  320. }
  321. }
  322. }
  323. }
  324. };
  325. zip.HuffmanTree = class {
  326. static create(tree) {
  327. let bits = tree[0];
  328. for (let i = 1; i < tree.length; ++i) {
  329. if (tree[i] > bits) {
  330. bits = tree[i];
  331. }
  332. }
  333. // Algorithm from https://github.com/photopea/UZIP.js
  334. let rev15 = zip.HuffmanTree._rev15;
  335. if (!rev15) {
  336. const length = 1 << 15;
  337. rev15 = new Uint16Array(length);
  338. for (let i = 0; i < length; i++) {
  339. let x = i;
  340. x = (((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1));
  341. x = (((x & 0xcccccccc) >>> 2) | ((x & 0x33333333) << 2));
  342. x = (((x & 0xf0f0f0f0) >>> 4) | ((x & 0x0f0f0f0f) << 4));
  343. x = (((x & 0xff00ff00) >>> 8) | ((x & 0x00ff00ff) << 8));
  344. rev15[i] = (((x >>> 16) | (x << 16))) >>> 17;
  345. }
  346. zip.HuffmanTree._rev15 = rev15;
  347. zip.HuffmanTree._bitLengthCounts = new Uint16Array(16);
  348. zip.HuffmanTree._nextCodes = new Uint16Array(16);
  349. }
  350. const length = tree.length;
  351. const bitLengthCounts = zip.HuffmanTree._bitLengthCounts;
  352. for (let i = 0; i < 16; i++) {
  353. bitLengthCounts[i] = 0;
  354. }
  355. for (let i = 0; i < length; i++) {
  356. bitLengthCounts[tree[i]]++;
  357. }
  358. const nextCodes = zip.HuffmanTree._nextCodes;
  359. let code = 0;
  360. bitLengthCounts[0] = 0;
  361. for (let i = 0; i < bits; i++) {
  362. code = (code + bitLengthCounts[i]) << 1;
  363. nextCodes[i + 1] = code;
  364. }
  365. const codes = new Uint16Array(length);
  366. for (let i = 0; i < length; i++) {
  367. const index = tree[i];
  368. if (index !== 0) {
  369. codes[i] = nextCodes[index];
  370. nextCodes[index]++;
  371. }
  372. }
  373. const shift = 15 - bits;
  374. const table = new Uint16Array(1 << bits);
  375. for (let i = 0; i < length; i++) {
  376. const c = tree[i];
  377. if (c !== 0) {
  378. const value = (i << 4) | c;
  379. const rest = bits - c;
  380. let index = codes[i] << rest;
  381. const max = index + (1 << rest);
  382. for (; index != max; index++) {
  383. table[rev15[index] >>> shift] = value;
  384. }
  385. }
  386. }
  387. return table;
  388. }
  389. };
  390. zip.BitReader = class {
  391. constructor(buffer) {
  392. this.buffer = buffer;
  393. this.position = 0;
  394. }
  395. bits(count) {
  396. const offset = (this.position / 8) >> 0;
  397. const shift = (this.position & 7);
  398. this.position += count;
  399. return ((this.buffer[offset] | (this.buffer[offset + 1] << 8)) >>> shift) & ((1 << count) - 1);
  400. }
  401. bits16() {
  402. const offset = (this.position / 8) >> 0;
  403. return ((this.buffer[offset] | (this.buffer[offset + 1] << 8) | (this.buffer[offset + 2] << 16)) >>> (this.position & 7));
  404. }
  405. read(length) {
  406. this.position = (this.position + 7) & ~7; // align
  407. const offset = (this.position / 8) >> 0;
  408. this.position += length * 8;
  409. return this.buffer.subarray(offset, offset + length);
  410. }
  411. uint16() {
  412. this.position = (this.position + 7) & ~7; // align
  413. const offset = (this.position / 8) >> 0;
  414. this.position += 16;
  415. return this.buffer[offset] | (this.buffer[offset + 1] << 8);
  416. }
  417. };
  418. zip.BlockWriter = class {
  419. constructor() {
  420. this.blocks = [];
  421. this.buffer = new Uint8Array(65536);
  422. this.position = 0;
  423. this.length = 0;
  424. this.threshold = 0xf400;
  425. }
  426. push(position) {
  427. this.blocks.push(new Uint8Array(this.buffer.subarray(this.position, position)));
  428. this.length += position - this.position;
  429. this.position = position;
  430. return this._reset();
  431. }
  432. write(buffer) {
  433. this.blocks.push(buffer);
  434. const length = buffer.length;
  435. this.length += length;
  436. if (length > 32768) {
  437. this.buffer.set(buffer.subarray(length - 32768, length), 0);
  438. this.position = 32768;
  439. }
  440. else {
  441. this._reset();
  442. this.buffer.set(buffer, this.position);
  443. this.position += length;
  444. }
  445. }
  446. toBuffer() {
  447. const buffer = new Uint8Array(this.length);
  448. let offset = 0;
  449. for (const block of this.blocks) {
  450. buffer.set(block, offset);
  451. offset += block.length;
  452. }
  453. return buffer;
  454. }
  455. _reset() {
  456. if (this.position > 32768) {
  457. this.buffer.set(this.buffer.subarray(this.position - 32768, this.position), 0);
  458. this.position = 32768;
  459. }
  460. return this.position;
  461. }
  462. };
  463. zip.BufferWriter = class {
  464. constructor(length) {
  465. this.buffer = new Uint8Array(length);
  466. this.length = length;
  467. this.position = 0;
  468. }
  469. push(position) {
  470. this.position = position;
  471. if (this.position > this.length) {
  472. throw new zip.Error('Invalid size.');
  473. }
  474. return this.position;
  475. }
  476. write(buffer) {
  477. this.buffer.set(buffer, this.position);
  478. this.position += buffer.length;
  479. if (this.position > this.length) {
  480. throw new zip.Error('Invalid size.');
  481. }
  482. return this.position;
  483. }
  484. toBuffer() {
  485. return this.buffer;
  486. }
  487. };
  488. zip.InflaterStream = class {
  489. constructor(stream, length) {
  490. this._stream = stream;
  491. this._offset = this._stream.position;
  492. this._position = 0;
  493. this._length = length;
  494. }
  495. get position() {
  496. return this._position;
  497. }
  498. get length() {
  499. if (this._length === undefined) {
  500. this._inflate();
  501. }
  502. return this._length;
  503. }
  504. seek(position) {
  505. if (this._buffer === undefined) {
  506. this._inflate();
  507. }
  508. this._position = position >= 0 ? position : this._length + position;
  509. }
  510. skip(offset) {
  511. if (this._buffer === undefined) {
  512. this._inflate();
  513. }
  514. this._position += offset;
  515. }
  516. peek(length) {
  517. const position = this._position;
  518. length = length !== undefined ? length : this._length - position;
  519. this.skip(length);
  520. const end = this._position;
  521. this.seek(position);
  522. if (position === 0 && length === this._length) {
  523. return this._buffer;
  524. }
  525. return this._buffer.subarray(position, end);
  526. }
  527. read(length) {
  528. const position = this._position;
  529. length = length !== undefined ? length : this._length - position;
  530. this.skip(length);
  531. if (position === 0 && length === this._length) {
  532. return this._buffer;
  533. }
  534. return this._buffer.subarray(position, this._position);
  535. }
  536. byte() {
  537. const position = this._position;
  538. this.skip(1);
  539. return this._buffer[position];
  540. }
  541. _inflate() {
  542. if (this._buffer === undefined) {
  543. const position = this._stream.position;
  544. this._stream.seek(this._offset);
  545. const buffer = this._stream.peek();
  546. this._buffer = new zip.Inflater().inflateRaw(buffer, this._length);
  547. this._length = this._buffer.length;
  548. this._stream.seek(position);
  549. delete this._stream;
  550. }
  551. }
  552. };
  553. zip.BinaryReader = class {
  554. constructor(buffer) {
  555. this._buffer = buffer;
  556. this._length = buffer.length;
  557. this._position = 0;
  558. this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
  559. }
  560. get position() {
  561. return this._position;
  562. }
  563. get length() {
  564. return this._length;
  565. }
  566. create(buffer) {
  567. return new zip.BinaryReader(buffer);
  568. }
  569. stream(length) {
  570. return this.create(this.read(length));
  571. }
  572. seek(position) {
  573. this._position = position >= 0 ? position : this._length + position;
  574. }
  575. skip(offset) {
  576. this._position += offset;
  577. }
  578. peek(length) {
  579. if (this._position === 0 && length === undefined) {
  580. return this._buffer;
  581. }
  582. const position = this._position;
  583. this.skip(length !== undefined ? length : this._length - this._position);
  584. const end = this._position;
  585. this.seek(position);
  586. return this._buffer.subarray(position, end);
  587. }
  588. read(length) {
  589. if (this._position === 0 && length === undefined) {
  590. this._position = this._length;
  591. return this._buffer;
  592. }
  593. const position = this._position;
  594. this.skip(length !== undefined ? length : this._length - this._position);
  595. return this._buffer.subarray(position, this._position);
  596. }
  597. byte() {
  598. const position = this._position;
  599. this.skip(1);
  600. return this._buffer[position];
  601. }
  602. uint16() {
  603. const position = this._position;
  604. this.skip(2);
  605. return this._view.getUint16(position, true);
  606. }
  607. uint32() {
  608. const position = this._position;
  609. this.skip(4);
  610. return this._view.getUint32(position, true);
  611. }
  612. };
  613. zlib.Archive = class {
  614. constructor(stream) {
  615. const position = stream.position;
  616. stream.read(2);
  617. const entry = new zlib.Entry(stream);
  618. this._entries = new Map([ [ entry.name, entry.stream ] ]);
  619. stream.seek(position);
  620. }
  621. get entries() {
  622. return this._entries;
  623. }
  624. };
  625. zlib.Entry = class {
  626. constructor(stream) {
  627. this._stream = new zip.InflaterStream(stream);
  628. }
  629. get name() {
  630. return '';
  631. }
  632. get stream() {
  633. return this._stream;
  634. }
  635. };
  636. zip.Error = class extends Error {
  637. constructor(message) {
  638. super(message);
  639. this.name = 'Zip Error';
  640. this.stack = undefined;
  641. }
  642. };
  643. if (typeof module !== 'undefined' && typeof module.exports === 'object') {
  644. module.exports.Archive = zip.Archive;
  645. module.exports.Inflater = zip.Inflater;
  646. }