Uname: Linux business55.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
Software: LiteSpeed
PHP version: 8.1.31 [ PHP INFO ] PHP os: Linux
Server Ip: 162.213.251.212
Your Ip: 18.117.105.195
User: allssztx (535) | Group: allssztx (533)
Safe Mode: OFF
Disable Function:
NONE

name : object.js
"use strict";

var support = require("./support.js");
var utils = require("./utils.js");
var _crc = require("./crc32.js");
var signature = require("./signature.js");
var defaults = require("./defaults.js");
var base64 = require("./base64.js");
var compressions = require("./compressions.js");
var CompressedObject = require("./compressedObject.js");
var nodeBuffer = require("./nodeBuffer.js");
var utf8 = require("./utf8.js");
var StringWriter = require("./stringWriter.js");
var Uint8ArrayWriter = require("./uint8ArrayWriter.js");

/**
 * Returns the raw data of a ZipObject, decompress the content if necessary.
 * @param {ZipObject} file the file to use.
 * @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
 */
function getRawData(file) {
  if (file._data instanceof CompressedObject) {
    file._data = file._data.getContent();
    file.options.binary = true;
    file.options.base64 = false;
    if (utils.getTypeOf(file._data) === "uint8array") {
      var copy = file._data;
      // when reading an arraybuffer, the CompressedObject mechanism will keep it and subarray() a Uint8Array.
      // if we request a file in the same format, we might get the same Uint8Array or its ArrayBuffer (the original zip file).
      file._data = new Uint8Array(copy.length);
      // with an empty Uint8Array, Opera fails with a "Offset larger than array size"
      if (copy.length !== 0) {
        file._data.set(copy, 0);
      }
    }
  }
  return file._data;
}

/**
 * Returns the data of a ZipObject in a binary form. If the content is an unicode string, encode it.
 * @param {ZipObject} file the file to use.
 * @return {String|ArrayBuffer|Uint8Array|Buffer} the data.
 */
function getBinaryData(file) {
  var result = getRawData(file),
    type = utils.getTypeOf(result);
  if (type === "string") {
    if (!file.options.binary) {
      // unicode text !
      // unicode string => binary string is a painful process, check if we can avoid it.
      if (support.nodebuffer) {
        return nodeBuffer(result, "utf-8");
      }
    }
    return file.asBinary();
  }
  return result;
}

// return the actual prototype of PizZip
var out = {
  /**
   * Read an existing zip and merge the data in the current PizZip object.
   * The implementation is in pizzip-load.js, don't forget to include it.
   * @param {String|ArrayBuffer|Uint8Array|Buffer} stream  The stream to load
   * @param {Object} options Options for loading the stream.
   *  options.base64 : is the stream in base64 ? default : false
   * @return {PizZip} the current PizZip object
   */
  load: function load() {
    throw new Error("Load method is not defined. Is the file pizzip-load.js included ?");
  },
  /**
   * 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 filter(search) {
    var result = [];
    var filename, relativePath, file, fileClone;
    for (filename in this.files) {
      if (!this.files.hasOwnProperty(filename)) {
        continue;
      }
      file = this.files[filename];
      // return a new object, don't let the user mess with our internal objects :)
      fileClone = new ZipObject(file.name, file._data, utils.extend(file.options));
      relativePath = filename.slice(this.root.length, filename.length);
      if (filename.slice(0, this.root.length) === this.root &&
      // the file is in the current root
      search(relativePath, fileClone)) {
        // and the file matches the function
        result.push(fileClone);
      }
    }
    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  {PizZip|Object|Array} this PizZip object (when adding a file),
   * a file (when searching by string) or an array of files (when searching by regex).
   */
  file: function file(name, data, o) {
    if (arguments.length === 1) {
      if (utils.isRegExp(name)) {
        var regexp = name;
        return this.filter(function (relativePath, file) {
          return !file.dir && regexp.test(relativePath);
        });
      }
      // text
      return this.filter(function (relativePath, file) {
        return !file.dir && relativePath === name;
      })[0] || null;
    }
    // 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  {PizZip} an object with the new directory as the root, or an array containing matching folders.
   */
  folder: function folder(arg) {
    if (!arg) {
      return this;
    }
    if (utils.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.shallowClone();
    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 {PizZip} this PizZip object
   */
  remove: function remove(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;
  },
  /**
   * Generate the complete zip file
   * @param {Object} options the options to generate the zip file :
   * - base64, (deprecated, use type instead) true to generate base64.
   * - compression, "STORE" by default.
   * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob.
   * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file
   */
  generate: function generate(options) {
    options = utils.extend(options || {}, {
      base64: true,
      compression: "STORE",
      compressionOptions: null,
      type: "base64",
      platform: "DOS",
      comment: null,
      mimeType: "application/zip",
      encodeFileName: utf8.utf8encode
    });
    utils.checkSupport(options.type);

    // accept nodejs `process.platform`
    if (options.platform === "darwin" || options.platform === "freebsd" || options.platform === "linux" || options.platform === "sunos") {
      options.platform = "UNIX";
    }
    if (options.platform === "win32") {
      options.platform = "DOS";
    }
    var zipData = [],
      encodedComment = utils.transformTo("string", options.encodeFileName(options.comment || this.comment || ""));
    var localDirLength = 0,
      centralDirLength = 0,
      writer,
      i;

    // first, generate all the zip parts.
    for (var name in this.files) {
      if (!this.files.hasOwnProperty(name)) {
        continue;
      }
      var file = this.files[name];
      var compressionName = file.options.compression || options.compression.toUpperCase();
      var compression = compressions[compressionName];
      if (!compression) {
        throw new Error(compressionName + " is not a valid compression method !");
      }
      var compressionOptions = file.options.compressionOptions || options.compressionOptions || {};
      var compressedObject = generateCompressedObjectFrom.call(this, file, compression, compressionOptions);
      var zipPart = generateZipParts.call(this, name, file, compressedObject, localDirLength, options.platform, options.encodeFileName);
      localDirLength += zipPart.fileRecord.length + compressedObject.compressedSize;
      centralDirLength += zipPart.dirRecord.length;
      zipData.push(zipPart);
    }
    var dirEnd = "";

    // 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(zipData.length, 2) +
    // total number of entries in the central directory
    decToHex(zipData.length, 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;

    // we have all the parts (and the total length)
    // time to create a writer !
    var typeName = options.type.toLowerCase();
    if (typeName === "uint8array" || typeName === "arraybuffer" || typeName === "blob" || typeName === "nodebuffer") {
      writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length);
    } else {
      writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length);
    }
    for (i = 0; i < zipData.length; i++) {
      writer.append(zipData[i].fileRecord);
      writer.append(zipData[i].compressedObject.compressedContent);
    }
    for (i = 0; i < zipData.length; i++) {
      writer.append(zipData[i].dirRecord);
    }
    writer.append(dirEnd);
    var zip = writer.finalize();
    switch (options.type.toLowerCase()) {
      // case "zip is an Uint8Array"
      case "uint8array":
      case "arraybuffer":
      case "nodebuffer":
        return utils.transformTo(options.type.toLowerCase(), zip);
      case "blob":
        return utils.arrayBuffer2Blob(utils.transformTo("arraybuffer", zip), options.mimeType);
      // case "zip is a string"
      case "base64":
        return options.base64 ? base64.encode(zip) : zip;
      default:
        // case "string" :
        return zip;
    }
  },
  /**
   * @deprecated
   * This method will be removed in a future version without replacement.
   */
  crc32: function crc32(input, crc) {
    return _crc(input, crc);
  },
  /**
   * @deprecated
   * This method will be removed in a future version without replacement.
   */
  utf8encode: function utf8encode(string) {
    return utils.transformTo("string", utf8.utf8encode(string));
  },
  /**
   * @deprecated
   * This method will be removed in a future version without replacement.
   */
  utf8decode: function utf8decode(input) {
    return utf8.utf8decode(input);
  }
};
/**
 * Transform this._data into a string.
 * @param {function} filter a function String -> String, applied if not null on the result.
 * @return {String} the string representing this._data.
 */
function dataToString(asUTF8) {
  var result = getRawData(this);
  if (result === null || typeof result === "undefined") {
    return "";
  }
  // if the data is a base64 string, we decode it before checking the encoding !
  if (this.options.base64) {
    result = base64.decode(result);
  }
  if (asUTF8 && this.options.binary) {
    // PizZip.prototype.utf8decode supports arrays as input
    // skip to array => string step, utf8decode will do it.
    result = out.utf8decode(result);
  } else {
    // no utf8 transformation, do the array => string step.
    result = utils.transformTo("string", result);
  }
  if (!asUTF8 && !this.options.binary) {
    result = utils.transformTo("string", out.utf8encode(result));
  }
  return result;
}
/**
 * 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
 */
function ZipObject(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.options = options;

  /*
   * This object contains initial values for dir and date.
   * With them, we can check if the user changed the deprecated metadata in
   * `ZipObject#options` or not.
   */
  this._initialMetadata = {
    dir: options.dir,
    date: options.date
  };
}
ZipObject.prototype = {
  /**
   * Return the content as UTF8 string.
   * @return {string} the UTF8 string.
   */
  asText: function asText() {
    return dataToString.call(this, true);
  },
  /**
   * Returns the binary content.
   * @return {string} the content as binary.
   */
  asBinary: function asBinary() {
    return dataToString.call(this, false);
  },
  /**
   * Returns the content as a nodejs Buffer.
   * @return {Buffer} the content as a Buffer.
   */
  asNodeBuffer: function asNodeBuffer() {
    var result = getBinaryData(this);
    return utils.transformTo("nodebuffer", result);
  },
  /**
   * Returns the content as an Uint8Array.
   * @return {Uint8Array} the content as an Uint8Array.
   */
  asUint8Array: function asUint8Array() {
    var result = getBinaryData(this);
    return utils.transformTo("uint8array", result);
  },
  /**
   * Returns the content as an ArrayBuffer.
   * @return {ArrayBuffer} the content as an ArrayBufer.
   */
  asArrayBuffer: function asArrayBuffer() {
    return this.asUint8Array().buffer;
  }
};

/**
 * 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.
 */
function decToHex(dec, bytes) {
  var hex = "",
    i;
  for (i = 0; i < bytes; i++) {
    hex += String.fromCharCode(dec & 0xff);
    dec >>>= 8;
  }
  return hex;
}

/**
 * Transforms the (incomplete) options from the user into the complete
 * set of options to create a file.
 * @private
 * @param {Object} o the options from the user.
 * @return {Object} the complete set of options.
 */
function prepareFileAttrs(o) {
  o = o || {};
  if (o.base64 === true && (o.binary === null || o.binary === undefined)) {
    o.binary = true;
  }
  o = utils.extend(o, defaults);
  o.date = o.date || new Date();
  if (o.compression !== null) {
    o.compression = o.compression.toUpperCase();
  }
  return o;
}

/**
 * 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} o the options of the file
 * @return {Object} the new file.
 */
function fileAdd(name, data, o) {
  // be sure sub folders exist
  var dataType = utils.getTypeOf(data),
    parent;
  o = prepareFileAttrs(o);
  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);
  }
  if (o.dir || data === null || typeof data === "undefined") {
    o.base64 = false;
    o.binary = false;
    data = null;
    dataType = null;
  } else if (dataType === "string") {
    if (o.binary && !o.base64) {
      // optimizedBinaryString == true means that the file has already been filtered with a 0xFF mask
      if (o.optimizedBinaryString !== true) {
        // this is a string, not in a base64 format.
        // Be sure that this is a correct "binary string"
        data = utils.string2binary(data);
      }
    }
  } else {
    // arraybuffer, uint8array, ...
    o.base64 = false;
    o.binary = true;
    if (!dataType && !(data instanceof CompressedObject)) {
      throw new Error("The data of '" + name + "' is in an unsupported format !");
    }

    // special case : it's way easier to work with Uint8Array than with ArrayBuffer
    if (dataType === "arraybuffer") {
      data = utils.transformTo("uint8array", data);
    }
  }
  var object = new ZipObject(name, data, o);
  this.files[name] = object;
  return object;
}

/**
 * Find the parent folder of the path.
 * @private
 * @param {string} path the path to use
 * @return {string} the parent folder, or ""
 */
function parentFolder(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.
 */
function forceTrailingSlash(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.
 */
function folderAdd(name, createFolders) {
  createFolders = typeof createFolders !== "undefined" ? createFolders : false;
  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];
}

/**
 * Generate a PizZip.CompressedObject for a given zipOject.
 * @param {ZipObject} file the object to read.
 * @param {PizZip.compression} compression the compression to use.
 * @param {Object} compressionOptions the options to use when compressing.
 * @return {PizZip.CompressedObject} the compressed result.
 */
function generateCompressedObjectFrom(file, compression, compressionOptions) {
  var result = new CompressedObject();
  var content;

  // the data has not been decompressed, we might reuse things !
  if (file._data instanceof CompressedObject) {
    result.uncompressedSize = file._data.uncompressedSize;
    result.crc32 = file._data.crc32;
    if (result.uncompressedSize === 0 || file.dir) {
      compression = compressions.STORE;
      result.compressedContent = "";
      result.crc32 = 0;
    } else if (file._data.compressionMethod === compression.magic) {
      result.compressedContent = file._data.getCompressedContent();
    } else {
      content = file._data.getContent();
      // need to decompress / recompress
      result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions);
    }
  } else {
    // have uncompressed data
    content = getBinaryData(file);
    if (!content || content.length === 0 || file.dir) {
      compression = compressions.STORE;
      content = "";
    }
    result.uncompressedSize = content.length;
    result.crc32 = _crc(content);
    result.compressedContent = compression.compress(utils.transformTo(compression.compressInputType, content), compressionOptions);
  }
  result.compressedSize = result.compressedContent.length;
  result.compressionMethod = compression.magic;
  return result;
}

/**
 * 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
 */
function generateUnixExternalFileAttr(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
 */
function generateDosExternalFileAttr(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 {string} name the file name.
 * @param {ZipObject} file the file content.
 * @param {PizZip.CompressedObject} compressedObject the compressed object.
 * @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.
 */
function generateZipParts(name, file, compressedObject, offset, platform, encodeFileName) {
  var 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,
    o = file.options;
  var dosTime,
    dosDate,
    extraFields = "",
    unicodePathExtraField = "",
    unicodeCommentExtraField = "",
    dir,
    date;

  // handle the deprecated options.dir
  if (file._initialMetadata.dir !== file.dir) {
    dir = file.dir;
  } else {
    dir = o.dir;
  }

  // handle the deprecated options.date
  if (file._initialMetadata.date !== file.date) {
    date = file.date;
  } else {
    date = o.date;
  }
  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.getHours();
  dosTime <<= 6;
  dosTime |= date.getMinutes();
  dosTime <<= 5;
  dosTime |= date.getSeconds() / 2;
  dosDate = date.getFullYear() - 1980;
  dosDate <<= 4;
  dosDate |= date.getMonth() + 1;
  dosDate <<= 5;
  dosDate |= date.getDate();
  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(_crc(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(this.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
  // set bit 11 if utf8
  header += !useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment) ? "\x00\x08" : "\x00\x00";
  // compression method
  header += compressedObject.compressionMethod;
  // last mod file time
  header += decToHex(dosTime, 2);
  // last mod file date
  header += decToHex(dosDate, 2);
  // crc-32
  header += decToHex(compressedObject.crc32, 4);
  // compressed size
  header += decToHex(compressedObject.compressedSize, 4);
  // uncompressed size
  header += decToHex(compressedObject.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
  "\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,
    compressedObject: compressedObject
  };
}
module.exports = out;
© 2025 GrazzMean-Shell