UNPKG

api-console-assets

Version:

This repo only exists to publish api console components to npm

888 lines (798 loc) 31.4 kB
/* Copyright (c) 2013 Gildas Lormeau. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of the authors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ (function (obj) { var ERR_BAD_FORMAT = "File format is not recognized."; var ERR_ENCRYPTED = "File contains encrypted entry."; var ERR_ZIP64 = "File is using Zip64 (4gb+ file size)."; var ERR_READ = "Error while reading zip file."; var ERR_WRITE = "Error while writing zip file."; var ERR_WRITE_DATA = "Error while writing file data."; var ERR_READ_DATA = "Error while reading file data."; var ERR_DUPLICATED_NAME = "File already exists."; var CHUNK_SIZE = 512 * 1024; var INFLATE_JS = "inflate.js"; var DEFLATE_JS = "deflate.js"; var TEXT_PLAIN = "text/plain"; var MESSAGE_EVENT = "message"; var appendABViewSupported; try { appendABViewSupported = new Blob([new DataView(new ArrayBuffer(0))]).size === 0; } catch (e) { } function Crc32() { this.crc = -1; } Crc32.prototype.append = function append(data) { var crc = this.crc | 0, table = this.table; for (var offset = 0, len = data.length | 0; offset < len; offset++) crc = (crc >>> 8) ^ table[(crc ^ data[offset]) & 0xFF]; this.crc = crc; }; Crc32.prototype.get = function get() { return ~this.crc; }; Crc32.prototype.table = (function () { var i, j, t, table = []; // Uint32Array is actually slower than [] for (i = 0; i < 256; i++) { t = i; for (j = 0; j < 8; j++) if (t & 1) t = (t >>> 1) ^ 0xEDB88320; else t = t >>> 1; table[i] = t; } return table; })(); // "no-op" codec function NOOP() { } NOOP.prototype.append = function append(bytes, onprogress) { return bytes; }; NOOP.prototype.flush = function flush() { }; function blobSlice(blob, index, length) { if (index < 0 || length < 0 || index + length > blob.size) throw new RangeError('index=' + index + ', length:' + length + ', size:' + blob.size); if (blob.slice) return blob.slice(index, index + length); else if (blob.webkitSlice) return blob.webkitSlice(index, index + length); else if (blob.mozSlice) return blob.mozSlice(index, index + length); else if (blob.msSlice) return blob.msSlice(index, index + length); } function getDataHelper(byteLength, bytes) { var dataBuffer, dataArray; dataBuffer = new ArrayBuffer(byteLength); dataArray = new Uint8Array(dataBuffer); if (bytes) dataArray.set(bytes, 0); return { buffer: dataBuffer, array: dataArray, view: new DataView(dataBuffer) }; } // Readers function Reader() { } function TextReader(text) { var that = this, blobReader; function init(callback, onerror) { var blob = new Blob([text], { type: TEXT_PLAIN }); blobReader = new BlobReader(blob); blobReader.init(function () { that.size = blobReader.size; callback(); }, onerror); } function readUint8Array(index, length, callback, onerror) { blobReader.readUint8Array(index, length, callback, onerror); } that.size = 0; that.init = init; that.readUint8Array = readUint8Array; } TextReader.prototype = new Reader(); TextReader.prototype.constructor = TextReader; function Data64URIReader(dataURI) { var that = this, dataStart; function init(callback) { var dataEnd = dataURI.length; while (dataURI.charAt(dataEnd - 1) == "=") dataEnd--; dataStart = dataURI.indexOf(",") + 1; that.size = Math.floor((dataEnd - dataStart) * 0.75); callback(); } function readUint8Array(index, length, callback) { var i, data = getDataHelper(length); var start = Math.floor(index / 3) * 4; var end = Math.ceil((index + length) / 3) * 4; var bytes = obj.atob(dataURI.substring(start + dataStart, end + dataStart)); var delta = index - Math.floor(start / 4) * 3; for (i = delta; i < delta + length; i++) data.array[i - delta] = bytes.charCodeAt(i); callback(data.array); } that.size = 0; that.init = init; that.readUint8Array = readUint8Array; } Data64URIReader.prototype = new Reader(); Data64URIReader.prototype.constructor = Data64URIReader; function BlobReader(blob) { var that = this; function init(callback) { this.size = blob.size; callback(); } function readUint8Array(index, length, callback, onerror) { var reader = new FileReader(); reader.onload = function (e) { callback(new Uint8Array(e.target.result)); }; reader.onerror = onerror; reader.readAsArrayBuffer(blobSlice(blob, index, length)); } that.size = 0; that.init = init; that.readUint8Array = readUint8Array; } BlobReader.prototype = new Reader(); BlobReader.prototype.constructor = BlobReader; // Writers function Writer() { } Writer.prototype.getData = function (callback) { callback(this.data); }; function TextWriter(encoding) { var that = this, blob; function init(callback) { blob = new Blob([], { type: TEXT_PLAIN }); callback(); } function writeUint8Array(array, callback) { blob = new Blob([blob, appendABViewSupported ? array : array.buffer], { type: TEXT_PLAIN }); callback(); } function getData(callback, onerror) { var reader = new FileReader(); reader.onload = function (e) { callback(e.target.result); }; reader.onerror = onerror; reader.readAsText(blob, encoding); } that.init = init; that.writeUint8Array = writeUint8Array; that.getData = getData; } TextWriter.prototype = new Writer(); TextWriter.prototype.constructor = TextWriter; function Data64URIWriter(contentType) { var that = this, data = "", pending = ""; function init(callback) { data += "data:" + (contentType || "") + ";base64,"; callback(); } function writeUint8Array(array, callback) { var i, delta = pending.length, dataString = pending; pending = ""; for (i = 0; i < (Math.floor((delta + array.length) / 3) * 3) - delta; i++) dataString += String.fromCharCode(array[i]); for (; i < array.length; i++) pending += String.fromCharCode(array[i]); if (dataString.length > 2) data += obj.btoa(dataString); else pending = dataString; callback(); } function getData(callback) { callback(data + obj.btoa(pending)); } that.init = init; that.writeUint8Array = writeUint8Array; that.getData = getData; } Data64URIWriter.prototype = new Writer(); Data64URIWriter.prototype.constructor = Data64URIWriter; // ByteArrayWriter simply retain or copy the Uint8Array written to it, and its getData() returns an array of Uint8Array. function ByteArrayWriter() { this.data = []; } ByteArrayWriter.prototype = Object.create(Writer.prototype); ByteArrayWriter.prototype.constructor = ByteArrayWriter; ByteArrayWriter.prototype.init = function init(callback) { callback(); }; // copyInput: whether this writer should copy the array, or can retain it. ByteArrayWriter.prototype.writeUint8Array = function writeUint8Array(array, callback, onerror, copyInput) { this.data.push(copyInput ? new Uint8Array(array) : array); callback(); }; // BlobWriter extends ByteArrayWriter, and construct and return a blob in its getData(). function BlobWriter(contentType) { this.contentType = contentType; ByteArrayWriter.call(this); } BlobWriter.prototype = Object.create(ByteArrayWriter.prototype); BlobWriter.prototype.getData = function BW_getData(callback) { callback(new Blob(this.data, { type: this.contentType })); }; /** * inflate/deflate core functions * @param worker {Worker} web worker for the task. * @param initialMessage {Object} initial message to be sent to the worker. should contains * sn(serial number for distinguishing multiple tasks sent to the worker), and codecClass. * This function may add more properties before sending. */ function launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror) { var chunkIndex = 0, index, outputSize, sn = initialMessage.sn, crc; function onflush() { worker.removeEventListener(MESSAGE_EVENT, onmessage, false); onend(outputSize, crc); } function onmessage(event) { var message = event.data, data = message.data; if (message.error) { console.error('zip.js:launchWorkerProcess: error message: ', message); return; } if (message.sn !== sn) return; if (typeof message.codecTime === 'number') worker.codecTime += message.codecTime; // should be before onflush() if (typeof message.crcTime === 'number') worker.crcTime += message.crcTime; switch (message.type) { case 'append': //console.log('codecTime:' + worker.codecTime + ', crcTime: ' + worker.crcTime); //profile if (data) { outputSize += data.length; writer.writeUint8Array(data, function () { step(); }, onwriteerror); } else step(); break; case 'flush': //console.log('codecTime:' + worker.codecTime + ', crcTime: ' + worker.crcTime); //profile crc = message.crc; if (data) { outputSize += data.length; writer.writeUint8Array(data, function () { onflush(); }, onwriteerror); } else onflush(); break; case 'progress': onprogress && onprogress(index + message.loaded, size); break; case 'importScripts': //no need to handle here case 'newTask': case 'echo': break; default: console.warn('zip.js:launchWorkerProcess: unknown message: ', message); } } function step() { index = chunkIndex * CHUNK_SIZE; if (index < size) { reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function (array) { if (onprogress) onprogress(index, size); var msg = index === 0 ? initialMessage : { sn: sn }; msg.type = 'append'; msg.data = array; worker.postMessage(msg, [array.buffer]); chunkIndex++; }, onreaderror); } else { worker.postMessage({ sn: sn, type: 'flush' }); } } outputSize = 0; worker.addEventListener(MESSAGE_EVENT, onmessage, false); step(); } function launchProcess(process, reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror) { var chunkIndex = 0, index, outputSize = 0, crcInput = crcType === 'input', crcOutput = crcType === 'output', crc = new Crc32(); function step() { var outputData; index = chunkIndex * CHUNK_SIZE; if (index < size) reader.readUint8Array(offset + index, Math.min(CHUNK_SIZE, size - index), function (inputData) { var outputData = process.append(inputData, function (loaded) { if (onprogress) onprogress(index + loaded, size); }); if (outputData) { outputSize += outputData.length; writer.writeUint8Array(outputData, function () { chunkIndex++; setTimeout(step, 1); }, onwriteerror); crcOutput && crc.append(outputData); } else { chunkIndex++; setTimeout(step, 1); } crcInput && crc.append(inputData); if (onprogress) onprogress(index, size); }, onreaderror); else { outputData = process.flush(); if (outputData) { crcOutput && crc.append(outputData); outputSize += outputData.length; writer.writeUint8Array(outputData, function () { onend(outputSize, crc.get()); }, onwriteerror); } else onend(outputSize, crc.get()); } } step(); } function inflate(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { var crcType = computeCrc32 ? 'output' : 'none'; var initialMessage = { sn: sn, codecClass: 'Inflater', crcType: crcType, }; if (obj.zip.useWebWorkers) { launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror); } else launchProcess(new obj.zip.Inflater(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror); } function deflate(worker, sn, reader, writer, level, onend, onprogress, onreaderror, onwriteerror) { var crcType = 'input'; var initialMessage = { sn: sn, options: { level: level }, codecClass: 'Deflater', crcType: crcType, }; if (obj.zip.useWebWorkers) { launchWorkerProcess(worker, initialMessage, reader, writer, 0, reader.size, onprogress, onend, onreaderror, onwriteerror); } else launchProcess(new obj.zip.Deflater(), reader, writer, 0, reader.size, crcType, onprogress, onend, onreaderror, onwriteerror); } function copy(worker, sn, reader, writer, offset, size, computeCrc32, onend, onprogress, onreaderror, onwriteerror) { var crcType = 'input'; if (obj.zip.useWebWorkers && computeCrc32) { var initialMessage = { sn: sn, codecClass: 'NOOP', crcType: crcType, }; launchWorkerProcess(worker, initialMessage, reader, writer, offset, size, onprogress, onend, onreaderror, onwriteerror); } else launchProcess(new NOOP(), reader, writer, offset, size, crcType, onprogress, onend, onreaderror, onwriteerror); } // ZipReader function decodeASCII(str) { var i, out = "", charCode, extendedASCII = ['\u00C7', '\u00FC', '\u00E9', '\u00E2', '\u00E4', '\u00E0', '\u00E5', '\u00E7', '\u00EA', '\u00EB', '\u00E8', '\u00EF', '\u00EE', '\u00EC', '\u00C4', '\u00C5', '\u00C9', '\u00E6', '\u00C6', '\u00F4', '\u00F6', '\u00F2', '\u00FB', '\u00F9', '\u00FF', '\u00D6', '\u00DC', '\u00F8', '\u00A3', '\u00D8', '\u00D7', '\u0192', '\u00E1', '\u00ED', '\u00F3', '\u00FA', '\u00F1', '\u00D1', '\u00AA', '\u00BA', '\u00BF', '\u00AE', '\u00AC', '\u00BD', '\u00BC', '\u00A1', '\u00AB', '\u00BB', '_', '_', '_', '\u00A6', '\u00A6', '\u00C1', '\u00C2', '\u00C0', '\u00A9', '\u00A6', '\u00A6', '+', '+', '\u00A2', '\u00A5', '+', '+', '-', '-', '+', '-', '+', '\u00E3', '\u00C3', '+', '+', '-', '-', '\u00A6', '-', '+', '\u00A4', '\u00F0', '\u00D0', '\u00CA', '\u00CB', '\u00C8', 'i', '\u00CD', '\u00CE', '\u00CF', '+', '+', '_', '_', '\u00A6', '\u00CC', '_', '\u00D3', '\u00DF', '\u00D4', '\u00D2', '\u00F5', '\u00D5', '\u00B5', '\u00FE', '\u00DE', '\u00DA', '\u00DB', '\u00D9', '\u00FD', '\u00DD', '\u00AF', '\u00B4', '\u00AD', '\u00B1', '_', '\u00BE', '\u00B6', '\u00A7', '\u00F7', '\u00B8', '\u00B0', '\u00A8', '\u00B7', '\u00B9', '\u00B3', '\u00B2', '_', ' ']; for (i = 0; i < str.length; i++) { charCode = str.charCodeAt(i) & 0xFF; if (charCode > 127) out += extendedASCII[charCode - 128]; else out += String.fromCharCode(charCode); } return out; } function decodeUTF8(string) { return decodeURIComponent(escape(string)); } function getString(bytes) { var i, str = ""; for (i = 0; i < bytes.length; i++) str += String.fromCharCode(bytes[i]); return str; } function getDate(timeRaw) { var date = (timeRaw & 0xffff0000) >> 16, time = timeRaw & 0x0000ffff; try { return new Date(1980 + ((date & 0xFE00) >> 9), ((date & 0x01E0) >> 5) - 1, date & 0x001F, (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) * 2, 0); } catch (e) { } } function readCommonHeader(entry, data, index, centralDirectory, onerror) { entry.version = data.view.getUint16(index, true); entry.bitFlag = data.view.getUint16(index + 2, true); entry.compressionMethod = data.view.getUint16(index + 4, true); entry.lastModDateRaw = data.view.getUint32(index + 6, true); entry.lastModDate = getDate(entry.lastModDateRaw); if ((entry.bitFlag & 0x01) === 0x01) { onerror(ERR_ENCRYPTED); return; } if (centralDirectory || (entry.bitFlag & 0x0008) != 0x0008) { entry.crc32 = data.view.getUint32(index + 10, true); entry.compressedSize = data.view.getUint32(index + 14, true); entry.uncompressedSize = data.view.getUint32(index + 18, true); } if (entry.compressedSize === 0xFFFFFFFF || entry.uncompressedSize === 0xFFFFFFFF) { onerror(ERR_ZIP64); return; } entry.filenameLength = data.view.getUint16(index + 22, true); entry.extraFieldLength = data.view.getUint16(index + 24, true); } function createZipReader(reader, callback, onerror) { var inflateSN = 0; function Entry() { } Entry.prototype.getData = function (writer, onend, onprogress, checkCrc32) { var that = this; function testCrc32(crc32) { var dataCrc32 = getDataHelper(4); dataCrc32.view.setUint32(0, crc32); return that.crc32 == dataCrc32.view.getUint32(0); } function getWriterData(uncompressedSize, crc32) { if (checkCrc32 && !testCrc32(crc32)) onreaderror(); else writer.getData(function (data) { onend(data); }); } function onreaderror() { onerror(ERR_READ_DATA); } function onwriteerror() { onerror(ERR_READ_DATA); } reader.readUint8Array(that.offset, 30, function (bytes) { var data = getDataHelper(bytes.length, bytes), dataOffset; if (data.view.getUint32(0) != 0x504b0304) { onerror(ERR_BAD_FORMAT); return; } readCommonHeader(that, data, 4, false, onerror); dataOffset = that.offset + 30 + that.filenameLength + that.extraFieldLength; writer.init(function () { if (that.compressionMethod === 0) copy(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); else inflate(that._worker, inflateSN++, reader, writer, dataOffset, that.compressedSize, checkCrc32, getWriterData, onprogress, onreaderror, onwriteerror); }, onwriteerror); }, onreaderror); }; function seekEOCDR(eocdrCallback) { var EOCDR_MIN = 22, EOCDR_MAX = 256 * 256 + EOCDR_MIN; var bufSize = EOCDR_MIN, offset = reader.size - EOCDR_MIN, searchLength = 1; step(); function step() { reader.readUint8Array(offset, bufSize, function (bytes) { for (var i = searchLength - 1; i >= 0; i--) { if (bytes[i] === 0x50 && bytes[i + 1] === 0x4b && bytes[i + 2] === 0x05 && bytes[i + 3] === 0x06) { eocdrCallback(new DataView(bytes.buffer, i, EOCDR_MIN)); return; } } var dist = reader.size - offset; if (offset === 0 || dist >= EOCDR_MAX) { onerror(ERR_BAD_FORMAT); // EOCDR not found return; } var newOffset = Math.max(offset - dist, 0); searchLength = offset - newOffset; offset = newOffset; bufSize = searchLength + EOCDR_MIN - 1; step(); }, function () { onerror(ERR_READ); }); } } var zipReader = { getEntries: function (callback) { if (reader.size < 22) { onerror(ERR_BAD_FORMAT); return; } var worker = this._worker; // look for End of central directory record seekEOCDR(function (dataView) { var datalength, fileslength; datalength = dataView.getUint32(16, true); fileslength = dataView.getUint16(8, true); if (datalength < 0 || datalength >= reader.size) { onerror(ERR_BAD_FORMAT); return; } reader.readUint8Array(datalength, reader.size - datalength, function (bytes) { var i, index = 0, entries = [], entry, filename, comment, data = getDataHelper(bytes.length, bytes); for (i = 0; i < fileslength; i++) { entry = new Entry(); entry._worker = worker; if (data.view.getUint32(index) != 0x504b0102) { onerror(ERR_BAD_FORMAT); return; } readCommonHeader(entry, data, index + 6, true, onerror); entry.commentLength = data.view.getUint16(index + 32, true); entry.directory = ((data.view.getUint8(index + 38) & 0x10) == 0x10); entry.offset = data.view.getUint32(index + 42, true); filename = getString(data.array.subarray(index + 46, index + 46 + entry.filenameLength)); entry.filename = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(filename) : decodeASCII(filename); if (!entry.directory && entry.filename.charAt(entry.filename.length - 1) == "/") entry.directory = true; comment = getString(data.array.subarray(index + 46 + entry.filenameLength + entry.extraFieldLength, index + 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength)); entry.comment = ((entry.bitFlag & 0x0800) === 0x0800) ? decodeUTF8(comment) : decodeASCII(comment); entries.push(entry); index += 46 + entry.filenameLength + entry.extraFieldLength + entry.commentLength; } callback(entries); }, function () { onerror(ERR_READ); }); }); }, close: function (callback) { if (this._worker) { this._worker.terminate(); this._worker = null; } if (callback) callback(); }, _worker: null }; if (!obj.zip.useWebWorkers) callback(zipReader); else { createWorker(obj.zip.workerScripts.inflater, function (worker) { zipReader._worker = worker; callback(zipReader); }, function (err) { onerror(err); } ); } } // ZipWriter function encodeUTF8(string) { return unescape(encodeURIComponent(string)); } function getBytes(str) { var i, array = []; for (i = 0; i < str.length; i++) array.push(str.charCodeAt(i)); return array; } function createZipWriter(writer, callback, onerror, dontDeflate) { var files = {}, filenames = [], datalength = 0; var deflateSN = 0; function onwriteerror() { onerror(ERR_WRITE); } function onreaderror() { onerror(ERR_READ_DATA); } var zipWriter = { add: function (name, reader, onend, onprogress, options) { var header, filename, date; var worker = this._worker; function writeHeader(callback) { var data; date = options.lastModDate || new Date(); header = getDataHelper(26); files[name] = { headerArray: header.array, directory: options.directory, filename: filename, offset: datalength, comment: getBytes(encodeUTF8(options.comment || "")) }; header.view.setUint32(0, 0x14000808); if (options.version) header.view.setUint8(0, options.version); if (!dontDeflate && options.level !== 0 && !options.directory) header.view.setUint16(4, 0x0800); header.view.setUint16(6, (((date.getHours() << 6) | date.getMinutes()) << 5) | date.getSeconds() / 2, true); header.view.setUint16(8, ((((date.getFullYear() - 1980) << 4) | (date.getMonth() + 1)) << 5) | date.getDate(), true); header.view.setUint16(22, filename.length, true); data = getDataHelper(30 + filename.length); data.view.setUint32(0, 0x504b0304); data.array.set(header.array, 4); data.array.set(filename, 30); datalength += data.array.length; writer.writeUint8Array(data.array, callback, onwriteerror); } function writeFooter(compressedLength, crc32) { var footer = getDataHelper(16); datalength += compressedLength || 0; footer.view.setUint32(0, 0x504b0708); if (typeof crc32 != "undefined") { header.view.setUint32(10, crc32, true); footer.view.setUint32(4, crc32, true); } if (reader) { footer.view.setUint32(8, compressedLength, true); header.view.setUint32(14, compressedLength, true); footer.view.setUint32(12, reader.size, true); header.view.setUint32(18, reader.size, true); } writer.writeUint8Array(footer.array, function () { datalength += 16; onend(); }, onwriteerror); } function writeFile() { options = options || {}; name = name.trim(); if (options.directory && name.charAt(name.length - 1) != "/") name += "/"; if (files.hasOwnProperty(name)) { onerror(ERR_DUPLICATED_NAME); return; } filename = getBytes(encodeUTF8(name)); filenames.push(name); writeHeader(function () { if (reader) if (dontDeflate || options.level === 0) copy(worker, deflateSN++, reader, writer, 0, reader.size, true, writeFooter, onprogress, onreaderror, onwriteerror); else deflate(worker, deflateSN++, reader, writer, options.level, writeFooter, onprogress, onreaderror, onwriteerror); else writeFooter(); }, onwriteerror); } if (reader) reader.init(writeFile, onreaderror); else writeFile(); }, close: function (callback) { if (this._worker) { this._worker.terminate(); this._worker = null; } var data, length = 0, index = 0, indexFilename, file; for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { file = files[filenames[indexFilename]]; length += 46 + file.filename.length + file.comment.length; } data = getDataHelper(length + 22); for (indexFilename = 0; indexFilename < filenames.length; indexFilename++) { file = files[filenames[indexFilename]]; data.view.setUint32(index, 0x504b0102); data.view.setUint16(index + 4, 0x1400); data.array.set(file.headerArray, index + 6); data.view.setUint16(index + 32, file.comment.length, true); if (file.directory) data.view.setUint8(index + 38, 0x10); data.view.setUint32(index + 42, file.offset, true); data.array.set(file.filename, index + 46); data.array.set(file.comment, index + 46 + file.filename.length); index += 46 + file.filename.length + file.comment.length; } data.view.setUint32(index, 0x504b0506); data.view.setUint16(index + 8, filenames.length, true); data.view.setUint16(index + 10, filenames.length, true); data.view.setUint32(index + 12, length, true); data.view.setUint32(index + 16, datalength, true); writer.writeUint8Array(data.array, function () { writer.getData(callback); }, onwriteerror); }, _worker: null }; if (!obj.zip.useWebWorkers) callback(zipWriter); else { createWorker(obj.zip.workerScripts.deflater, function (worker) { zipWriter._worker = worker; callback(zipWriter); }, function (err) { onerror(err); } ); } } function createWorker(scripts, callback, onerror) { var worker = new Worker(scripts[0]); // record total comsumed time by inflater/deflater/crc32 in this worker worker.codecTime = worker.crcTime = 0; worker.postMessage({ type: 'importScripts', scripts: scripts.slice(1) }); worker.addEventListener(MESSAGE_EVENT, onmessage); function onmessage(ev) { var msg = ev.data; if (msg.error) { console.error('zip.js:createWorker:error message: ', msg); worker.terminate(); // before onerror(), in cases onerror() throws. onerror(msg.error); return; } if (msg.type === 'importScripts') { worker.removeEventListener(MESSAGE_EVENT, onmessage); callback(worker); } } // for debug // worker.addEventListener(MESSAGE_EVENT, function(ev) { // console.log('msg from worker:', ev.data); // }); } obj.zip = { Reader: Reader, Writer: Writer, BlobReader: BlobReader, Data64URIReader: Data64URIReader, TextReader: TextReader, ByteArrayWriter: ByteArrayWriter, BlobWriter: BlobWriter, Data64URIWriter: Data64URIWriter, TextWriter: TextWriter, createReader: function (reader, callback, onerror) { reader.init(function () { createZipReader(reader, callback, onerror); }, onerror); }, createWriter: function (writer, callback, onerror, dontDeflate) { writer.init(function () { createZipWriter(writer, callback, onerror, dontDeflate); }, onerror); }, // In deflater/inflater property, first script is used to start the worker, and other scripts are loaded by importScripts in that worker. workerScripts: { deflater: ['z-worker.js', 'deflate.js'], inflater: ['z-worker.js', 'inflate.js'] }, useWebWorkers: true }; })(this);