From 1820dd4c00c63e5d7fd465154fbe50787f5b749d Mon Sep 17 00:00:00 2001 From: yayunhuang Date: Tue, 27 Aug 2024 11:55:09 +0800 Subject: [PATCH] Remove jszip cdn files --- public/scripts/jszip.js | 12901 ---------------------------------- public/scripts/jszip.min.js | 6242 ---------------- 2 files changed, 19143 deletions(-) delete mode 100644 public/scripts/jszip.js delete mode 100644 public/scripts/jszip.min.js diff --git a/public/scripts/jszip.js b/public/scripts/jszip.js deleted file mode 100644 index 7c7977b..0000000 --- a/public/scripts/jszip.js +++ /dev/null @@ -1,12901 +0,0 @@ -/*! - -JSZip v3.10.1 - A JavaScript class for generating and reading zip files - - -(c) 2009-2016 Stuart Knightley -Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. - -JSZip uses the library pako released under the MIT license : -https://github.com/nodeca/pako/blob/main/LICENSE -*/ - -(function (f) { - if (typeof exports === "object" && typeof module !== "undefined") { - module.exports = f(); - } else if (typeof define === "function" && define.amd) { - define([], f); - } else { - var g; - if (typeof window !== "undefined") { - g = window; - } else if (typeof global !== "undefined") { - g = global; - } else if (typeof self !== "undefined") { - g = self; - } else { - g = this; - } - g.JSZip = f(); - } -})(function () { - var define, module, exports; - return (function e(t, n, r) { - function s(o, u) { - if (!n[o]) { - if (!t[o]) { - var a = typeof require == "function" && require; - if (!u && a) return a(o, !0); - if (i) return i(o, !0); - var f = new Error("Cannot find module '" + o + "'"); - throw ((f.code = "MODULE_NOT_FOUND"), f); - } - var l = (n[o] = { exports: {} }); - t[o][0].call( - l.exports, - function (e) { - var n = t[o][1][e]; - return s(n ? n : e); - }, - l, - l.exports, - e, - t, - n, - r, - ); - } - return n[o].exports; - } - var i = typeof require == "function" && require; - for (var o = 0; o < r.length; o++) s(r[o]); - return s; - })( - { - 1: [ - function (require, module, exports) { - "use strict"; - var utils = require("./utils"); - var support = require("./support"); - // private property - var _keyStr = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - - // public method for encoding - exports.encode = function (input) { - var output = []; - var chr1, chr2, chr3, enc1, enc2, enc3, enc4; - var i = 0, - len = input.length, - remainingBytes = len; - - var isArray = utils.getTypeOf(input) !== "string"; - while (i < input.length) { - remainingBytes = len - i; - - if (!isArray) { - chr1 = input.charCodeAt(i++); - chr2 = i < len ? input.charCodeAt(i++) : 0; - chr3 = i < len ? input.charCodeAt(i++) : 0; - } else { - chr1 = input[i++]; - chr2 = i < len ? input[i++] : 0; - chr3 = i < len ? input[i++] : 0; - } - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = remainingBytes > 1 ? ((chr2 & 15) << 2) | (chr3 >> 6) : 64; - enc4 = remainingBytes > 2 ? chr3 & 63 : 64; - - output.push( - _keyStr.charAt(enc1) + - _keyStr.charAt(enc2) + - _keyStr.charAt(enc3) + - _keyStr.charAt(enc4), - ); - } - - return output.join(""); - }; - - // public method for decoding - exports.decode = function (input) { - var chr1, chr2, chr3; - var enc1, enc2, enc3, enc4; - var i = 0, - resultIndex = 0; - - var dataUrlPrefix = "data:"; - - if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) { - // This is a common error: people give a data url - // (data:image/png;base64,iVBOR...) with a {base64: true} and - // wonders why things don't work. - // We can detect that the string input looks like a data url but we - // *can't* be sure it is one: removing everything up to the comma would - // be too dangerous. - throw new Error( - "Invalid base64 input, it looks like a data url.", - ); - } - - input = input.replace(/[^A-Za-z0-9+/=]/g, ""); - - var totalLength = (input.length * 3) / 4; - if (input.charAt(input.length - 1) === _keyStr.charAt(64)) { - totalLength--; - } - if (input.charAt(input.length - 2) === _keyStr.charAt(64)) { - totalLength--; - } - if (totalLength % 1 !== 0) { - // totalLength is not an integer, the length does not match a valid - // base64 content. That can happen if: - // - the input is not a base64 content - // - the input is *almost* a base64 content, with a extra chars at the - // beginning or at the end - // - the input uses a base64 variant (base64url for example) - throw new Error("Invalid base64 input, bad content length."); - } - var output; - if (support.uint8array) { - output = new Uint8Array(totalLength | 0); - } else { - output = new Array(totalLength | 0); - } - - while (i < input.length) { - enc1 = _keyStr.indexOf(input.charAt(i++)); - enc2 = _keyStr.indexOf(input.charAt(i++)); - enc3 = _keyStr.indexOf(input.charAt(i++)); - enc4 = _keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output[resultIndex++] = chr1; - - if (enc3 !== 64) { - output[resultIndex++] = chr2; - } - if (enc4 !== 64) { - output[resultIndex++] = chr3; - } - } - - return output; - }; - }, - { "./support": 30, "./utils": 32 }, - ], - 2: [ - function (require, module, exports) { - "use strict"; - - var external = require("./external"); - var DataWorker = require("./stream/DataWorker"); - var Crc32Probe = require("./stream/Crc32Probe"); - var DataLengthProbe = require("./stream/DataLengthProbe"); - - /** - * Represent a compressed object, with everything needed to decompress it. - * @constructor - * @param {number} compressedSize the size of the data compressed. - * @param {number} uncompressedSize the size of the data after decompression. - * @param {number} crc32 the crc32 of the decompressed file. - * @param {object} compression the type of compression, see lib/compressions.js. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data. - */ - function CompressedObject( - compressedSize, - uncompressedSize, - crc32, - compression, - data, - ) { - this.compressedSize = compressedSize; - this.uncompressedSize = uncompressedSize; - this.crc32 = crc32; - this.compression = compression; - this.compressedContent = data; - } - - CompressedObject.prototype = { - /** - * Create a worker to get the uncompressed content. - * @return {GenericWorker} the worker. - */ - getContentWorker: function () { - var worker = new DataWorker( - external.Promise.resolve(this.compressedContent), - ) - .pipe(this.compression.uncompressWorker()) - .pipe(new DataLengthProbe("data_length")); - - var that = this; - worker.on("end", function () { - if (this.streamInfo["data_length"] !== that.uncompressedSize) { - throw new Error("Bug : uncompressed data size mismatch"); - } - }); - return worker; - }, - /** - * Create a worker to get the compressed content. - * @return {GenericWorker} the worker. - */ - getCompressedWorker: function () { - return new DataWorker( - external.Promise.resolve(this.compressedContent), - ) - .withStreamInfo("compressedSize", this.compressedSize) - .withStreamInfo("uncompressedSize", this.uncompressedSize) - .withStreamInfo("crc32", this.crc32) - .withStreamInfo("compression", this.compression); - }, - }; - - /** - * Chain the given worker with other workers to compress the content with the - * given compression. - * @param {GenericWorker} uncompressedWorker the worker to pipe. - * @param {Object} compression the compression object. - * @param {Object} compressionOptions the options to use when compressing. - * @return {GenericWorker} the new worker compressing the content. - */ - CompressedObject.createWorkerFrom = function ( - uncompressedWorker, - compression, - compressionOptions, - ) { - return uncompressedWorker - .pipe(new Crc32Probe()) - .pipe(new DataLengthProbe("uncompressedSize")) - .pipe(compression.compressWorker(compressionOptions)) - .pipe(new DataLengthProbe("compressedSize")) - .withStreamInfo("compression", compression); - }; - - module.exports = CompressedObject; - }, - { - "./external": 6, - "./stream/Crc32Probe": 25, - "./stream/DataLengthProbe": 26, - "./stream/DataWorker": 27, - }, - ], - 3: [ - function (require, module, exports) { - "use strict"; - - var GenericWorker = require("./stream/GenericWorker"); - - exports.STORE = { - magic: "\x00\x00", - compressWorker: function () { - return new GenericWorker("STORE compression"); - }, - uncompressWorker: function () { - return new GenericWorker("STORE decompression"); - }, - }; - exports.DEFLATE = require("./flate"); - }, - { "./flate": 7, "./stream/GenericWorker": 28 }, - ], - 4: [ - function (require, module, exports) { - "use strict"; - - var utils = require("./utils"); - - /** - * The following functions come from pako, from pako/lib/zlib/crc32.js - * released under the MIT license, see pako https://github.com/nodeca/pako/ - */ - - // Use ordinary array, since untyped makes no boost here - function makeTable() { - var c, - table = []; - - for (var n = 0; n < 256; n++) { - c = n; - for (var k = 0; k < 8; k++) { - c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; - } - table[n] = c; - } - - return table; - } - - // Create table on load. Just 255 signed longs. Not a problem. - var crcTable = makeTable(); - - function crc32(crc, buf, len, pos) { - var t = crcTable, - end = pos + len; - - crc = crc ^ -1; - - for (var i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xff]; - } - - return crc ^ -1; // >>> 0; - } - - // That's all for the pako functions. - - /** - * Compute the crc32 of a string. - * This is almost the same as the function crc32, but for strings. Using the - * same function for the two use cases leads to horrible performances. - * @param {Number} crc the starting value of the crc. - * @param {String} str the string to use. - * @param {Number} len the length of the string. - * @param {Number} pos the starting position for the crc32 computation. - * @return {Number} the computed crc32. - */ - function crc32str(crc, str, len, pos) { - var t = crcTable, - end = pos + len; - - crc = crc ^ -1; - - for (var i = pos; i < end; i++) { - crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xff]; - } - - return crc ^ -1; // >>> 0; - } - - module.exports = function crc32wrapper(input, crc) { - if (typeof input === "undefined" || !input.length) { - return 0; - } - - var isArray = utils.getTypeOf(input) !== "string"; - - if (isArray) { - return crc32(crc | 0, input, input.length, 0); - } else { - return crc32str(crc | 0, input, input.length, 0); - } - }; - }, - { "./utils": 32 }, - ], - 5: [ - function (require, module, exports) { - "use strict"; - exports.base64 = false; - exports.binary = false; - exports.dir = false; - exports.createFolders = true; - exports.date = null; - exports.compression = null; - exports.compressionOptions = null; - exports.comment = null; - exports.unixPermissions = null; - exports.dosPermissions = null; - }, - {}, - ], - 6: [ - function (require, module, exports) { - "use strict"; - - // load the global object first: - // - it should be better integrated in the system (unhandledRejection in node) - // - the environment may have a custom Promise implementation (see zone.js) - var ES6Promise = null; - if (typeof Promise !== "undefined") { - ES6Promise = Promise; - } else { - ES6Promise = require("lie"); - } - - /** - * Let the user use/change some implementations. - */ - module.exports = { - Promise: ES6Promise, - }; - }, - { lie: 37 }, - ], - 7: [ - function (require, module, exports) { - "use strict"; - var USE_TYPEDARRAY = - typeof Uint8Array !== "undefined" && - typeof Uint16Array !== "undefined" && - typeof Uint32Array !== "undefined"; - - var pako = require("pako"); - var utils = require("./utils"); - var GenericWorker = require("./stream/GenericWorker"); - - var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array"; - - exports.magic = "\x08\x00"; - - /** - * Create a worker that uses pako to inflate/deflate. - * @constructor - * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate". - * @param {Object} options the options to use when (de)compressing. - */ - function FlateWorker(action, options) { - GenericWorker.call(this, "FlateWorker/" + action); - - this._pako = null; - this._pakoAction = action; - this._pakoOptions = options; - // the `meta` object from the last chunk received - // this allow this worker to pass around metadata - this.meta = {}; - } - - utils.inherits(FlateWorker, GenericWorker); - - /** - * @see GenericWorker.processChunk - */ - FlateWorker.prototype.processChunk = function (chunk) { - this.meta = chunk.meta; - if (this._pako === null) { - this._createPako(); - } - this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false); - }; - - /** - * @see GenericWorker.flush - */ - FlateWorker.prototype.flush = function () { - GenericWorker.prototype.flush.call(this); - if (this._pako === null) { - this._createPako(); - } - this._pako.push([], true); - }; - /** - * @see GenericWorker.cleanUp - */ - FlateWorker.prototype.cleanUp = function () { - GenericWorker.prototype.cleanUp.call(this); - this._pako = null; - }; - - /** - * Create the _pako object. - * TODO: lazy-loading this object isn't the best solution but it's the - * quickest. The best solution is to lazy-load the worker list. See also the - * issue #446. - */ - FlateWorker.prototype._createPako = function () { - this._pako = new pako[this._pakoAction]({ - raw: true, - level: this._pakoOptions.level || -1, // default compression - }); - var self = this; - this._pako.onData = function (data) { - self.push({ - data: data, - meta: self.meta, - }); - }; - }; - - exports.compressWorker = function (compressionOptions) { - return new FlateWorker("Deflate", compressionOptions); - }; - exports.uncompressWorker = function () { - return new FlateWorker("Inflate", {}); - }; - }, - { "./stream/GenericWorker": 28, "./utils": 32, pako: 38 }, - ], - 8: [ - function (require, module, exports) { - "use strict"; - - var utils = require("../utils"); - var GenericWorker = require("../stream/GenericWorker"); - var utf8 = require("../utf8"); - var crc32 = require("../crc32"); - var signature = require("../signature"); - - /** - * Transform an integer into a string in hexadecimal. - * @private - * @param {number} dec the number to convert. - * @param {number} bytes the number of bytes to generate. - * @returns {string} the result. - */ - var decToHex = function (dec, bytes) { - var hex = "", - i; - for (i = 0; i < bytes; i++) { - hex += String.fromCharCode(dec & 0xff); - dec = dec >>> 8; - } - return hex; - }; - - /** - * Generate the UNIX part of the external file attributes. - * @param {Object} unixPermissions the unix permissions or null. - * @param {Boolean} isDir true if the entry is a directory, false otherwise. - * @return {Number} a 32 bit integer. - * - * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : - * - * TTTTsstrwxrwxrwx0000000000ADVSHR - * ^^^^____________________________ file type, see zipinfo.c (UNX_*) - * ^^^_________________________ setuid, setgid, sticky - * ^^^^^^^^^________________ permissions - * ^^^^^^^^^^______ not used ? - * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only - */ - var generateUnixExternalFileAttr = function (unixPermissions, isDir) { - var result = unixPermissions; - if (!unixPermissions) { - // I can't use octal values in strict mode, hence the hexa. - // 040775 => 0x41fd - // 0100664 => 0x81b4 - result = isDir ? 0x41fd : 0x81b4; - } - return (result & 0xffff) << 16; - }; - - /** - * Generate the DOS part of the external file attributes. - * @param {Object} dosPermissions the dos permissions or null. - * @param {Boolean} isDir true if the entry is a directory, false otherwise. - * @return {Number} a 32 bit integer. - * - * Bit 0 Read-Only - * Bit 1 Hidden - * Bit 2 System - * Bit 3 Volume Label - * Bit 4 Directory - * Bit 5 Archive - */ - var generateDosExternalFileAttr = function (dosPermissions) { - // the dir flag is already set for compatibility - return (dosPermissions || 0) & 0x3f; - }; - - /** - * Generate the various parts used in the construction of the final zip file. - * @param {Object} streamInfo the hash with information about the compressed file. - * @param {Boolean} streamedContent is the content streamed ? - * @param {Boolean} streamingEnded is the stream finished ? - * @param {number} offset the current offset from the start of the zip file. - * @param {String} platform let's pretend we are this platform (change platform dependents fields) - * @param {Function} encodeFileName the function to encode the file name / comment. - * @return {Object} the zip parts. - */ - var generateZipParts = function ( - streamInfo, - streamedContent, - streamingEnded, - offset, - platform, - encodeFileName, - ) { - var file = streamInfo["file"], - compression = streamInfo["compression"], - useCustomEncoding = encodeFileName !== utf8.utf8encode, - encodedFileName = utils.transformTo( - "string", - encodeFileName(file.name), - ), - utfEncodedFileName = utils.transformTo( - "string", - utf8.utf8encode(file.name), - ), - comment = file.comment, - encodedComment = utils.transformTo( - "string", - encodeFileName(comment), - ), - utfEncodedComment = utils.transformTo( - "string", - utf8.utf8encode(comment), - ), - useUTF8ForFileName = - utfEncodedFileName.length !== file.name.length, - useUTF8ForComment = utfEncodedComment.length !== comment.length, - dosTime, - dosDate, - extraFields = "", - unicodePathExtraField = "", - unicodeCommentExtraField = "", - dir = file.dir, - date = file.date; - - var dataInfo = { - crc32: 0, - compressedSize: 0, - uncompressedSize: 0, - }; - - // if the content is streamed, the sizes/crc32 are only available AFTER - // the end of the stream. - if (!streamedContent || streamingEnded) { - dataInfo.crc32 = streamInfo["crc32"]; - dataInfo.compressedSize = streamInfo["compressedSize"]; - dataInfo.uncompressedSize = streamInfo["uncompressedSize"]; - } - - var bitflag = 0; - if (streamedContent) { - // Bit 3: the sizes/crc32 are set to zero in the local header. - // The correct values are put in the data descriptor immediately - // following the compressed data. - bitflag |= 0x0008; - } - if ( - !useCustomEncoding && - (useUTF8ForFileName || useUTF8ForComment) - ) { - // Bit 11: Language encoding flag (EFS). - bitflag |= 0x0800; - } - - var extFileAttr = 0; - var versionMadeBy = 0; - if (dir) { - // dos or unix, we set the dos dir flag - extFileAttr |= 0x00010; - } - if (platform === "UNIX") { - versionMadeBy = 0x031e; // UNIX, version 3.0 - extFileAttr |= generateUnixExternalFileAttr( - file.unixPermissions, - dir, - ); - } else { - // DOS or other, fallback to DOS - versionMadeBy = 0x0014; // DOS, version 2.0 - extFileAttr |= generateDosExternalFileAttr( - file.dosPermissions, - dir, - ); - } - - // date - // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html - // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html - // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html - - dosTime = date.getUTCHours(); - dosTime = dosTime << 6; - dosTime = dosTime | date.getUTCMinutes(); - dosTime = dosTime << 5; - dosTime = dosTime | (date.getUTCSeconds() / 2); - - dosDate = date.getUTCFullYear() - 1980; - dosDate = dosDate << 4; - dosDate = dosDate | (date.getUTCMonth() + 1); - dosDate = dosDate << 5; - dosDate = dosDate | date.getUTCDate(); - - if (useUTF8ForFileName) { - // set the unicode path extra field. unzip needs at least one extra - // field to correctly handle unicode path, so using the path is as good - // as any other information. This could improve the situation with - // other archive managers too. - // This field is usually used without the utf8 flag, with a non - // unicode path in the header (winrar, winzip). This helps (a bit) - // with the messy Windows' default compressed folders feature but - // breaks on p7zip which doesn't seek the unicode path extra field. - // So for now, UTF-8 everywhere ! - unicodePathExtraField = - // Version - decToHex(1, 1) + - // NameCRC32 - decToHex(crc32(encodedFileName), 4) + - // UnicodeName - utfEncodedFileName; - - extraFields += - // Info-ZIP Unicode Path Extra Field - "\x75\x70" + - // size - decToHex(unicodePathExtraField.length, 2) + - // content - unicodePathExtraField; - } - - if (useUTF8ForComment) { - unicodeCommentExtraField = - // Version - decToHex(1, 1) + - // CommentCRC32 - decToHex(crc32(encodedComment), 4) + - // UnicodeName - utfEncodedComment; - - extraFields += - // Info-ZIP Unicode Path Extra Field - "\x75\x63" + - // size - decToHex(unicodeCommentExtraField.length, 2) + - // content - unicodeCommentExtraField; - } - - var header = ""; - - // version needed to extract - header += "\x0A\x00"; - // general purpose bit flag - header += decToHex(bitflag, 2); - // compression method - header += compression.magic; - // last mod file time - header += decToHex(dosTime, 2); - // last mod file date - header += decToHex(dosDate, 2); - // crc-32 - header += decToHex(dataInfo.crc32, 4); - // compressed size - header += decToHex(dataInfo.compressedSize, 4); - // uncompressed size - header += decToHex(dataInfo.uncompressedSize, 4); - // file name length - header += decToHex(encodedFileName.length, 2); - // extra field length - header += decToHex(extraFields.length, 2); - - var fileRecord = - signature.LOCAL_FILE_HEADER + - header + - encodedFileName + - extraFields; - - var dirRecord = - signature.CENTRAL_FILE_HEADER + - // version made by (00: DOS) - decToHex(versionMadeBy, 2) + - // file header (common to file and central directory) - header + - // file comment length - decToHex(encodedComment.length, 2) + - // disk number start - "\x00\x00" + - // internal file attributes TODO - "\x00\x00" + - // external file attributes - decToHex(extFileAttr, 4) + - // relative offset of local header - decToHex(offset, 4) + - // file name - encodedFileName + - // extra field - extraFields + - // file comment - encodedComment; - - return { - fileRecord: fileRecord, - dirRecord: dirRecord, - }; - }; - - /** - * Generate the EOCD record. - * @param {Number} entriesCount the number of entries in the zip file. - * @param {Number} centralDirLength the length (in bytes) of the central dir. - * @param {Number} localDirLength the length (in bytes) of the local dir. - * @param {String} comment the zip file comment as a binary string. - * @param {Function} encodeFileName the function to encode the comment. - * @return {String} the EOCD record. - */ - var generateCentralDirectoryEnd = function ( - entriesCount, - centralDirLength, - localDirLength, - comment, - encodeFileName, - ) { - var dirEnd = ""; - var encodedComment = utils.transformTo( - "string", - encodeFileName(comment), - ); - - // end of central dir signature - dirEnd = - signature.CENTRAL_DIRECTORY_END + - // number of this disk - "\x00\x00" + - // number of the disk with the start of the central directory - "\x00\x00" + - // total number of entries in the central directory on this disk - decToHex(entriesCount, 2) + - // total number of entries in the central directory - decToHex(entriesCount, 2) + - // size of the central directory 4 bytes - decToHex(centralDirLength, 4) + - // offset of start of central directory with respect to the starting disk number - decToHex(localDirLength, 4) + - // .ZIP file comment length - decToHex(encodedComment.length, 2) + - // .ZIP file comment - encodedComment; - - return dirEnd; - }; - - /** - * Generate data descriptors for a file entry. - * @param {Object} streamInfo the hash generated by a worker, containing information - * on the file entry. - * @return {String} the data descriptors. - */ - var generateDataDescriptors = function (streamInfo) { - var descriptor = ""; - descriptor = - signature.DATA_DESCRIPTOR + - // crc-32 4 bytes - decToHex(streamInfo["crc32"], 4) + - // compressed size 4 bytes - decToHex(streamInfo["compressedSize"], 4) + - // uncompressed size 4 bytes - decToHex(streamInfo["uncompressedSize"], 4); - - return descriptor; - }; - - /** - * A worker to concatenate other workers to create a zip file. - * @param {Boolean} streamFiles `true` to stream the content of the files, - * `false` to accumulate it. - * @param {String} comment the comment to use. - * @param {String} platform the platform to use, "UNIX" or "DOS". - * @param {Function} encodeFileName the function to encode file names and comments. - */ - function ZipFileWorker( - streamFiles, - comment, - platform, - encodeFileName, - ) { - GenericWorker.call(this, "ZipFileWorker"); - // The number of bytes written so far. This doesn't count accumulated chunks. - this.bytesWritten = 0; - // The comment of the zip file - this.zipComment = comment; - // The platform "generating" the zip file. - this.zipPlatform = platform; - // the function to encode file names and comments. - this.encodeFileName = encodeFileName; - // Should we stream the content of the files ? - this.streamFiles = streamFiles; - // If `streamFiles` is false, we will need to accumulate the content of the - // files to calculate sizes / crc32 (and write them *before* the content). - // This boolean indicates if we are accumulating chunks (it will change a lot - // during the lifetime of this worker). - this.accumulate = false; - // The buffer receiving chunks when accumulating content. - this.contentBuffer = []; - // The list of generated directory records. - this.dirRecords = []; - // The offset (in bytes) from the beginning of the zip file for the current source. - this.currentSourceOffset = 0; - // The total number of entries in this zip file. - this.entriesCount = 0; - // the name of the file currently being added, null when handling the end of the zip file. - // Used for the emitted metadata. - this.currentFile = null; - - this._sources = []; - } - utils.inherits(ZipFileWorker, GenericWorker); - - /** - * @see GenericWorker.push - */ - ZipFileWorker.prototype.push = function (chunk) { - var currentFilePercent = chunk.meta.percent || 0; - var entriesCount = this.entriesCount; - var remainingFiles = this._sources.length; - - if (this.accumulate) { - this.contentBuffer.push(chunk); - } else { - this.bytesWritten += chunk.data.length; - - GenericWorker.prototype.push.call(this, { - data: chunk.data, - meta: { - currentFile: this.currentFile, - percent: entriesCount - ? (currentFilePercent + - 100 * (entriesCount - remainingFiles - 1)) / - entriesCount - : 100, - }, - }); - } - }; - - /** - * The worker started a new source (an other worker). - * @param {Object} streamInfo the streamInfo object from the new source. - */ - ZipFileWorker.prototype.openedSource = function (streamInfo) { - this.currentSourceOffset = this.bytesWritten; - this.currentFile = streamInfo["file"].name; - - var streamedContent = this.streamFiles && !streamInfo["file"].dir; - - // don't stream folders (because they don't have any content) - if (streamedContent) { - var record = generateZipParts( - streamInfo, - streamedContent, - false, - this.currentSourceOffset, - this.zipPlatform, - this.encodeFileName, - ); - this.push({ - data: record.fileRecord, - meta: { percent: 0 }, - }); - } else { - // we need to wait for the whole file before pushing anything - this.accumulate = true; - } - }; - - /** - * The worker finished a source (an other worker). - * @param {Object} streamInfo the streamInfo object from the finished source. - */ - ZipFileWorker.prototype.closedSource = function (streamInfo) { - this.accumulate = false; - var streamedContent = this.streamFiles && !streamInfo["file"].dir; - var record = generateZipParts( - streamInfo, - streamedContent, - true, - this.currentSourceOffset, - this.zipPlatform, - this.encodeFileName, - ); - - this.dirRecords.push(record.dirRecord); - if (streamedContent) { - // after the streamed file, we put data descriptors - this.push({ - data: generateDataDescriptors(streamInfo), - meta: { percent: 100 }, - }); - } else { - // the content wasn't streamed, we need to push everything now - // first the file record, then the content - this.push({ - data: record.fileRecord, - meta: { percent: 0 }, - }); - while (this.contentBuffer.length) { - this.push(this.contentBuffer.shift()); - } - } - this.currentFile = null; - }; - - /** - * @see GenericWorker.flush - */ - ZipFileWorker.prototype.flush = function () { - var localDirLength = this.bytesWritten; - for (var i = 0; i < this.dirRecords.length; i++) { - this.push({ - data: this.dirRecords[i], - meta: { percent: 100 }, - }); - } - var centralDirLength = this.bytesWritten - localDirLength; - - var dirEnd = generateCentralDirectoryEnd( - this.dirRecords.length, - centralDirLength, - localDirLength, - this.zipComment, - this.encodeFileName, - ); - - this.push({ - data: dirEnd, - meta: { percent: 100 }, - }); - }; - - /** - * Prepare the next source to be read. - */ - ZipFileWorker.prototype.prepareNextSource = function () { - this.previous = this._sources.shift(); - this.openedSource(this.previous.streamInfo); - if (this.isPaused) { - this.previous.pause(); - } else { - this.previous.resume(); - } - }; - - /** - * @see GenericWorker.registerPrevious - */ - ZipFileWorker.prototype.registerPrevious = function (previous) { - this._sources.push(previous); - var self = this; - - previous.on("data", function (chunk) { - self.processChunk(chunk); - }); - previous.on("end", function () { - self.closedSource(self.previous.streamInfo); - if (self._sources.length) { - self.prepareNextSource(); - } else { - self.end(); - } - }); - previous.on("error", function (e) { - self.error(e); - }); - return this; - }; - - /** - * @see GenericWorker.resume - */ - ZipFileWorker.prototype.resume = function () { - if (!GenericWorker.prototype.resume.call(this)) { - return false; - } - - if (!this.previous && this._sources.length) { - this.prepareNextSource(); - return true; - } - if ( - !this.previous && - !this._sources.length && - !this.generatedError - ) { - this.end(); - return true; - } - }; - - /** - * @see GenericWorker.error - */ - ZipFileWorker.prototype.error = function (e) { - var sources = this._sources; - if (!GenericWorker.prototype.error.call(this, e)) { - return false; - } - for (var i = 0; i < sources.length; i++) { - try { - sources[i].error(e); - } catch (e) { - // the `error` exploded, nothing to do - } - } - return true; - }; - - /** - * @see GenericWorker.lock - */ - ZipFileWorker.prototype.lock = function () { - GenericWorker.prototype.lock.call(this); - var sources = this._sources; - for (var i = 0; i < sources.length; i++) { - sources[i].lock(); - } - }; - - module.exports = ZipFileWorker; - }, - { - "../crc32": 4, - "../signature": 23, - "../stream/GenericWorker": 28, - "../utf8": 31, - "../utils": 32, - }, - ], - 9: [ - function (require, module, exports) { - "use strict"; - - var compressions = require("../compressions"); - var ZipFileWorker = require("./ZipFileWorker"); - - /** - * Find the compression to use. - * @param {String} fileCompression the compression defined at the file level, if any. - * @param {String} zipCompression the compression defined at the load() level. - * @return {Object} the compression object to use. - */ - var getCompression = function (fileCompression, zipCompression) { - var compressionName = fileCompression || zipCompression; - var compression = compressions[compressionName]; - if (!compression) { - throw new Error( - compressionName + " is not a valid compression method !", - ); - } - return compression; - }; - - /** - * Create a worker to generate a zip file. - * @param {JSZip} zip the JSZip instance at the right root level. - * @param {Object} options to generate the zip file. - * @param {String} comment the comment to use. - */ - exports.generateWorker = function (zip, options, comment) { - var zipFileWorker = new ZipFileWorker( - options.streamFiles, - comment, - options.platform, - options.encodeFileName, - ); - var entriesCount = 0; - try { - zip.forEach(function (relativePath, file) { - entriesCount++; - var compression = getCompression( - file.options.compression, - options.compression, - ); - var compressionOptions = - file.options.compressionOptions || - options.compressionOptions || - {}; - var dir = file.dir, - date = file.date; - - file - ._compressWorker(compression, compressionOptions) - .withStreamInfo("file", { - name: relativePath, - dir: dir, - date: date, - comment: file.comment || "", - unixPermissions: file.unixPermissions, - dosPermissions: file.dosPermissions, - }) - .pipe(zipFileWorker); - }); - zipFileWorker.entriesCount = entriesCount; - } catch (e) { - zipFileWorker.error(e); - } - - return zipFileWorker; - }; - }, - { "../compressions": 3, "./ZipFileWorker": 8 }, - ], - 10: [ - function (require, module, exports) { - "use strict"; - - /** - * Representation a of zip file in js - * @constructor - */ - function JSZip() { - // if this constructor is used without `new`, it adds `new` before itself: - if (!(this instanceof JSZip)) { - return new JSZip(); - } - - if (arguments.length) { - throw new Error( - "The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.", - ); - } - - // object containing the files : - // { - // "folder/" : {...}, - // "folder/data.txt" : {...} - // } - // NOTE: we use a null prototype because we do not - // want filenames like "toString" coming from a zip file - // to overwrite methods and attributes in a normal Object. - this.files = Object.create(null); - - this.comment = null; - - // Where we are in the hierarchy - this.root = ""; - this.clone = function () { - var newObj = new JSZip(); - for (var i in this) { - if (typeof this[i] !== "function") { - newObj[i] = this[i]; - } - } - return newObj; - }; - } - JSZip.prototype = require("./object"); - JSZip.prototype.loadAsync = require("./load"); - JSZip.support = require("./support"); - JSZip.defaults = require("./defaults"); - - // TODO find a better way to handle this version, - // a require('package.json').version doesn't work with webpack, see #327 - JSZip.version = "3.10.1"; - - JSZip.loadAsync = function (content, options) { - return new JSZip().loadAsync(content, options); - }; - - JSZip.external = require("./external"); - module.exports = JSZip; - }, - { - "./defaults": 5, - "./external": 6, - "./load": 11, - "./object": 15, - "./support": 30, - }, - ], - 11: [ - function (require, module, exports) { - "use strict"; - var utils = require("./utils"); - var external = require("./external"); - var utf8 = require("./utf8"); - var ZipEntries = require("./zipEntries"); - var Crc32Probe = require("./stream/Crc32Probe"); - var nodejsUtils = require("./nodejsUtils"); - - /** - * Check the CRC32 of an entry. - * @param {ZipEntry} zipEntry the zip entry to check. - * @return {Promise} the result. - */ - function checkEntryCRC32(zipEntry) { - return new external.Promise(function (resolve, reject) { - var worker = zipEntry.decompressed - .getContentWorker() - .pipe(new Crc32Probe()); - worker - .on("error", function (e) { - reject(e); - }) - .on("end", function () { - if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) { - reject(new Error("Corrupted zip : CRC32 mismatch")); - } else { - resolve(); - } - }) - .resume(); - }); - } - - module.exports = function (data, options) { - var zip = this; - options = utils.extend(options || {}, { - base64: false, - checkCRC32: false, - optimizedBinaryString: false, - createFolders: false, - decodeFileName: utf8.utf8decode, - }); - - if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { - return external.Promise.reject( - new Error( - "JSZip can't accept a stream when loading a zip file.", - ), - ); - } - - return utils - .prepareContent( - "the loaded zip file", - data, - true, - options.optimizedBinaryString, - options.base64, - ) - .then(function (data) { - var zipEntries = new ZipEntries(options); - zipEntries.load(data); - return zipEntries; - }) - .then(function checkCRC32(zipEntries) { - var promises = [external.Promise.resolve(zipEntries)]; - var files = zipEntries.files; - if (options.checkCRC32) { - for (var i = 0; i < files.length; i++) { - promises.push(checkEntryCRC32(files[i])); - } - } - return external.Promise.all(promises); - }) - .then(function addFiles(results) { - var zipEntries = results.shift(); - var files = zipEntries.files; - for (var i = 0; i < files.length; i++) { - var input = files[i]; - - var unsafeName = input.fileNameStr; - var safeName = utils.resolve(input.fileNameStr); - - zip.file(safeName, input.decompressed, { - binary: true, - optimizedBinaryString: true, - date: input.date, - dir: input.dir, - comment: input.fileCommentStr.length - ? input.fileCommentStr - : null, - unixPermissions: input.unixPermissions, - dosPermissions: input.dosPermissions, - createFolders: options.createFolders, - }); - if (!input.dir) { - zip.file(safeName).unsafeOriginalName = unsafeName; - } - } - if (zipEntries.zipComment.length) { - zip.comment = zipEntries.zipComment; - } - - return zip; - }); - }; - }, - { - "./external": 6, - "./nodejsUtils": 14, - "./stream/Crc32Probe": 25, - "./utf8": 31, - "./utils": 32, - "./zipEntries": 33, - }, - ], - 12: [ - function (require, module, exports) { - "use strict"; - - var utils = require("../utils"); - var GenericWorker = require("../stream/GenericWorker"); - - /** - * A worker that use a nodejs stream as source. - * @constructor - * @param {String} filename the name of the file entry for this stream. - * @param {Readable} stream the nodejs stream. - */ - function NodejsStreamInputAdapter(filename, stream) { - GenericWorker.call( - this, - "Nodejs stream input adapter for " + filename, - ); - this._upstreamEnded = false; - this._bindStream(stream); - } - - utils.inherits(NodejsStreamInputAdapter, GenericWorker); - - /** - * Prepare the stream and bind the callbacks on it. - * Do this ASAP on node 0.10 ! A lazy binding doesn't always work. - * @param {Stream} stream the nodejs stream to use. - */ - NodejsStreamInputAdapter.prototype._bindStream = function (stream) { - var self = this; - this._stream = stream; - stream.pause(); - stream - .on("data", function (chunk) { - self.push({ - data: chunk, - meta: { - percent: 0, - }, - }); - }) - .on("error", function (e) { - if (self.isPaused) { - this.generatedError = e; - } else { - self.error(e); - } - }) - .on("end", function () { - if (self.isPaused) { - self._upstreamEnded = true; - } else { - self.end(); - } - }); - }; - NodejsStreamInputAdapter.prototype.pause = function () { - if (!GenericWorker.prototype.pause.call(this)) { - return false; - } - this._stream.pause(); - return true; - }; - NodejsStreamInputAdapter.prototype.resume = function () { - if (!GenericWorker.prototype.resume.call(this)) { - return false; - } - - if (this._upstreamEnded) { - this.end(); - } else { - this._stream.resume(); - } - - return true; - }; - - module.exports = NodejsStreamInputAdapter; - }, - { "../stream/GenericWorker": 28, "../utils": 32 }, - ], - 13: [ - function (require, module, exports) { - "use strict"; - - var Readable = require("readable-stream").Readable; - - var utils = require("../utils"); - utils.inherits(NodejsStreamOutputAdapter, Readable); - - /** - * A nodejs stream using a worker as source. - * @see the SourceWrapper in http://nodejs.org/api/stream.html - * @constructor - * @param {StreamHelper} helper the helper wrapping the worker - * @param {Object} options the nodejs stream options - * @param {Function} updateCb the update callback. - */ - function NodejsStreamOutputAdapter(helper, options, updateCb) { - Readable.call(this, options); - this._helper = helper; - - var self = this; - helper - .on("data", function (data, meta) { - if (!self.push(data)) { - self._helper.pause(); - } - if (updateCb) { - updateCb(meta); - } - }) - .on("error", function (e) { - self.emit("error", e); - }) - .on("end", function () { - self.push(null); - }); - } - - NodejsStreamOutputAdapter.prototype._read = function () { - this._helper.resume(); - }; - - module.exports = NodejsStreamOutputAdapter; - }, - { "../utils": 32, "readable-stream": 16 }, - ], - 14: [ - function (require, module, exports) { - "use strict"; - - module.exports = { - /** - * True if this is running in Nodejs, will be undefined in a browser. - * In a browser, browserify won't include this file and the whole module - * will be resolved an empty object. - */ - isNode: typeof Buffer !== "undefined", - /** - * Create a new nodejs Buffer from an existing content. - * @param {Object} data the data to pass to the constructor. - * @param {String} encoding the encoding to use. - * @return {Buffer} a new Buffer. - */ - newBufferFrom: function (data, encoding) { - if (Buffer.from && Buffer.from !== Uint8Array.from) { - return Buffer.from(data, encoding); - } else { - if (typeof data === "number") { - // Safeguard for old Node.js versions. On newer versions, - // Buffer.from(number) / Buffer(number, encoding) already throw. - throw new Error('The "data" argument must not be a number'); - } - return new Buffer(data, encoding); - } - }, - /** - * Create a new nodejs Buffer with the specified size. - * @param {Integer} size the size of the buffer. - * @return {Buffer} a new Buffer. - */ - allocBuffer: function (size) { - if (Buffer.alloc) { - return Buffer.alloc(size); - } else { - var buf = new Buffer(size); - buf.fill(0); - return buf; - } - }, - /** - * Find out if an object is a Buffer. - * @param {Object} b the object to test. - * @return {Boolean} true if the object is a Buffer, false otherwise. - */ - isBuffer: function (b) { - return Buffer.isBuffer(b); - }, - - isStream: function (obj) { - return ( - obj && - typeof obj.on === "function" && - typeof obj.pause === "function" && - typeof obj.resume === "function" - ); - }, - }; - }, - {}, - ], - 15: [ - function (require, module, exports) { - "use strict"; - var utf8 = require("./utf8"); - var utils = require("./utils"); - var GenericWorker = require("./stream/GenericWorker"); - var StreamHelper = require("./stream/StreamHelper"); - var defaults = require("./defaults"); - var CompressedObject = require("./compressedObject"); - var ZipObject = require("./zipObject"); - var generate = require("./generate"); - var nodejsUtils = require("./nodejsUtils"); - var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter"); - - /** - * Add a file in the current folder. - * @private - * @param {string} name the name of the file - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file - * @param {Object} originalOptions the options of the file - * @return {Object} the new file. - */ - var fileAdd = function (name, data, originalOptions) { - // be sure sub folders exist - var dataType = utils.getTypeOf(data), - parent; - - /* - * Correct options. - */ - - var o = utils.extend(originalOptions || {}, defaults); - o.date = o.date || new Date(); - if (o.compression !== null) { - o.compression = o.compression.toUpperCase(); - } - - if (typeof o.unixPermissions === "string") { - o.unixPermissions = parseInt(o.unixPermissions, 8); - } - - // UNX_IFDIR 0040000 see zipinfo.c - if (o.unixPermissions && o.unixPermissions & 0x4000) { - o.dir = true; - } - // Bit 4 Directory - if (o.dosPermissions && o.dosPermissions & 0x0010) { - o.dir = true; - } - - if (o.dir) { - name = forceTrailingSlash(name); - } - if (o.createFolders && (parent = parentFolder(name))) { - folderAdd.call(this, parent, true); - } - - var isUnicodeString = - dataType === "string" && o.binary === false && o.base64 === false; - if ( - !originalOptions || - typeof originalOptions.binary === "undefined" - ) { - o.binary = !isUnicodeString; - } - - var isCompressedEmpty = - data instanceof CompressedObject && data.uncompressedSize === 0; - - if (isCompressedEmpty || o.dir || !data || data.length === 0) { - o.base64 = false; - o.binary = true; - data = ""; - o.compression = "STORE"; - dataType = "string"; - } - - /* - * Convert content to fit. - */ - - var zipObjectContent = null; - if ( - data instanceof CompressedObject || - data instanceof GenericWorker - ) { - zipObjectContent = data; - } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { - zipObjectContent = new NodejsStreamInputAdapter(name, data); - } else { - zipObjectContent = utils.prepareContent( - name, - data, - o.binary, - o.optimizedBinaryString, - o.base64, - ); - } - - var object = new ZipObject(name, zipObjectContent, o); - this.files[name] = object; - /* - TODO: we can't throw an exception because we have async promises - (we can have a promise of a Date() for example) but returning a - promise is useless because file(name, data) returns the JSZip - object for chaining. Should we break that to allow the user - to catch the error ? - - return external.Promise.resolve(zipObjectContent) - .then(function () { - return object; - }); - */ - }; - - /** - * Find the parent folder of the path. - * @private - * @param {string} path the path to use - * @return {string} the parent folder, or "" - */ - var parentFolder = function (path) { - if (path.slice(-1) === "/") { - path = path.substring(0, path.length - 1); - } - var lastSlash = path.lastIndexOf("/"); - return lastSlash > 0 ? path.substring(0, lastSlash) : ""; - }; - - /** - * Returns the path with a slash at the end. - * @private - * @param {String} path the path to check. - * @return {String} the path with a trailing slash. - */ - var forceTrailingSlash = function (path) { - // Check the name ends with a / - if (path.slice(-1) !== "/") { - path += "/"; // IE doesn't like substr(-1) - } - return path; - }; - - /** - * Add a (sub) folder in the current folder. - * @private - * @param {string} name the folder's name - * @param {boolean=} [createFolders] If true, automatically create sub - * folders. Defaults to false. - * @return {Object} the new folder. - */ - var folderAdd = function (name, createFolders) { - createFolders = - typeof createFolders !== "undefined" - ? createFolders - : defaults.createFolders; - - name = forceTrailingSlash(name); - - // Does this folder already exist? - if (!this.files[name]) { - fileAdd.call(this, name, null, { - dir: true, - createFolders: createFolders, - }); - } - return this.files[name]; - }; - - /** - * Cross-window, cross-Node-context regular expression detection - * @param {Object} object Anything - * @return {Boolean} true if the object is a regular expression, - * false otherwise - */ - function isRegExp(object) { - return Object.prototype.toString.call(object) === "[object RegExp]"; - } - - // return the actual prototype of JSZip - var out = { - /** - * @see loadAsync - */ - load: function () { - throw new Error( - "This method has been removed in JSZip 3.0, please check the upgrade guide.", - ); - }, - - /** - * Call a callback function for each entry at this folder level. - * @param {Function} cb the callback function: - * function (relativePath, file) {...} - * It takes 2 arguments : the relative path and the file. - */ - forEach: function (cb) { - var filename, relativePath, file; - // ignore warning about unwanted properties because this.files is a null prototype object - /* eslint-disable-next-line guard-for-in */ - for (filename in this.files) { - file = this.files[filename]; - relativePath = filename.slice( - this.root.length, - filename.length, - ); - if ( - relativePath && - filename.slice(0, this.root.length) === this.root - ) { - // the file is in the current root - cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn... - } - } - }, - - /** - * Filter nested files/folders with the specified function. - * @param {Function} search the predicate to use : - * function (relativePath, file) {...} - * It takes 2 arguments : the relative path and the file. - * @return {Array} An array of matching elements. - */ - filter: function (search) { - var result = []; - this.forEach(function (relativePath, entry) { - if (search(relativePath, entry)) { - // the file matches the function - result.push(entry); - } - }); - return result; - }, - - /** - * Add a file to the zip file, or search a file. - * @param {string|RegExp} name The name of the file to add (if data is defined), - * the name of the file to find (if no data) or a regex to match files. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded - * @param {Object} o File options - * @return {JSZip|Object|Array} this JSZip object (when adding a file), - * a file (when searching by string) or an array of files (when searching by regex). - */ - file: function (name, data, o) { - if (arguments.length === 1) { - if (isRegExp(name)) { - var regexp = name; - return this.filter(function (relativePath, file) { - return !file.dir && regexp.test(relativePath); - }); - } else { - // text - var obj = this.files[this.root + name]; - if (obj && !obj.dir) { - return obj; - } else { - return null; - } - } - } else { - // more than one argument : we have data ! - name = this.root + name; - fileAdd.call(this, name, data, o); - } - return this; - }, - - /** - * Add a directory to the zip file, or search. - * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. - * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. - */ - folder: function (arg) { - if (!arg) { - return this; - } - - if (isRegExp(arg)) { - return this.filter(function (relativePath, file) { - return file.dir && arg.test(relativePath); - }); - } - - // else, name is a new folder - var name = this.root + arg; - var newFolder = folderAdd.call(this, name); - - // Allow chaining by returning a new object with this folder as the root - var ret = this.clone(); - ret.root = newFolder.name; - return ret; - }, - - /** - * Delete a file, or a directory and all sub-files, from the zip - * @param {string} name the name of the file to delete - * @return {JSZip} this JSZip object - */ - remove: function (name) { - name = this.root + name; - var file = this.files[name]; - if (!file) { - // Look for any folders - if (name.slice(-1) !== "/") { - name += "/"; - } - file = this.files[name]; - } - - if (file && !file.dir) { - // file - delete this.files[name]; - } else { - // maybe a folder, delete recursively - var kids = this.filter(function (relativePath, file) { - return file.name.slice(0, name.length) === name; - }); - for (var i = 0; i < kids.length; i++) { - delete this.files[kids[i].name]; - } - } - - return this; - }, - - /** - * @deprecated This method has been removed in JSZip 3.0, please check the upgrade guide. - */ - generate: function () { - throw new Error( - "This method has been removed in JSZip 3.0, please check the upgrade guide.", - ); - }, - - /** - * Generate the complete zip file as an internal stream. - * @param {Object} options the options to generate the zip file : - * - compression, "STORE" by default. - * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. - * @return {StreamHelper} the streamed zip file. - */ - generateInternalStream: function (options) { - var worker, - opts = {}; - try { - opts = utils.extend(options || {}, { - streamFiles: false, - compression: "STORE", - compressionOptions: null, - type: "", - platform: "DOS", - comment: null, - mimeType: "application/zip", - encodeFileName: utf8.utf8encode, - }); - - opts.type = opts.type.toLowerCase(); - opts.compression = opts.compression.toUpperCase(); - - // "binarystring" is preferred but the internals use "string". - if (opts.type === "binarystring") { - opts.type = "string"; - } - - if (!opts.type) { - throw new Error("No output type specified."); - } - - utils.checkSupport(opts.type); - - // accept nodejs `process.platform` - if ( - opts.platform === "darwin" || - opts.platform === "freebsd" || - opts.platform === "linux" || - opts.platform === "sunos" - ) { - opts.platform = "UNIX"; - } - if (opts.platform === "win32") { - opts.platform = "DOS"; - } - - var comment = opts.comment || this.comment || ""; - worker = generate.generateWorker(this, opts, comment); - } catch (e) { - worker = new GenericWorker("error"); - worker.error(e); - } - return new StreamHelper( - worker, - opts.type || "string", - opts.mimeType, - ); - }, - /** - * Generate the complete zip file asynchronously. - * @see generateInternalStream - */ - generateAsync: function (options, onUpdate) { - return this.generateInternalStream(options).accumulate(onUpdate); - }, - /** - * Generate the complete zip file asynchronously. - * @see generateInternalStream - */ - generateNodeStream: function (options, onUpdate) { - options = options || {}; - if (!options.type) { - options.type = "nodebuffer"; - } - return this.generateInternalStream(options).toNodejsStream( - onUpdate, - ); - }, - }; - module.exports = out; - }, - { - "./compressedObject": 2, - "./defaults": 5, - "./generate": 9, - "./nodejs/NodejsStreamInputAdapter": 12, - "./nodejsUtils": 14, - "./stream/GenericWorker": 28, - "./stream/StreamHelper": 29, - "./utf8": 31, - "./utils": 32, - "./zipObject": 35, - }, - ], - 16: [ - function (require, module, exports) { - "use strict"; - /* - * This file is used by module bundlers (browserify/webpack/etc) when - * including a stream implementation. We use "readable-stream" to get a - * consistent behavior between nodejs versions but bundlers often have a shim - * for "stream". Using this shim greatly improve the compatibility and greatly - * reduce the final size of the bundle (only one stream implementation, not - * two). - */ - module.exports = require("stream"); - }, - { stream: undefined }, - ], - 17: [ - function (require, module, exports) { - "use strict"; - var DataReader = require("./DataReader"); - var utils = require("../utils"); - - function ArrayReader(data) { - DataReader.call(this, data); - for (var i = 0; i < this.data.length; i++) { - data[i] = data[i] & 0xff; - } - } - utils.inherits(ArrayReader, DataReader); - /** - * @see DataReader.byteAt - */ - ArrayReader.prototype.byteAt = function (i) { - return this.data[this.zero + i]; - }; - /** - * @see DataReader.lastIndexOfSignature - */ - ArrayReader.prototype.lastIndexOfSignature = function (sig) { - var sig0 = sig.charCodeAt(0), - sig1 = sig.charCodeAt(1), - sig2 = sig.charCodeAt(2), - sig3 = sig.charCodeAt(3); - for (var i = this.length - 4; i >= 0; --i) { - if ( - this.data[i] === sig0 && - this.data[i + 1] === sig1 && - this.data[i + 2] === sig2 && - this.data[i + 3] === sig3 - ) { - return i - this.zero; - } - } - - return -1; - }; - /** - * @see DataReader.readAndCheckSignature - */ - ArrayReader.prototype.readAndCheckSignature = function (sig) { - var sig0 = sig.charCodeAt(0), - sig1 = sig.charCodeAt(1), - sig2 = sig.charCodeAt(2), - sig3 = sig.charCodeAt(3), - data = this.readData(4); - return ( - sig0 === data[0] && - sig1 === data[1] && - sig2 === data[2] && - sig3 === data[3] - ); - }; - /** - * @see DataReader.readData - */ - ArrayReader.prototype.readData = function (size) { - this.checkOffset(size); - if (size === 0) { - return []; - } - var result = this.data.slice( - this.zero + this.index, - this.zero + this.index + size, - ); - this.index += size; - return result; - }; - module.exports = ArrayReader; - }, - { "../utils": 32, "./DataReader": 18 }, - ], - 18: [ - function (require, module, exports) { - "use strict"; - var utils = require("../utils"); - - function DataReader(data) { - this.data = data; // type : see implementation - this.length = data.length; - this.index = 0; - this.zero = 0; - } - DataReader.prototype = { - /** - * Check that the offset will not go too far. - * @param {string} offset the additional offset to check. - * @throws {Error} an Error if the offset is out of bounds. - */ - checkOffset: function (offset) { - this.checkIndex(this.index + offset); - }, - /** - * Check that the specified index will not be too far. - * @param {string} newIndex the index to check. - * @throws {Error} an Error if the index is out of bounds. - */ - checkIndex: function (newIndex) { - if (this.length < this.zero + newIndex || newIndex < 0) { - throw new Error( - "End of data reached (data length = " + - this.length + - ", asked index = " + - newIndex + - "). Corrupted zip ?", - ); - } - }, - /** - * Change the index. - * @param {number} newIndex The new index. - * @throws {Error} if the new index is out of the data. - */ - setIndex: function (newIndex) { - this.checkIndex(newIndex); - this.index = newIndex; - }, - /** - * Skip the next n bytes. - * @param {number} n the number of bytes to skip. - * @throws {Error} if the new index is out of the data. - */ - skip: function (n) { - this.setIndex(this.index + n); - }, - /** - * Get the byte at the specified index. - * @param {number} i the index to use. - * @return {number} a byte. - */ - byteAt: function () { - // see implementations - }, - /** - * Get the next number with a given byte size. - * @param {number} size the number of bytes to read. - * @return {number} the corresponding number. - */ - readInt: function (size) { - var result = 0, - i; - this.checkOffset(size); - for (i = this.index + size - 1; i >= this.index; i--) { - result = (result << 8) + this.byteAt(i); - } - this.index += size; - return result; - }, - /** - * Get the next string with a given byte size. - * @param {number} size the number of bytes to read. - * @return {string} the corresponding string. - */ - readString: function (size) { - return utils.transformTo("string", this.readData(size)); - }, - /** - * Get raw data without conversion, bytes. - * @param {number} size the number of bytes to read. - * @return {Object} the raw data, implementation specific. - */ - readData: function () { - // see implementations - }, - /** - * Find the last occurrence of a zip signature (4 bytes). - * @param {string} sig the signature to find. - * @return {number} the index of the last occurrence, -1 if not found. - */ - lastIndexOfSignature: function () { - // see implementations - }, - /** - * Read the signature (4 bytes) at the current position and compare it with sig. - * @param {string} sig the expected signature - * @return {boolean} true if the signature matches, false otherwise. - */ - readAndCheckSignature: function () { - // see implementations - }, - /** - * Get the next date. - * @return {Date} the date. - */ - readDate: function () { - var dostime = this.readInt(4); - return new Date( - Date.UTC( - ((dostime >> 25) & 0x7f) + 1980, // year - ((dostime >> 21) & 0x0f) - 1, // month - (dostime >> 16) & 0x1f, // day - (dostime >> 11) & 0x1f, // hour - (dostime >> 5) & 0x3f, // minute - (dostime & 0x1f) << 1, - ), - ); // second - }, - }; - module.exports = DataReader; - }, - { "../utils": 32 }, - ], - 19: [ - function (require, module, exports) { - "use strict"; - var Uint8ArrayReader = require("./Uint8ArrayReader"); - var utils = require("../utils"); - - function NodeBufferReader(data) { - Uint8ArrayReader.call(this, data); - } - utils.inherits(NodeBufferReader, Uint8ArrayReader); - - /** - * @see DataReader.readData - */ - NodeBufferReader.prototype.readData = function (size) { - this.checkOffset(size); - var result = this.data.slice( - this.zero + this.index, - this.zero + this.index + size, - ); - this.index += size; - return result; - }; - module.exports = NodeBufferReader; - }, - { "../utils": 32, "./Uint8ArrayReader": 21 }, - ], - 20: [ - function (require, module, exports) { - "use strict"; - var DataReader = require("./DataReader"); - var utils = require("../utils"); - - function StringReader(data) { - DataReader.call(this, data); - } - utils.inherits(StringReader, DataReader); - /** - * @see DataReader.byteAt - */ - StringReader.prototype.byteAt = function (i) { - return this.data.charCodeAt(this.zero + i); - }; - /** - * @see DataReader.lastIndexOfSignature - */ - StringReader.prototype.lastIndexOfSignature = function (sig) { - return this.data.lastIndexOf(sig) - this.zero; - }; - /** - * @see DataReader.readAndCheckSignature - */ - StringReader.prototype.readAndCheckSignature = function (sig) { - var data = this.readData(4); - return sig === data; - }; - /** - * @see DataReader.readData - */ - StringReader.prototype.readData = function (size) { - this.checkOffset(size); - // this will work because the constructor applied the "& 0xff" mask. - var result = this.data.slice( - this.zero + this.index, - this.zero + this.index + size, - ); - this.index += size; - return result; - }; - module.exports = StringReader; - }, - { "../utils": 32, "./DataReader": 18 }, - ], - 21: [ - function (require, module, exports) { - "use strict"; - var ArrayReader = require("./ArrayReader"); - var utils = require("../utils"); - - function Uint8ArrayReader(data) { - ArrayReader.call(this, data); - } - utils.inherits(Uint8ArrayReader, ArrayReader); - /** - * @see DataReader.readData - */ - Uint8ArrayReader.prototype.readData = function (size) { - this.checkOffset(size); - if (size === 0) { - // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. - return new Uint8Array(0); - } - var result = this.data.subarray( - this.zero + this.index, - this.zero + this.index + size, - ); - this.index += size; - return result; - }; - module.exports = Uint8ArrayReader; - }, - { "../utils": 32, "./ArrayReader": 17 }, - ], - 22: [ - function (require, module, exports) { - "use strict"; - - var utils = require("../utils"); - var support = require("../support"); - var ArrayReader = require("./ArrayReader"); - var StringReader = require("./StringReader"); - var NodeBufferReader = require("./NodeBufferReader"); - var Uint8ArrayReader = require("./Uint8ArrayReader"); - - /** - * Create a reader adapted to the data. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read. - * @return {DataReader} the data reader. - */ - module.exports = function (data) { - var type = utils.getTypeOf(data); - utils.checkSupport(type); - if (type === "string" && !support.uint8array) { - return new StringReader(data); - } - if (type === "nodebuffer") { - return new NodeBufferReader(data); - } - if (support.uint8array) { - return new Uint8ArrayReader( - utils.transformTo("uint8array", data), - ); - } - return new ArrayReader(utils.transformTo("array", data)); - }; - }, - { - "../support": 30, - "../utils": 32, - "./ArrayReader": 17, - "./NodeBufferReader": 19, - "./StringReader": 20, - "./Uint8ArrayReader": 21, - }, - ], - 23: [ - function (require, module, exports) { - "use strict"; - exports.LOCAL_FILE_HEADER = "PK\x03\x04"; - exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; - exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; - exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; - exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; - exports.DATA_DESCRIPTOR = "PK\x07\x08"; - }, - {}, - ], - 24: [ - function (require, module, exports) { - "use strict"; - - var GenericWorker = require("./GenericWorker"); - var utils = require("../utils"); - - /** - * A worker which convert chunks to a specified type. - * @constructor - * @param {String} destType the destination type. - */ - function ConvertWorker(destType) { - GenericWorker.call(this, "ConvertWorker to " + destType); - this.destType = destType; - } - utils.inherits(ConvertWorker, GenericWorker); - - /** - * @see GenericWorker.processChunk - */ - ConvertWorker.prototype.processChunk = function (chunk) { - this.push({ - data: utils.transformTo(this.destType, chunk.data), - meta: chunk.meta, - }); - }; - module.exports = ConvertWorker; - }, - { "../utils": 32, "./GenericWorker": 28 }, - ], - 25: [ - function (require, module, exports) { - "use strict"; - - var GenericWorker = require("./GenericWorker"); - var crc32 = require("../crc32"); - var utils = require("../utils"); - - /** - * A worker which calculate the crc32 of the data flowing through. - * @constructor - */ - function Crc32Probe() { - GenericWorker.call(this, "Crc32Probe"); - this.withStreamInfo("crc32", 0); - } - utils.inherits(Crc32Probe, GenericWorker); - - /** - * @see GenericWorker.processChunk - */ - Crc32Probe.prototype.processChunk = function (chunk) { - this.streamInfo.crc32 = crc32( - chunk.data, - this.streamInfo.crc32 || 0, - ); - this.push(chunk); - }; - module.exports = Crc32Probe; - }, - { "../crc32": 4, "../utils": 32, "./GenericWorker": 28 }, - ], - 26: [ - function (require, module, exports) { - "use strict"; - - var utils = require("../utils"); - var GenericWorker = require("./GenericWorker"); - - /** - * A worker which calculate the total length of the data flowing through. - * @constructor - * @param {String} propName the name used to expose the length - */ - function DataLengthProbe(propName) { - GenericWorker.call(this, "DataLengthProbe for " + propName); - this.propName = propName; - this.withStreamInfo(propName, 0); - } - utils.inherits(DataLengthProbe, GenericWorker); - - /** - * @see GenericWorker.processChunk - */ - DataLengthProbe.prototype.processChunk = function (chunk) { - if (chunk) { - var length = this.streamInfo[this.propName] || 0; - this.streamInfo[this.propName] = length + chunk.data.length; - } - GenericWorker.prototype.processChunk.call(this, chunk); - }; - module.exports = DataLengthProbe; - }, - { "../utils": 32, "./GenericWorker": 28 }, - ], - 27: [ - function (require, module, exports) { - "use strict"; - - var utils = require("../utils"); - var GenericWorker = require("./GenericWorker"); - - // the size of the generated chunks - // TODO expose this as a public variable - var DEFAULT_BLOCK_SIZE = 16 * 1024; - - /** - * A worker that reads a content and emits chunks. - * @constructor - * @param {Promise} dataP the promise of the data to split - */ - function DataWorker(dataP) { - GenericWorker.call(this, "DataWorker"); - var self = this; - this.dataIsReady = false; - this.index = 0; - this.max = 0; - this.data = null; - this.type = ""; - - this._tickScheduled = false; - - dataP.then( - function (data) { - self.dataIsReady = true; - self.data = data; - self.max = (data && data.length) || 0; - self.type = utils.getTypeOf(data); - if (!self.isPaused) { - self._tickAndRepeat(); - } - }, - function (e) { - self.error(e); - }, - ); - } - - utils.inherits(DataWorker, GenericWorker); - - /** - * @see GenericWorker.cleanUp - */ - DataWorker.prototype.cleanUp = function () { - GenericWorker.prototype.cleanUp.call(this); - this.data = null; - }; - - /** - * @see GenericWorker.resume - */ - DataWorker.prototype.resume = function () { - if (!GenericWorker.prototype.resume.call(this)) { - return false; - } - - if (!this._tickScheduled && this.dataIsReady) { - this._tickScheduled = true; - utils.delay(this._tickAndRepeat, [], this); - } - return true; - }; - - /** - * Trigger a tick a schedule an other call to this function. - */ - DataWorker.prototype._tickAndRepeat = function () { - this._tickScheduled = false; - if (this.isPaused || this.isFinished) { - return; - } - this._tick(); - if (!this.isFinished) { - utils.delay(this._tickAndRepeat, [], this); - this._tickScheduled = true; - } - }; - - /** - * Read and push a chunk. - */ - DataWorker.prototype._tick = function () { - if (this.isPaused || this.isFinished) { - return false; - } - - var size = DEFAULT_BLOCK_SIZE; - var data = null, - nextIndex = Math.min(this.max, this.index + size); - if (this.index >= this.max) { - // EOF - return this.end(); - } else { - switch (this.type) { - case "string": - data = this.data.substring(this.index, nextIndex); - break; - case "uint8array": - data = this.data.subarray(this.index, nextIndex); - break; - case "array": - case "nodebuffer": - data = this.data.slice(this.index, nextIndex); - break; - } - this.index = nextIndex; - return this.push({ - data: data, - meta: { - percent: this.max ? (this.index / this.max) * 100 : 0, - }, - }); - } - }; - - module.exports = DataWorker; - }, - { "../utils": 32, "./GenericWorker": 28 }, - ], - 28: [ - function (require, module, exports) { - "use strict"; - - /** - * A worker that does nothing but passing chunks to the next one. This is like - * a nodejs stream but with some differences. On the good side : - * - it works on IE 6-9 without any issue / polyfill - * - it weights less than the full dependencies bundled with browserify - * - it forwards errors (no need to declare an error handler EVERYWHERE) - * - * A chunk is an object with 2 attributes : `meta` and `data`. The former is an - * object containing anything (`percent` for example), see each worker for more - * details. The latter is the real data (String, Uint8Array, etc). - * - * @constructor - * @param {String} name the name of the stream (mainly used for debugging purposes) - */ - function GenericWorker(name) { - // the name of the worker - this.name = name || "default"; - // an object containing metadata about the workers chain - this.streamInfo = {}; - // an error which happened when the worker was paused - this.generatedError = null; - // an object containing metadata to be merged by this worker into the general metadata - this.extraStreamInfo = {}; - // true if the stream is paused (and should not do anything), false otherwise - this.isPaused = true; - // true if the stream is finished (and should not do anything), false otherwise - this.isFinished = false; - // true if the stream is locked to prevent further structure updates (pipe), false otherwise - this.isLocked = false; - // the event listeners - this._listeners = { - data: [], - end: [], - error: [], - }; - // the previous worker, if any - this.previous = null; - } - - GenericWorker.prototype = { - /** - * Push a chunk to the next workers. - * @param {Object} chunk the chunk to push - */ - push: function (chunk) { - this.emit("data", chunk); - }, - /** - * End the stream. - * @return {Boolean} true if this call ended the worker, false otherwise. - */ - end: function () { - if (this.isFinished) { - return false; - } - - this.flush(); - try { - this.emit("end"); - this.cleanUp(); - this.isFinished = true; - } catch (e) { - this.emit("error", e); - } - return true; - }, - /** - * End the stream with an error. - * @param {Error} e the error which caused the premature end. - * @return {Boolean} true if this call ended the worker with an error, false otherwise. - */ - error: function (e) { - if (this.isFinished) { - return false; - } - - if (this.isPaused) { - this.generatedError = e; - } else { - this.isFinished = true; - - this.emit("error", e); - - // in the workers chain exploded in the middle of the chain, - // the error event will go downward but we also need to notify - // workers upward that there has been an error. - if (this.previous) { - this.previous.error(e); - } - - this.cleanUp(); - } - return true; - }, - /** - * Add a callback on an event. - * @param {String} name the name of the event (data, end, error) - * @param {Function} listener the function to call when the event is triggered - * @return {GenericWorker} the current object for chainability - */ - on: function (name, listener) { - this._listeners[name].push(listener); - return this; - }, - /** - * Clean any references when a worker is ending. - */ - cleanUp: function () { - this.streamInfo = - this.generatedError = - this.extraStreamInfo = - null; - this._listeners = []; - }, - /** - * Trigger an event. This will call registered callback with the provided arg. - * @param {String} name the name of the event (data, end, error) - * @param {Object} arg the argument to call the callback with. - */ - emit: function (name, arg) { - if (this._listeners[name]) { - for (var i = 0; i < this._listeners[name].length; i++) { - this._listeners[name][i].call(this, arg); - } - } - }, - /** - * Chain a worker with an other. - * @param {Worker} next the worker receiving events from the current one. - * @return {worker} the next worker for chainability - */ - pipe: function (next) { - return next.registerPrevious(this); - }, - /** - * Same as `pipe` in the other direction. - * Using an API with `pipe(next)` is very easy. - * Implementing the API with the point of view of the next one registering - * a source is easier, see the ZipFileWorker. - * @param {Worker} previous the previous worker, sending events to this one - * @return {Worker} the current worker for chainability - */ - registerPrevious: function (previous) { - if (this.isLocked) { - throw new Error( - "The stream '" + this + "' has already been used.", - ); - } - - // sharing the streamInfo... - this.streamInfo = previous.streamInfo; - // ... and adding our own bits - this.mergeStreamInfo(); - this.previous = previous; - var self = this; - previous.on("data", function (chunk) { - self.processChunk(chunk); - }); - previous.on("end", function () { - self.end(); - }); - previous.on("error", function (e) { - self.error(e); - }); - return this; - }, - /** - * Pause the stream so it doesn't send events anymore. - * @return {Boolean} true if this call paused the worker, false otherwise. - */ - pause: function () { - if (this.isPaused || this.isFinished) { - return false; - } - this.isPaused = true; - - if (this.previous) { - this.previous.pause(); - } - return true; - }, - /** - * Resume a paused stream. - * @return {Boolean} true if this call resumed the worker, false otherwise. - */ - resume: function () { - if (!this.isPaused || this.isFinished) { - return false; - } - this.isPaused = false; - - // if true, the worker tried to resume but failed - var withError = false; - if (this.generatedError) { - this.error(this.generatedError); - withError = true; - } - if (this.previous) { - this.previous.resume(); - } - - return !withError; - }, - /** - * Flush any remaining bytes as the stream is ending. - */ - flush: function () {}, - /** - * Process a chunk. This is usually the method overridden. - * @param {Object} chunk the chunk to process. - */ - processChunk: function (chunk) { - this.push(chunk); - }, - /** - * Add a key/value to be added in the workers chain streamInfo once activated. - * @param {String} key the key to use - * @param {Object} value the associated value - * @return {Worker} the current worker for chainability - */ - withStreamInfo: function (key, value) { - this.extraStreamInfo[key] = value; - this.mergeStreamInfo(); - return this; - }, - /** - * Merge this worker's streamInfo into the chain's streamInfo. - */ - mergeStreamInfo: function () { - for (var key in this.extraStreamInfo) { - if ( - !Object.prototype.hasOwnProperty.call( - this.extraStreamInfo, - key, - ) - ) { - continue; - } - this.streamInfo[key] = this.extraStreamInfo[key]; - } - }, - - /** - * Lock the stream to prevent further updates on the workers chain. - * After calling this method, all calls to pipe will fail. - */ - lock: function () { - if (this.isLocked) { - throw new Error( - "The stream '" + this + "' has already been used.", - ); - } - this.isLocked = true; - if (this.previous) { - this.previous.lock(); - } - }, - - /** - * - * Pretty print the workers chain. - */ - toString: function () { - var me = "Worker " + this.name; - if (this.previous) { - return this.previous + " -> " + me; - } else { - return me; - } - }, - }; - - module.exports = GenericWorker; - }, - {}, - ], - 29: [ - function (require, module, exports) { - "use strict"; - - var utils = require("../utils"); - var ConvertWorker = require("./ConvertWorker"); - var GenericWorker = require("./GenericWorker"); - var base64 = require("../base64"); - var support = require("../support"); - var external = require("../external"); - - var NodejsStreamOutputAdapter = null; - if (support.nodestream) { - try { - NodejsStreamOutputAdapter = require("../nodejs/NodejsStreamOutputAdapter"); - } catch (e) { - // ignore - } - } - - /** - * Apply the final transformation of the data. If the user wants a Blob for - * example, it's easier to work with an U8intArray and finally do the - * ArrayBuffer/Blob conversion. - * @param {String} type the name of the final type - * @param {String|Uint8Array|Buffer} content the content to transform - * @param {String} mimeType the mime type of the content, if applicable. - * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format. - */ - function transformZipOutput(type, content, mimeType) { - switch (type) { - case "blob": - return utils.newBlob( - utils.transformTo("arraybuffer", content), - mimeType, - ); - case "base64": - return base64.encode(content); - default: - return utils.transformTo(type, content); - } - } - - /** - * Concatenate an array of data of the given type. - * @param {String} type the type of the data in the given array. - * @param {Array} dataArray the array containing the data chunks to concatenate - * @return {String|Uint8Array|Buffer} the concatenated data - * @throws Error if the asked type is unsupported - */ - function concat(type, dataArray) { - var i, - index = 0, - res = null, - totalLength = 0; - for (i = 0; i < dataArray.length; i++) { - totalLength += dataArray[i].length; - } - switch (type) { - case "string": - return dataArray.join(""); - case "array": - return Array.prototype.concat.apply([], dataArray); - case "uint8array": - res = new Uint8Array(totalLength); - for (i = 0; i < dataArray.length; i++) { - res.set(dataArray[i], index); - index += dataArray[i].length; - } - return res; - case "nodebuffer": - return Buffer.concat(dataArray); - default: - throw new Error("concat : unsupported type '" + type + "'"); - } - } - - /** - * Listen a StreamHelper, accumulate its content and concatenate it into a - * complete block. - * @param {StreamHelper} helper the helper to use. - * @param {Function} updateCallback a callback called on each update. Called - * with one arg : - * - the metadata linked to the update received. - * @return Promise the promise for the accumulation. - */ - function accumulate(helper, updateCallback) { - return new external.Promise(function (resolve, reject) { - var dataArray = []; - var chunkType = helper._internalType, - resultType = helper._outputType, - mimeType = helper._mimeType; - helper - .on("data", function (data, meta) { - dataArray.push(data); - if (updateCallback) { - updateCallback(meta); - } - }) - .on("error", function (err) { - dataArray = []; - reject(err); - }) - .on("end", function () { - try { - var result = transformZipOutput( - resultType, - concat(chunkType, dataArray), - mimeType, - ); - resolve(result); - } catch (e) { - reject(e); - } - dataArray = []; - }) - .resume(); - }); - } - - /** - * An helper to easily use workers outside of JSZip. - * @constructor - * @param {Worker} worker the worker to wrap - * @param {String} outputType the type of data expected by the use - * @param {String} mimeType the mime type of the content, if applicable. - */ - function StreamHelper(worker, outputType, mimeType) { - var internalType = outputType; - switch (outputType) { - case "blob": - case "arraybuffer": - internalType = "uint8array"; - break; - case "base64": - internalType = "string"; - break; - } - - try { - // the type used internally - this._internalType = internalType; - // the type used to output results - this._outputType = outputType; - // the mime type - this._mimeType = mimeType; - utils.checkSupport(internalType); - this._worker = worker.pipe(new ConvertWorker(internalType)); - // the last workers can be rewired without issues but we need to - // prevent any updates on previous workers. - worker.lock(); - } catch (e) { - this._worker = new GenericWorker("error"); - this._worker.error(e); - } - } - - StreamHelper.prototype = { - /** - * Listen a StreamHelper, accumulate its content and concatenate it into a - * complete block. - * @param {Function} updateCb the update callback. - * @return Promise the promise for the accumulation. - */ - accumulate: function (updateCb) { - return accumulate(this, updateCb); - }, - /** - * Add a listener on an event triggered on a stream. - * @param {String} evt the name of the event - * @param {Function} fn the listener - * @return {StreamHelper} the current helper. - */ - on: function (evt, fn) { - var self = this; - - if (evt === "data") { - this._worker.on(evt, function (chunk) { - fn.call(self, chunk.data, chunk.meta); - }); - } else { - this._worker.on(evt, function () { - utils.delay(fn, arguments, self); - }); - } - return this; - }, - /** - * Resume the flow of chunks. - * @return {StreamHelper} the current helper. - */ - resume: function () { - utils.delay(this._worker.resume, [], this._worker); - return this; - }, - /** - * Pause the flow of chunks. - * @return {StreamHelper} the current helper. - */ - pause: function () { - this._worker.pause(); - return this; - }, - /** - * Return a nodejs stream for this helper. - * @param {Function} updateCb the update callback. - * @return {NodejsStreamOutputAdapter} the nodejs stream. - */ - toNodejsStream: function (updateCb) { - utils.checkSupport("nodestream"); - if (this._outputType !== "nodebuffer") { - // an object stream containing blob/arraybuffer/uint8array/string - // is strange and I don't know if it would be useful. - // I you find this comment and have a good usecase, please open a - // bug report ! - throw new Error( - this._outputType + " is not supported by this method", - ); - } - - return new NodejsStreamOutputAdapter( - this, - { - objectMode: this._outputType !== "nodebuffer", - }, - updateCb, - ); - }, - }; - - module.exports = StreamHelper; - }, - { - "../base64": 1, - "../external": 6, - "../nodejs/NodejsStreamOutputAdapter": 13, - "../support": 30, - "../utils": 32, - "./ConvertWorker": 24, - "./GenericWorker": 28, - }, - ], - 30: [ - function (require, module, exports) { - "use strict"; - - exports.base64 = true; - exports.array = true; - exports.string = true; - exports.arraybuffer = - typeof ArrayBuffer !== "undefined" && - typeof Uint8Array !== "undefined"; - exports.nodebuffer = typeof Buffer !== "undefined"; - // contains true if JSZip can read/generate Uint8Array, false otherwise. - exports.uint8array = typeof Uint8Array !== "undefined"; - - if (typeof ArrayBuffer === "undefined") { - exports.blob = false; - } else { - var buffer = new ArrayBuffer(0); - try { - exports.blob = - new Blob([buffer], { - type: "application/zip", - }).size === 0; - } catch (e) { - try { - var Builder = - self.BlobBuilder || - self.WebKitBlobBuilder || - self.MozBlobBuilder || - self.MSBlobBuilder; - var builder = new Builder(); - builder.append(buffer); - exports.blob = builder.getBlob("application/zip").size === 0; - } catch (e) { - exports.blob = false; - } - } - } - - try { - exports.nodestream = !!require("readable-stream").Readable; - } catch (e) { - exports.nodestream = false; - } - }, - { "readable-stream": 16 }, - ], - 31: [ - function (require, module, exports) { - "use strict"; - - var utils = require("./utils"); - var support = require("./support"); - var nodejsUtils = require("./nodejsUtils"); - var GenericWorker = require("./stream/GenericWorker"); - - /** - * The following functions come from pako, from pako/lib/utils/strings - * released under the MIT license, see pako https://github.com/nodeca/pako/ - */ - - // Table with utf8 lengths (calculated by first byte of sequence) - // Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, - // because max possible codepoint is 0x10ffff - var _utf8len = new Array(256); - for (var i = 0; i < 256; i++) { - _utf8len[i] = - i >= 252 - ? 6 - : i >= 248 - ? 5 - : i >= 240 - ? 4 - : i >= 224 - ? 3 - : i >= 192 - ? 2 - : 1; - } - _utf8len[254] = _utf8len[254] = 1; // Invalid sequence start - - // convert string to array (typed, when possible) - var string2buf = function (str) { - var buf, - c, - c2, - m_pos, - i, - str_len = str.length, - buf_len = 0; - - // count binary size - for (m_pos = 0; m_pos < str_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; - } - - // allocate buffer - if (support.uint8array) { - buf = new Uint8Array(buf_len); - } else { - buf = new Array(buf_len); - } - - // convert - for (i = 0, m_pos = 0; i < buf_len; m_pos++) { - c = str.charCodeAt(m_pos); - if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) { - c2 = str.charCodeAt(m_pos + 1); - if ((c2 & 0xfc00) === 0xdc00) { - c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); - m_pos++; - } - } - if (c < 0x80) { - /* one byte */ - buf[i++] = c; - } else if (c < 0x800) { - /* two bytes */ - buf[i++] = 0xc0 | (c >>> 6); - buf[i++] = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - /* three bytes */ - buf[i++] = 0xe0 | (c >>> 12); - buf[i++] = 0x80 | ((c >>> 6) & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } else { - /* four bytes */ - buf[i++] = 0xf0 | (c >>> 18); - buf[i++] = 0x80 | ((c >>> 12) & 0x3f); - buf[i++] = 0x80 | ((c >>> 6) & 0x3f); - buf[i++] = 0x80 | (c & 0x3f); - } - } - - return buf; - }; - - // Calculate max possible position in utf8 buffer, - // that will not break sequence. If that's not possible - // - (very small limits) return max size as is. - // - // buf[] - utf8 bytes array - // max - length limit (mandatory); - var utf8border = function (buf, max) { - var pos; - - max = max || buf.length; - if (max > buf.length) { - max = buf.length; - } - - // go back from last position, until start of sequence found - pos = max - 1; - while (pos >= 0 && (buf[pos] & 0xc0) === 0x80) { - pos--; - } - - // Fuckup - very small and broken sequence, - // return max, because we should return something anyway. - if (pos < 0) { - return max; - } - - // If we came to start of buffer - that means vuffer is too small, - // return max too. - if (pos === 0) { - return max; - } - - return pos + _utf8len[buf[pos]] > max ? pos : max; - }; - - // convert array to string - var buf2string = function (buf) { - var i, out, c, c_len; - var len = buf.length; - - // Reserve max possible length (2 words per char) - // NB: by unknown reasons, Array is significantly faster for - // String.fromCharCode.apply than Uint16Array. - var utf16buf = new Array(len * 2); - - for (out = 0, i = 0; i < len; ) { - c = buf[i++]; - // quick process ascii - if (c < 0x80) { - utf16buf[out++] = c; - continue; - } - - c_len = _utf8len[c]; - // skip 5 & 6 byte codes - if (c_len > 4) { - utf16buf[out++] = 0xfffd; - i += c_len - 1; - continue; - } - - // apply mask on first byte - c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; - // join the rest - while (c_len > 1 && i < len) { - c = (c << 6) | (buf[i++] & 0x3f); - c_len--; - } - - // terminated by end of string? - if (c_len > 1) { - utf16buf[out++] = 0xfffd; - continue; - } - - if (c < 0x10000) { - utf16buf[out++] = c; - } else { - c -= 0x10000; - utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); - utf16buf[out++] = 0xdc00 | (c & 0x3ff); - } - } - - // shrinkBuf(utf16buf, out) - if (utf16buf.length !== out) { - if (utf16buf.subarray) { - utf16buf = utf16buf.subarray(0, out); - } else { - utf16buf.length = out; - } - } - - // return String.fromCharCode.apply(null, utf16buf); - return utils.applyFromCharCode(utf16buf); - }; - - // That's all for the pako functions. - - /** - * Transform a javascript string into an array (typed if possible) of bytes, - * UTF-8 encoded. - * @param {String} str the string to encode - * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. - */ - exports.utf8encode = function utf8encode(str) { - if (support.nodebuffer) { - return nodejsUtils.newBufferFrom(str, "utf-8"); - } - - return string2buf(str); - }; - - /** - * Transform a bytes array (or a representation) representing an UTF-8 encoded - * string into a javascript string. - * @param {Array|Uint8Array|Buffer} buf the data de decode - * @return {String} the decoded string. - */ - exports.utf8decode = function utf8decode(buf) { - if (support.nodebuffer) { - return utils.transformTo("nodebuffer", buf).toString("utf-8"); - } - - buf = utils.transformTo( - support.uint8array ? "uint8array" : "array", - buf, - ); - - return buf2string(buf); - }; - - /** - * A worker to decode utf8 encoded binary chunks into string chunks. - * @constructor - */ - function Utf8DecodeWorker() { - GenericWorker.call(this, "utf-8 decode"); - // the last bytes if a chunk didn't end with a complete codepoint. - this.leftOver = null; - } - utils.inherits(Utf8DecodeWorker, GenericWorker); - - /** - * @see GenericWorker.processChunk - */ - Utf8DecodeWorker.prototype.processChunk = function (chunk) { - var data = utils.transformTo( - support.uint8array ? "uint8array" : "array", - chunk.data, - ); - - // 1st step, re-use what's left of the previous chunk - if (this.leftOver && this.leftOver.length) { - if (support.uint8array) { - var previousData = data; - data = new Uint8Array( - previousData.length + this.leftOver.length, - ); - data.set(this.leftOver, 0); - data.set(previousData, this.leftOver.length); - } else { - data = this.leftOver.concat(data); - } - this.leftOver = null; - } - - var nextBoundary = utf8border(data); - var usableData = data; - if (nextBoundary !== data.length) { - if (support.uint8array) { - usableData = data.subarray(0, nextBoundary); - this.leftOver = data.subarray(nextBoundary, data.length); - } else { - usableData = data.slice(0, nextBoundary); - this.leftOver = data.slice(nextBoundary, data.length); - } - } - - this.push({ - data: exports.utf8decode(usableData), - meta: chunk.meta, - }); - }; - - /** - * @see GenericWorker.flush - */ - Utf8DecodeWorker.prototype.flush = function () { - if (this.leftOver && this.leftOver.length) { - this.push({ - data: exports.utf8decode(this.leftOver), - meta: {}, - }); - this.leftOver = null; - } - }; - exports.Utf8DecodeWorker = Utf8DecodeWorker; - - /** - * A worker to endcode string chunks into utf8 encoded binary chunks. - * @constructor - */ - function Utf8EncodeWorker() { - GenericWorker.call(this, "utf-8 encode"); - } - utils.inherits(Utf8EncodeWorker, GenericWorker); - - /** - * @see GenericWorker.processChunk - */ - Utf8EncodeWorker.prototype.processChunk = function (chunk) { - this.push({ - data: exports.utf8encode(chunk.data), - meta: chunk.meta, - }); - }; - exports.Utf8EncodeWorker = Utf8EncodeWorker; - }, - { - "./nodejsUtils": 14, - "./stream/GenericWorker": 28, - "./support": 30, - "./utils": 32, - }, - ], - 32: [ - function (require, module, exports) { - "use strict"; - - var support = require("./support"); - var base64 = require("./base64"); - var nodejsUtils = require("./nodejsUtils"); - var external = require("./external"); - require("setimmediate"); - - /** - * Convert a string that pass as a "binary string": it should represent a byte - * array but may have > 255 char codes. Be sure to take only the first byte - * and returns the byte array. - * @param {String} str the string to transform. - * @return {Array|Uint8Array} the string in a binary format. - */ - function string2binary(str) { - var result = null; - if (support.uint8array) { - result = new Uint8Array(str.length); - } else { - result = new Array(str.length); - } - return stringToArrayLike(str, result); - } - - /** - * Create a new blob with the given content and the given type. - * @param {String|ArrayBuffer} part the content to put in the blob. DO NOT use - * an Uint8Array because the stock browser of android 4 won't accept it (it - * will be silently converted to a string, "[object Uint8Array]"). - * - * Use only ONE part to build the blob to avoid a memory leak in IE11 / Edge: - * when a large amount of Array is used to create the Blob, the amount of - * memory consumed is nearly 100 times the original data amount. - * - * @param {String} type the mime type of the blob. - * @return {Blob} the created blob. - */ - exports.newBlob = function (part, type) { - exports.checkSupport("blob"); - - try { - // Blob constructor - return new Blob([part], { - type: type, - }); - } catch (e) { - try { - // deprecated, browser only, old way - var Builder = - self.BlobBuilder || - self.WebKitBlobBuilder || - self.MozBlobBuilder || - self.MSBlobBuilder; - var builder = new Builder(); - builder.append(part); - return builder.getBlob(type); - } catch (e) { - // well, fuck ?! - throw new Error("Bug : can't construct the Blob."); - } - } - }; - /** - * The identity function. - * @param {Object} input the input. - * @return {Object} the same input. - */ - function identity(input) { - return input; - } - - /** - * Fill in an array with a string. - * @param {String} str the string to use. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). - * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. - */ - function stringToArrayLike(str, array) { - for (var i = 0; i < str.length; ++i) { - array[i] = str.charCodeAt(i) & 0xff; - } - return array; - } - - /** - * An helper for the function arrayLikeToString. - * This contains static information and functions that - * can be optimized by the browser JIT compiler. - */ - var arrayToStringHelper = { - /** - * Transform an array of int into a string, chunk by chunk. - * See the performances notes on arrayLikeToString. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. - * @param {String} type the type of the array. - * @param {Integer} chunk the chunk size. - * @return {String} the resulting string. - * @throws Error if the chunk is too big for the stack. - */ - stringifyByChunk: function (array, type, chunk) { - var result = [], - k = 0, - len = array.length; - // shortcut - if (len <= chunk) { - return String.fromCharCode.apply(null, array); - } - while (k < len) { - if (type === "array" || type === "nodebuffer") { - result.push( - String.fromCharCode.apply( - null, - array.slice(k, Math.min(k + chunk, len)), - ), - ); - } else { - result.push( - String.fromCharCode.apply( - null, - array.subarray(k, Math.min(k + chunk, len)), - ), - ); - } - k += chunk; - } - return result.join(""); - }, - /** - * Call String.fromCharCode on every item in the array. - * This is the naive implementation, which generate A LOT of intermediate string. - * This should be used when everything else fail. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. - * @return {String} the result. - */ - stringifyByChar: function (array) { - var resultStr = ""; - for (var i = 0; i < array.length; i++) { - resultStr += String.fromCharCode(array[i]); - } - return resultStr; - }, - applyCanBeUsed: { - /** - * true if the browser accepts to use String.fromCharCode on Uint8Array - */ - uint8array: (function () { - try { - return ( - support.uint8array && - String.fromCharCode.apply(null, new Uint8Array(1)) - .length === 1 - ); - } catch (e) { - return false; - } - })(), - /** - * true if the browser accepts to use String.fromCharCode on nodejs Buffer. - */ - nodebuffer: (function () { - try { - return ( - support.nodebuffer && - String.fromCharCode.apply(null, nodejsUtils.allocBuffer(1)) - .length === 1 - ); - } catch (e) { - return false; - } - })(), - }, - }; - - /** - * Transform an array-like object to a string. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. - * @return {String} the result. - */ - function arrayLikeToString(array) { - // Performances notes : - // -------------------- - // String.fromCharCode.apply(null, array) is the fastest, see - // see http://jsperf.com/converting-a-uint8array-to-a-string/2 - // but the stack is limited (and we can get huge arrays !). - // - // result += String.fromCharCode(array[i]); generate too many strings ! - // - // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 - // TODO : we now have workers that split the work. Do we still need that ? - var chunk = 65536, - type = exports.getTypeOf(array), - canUseApply = true; - if (type === "uint8array") { - canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array; - } else if (type === "nodebuffer") { - canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer; - } - - if (canUseApply) { - while (chunk > 1) { - try { - return arrayToStringHelper.stringifyByChunk( - array, - type, - chunk, - ); - } catch (e) { - chunk = Math.floor(chunk / 2); - } - } - } - - // no apply or chunk error : slow and painful algorithm - // default browser on android 4.* - return arrayToStringHelper.stringifyByChar(array); - } - - exports.applyFromCharCode = arrayLikeToString; - - /** - * Copy the data from an array-like to an other array-like. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. - * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. - * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. - */ - function arrayLikeToArrayLike(arrayFrom, arrayTo) { - for (var i = 0; i < arrayFrom.length; i++) { - arrayTo[i] = arrayFrom[i]; - } - return arrayTo; - } - - // a matrix containing functions to transform everything into everything. - var transform = {}; - - // string to ? - transform["string"] = { - string: identity, - array: function (input) { - return stringToArrayLike(input, new Array(input.length)); - }, - arraybuffer: function (input) { - return transform["string"]["uint8array"](input).buffer; - }, - uint8array: function (input) { - return stringToArrayLike(input, new Uint8Array(input.length)); - }, - nodebuffer: function (input) { - return stringToArrayLike( - input, - nodejsUtils.allocBuffer(input.length), - ); - }, - }; - - // array to ? - transform["array"] = { - string: arrayLikeToString, - array: identity, - arraybuffer: function (input) { - return new Uint8Array(input).buffer; - }, - uint8array: function (input) { - return new Uint8Array(input); - }, - nodebuffer: function (input) { - return nodejsUtils.newBufferFrom(input); - }, - }; - - // arraybuffer to ? - transform["arraybuffer"] = { - string: function (input) { - return arrayLikeToString(new Uint8Array(input)); - }, - array: function (input) { - return arrayLikeToArrayLike( - new Uint8Array(input), - new Array(input.byteLength), - ); - }, - arraybuffer: identity, - uint8array: function (input) { - return new Uint8Array(input); - }, - nodebuffer: function (input) { - return nodejsUtils.newBufferFrom(new Uint8Array(input)); - }, - }; - - // uint8array to ? - transform["uint8array"] = { - string: arrayLikeToString, - array: function (input) { - return arrayLikeToArrayLike(input, new Array(input.length)); - }, - arraybuffer: function (input) { - return input.buffer; - }, - uint8array: identity, - nodebuffer: function (input) { - return nodejsUtils.newBufferFrom(input); - }, - }; - - // nodebuffer to ? - transform["nodebuffer"] = { - string: arrayLikeToString, - array: function (input) { - return arrayLikeToArrayLike(input, new Array(input.length)); - }, - arraybuffer: function (input) { - return transform["nodebuffer"]["uint8array"](input).buffer; - }, - uint8array: function (input) { - return arrayLikeToArrayLike(input, new Uint8Array(input.length)); - }, - nodebuffer: identity, - }; - - /** - * Transform an input into any type. - * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. - * If no output type is specified, the unmodified input will be returned. - * @param {String} outputType the output type. - * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. - * @throws {Error} an Error if the browser doesn't support the requested output type. - */ - exports.transformTo = function (outputType, input) { - if (!input) { - // undefined, null, etc - // an empty string won't harm. - input = ""; - } - if (!outputType) { - return input; - } - exports.checkSupport(outputType); - var inputType = exports.getTypeOf(input); - var result = transform[inputType][outputType](input); - return result; - }; - - /** - * Resolve all relative path components, "." and "..", in a path. If these relative components - * traverse above the root then the resulting path will only contain the final path component. - * - * All empty components, e.g. "//", are removed. - * @param {string} path A path with / or \ separators - * @returns {string} The path with all relative path components resolved. - */ - exports.resolve = function (path) { - var parts = path.split("/"); - var result = []; - for (var index = 0; index < parts.length; index++) { - var part = parts[index]; - // Allow the first and last component to be empty for trailing slashes. - if ( - part === "." || - (part === "" && index !== 0 && index !== parts.length - 1) - ) { - continue; - } else if (part === "..") { - result.pop(); - } else { - result.push(part); - } - } - return result.join("/"); - }; - - /** - * Return the type of the input. - * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. - * @param {Object} input the input to identify. - * @return {String} the (lowercase) type of the input. - */ - exports.getTypeOf = function (input) { - if (typeof input === "string") { - return "string"; - } - if (Object.prototype.toString.call(input) === "[object Array]") { - return "array"; - } - if (support.nodebuffer && nodejsUtils.isBuffer(input)) { - return "nodebuffer"; - } - if (support.uint8array && input instanceof Uint8Array) { - return "uint8array"; - } - if (support.arraybuffer && input instanceof ArrayBuffer) { - return "arraybuffer"; - } - }; - - /** - * Throw an exception if the type is not supported. - * @param {String} type the type to check. - * @throws {Error} an Error if the browser doesn't support the requested type. - */ - exports.checkSupport = function (type) { - var supported = support[type.toLowerCase()]; - if (!supported) { - throw new Error(type + " is not supported by this platform"); - } - }; - - exports.MAX_VALUE_16BITS = 65535; - exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 - - /** - * Prettify a string read as binary. - * @param {string} str the string to prettify. - * @return {string} a pretty string. - */ - exports.pretty = function (str) { - var res = "", - code, - i; - for (i = 0; i < (str || "").length; i++) { - code = str.charCodeAt(i); - res += - "\\x" + - (code < 16 ? "0" : "") + - code.toString(16).toUpperCase(); - } - return res; - }; - - /** - * Defer the call of a function. - * @param {Function} callback the function to call asynchronously. - * @param {Array} args the arguments to give to the callback. - */ - exports.delay = function (callback, args, self) { - setImmediate(function () { - callback.apply(self || null, args || []); - }); - }; - - /** - * Extends a prototype with an other, without calling a constructor with - * side effects. Inspired by nodejs' `utils.inherits` - * @param {Function} ctor the constructor to augment - * @param {Function} superCtor the parent constructor to use - */ - exports.inherits = function (ctor, superCtor) { - var Obj = function () {}; - Obj.prototype = superCtor.prototype; - ctor.prototype = new Obj(); - }; - - /** - * Merge the objects passed as parameters into a new one. - * @private - * @param {...Object} var_args All objects to merge. - * @return {Object} a new object with the data of the others. - */ - exports.extend = function () { - var result = {}, - i, - attr; - for (i = 0; i < arguments.length; i++) { - // arguments is not enumerable in some browsers - for (attr in arguments[i]) { - if ( - Object.prototype.hasOwnProperty.call(arguments[i], attr) && - typeof result[attr] === "undefined" - ) { - result[attr] = arguments[i][attr]; - } - } - } - return result; - }; - - /** - * Transform arbitrary content into a Promise. - * @param {String} name a name for the content being processed. - * @param {Object} inputData the content to process. - * @param {Boolean} isBinary true if the content is not an unicode string - * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character. - * @param {Boolean} isBase64 true if the string content is encoded with base64. - * @return {Promise} a promise in a format usable by JSZip. - */ - exports.prepareContent = function ( - name, - inputData, - isBinary, - isOptimizedBinaryString, - isBase64, - ) { - // if inputData is already a promise, this flatten it. - var promise = external.Promise.resolve(inputData).then( - function (data) { - var isBlob = - support.blob && - (data instanceof Blob || - ["[object File]", "[object Blob]"].indexOf( - Object.prototype.toString.call(data), - ) !== -1); - - if (isBlob && typeof FileReader !== "undefined") { - return new external.Promise(function (resolve, reject) { - var reader = new FileReader(); - - reader.onload = function (e) { - resolve(e.target.result); - }; - reader.onerror = function (e) { - reject(e.target.error); - }; - reader.readAsArrayBuffer(data); - }); - } else { - return data; - } - }, - ); - - return promise.then(function (data) { - var dataType = exports.getTypeOf(data); - - if (!dataType) { - return external.Promise.reject( - new Error( - "Can't read the data of '" + - name + - "'. Is it " + - "in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?", - ), - ); - } - // special case : it's way easier to work with Uint8Array than with ArrayBuffer - if (dataType === "arraybuffer") { - data = exports.transformTo("uint8array", data); - } else if (dataType === "string") { - if (isBase64) { - data = base64.decode(data); - } else if (isBinary) { - // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask - if (isOptimizedBinaryString !== true) { - // this is a string, not in a base64 format. - // Be sure that this is a correct "binary string" - data = string2binary(data); - } - } - } - return data; - }); - }; - }, - { - "./base64": 1, - "./external": 6, - "./nodejsUtils": 14, - "./support": 30, - setimmediate: 54, - }, - ], - 33: [ - function (require, module, exports) { - "use strict"; - var readerFor = require("./reader/readerFor"); - var utils = require("./utils"); - var sig = require("./signature"); - var ZipEntry = require("./zipEntry"); - var support = require("./support"); - // class ZipEntries {{{ - /** - * All the entries in the zip file. - * @constructor - * @param {Object} loadOptions Options for loading the stream. - */ - function ZipEntries(loadOptions) { - this.files = []; - this.loadOptions = loadOptions; - } - ZipEntries.prototype = { - /** - * Check that the reader is on the specified signature. - * @param {string} expectedSignature the expected signature. - * @throws {Error} if it is an other signature. - */ - checkSignature: function (expectedSignature) { - if (!this.reader.readAndCheckSignature(expectedSignature)) { - this.reader.index -= 4; - var signature = this.reader.readString(4); - throw new Error( - "Corrupted zip or bug: unexpected signature " + - "(" + - utils.pretty(signature) + - ", expected " + - utils.pretty(expectedSignature) + - ")", - ); - } - }, - /** - * Check if the given signature is at the given index. - * @param {number} askedIndex the index to check. - * @param {string} expectedSignature the signature to expect. - * @return {boolean} true if the signature is here, false otherwise. - */ - isSignature: function (askedIndex, expectedSignature) { - var currentIndex = this.reader.index; - this.reader.setIndex(askedIndex); - var signature = this.reader.readString(4); - var result = signature === expectedSignature; - this.reader.setIndex(currentIndex); - return result; - }, - /** - * Read the end of the central directory. - */ - readBlockEndOfCentral: function () { - this.diskNumber = this.reader.readInt(2); - this.diskWithCentralDirStart = this.reader.readInt(2); - this.centralDirRecordsOnThisDisk = this.reader.readInt(2); - this.centralDirRecords = this.reader.readInt(2); - this.centralDirSize = this.reader.readInt(4); - this.centralDirOffset = this.reader.readInt(4); - - this.zipCommentLength = this.reader.readInt(2); - // warning : the encoding depends of the system locale - // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. - // On a windows machine, this field is encoded with the localized windows code page. - var zipComment = this.reader.readData(this.zipCommentLength); - var decodeParamType = support.uint8array ? "uint8array" : "array"; - // To get consistent behavior with the generation part, we will assume that - // this is utf8 encoded unless specified otherwise. - var decodeContent = utils.transformTo( - decodeParamType, - zipComment, - ); - this.zipComment = this.loadOptions.decodeFileName(decodeContent); - }, - /** - * Read the end of the Zip 64 central directory. - * Not merged with the method readEndOfCentral : - * The end of central can coexist with its Zip64 brother, - * I don't want to read the wrong number of bytes ! - */ - readBlockZip64EndOfCentral: function () { - this.zip64EndOfCentralSize = this.reader.readInt(8); - this.reader.skip(4); - // this.versionMadeBy = this.reader.readString(2); - // this.versionNeeded = this.reader.readInt(2); - this.diskNumber = this.reader.readInt(4); - this.diskWithCentralDirStart = this.reader.readInt(4); - this.centralDirRecordsOnThisDisk = this.reader.readInt(8); - this.centralDirRecords = this.reader.readInt(8); - this.centralDirSize = this.reader.readInt(8); - this.centralDirOffset = this.reader.readInt(8); - - this.zip64ExtensibleData = {}; - var extraDataSize = this.zip64EndOfCentralSize - 44, - index = 0, - extraFieldId, - extraFieldLength, - extraFieldValue; - while (index < extraDataSize) { - extraFieldId = this.reader.readInt(2); - extraFieldLength = this.reader.readInt(4); - extraFieldValue = this.reader.readData(extraFieldLength); - this.zip64ExtensibleData[extraFieldId] = { - id: extraFieldId, - length: extraFieldLength, - value: extraFieldValue, - }; - } - }, - /** - * Read the end of the Zip 64 central directory locator. - */ - readBlockZip64EndOfCentralLocator: function () { - this.diskWithZip64CentralDirStart = this.reader.readInt(4); - this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); - this.disksCount = this.reader.readInt(4); - if (this.disksCount > 1) { - throw new Error("Multi-volumes zip are not supported"); - } - }, - /** - * Read the local files, based on the offset read in the central part. - */ - readLocalFiles: function () { - var i, file; - for (i = 0; i < this.files.length; i++) { - file = this.files[i]; - this.reader.setIndex(file.localHeaderOffset); - this.checkSignature(sig.LOCAL_FILE_HEADER); - file.readLocalPart(this.reader); - file.handleUTF8(); - file.processAttributes(); - } - }, - /** - * Read the central directory. - */ - readCentralDir: function () { - var file; - - this.reader.setIndex(this.centralDirOffset); - while ( - this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER) - ) { - file = new ZipEntry( - { - zip64: this.zip64, - }, - this.loadOptions, - ); - file.readCentralPart(this.reader); - this.files.push(file); - } - - if (this.centralDirRecords !== this.files.length) { - if (this.centralDirRecords !== 0 && this.files.length === 0) { - // We expected some records but couldn't find ANY. - // This is really suspicious, as if something went wrong. - throw new Error( - "Corrupted zip or bug: expected " + - this.centralDirRecords + - " records in central dir, got " + - this.files.length, - ); - } else { - // We found some records but not all. - // Something is wrong but we got something for the user: no error here. - // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); - } - } - }, - /** - * Read the end of central directory. - */ - readEndOfCentral: function () { - var offset = this.reader.lastIndexOfSignature( - sig.CENTRAL_DIRECTORY_END, - ); - if (offset < 0) { - // Check if the content is a truncated zip or complete garbage. - // A "LOCAL_FILE_HEADER" is not required at the beginning (auto - // extractible zip for example) but it can give a good hint. - // If an ajax request was used without responseType, we will also - // get unreadable data. - var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER); - - if (isGarbage) { - throw new Error( - "Can't find end of central directory : is this a zip file ? " + - "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html", - ); - } else { - throw new Error( - "Corrupted zip: can't find end of central directory", - ); - } - } - this.reader.setIndex(offset); - var endOfCentralDirOffset = offset; - this.checkSignature(sig.CENTRAL_DIRECTORY_END); - this.readBlockEndOfCentral(); - - /* extract from the zip spec : - 4) If one of the fields in the end of central directory - record is too small to hold required data, the field - should be set to -1 (0xFFFF or 0xFFFFFFFF) and the - ZIP64 format record should be created. - 5) The end of central directory record and the - Zip64 end of central directory locator record must - reside on the same disk when splitting or spanning - an archive. - */ - if ( - this.diskNumber === utils.MAX_VALUE_16BITS || - this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || - this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || - this.centralDirRecords === utils.MAX_VALUE_16BITS || - this.centralDirSize === utils.MAX_VALUE_32BITS || - this.centralDirOffset === utils.MAX_VALUE_32BITS - ) { - this.zip64 = true; - - /* - Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from - the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents - all numbers as 64-bit double precision IEEE 754 floating point numbers. - So, we have 53bits for integers and bitwise operations treat everything as 32bits. - see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators - and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 - */ - - // should look for a zip64 EOCD locator - offset = this.reader.lastIndexOfSignature( - sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR, - ); - if (offset < 0) { - throw new Error( - "Corrupted zip: can't find the ZIP64 end of central directory locator", - ); - } - this.reader.setIndex(offset); - this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); - this.readBlockZip64EndOfCentralLocator(); - - // now the zip64 EOCD record - if ( - !this.isSignature( - this.relativeOffsetEndOfZip64CentralDir, - sig.ZIP64_CENTRAL_DIRECTORY_END, - ) - ) { - // console.warn("ZIP64 end of central directory not where expected."); - this.relativeOffsetEndOfZip64CentralDir = - this.reader.lastIndexOfSignature( - sig.ZIP64_CENTRAL_DIRECTORY_END, - ); - if (this.relativeOffsetEndOfZip64CentralDir < 0) { - throw new Error( - "Corrupted zip: can't find the ZIP64 end of central directory", - ); - } - } - this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); - this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); - this.readBlockZip64EndOfCentral(); - } - - var expectedEndOfCentralDirOffset = - this.centralDirOffset + this.centralDirSize; - if (this.zip64) { - expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator - expectedEndOfCentralDirOffset += - 12 /* should not include the leading 12 bytes */ + - this.zip64EndOfCentralSize; - } - - var extraBytes = - endOfCentralDirOffset - expectedEndOfCentralDirOffset; - - if (extraBytes > 0) { - // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); - if ( - this.isSignature( - endOfCentralDirOffset, - sig.CENTRAL_FILE_HEADER, - ) - ) { - // The offsets seem wrong, but we have something at the specified offset. - // So… we keep it. - } else { - // the offset is wrong, update the "zero" of the reader - // this happens if data has been prepended (crx files for example) - this.reader.zero = extraBytes; - } - } else if (extraBytes < 0) { - throw new Error( - "Corrupted zip: missing " + Math.abs(extraBytes) + " bytes.", - ); - } - }, - prepareReader: function (data) { - this.reader = readerFor(data); - }, - /** - * Read a zip file and create ZipEntries. - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. - */ - load: function (data) { - this.prepareReader(data); - this.readEndOfCentral(); - this.readCentralDir(); - this.readLocalFiles(); - }, - }; - // }}} end of ZipEntries - module.exports = ZipEntries; - }, - { - "./reader/readerFor": 22, - "./signature": 23, - "./support": 30, - "./utils": 32, - "./zipEntry": 34, - }, - ], - 34: [ - function (require, module, exports) { - "use strict"; - var readerFor = require("./reader/readerFor"); - var utils = require("./utils"); - var CompressedObject = require("./compressedObject"); - var crc32fn = require("./crc32"); - var utf8 = require("./utf8"); - var compressions = require("./compressions"); - var support = require("./support"); - - var MADE_BY_DOS = 0x00; - var MADE_BY_UNIX = 0x03; - - /** - * Find a compression registered in JSZip. - * @param {string} compressionMethod the method magic to find. - * @return {Object|null} the JSZip compression object, null if none found. - */ - var findCompression = function (compressionMethod) { - for (var method in compressions) { - if (!Object.prototype.hasOwnProperty.call(compressions, method)) { - continue; - } - if (compressions[method].magic === compressionMethod) { - return compressions[method]; - } - } - return null; - }; - - // class ZipEntry {{{ - /** - * An entry in the zip file. - * @constructor - * @param {Object} options Options of the current file. - * @param {Object} loadOptions Options for loading the stream. - */ - function ZipEntry(options, loadOptions) { - this.options = options; - this.loadOptions = loadOptions; - } - ZipEntry.prototype = { - /** - * say if the file is encrypted. - * @return {boolean} true if the file is encrypted, false otherwise. - */ - isEncrypted: function () { - // bit 1 is set - return (this.bitFlag & 0x0001) === 0x0001; - }, - /** - * say if the file has utf-8 filename/comment. - * @return {boolean} true if the filename/comment is in utf-8, false otherwise. - */ - useUTF8: function () { - // bit 11 is set - return (this.bitFlag & 0x0800) === 0x0800; - }, - /** - * Read the local part of a zip file and add the info in this object. - * @param {DataReader} reader the reader to use. - */ - readLocalPart: function (reader) { - var compression, localExtraFieldsLength; - - // we already know everything from the central dir ! - // If the central dir data are false, we are doomed. - // On the bright side, the local part is scary : zip64, data descriptors, both, etc. - // The less data we get here, the more reliable this should be. - // Let's skip the whole header and dash to the data ! - reader.skip(22); - // in some zip created on windows, the filename stored in the central dir contains \ instead of /. - // Strangely, the filename here is OK. - // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes - // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... - // Search "unzip mismatching "local" filename continuing with "central" filename version" on - // the internet. - // - // I think I see the logic here : the central directory is used to display - // content and the local directory is used to extract the files. Mixing / and \ - // may be used to display \ to windows users and use / when extracting the files. - // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 - this.fileNameLength = reader.readInt(2); - localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir - // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding. - this.fileName = reader.readData(this.fileNameLength); - reader.skip(localExtraFieldsLength); - - if (this.compressedSize === -1 || this.uncompressedSize === -1) { - throw new Error( - "Bug or corrupted zip : didn't get enough information from the central directory " + - "(compressedSize === -1 || uncompressedSize === -1)", - ); - } - - compression = findCompression(this.compressionMethod); - if (compression === null) { - // no compression found - throw new Error( - "Corrupted zip : compression " + - utils.pretty(this.compressionMethod) + - " unknown (inner file : " + - utils.transformTo("string", this.fileName) + - ")", - ); - } - this.decompressed = new CompressedObject( - this.compressedSize, - this.uncompressedSize, - this.crc32, - compression, - reader.readData(this.compressedSize), - ); - }, - - /** - * Read the central part of a zip file and add the info in this object. - * @param {DataReader} reader the reader to use. - */ - readCentralPart: function (reader) { - this.versionMadeBy = reader.readInt(2); - reader.skip(2); - // this.versionNeeded = reader.readInt(2); - this.bitFlag = reader.readInt(2); - this.compressionMethod = reader.readString(2); - this.date = reader.readDate(); - this.crc32 = reader.readInt(4); - this.compressedSize = reader.readInt(4); - this.uncompressedSize = reader.readInt(4); - var fileNameLength = reader.readInt(2); - this.extraFieldsLength = reader.readInt(2); - this.fileCommentLength = reader.readInt(2); - this.diskNumberStart = reader.readInt(2); - this.internalFileAttributes = reader.readInt(2); - this.externalFileAttributes = reader.readInt(4); - this.localHeaderOffset = reader.readInt(4); - - if (this.isEncrypted()) { - throw new Error("Encrypted zip are not supported"); - } - - // will be read in the local part, see the comments there - reader.skip(fileNameLength); - this.readExtraFields(reader); - this.parseZIP64ExtraField(reader); - this.fileComment = reader.readData(this.fileCommentLength); - }, - - /** - * Parse the external file attributes and get the unix/dos permissions. - */ - processAttributes: function () { - this.unixPermissions = null; - this.dosPermissions = null; - var madeBy = this.versionMadeBy >> 8; - - // Check if we have the DOS directory flag set. - // We look for it in the DOS and UNIX permissions - // but some unknown platform could set it as a compatibility flag. - this.dir = this.externalFileAttributes & 0x0010 ? true : false; - - if (madeBy === MADE_BY_DOS) { - // first 6 bits (0 to 5) - this.dosPermissions = this.externalFileAttributes & 0x3f; - } - - if (madeBy === MADE_BY_UNIX) { - this.unixPermissions = - (this.externalFileAttributes >> 16) & 0xffff; - // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); - } - - // fail safe : if the name ends with a / it probably means a folder - if (!this.dir && this.fileNameStr.slice(-1) === "/") { - this.dir = true; - } - }, - - /** - * Parse the ZIP64 extra field and merge the info in the current ZipEntry. - * @param {DataReader} reader the reader to use. - */ - parseZIP64ExtraField: function () { - if (!this.extraFields[0x0001]) { - return; - } - - // should be something, preparing the extra reader - var extraReader = readerFor(this.extraFields[0x0001].value); - - // I really hope that these 64bits integer can fit in 32 bits integer, because js - // won't let us have more. - if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { - this.uncompressedSize = extraReader.readInt(8); - } - if (this.compressedSize === utils.MAX_VALUE_32BITS) { - this.compressedSize = extraReader.readInt(8); - } - if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { - this.localHeaderOffset = extraReader.readInt(8); - } - if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { - this.diskNumberStart = extraReader.readInt(4); - } - }, - /** - * Read the central part of a zip file and add the info in this object. - * @param {DataReader} reader the reader to use. - */ - readExtraFields: function (reader) { - var end = reader.index + this.extraFieldsLength, - extraFieldId, - extraFieldLength, - extraFieldValue; - - if (!this.extraFields) { - this.extraFields = {}; - } - - while (reader.index + 4 < end) { - extraFieldId = reader.readInt(2); - extraFieldLength = reader.readInt(2); - extraFieldValue = reader.readData(extraFieldLength); - - this.extraFields[extraFieldId] = { - id: extraFieldId, - length: extraFieldLength, - value: extraFieldValue, - }; - } - - reader.setIndex(end); - }, - /** - * Apply an UTF8 transformation if needed. - */ - handleUTF8: function () { - var decodeParamType = support.uint8array ? "uint8array" : "array"; - if (this.useUTF8()) { - this.fileNameStr = utf8.utf8decode(this.fileName); - this.fileCommentStr = utf8.utf8decode(this.fileComment); - } else { - var upath = this.findExtraFieldUnicodePath(); - if (upath !== null) { - this.fileNameStr = upath; - } else { - // ASCII text or unsupported code page - var fileNameByteArray = utils.transformTo( - decodeParamType, - this.fileName, - ); - this.fileNameStr = - this.loadOptions.decodeFileName(fileNameByteArray); - } - - var ucomment = this.findExtraFieldUnicodeComment(); - if (ucomment !== null) { - this.fileCommentStr = ucomment; - } else { - // ASCII text or unsupported code page - var commentByteArray = utils.transformTo( - decodeParamType, - this.fileComment, - ); - this.fileCommentStr = - this.loadOptions.decodeFileName(commentByteArray); - } - } - }, - - /** - * Find the unicode path declared in the extra field, if any. - * @return {String} the unicode path, null otherwise. - */ - findExtraFieldUnicodePath: function () { - var upathField = this.extraFields[0x7075]; - if (upathField) { - var extraReader = readerFor(upathField.value); - - // wrong version - if (extraReader.readInt(1) !== 1) { - return null; - } - - // the crc of the filename changed, this field is out of date. - if (crc32fn(this.fileName) !== extraReader.readInt(4)) { - return null; - } - - return utf8.utf8decode( - extraReader.readData(upathField.length - 5), - ); - } - return null; - }, - - /** - * Find the unicode comment declared in the extra field, if any. - * @return {String} the unicode comment, null otherwise. - */ - findExtraFieldUnicodeComment: function () { - var ucommentField = this.extraFields[0x6375]; - if (ucommentField) { - var extraReader = readerFor(ucommentField.value); - - // wrong version - if (extraReader.readInt(1) !== 1) { - return null; - } - - // the crc of the comment changed, this field is out of date. - if (crc32fn(this.fileComment) !== extraReader.readInt(4)) { - return null; - } - - return utf8.utf8decode( - extraReader.readData(ucommentField.length - 5), - ); - } - return null; - }, - }; - module.exports = ZipEntry; - }, - { - "./compressedObject": 2, - "./compressions": 3, - "./crc32": 4, - "./reader/readerFor": 22, - "./support": 30, - "./utf8": 31, - "./utils": 32, - }, - ], - 35: [ - function (require, module, exports) { - "use strict"; - - var StreamHelper = require("./stream/StreamHelper"); - var DataWorker = require("./stream/DataWorker"); - var utf8 = require("./utf8"); - var CompressedObject = require("./compressedObject"); - var GenericWorker = require("./stream/GenericWorker"); - - /** - * A simple object representing a file in the zip file. - * @constructor - * @param {string} name the name of the file - * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data - * @param {Object} options the options of the file - */ - var ZipObject = function (name, data, options) { - this.name = name; - this.dir = options.dir; - this.date = options.date; - this.comment = options.comment; - this.unixPermissions = options.unixPermissions; - this.dosPermissions = options.dosPermissions; - - this._data = data; - this._dataBinary = options.binary; - // keep only the compression - this.options = { - compression: options.compression, - compressionOptions: options.compressionOptions, - }; - }; - - ZipObject.prototype = { - /** - * Create an internal stream for the content of this object. - * @param {String} type the type of each chunk. - * @return StreamHelper the stream. - */ - internalStream: function (type) { - var result = null, - outputType = "string"; - try { - if (!type) { - throw new Error("No output type specified."); - } - outputType = type.toLowerCase(); - var askUnicodeString = - outputType === "string" || outputType === "text"; - if (outputType === "binarystring" || outputType === "text") { - outputType = "string"; - } - result = this._decompressWorker(); - - var isUnicodeString = !this._dataBinary; - - if (isUnicodeString && !askUnicodeString) { - result = result.pipe(new utf8.Utf8EncodeWorker()); - } - if (!isUnicodeString && askUnicodeString) { - result = result.pipe(new utf8.Utf8DecodeWorker()); - } - } catch (e) { - result = new GenericWorker("error"); - result.error(e); - } - - return new StreamHelper(result, outputType, ""); - }, - - /** - * Prepare the content in the asked type. - * @param {String} type the type of the result. - * @param {Function} onUpdate a function to call on each internal update. - * @return Promise the promise of the result. - */ - async: function (type, onUpdate) { - return this.internalStream(type).accumulate(onUpdate); - }, - - /** - * Prepare the content as a nodejs stream. - * @param {String} type the type of each chunk. - * @param {Function} onUpdate a function to call on each internal update. - * @return Stream the stream. - */ - nodeStream: function (type, onUpdate) { - return this.internalStream(type || "nodebuffer").toNodejsStream( - onUpdate, - ); - }, - - /** - * Return a worker for the compressed content. - * @private - * @param {Object} compression the compression object to use. - * @param {Object} compressionOptions the options to use when compressing. - * @return Worker the worker. - */ - _compressWorker: function (compression, compressionOptions) { - if ( - this._data instanceof CompressedObject && - this._data.compression.magic === compression.magic - ) { - return this._data.getCompressedWorker(); - } else { - var result = this._decompressWorker(); - if (!this._dataBinary) { - result = result.pipe(new utf8.Utf8EncodeWorker()); - } - return CompressedObject.createWorkerFrom( - result, - compression, - compressionOptions, - ); - } - }, - /** - * Return a worker for the decompressed content. - * @private - * @return Worker the worker. - */ - _decompressWorker: function () { - if (this._data instanceof CompressedObject) { - return this._data.getContentWorker(); - } else if (this._data instanceof GenericWorker) { - return this._data; - } else { - return new DataWorker(this._data); - } - }, - }; - - var removedMethods = [ - "asText", - "asBinary", - "asNodeBuffer", - "asUint8Array", - "asArrayBuffer", - ]; - var removedFn = function () { - throw new Error( - "This method has been removed in JSZip 3.0, please check the upgrade guide.", - ); - }; - - for (var i = 0; i < removedMethods.length; i++) { - ZipObject.prototype[removedMethods[i]] = removedFn; - } - module.exports = ZipObject; - }, - { - "./compressedObject": 2, - "./stream/DataWorker": 27, - "./stream/GenericWorker": 28, - "./stream/StreamHelper": 29, - "./utf8": 31, - }, - ], - 36: [ - function (require, module, exports) { - (function (global) { - "use strict"; - var Mutation = - global.MutationObserver || global.WebKitMutationObserver; - - var scheduleDrain; - - { - if (Mutation) { - var called = 0; - var observer = new Mutation(nextTick); - var element = global.document.createTextNode(""); - observer.observe(element, { - characterData: true, - }); - scheduleDrain = function () { - element.data = called = ++called % 2; - }; - } else if ( - !global.setImmediate && - typeof global.MessageChannel !== "undefined" - ) { - var channel = new global.MessageChannel(); - channel.port1.onmessage = nextTick; - scheduleDrain = function () { - channel.port2.postMessage(0); - }; - } else if ( - "document" in global && - "onreadystatechange" in global.document.createElement("script") - ) { - scheduleDrain = function () { - // Create a